mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-19 14:09:03 +00:00
Add some clang-format off/on comments to keep kernel code readable. Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
723 lines
26 KiB
C++
723 lines
26 KiB
C++
//
|
|
// Copyright (c) 2017 The Khronos Group Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
//
|
|
#include "testBase.h"
|
|
#if defined(__APPLE__)
|
|
#include <OpenGL/glu.h>
|
|
#else
|
|
#include <GL/glu.h>
|
|
#endif
|
|
|
|
const char *get_kernel_suffix(cl_image_format *format)
|
|
{
|
|
switch (format->image_channel_data_type)
|
|
{
|
|
case CL_UNORM_INT8:
|
|
case CL_UNORM_INT16:
|
|
case CL_UNORM_INT24:
|
|
case CL_SNORM_INT8:
|
|
case CL_SNORM_INT16:
|
|
case CL_HALF_FLOAT:
|
|
case CL_FLOAT:
|
|
case CL_UNORM_INT_101010: return "f";
|
|
case CL_SIGNED_INT8:
|
|
case CL_SIGNED_INT16:
|
|
case CL_SIGNED_INT32: return "i";
|
|
case CL_UNSIGNED_INT8:
|
|
case CL_UNSIGNED_INT16:
|
|
case CL_UNSIGNED_INT32: return "ui";
|
|
default:
|
|
log_error("Test error: unsupported kernel suffix for "
|
|
"image_channel_data_type 0x%X\n",
|
|
format->image_channel_data_type);
|
|
return "";
|
|
}
|
|
}
|
|
|
|
ExplicitType get_read_kernel_type(cl_image_format *format)
|
|
{
|
|
switch (format->image_channel_data_type)
|
|
{
|
|
case CL_UNORM_INT8:
|
|
case CL_UNORM_INT16:
|
|
case CL_UNORM_INT24:
|
|
case CL_SNORM_INT8:
|
|
case CL_SNORM_INT16:
|
|
case CL_HALF_FLOAT:
|
|
case CL_FLOAT:
|
|
case CL_UNORM_INT_101010:
|
|
#ifdef GL_VERSION_3_2
|
|
case CL_DEPTH:
|
|
#endif
|
|
return kFloat;
|
|
case CL_SIGNED_INT8:
|
|
case CL_SIGNED_INT16:
|
|
case CL_SIGNED_INT32: return kInt;
|
|
case CL_UNSIGNED_INT8:
|
|
case CL_UNSIGNED_INT16:
|
|
case CL_UNSIGNED_INT32: return kUInt;
|
|
default:
|
|
log_error("Test error: unsupported kernel suffix for "
|
|
"image_channel_data_type 0x%X\n",
|
|
format->image_channel_data_type);
|
|
return kNumExplicitTypes;
|
|
}
|
|
}
|
|
|
|
ExplicitType get_write_kernel_type(cl_image_format *format)
|
|
{
|
|
switch (format->image_channel_data_type)
|
|
{
|
|
case CL_UNORM_INT8: return kFloat;
|
|
case CL_UNORM_INT16: return kFloat;
|
|
case CL_UNORM_INT24: return kFloat;
|
|
case CL_SNORM_INT8: return kFloat;
|
|
case CL_SNORM_INT16: return kFloat;
|
|
case CL_HALF_FLOAT: return kHalf;
|
|
case CL_FLOAT: return kFloat;
|
|
case CL_SIGNED_INT8: return kChar;
|
|
case CL_SIGNED_INT16: return kShort;
|
|
case CL_SIGNED_INT32: return kInt;
|
|
case CL_UNSIGNED_INT8: return kUChar;
|
|
case CL_UNSIGNED_INT16: return kUShort;
|
|
case CL_UNSIGNED_INT32: return kUInt;
|
|
case CL_UNORM_INT_101010: return kFloat;
|
|
#ifdef GL_VERSION_3_2
|
|
case CL_DEPTH: return kFloat;
|
|
#endif
|
|
default: return kInt;
|
|
}
|
|
}
|
|
|
|
const char *get_write_conversion(cl_image_format *format, ExplicitType type)
|
|
{
|
|
switch (format->image_channel_data_type)
|
|
{
|
|
case CL_UNORM_INT8:
|
|
case CL_UNORM_INT16:
|
|
case CL_SNORM_INT8:
|
|
case CL_SNORM_INT16:
|
|
case CL_HALF_FLOAT:
|
|
case CL_FLOAT:
|
|
case CL_UNORM_INT_101010:
|
|
case CL_UNORM_INT24:
|
|
if (type != kFloat) return "convert_float4";
|
|
break;
|
|
case CL_SIGNED_INT8:
|
|
case CL_SIGNED_INT16:
|
|
case CL_SIGNED_INT32:
|
|
if (type != kInt) return "convert_int4";
|
|
break;
|
|
case CL_UNSIGNED_INT8:
|
|
case CL_UNSIGNED_INT16:
|
|
case CL_UNSIGNED_INT32:
|
|
if (type != kUInt) return "convert_uint4";
|
|
break;
|
|
default: return "";
|
|
}
|
|
return "";
|
|
}
|
|
|
|
// The only three input types to this function are kInt, kUInt and kFloat, due
|
|
// to the way we set up our tests The output types, though, are pretty much
|
|
// anything valid for GL to receive
|
|
|
|
#define DOWNSCALE_INTEGER_CASE(enum, type, bitShift) \
|
|
case enum: { \
|
|
cl_##type *dst = new cl_##type[numPixels * 4]; \
|
|
for (size_t i = 0; i < numPixels * 4; i++) dst[i] = src[i]; \
|
|
return (char *)dst; \
|
|
}
|
|
|
|
#define UPSCALE_FLOAT_CASE(enum, type, typeMax) \
|
|
case enum: { \
|
|
cl_##type *dst = new cl_##type[numPixels * 4]; \
|
|
for (size_t i = 0; i < numPixels * 4; i++) \
|
|
dst[i] = (cl_##type)(src[i] * typeMax); \
|
|
return (char *)dst; \
|
|
}
|
|
|
|
char *convert_to_expected(void *inputBuffer, size_t numPixels,
|
|
ExplicitType inType, ExplicitType outType,
|
|
size_t channelNum, GLenum glDataType)
|
|
{
|
|
#ifdef DEBUG
|
|
log_info("- Converting from input type '%s' to output type '%s'\n",
|
|
get_explicit_type_name(inType), get_explicit_type_name(outType));
|
|
#endif
|
|
|
|
if (inType == outType)
|
|
{
|
|
char *outData =
|
|
new char[numPixels * channelNum
|
|
* get_explicit_type_size(outType)]; // sizeof( cl_int ) ];
|
|
if (glDataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV)
|
|
{
|
|
for (size_t i = 0; i < numPixels; ++i)
|
|
{
|
|
((cl_float *)outData)[i] = ((cl_float *)inputBuffer)[2 * i];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
memcpy(outData, inputBuffer,
|
|
numPixels * channelNum * get_explicit_type_size(inType));
|
|
}
|
|
return outData;
|
|
}
|
|
else if (inType == kChar)
|
|
{
|
|
cl_char *src = (cl_char *)inputBuffer;
|
|
|
|
switch (outType)
|
|
{
|
|
case kInt: {
|
|
cl_int *outData = new cl_int[numPixels * channelNum];
|
|
for (size_t i = 0; i < numPixels * channelNum; i++)
|
|
{
|
|
outData[i] = (cl_int)((src[i]));
|
|
}
|
|
return (char *)outData;
|
|
}
|
|
case kFloat: {
|
|
// If we're converting to float, then CL decided that we should
|
|
// be normalized
|
|
cl_float *outData = new cl_float[numPixels * channelNum];
|
|
for (size_t i = 0; i < numPixels * channelNum; i++)
|
|
{
|
|
outData[i] = (cl_float)src[i] / 127.0f;
|
|
}
|
|
return (char *)outData;
|
|
}
|
|
default:
|
|
log_error("ERROR: Unsupported conversion from %s to %s!\n",
|
|
get_explicit_type_name(inType),
|
|
get_explicit_type_name(outType));
|
|
return NULL;
|
|
}
|
|
}
|
|
else if (inType == kUChar)
|
|
{
|
|
cl_uchar *src = (cl_uchar *)inputBuffer;
|
|
|
|
switch (outType)
|
|
{
|
|
case kUInt: {
|
|
cl_uint *outData = new cl_uint[numPixels * channelNum];
|
|
for (size_t i = 0; i < numPixels * channelNum; i++)
|
|
{
|
|
outData[i] = (cl_uint)((src[i]));
|
|
}
|
|
return (char *)outData;
|
|
}
|
|
case kFloat: {
|
|
// If we're converting to float, then CL decided that we should
|
|
// be normalized
|
|
cl_float *outData = new cl_float[numPixels * channelNum];
|
|
for (size_t i = 0; i < numPixels * channelNum; i++)
|
|
{
|
|
outData[i] = (cl_float)(src[i]) / 256.0f;
|
|
}
|
|
return (char *)outData;
|
|
}
|
|
default:
|
|
log_error("ERROR: Unsupported conversion from %s to %s!\n",
|
|
get_explicit_type_name(inType),
|
|
get_explicit_type_name(outType));
|
|
return NULL;
|
|
}
|
|
}
|
|
else if (inType == kShort)
|
|
{
|
|
cl_short *src = (cl_short *)inputBuffer;
|
|
|
|
switch (outType)
|
|
{
|
|
case kInt: {
|
|
cl_int *outData = new cl_int[numPixels * channelNum];
|
|
for (size_t i = 0; i < numPixels * channelNum; i++)
|
|
{
|
|
outData[i] = (cl_int)((src[i]));
|
|
}
|
|
return (char *)outData;
|
|
}
|
|
case kFloat: {
|
|
// If we're converting to float, then CL decided that we should
|
|
// be normalized
|
|
cl_float *outData = new cl_float[numPixels * channelNum];
|
|
for (size_t i = 0; i < numPixels * channelNum; i++)
|
|
{
|
|
outData[i] = (cl_float)src[i] / 32768.0f;
|
|
}
|
|
return (char *)outData;
|
|
}
|
|
default:
|
|
log_error("ERROR: Unsupported conversion from %s to %s!\n",
|
|
get_explicit_type_name(inType),
|
|
get_explicit_type_name(outType));
|
|
return NULL;
|
|
}
|
|
}
|
|
else if (inType == kUShort)
|
|
{
|
|
cl_ushort *src = (cl_ushort *)inputBuffer;
|
|
|
|
switch (outType)
|
|
{
|
|
case kUInt: {
|
|
cl_uint *outData = new cl_uint[numPixels * channelNum];
|
|
for (size_t i = 0; i < numPixels * channelNum; i++)
|
|
{
|
|
outData[i] = (cl_uint)((src[i]));
|
|
}
|
|
return (char *)outData;
|
|
}
|
|
case kFloat: {
|
|
// If we're converting to float, then CL decided that we should
|
|
// be normalized
|
|
cl_float *outData = new cl_float[numPixels * channelNum];
|
|
for (size_t i = 0; i < numPixels * channelNum; i++)
|
|
{
|
|
outData[i] = (cl_float)(src[i]) / 65535.0f;
|
|
}
|
|
return (char *)outData;
|
|
}
|
|
default:
|
|
log_error("ERROR: Unsupported conversion from %s to %s!\n",
|
|
get_explicit_type_name(inType),
|
|
get_explicit_type_name(outType));
|
|
return NULL;
|
|
}
|
|
}
|
|
else if (inType == kInt)
|
|
{
|
|
cl_int *src = (cl_int *)inputBuffer;
|
|
|
|
switch (outType)
|
|
{
|
|
DOWNSCALE_INTEGER_CASE(kShort, short, 16)
|
|
DOWNSCALE_INTEGER_CASE(kChar, char, 24)
|
|
case kFloat: {
|
|
// If we're converting to float, then CL decided that we should
|
|
// be normalized
|
|
cl_float *outData = new cl_float[numPixels * channelNum];
|
|
for (size_t i = 0; i < numPixels * channelNum; i++)
|
|
{
|
|
outData[i] =
|
|
(cl_float)fmaxf((float)src[i] / 2147483647.f, -1.f);
|
|
}
|
|
return (char *)outData;
|
|
}
|
|
default:
|
|
log_error("ERROR: Unsupported conversion from %s to %s!\n",
|
|
get_explicit_type_name(inType),
|
|
get_explicit_type_name(outType));
|
|
return NULL;
|
|
}
|
|
}
|
|
else if (inType == kUInt)
|
|
{
|
|
cl_uint *src = (cl_uint *)inputBuffer;
|
|
|
|
switch (outType)
|
|
{
|
|
DOWNSCALE_INTEGER_CASE(kUShort, ushort, 16)
|
|
DOWNSCALE_INTEGER_CASE(kUChar, uchar, 24)
|
|
case kFloat: {
|
|
// If we're converting to float, then CL decided that we should
|
|
// be normalized
|
|
cl_float *outData = new cl_float[numPixels * channelNum];
|
|
const cl_float MaxValue = (glDataType == GL_UNSIGNED_INT_24_8)
|
|
? 16777215.f
|
|
: 4294967295.f;
|
|
const cl_uint ShiftBits =
|
|
(glDataType == GL_UNSIGNED_INT_24_8) ? 8 : 0;
|
|
for (size_t i = 0; i < numPixels * channelNum; i++)
|
|
{
|
|
outData[i] = (cl_float)(src[i] >> ShiftBits) / MaxValue;
|
|
}
|
|
return (char *)outData;
|
|
}
|
|
default:
|
|
log_error("ERROR: Unsupported conversion from %s to %s!\n",
|
|
get_explicit_type_name(inType),
|
|
get_explicit_type_name(outType));
|
|
return NULL;
|
|
}
|
|
}
|
|
else if (inType == kHalf)
|
|
{
|
|
cl_half *src = (cl_half *)inputBuffer;
|
|
|
|
switch (outType)
|
|
{
|
|
case kFloat: {
|
|
cl_float *outData = new cl_float[numPixels * channelNum];
|
|
for (size_t i = 0; i < numPixels * channelNum; i++)
|
|
{
|
|
outData[i] = cl_half_to_float(src[i]);
|
|
}
|
|
return (char *)outData;
|
|
}
|
|
default:
|
|
log_error("ERROR: Unsupported conversion from %s to %s!\n",
|
|
get_explicit_type_name(inType),
|
|
get_explicit_type_name(outType));
|
|
return NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
cl_float *src = (cl_float *)inputBuffer;
|
|
|
|
switch (outType)
|
|
{
|
|
UPSCALE_FLOAT_CASE(kChar, char, 127.f)
|
|
UPSCALE_FLOAT_CASE(kUChar, uchar, 255.f)
|
|
UPSCALE_FLOAT_CASE(kShort, short, 32767.f)
|
|
UPSCALE_FLOAT_CASE(kUShort, ushort, 65535.f)
|
|
UPSCALE_FLOAT_CASE(kInt, int, 2147483647.f)
|
|
UPSCALE_FLOAT_CASE(kUInt, uint, 4294967295.f)
|
|
default:
|
|
log_error("ERROR: Unsupported conversion from %s to %s!\n",
|
|
get_explicit_type_name(inType),
|
|
get_explicit_type_name(outType));
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
int validate_integer_results(void *expectedResults, void *actualResults,
|
|
size_t width, size_t height, size_t sampleNum,
|
|
size_t typeSize)
|
|
{
|
|
return validate_integer_results(expectedResults, actualResults, width,
|
|
height, sampleNum, 0, typeSize);
|
|
}
|
|
|
|
int validate_integer_results(void *expectedResults, void *actualResults,
|
|
size_t width, size_t height, size_t depth,
|
|
size_t sampleNum, size_t typeSize)
|
|
{
|
|
char *expected = (char *)expectedResults;
|
|
char *actual = (char *)actualResults;
|
|
for (size_t s = 0; s < sampleNum; s++)
|
|
{
|
|
for (size_t z = 0; z < ((depth == 0) ? 1 : depth); z++)
|
|
{
|
|
for (size_t y = 0; y < height; y++)
|
|
{
|
|
for (size_t x = 0; x < width; x++)
|
|
{
|
|
if (memcmp(expected, actual, typeSize * 4) != 0)
|
|
{
|
|
char scratch[1024];
|
|
|
|
if (depth == 0)
|
|
log_error("ERROR: Data sample %d,%d,%d did not "
|
|
"validate!\n",
|
|
(int)x, (int)y, (int)s);
|
|
else
|
|
log_error("ERROR: Data sample %d,%d,%d,%d did not "
|
|
"validate!\n",
|
|
(int)x, (int)y, (int)z, (int)s);
|
|
log_error("\tExpected: %s\n",
|
|
GetDataVectorString(expected, typeSize, 4,
|
|
scratch));
|
|
log_error(
|
|
"\t Actual: %s\n",
|
|
GetDataVectorString(actual, typeSize, 4, scratch));
|
|
return -1;
|
|
}
|
|
expected += typeSize * 4;
|
|
actual += typeSize * 4;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int validate_float_results(void *expectedResults, void *actualResults,
|
|
size_t width, size_t height, size_t sampleNum,
|
|
size_t channelNum)
|
|
{
|
|
return validate_float_results(expectedResults, actualResults, width, height,
|
|
sampleNum, 0, channelNum);
|
|
}
|
|
|
|
int validate_float_results(void *expectedResults, void *actualResults,
|
|
size_t width, size_t height, size_t depth,
|
|
size_t sampleNum, size_t channelNum)
|
|
{
|
|
cl_float *expected = (cl_float *)expectedResults;
|
|
cl_float *actual = (cl_float *)actualResults;
|
|
for (size_t s = 0; s < sampleNum; s++)
|
|
{
|
|
for (size_t z = 0; z < ((depth == 0) ? 1 : depth); z++)
|
|
{
|
|
for (size_t y = 0; y < height; y++)
|
|
{
|
|
for (size_t x = 0; x < width; x++)
|
|
{
|
|
float err = 0.f;
|
|
for (size_t i = 0; i < channelNum; i++)
|
|
{
|
|
float error = fabsf(expected[i] - actual[i]);
|
|
if (error > err) err = error;
|
|
}
|
|
|
|
if (err > 1.f / 127.f) // Max expected range of error if we
|
|
// converted from an 8-bit integer to
|
|
// a normalized float
|
|
{
|
|
if (depth == 0)
|
|
log_error("ERROR: Data sample %d,%d,%d did not "
|
|
"validate!\n",
|
|
(int)x, (int)y, (int)s);
|
|
else
|
|
log_error("ERROR: Data sample %d,%d,%d,%d did not "
|
|
"validate!\n",
|
|
(int)x, (int)y, (int)z, (int)s);
|
|
|
|
if (channelNum == 4)
|
|
{
|
|
log_error("\tExpected: %f %f %f %f\n", expected[0],
|
|
expected[1], expected[2], expected[3]);
|
|
log_error("\t : %a %a %a %a\n", expected[0],
|
|
expected[1], expected[2], expected[3]);
|
|
log_error("\t Actual: %f %f %f %f\n", actual[0],
|
|
actual[1], actual[2], actual[3]);
|
|
log_error("\t : %a %a %a %a\n", actual[0],
|
|
actual[1], actual[2], actual[3]);
|
|
}
|
|
else if (channelNum == 1)
|
|
{
|
|
log_error("\tExpected: %f\n", expected[0]);
|
|
log_error("\t : %a\n", expected[0]);
|
|
log_error("\t Actual: %f\n", actual[0]);
|
|
log_error("\t : %a\n", actual[0]);
|
|
}
|
|
return -1;
|
|
}
|
|
expected += channelNum;
|
|
actual += channelNum;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int validate_float_results_rgb_101010(void *expectedResults,
|
|
void *actualResults, size_t width,
|
|
size_t height, size_t sampleNum)
|
|
{
|
|
return validate_float_results_rgb_101010(expectedResults, actualResults,
|
|
width, height, sampleNum, 0);
|
|
}
|
|
|
|
int validate_float_results_rgb_101010(void *expectedResults,
|
|
void *actualResults, size_t width,
|
|
size_t height, size_t depth,
|
|
size_t sampleNum)
|
|
{
|
|
cl_float *expected = (cl_float *)expectedResults;
|
|
cl_float *actual = (cl_float *)actualResults;
|
|
for (size_t s = 0; s < sampleNum; s++)
|
|
{
|
|
for (size_t z = 0; z < ((depth == 0) ? 1 : depth); z++)
|
|
{
|
|
for (size_t y = 0; y < height; y++)
|
|
{
|
|
for (size_t x = 0; x < width; x++)
|
|
{
|
|
float err = 0.f;
|
|
for (size_t i = 0; i < 3; i++) // skip the fourth channel
|
|
{
|
|
float error = fabsf(expected[i] - actual[i]);
|
|
if (error > err) err = error;
|
|
}
|
|
|
|
if (err > 1.f / 127.f) // Max expected range of error if we
|
|
// converted from an 8-bit integer to
|
|
// a normalized float
|
|
{
|
|
if (depth == 0)
|
|
log_error("ERROR: Data sample %d,%d,%d did not "
|
|
"validate!\n",
|
|
(int)x, (int)y, (int)s);
|
|
else
|
|
log_error("ERROR: Data sample %d,%d,%d,%d did not "
|
|
"validate!\n",
|
|
(int)x, (int)y, (int)z, (int)s);
|
|
log_error("\tExpected: %f %f %f\n", expected[0],
|
|
expected[1], expected[2]);
|
|
log_error("\t : %a %a %a\n", expected[0],
|
|
expected[1], expected[2]);
|
|
log_error("\t Actual: %f %f %f\n", actual[0],
|
|
actual[1], actual[2]);
|
|
log_error("\t : %a %a %a\n", actual[0],
|
|
actual[1], actual[2]);
|
|
return -1;
|
|
}
|
|
expected += 4;
|
|
actual += 4;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int CheckGLObjectInfo(cl_mem mem, cl_gl_object_type expected_cl_gl_type,
|
|
GLuint expected_gl_name,
|
|
GLenum expected_cl_gl_texture_target,
|
|
GLint expected_cl_gl_mipmap_level)
|
|
{
|
|
cl_gl_object_type object_type;
|
|
GLuint object_name;
|
|
GLenum texture_target;
|
|
GLint mipmap_level;
|
|
int error;
|
|
|
|
error = (*clGetGLObjectInfo_ptr)(mem, &object_type, &object_name);
|
|
test_error(error, "clGetGLObjectInfo failed");
|
|
if (object_type != expected_cl_gl_type)
|
|
{
|
|
log_error("clGetGLObjectInfo did not return expected object type: "
|
|
"expected %d, got %d.\n",
|
|
expected_cl_gl_type, object_type);
|
|
return -1;
|
|
}
|
|
if (object_name != expected_gl_name)
|
|
{
|
|
log_error("clGetGLObjectInfo did not return expected object name: "
|
|
"expected %d, got %d.\n",
|
|
expected_gl_name, object_name);
|
|
return -1;
|
|
}
|
|
|
|
// If we're dealing with a buffer or render buffer, we are done.
|
|
|
|
if (object_type == CL_GL_OBJECT_BUFFER
|
|
|| object_type == CL_GL_OBJECT_RENDERBUFFER)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
// Otherwise, it's a texture-based object and requires a bit more checking.
|
|
|
|
error = (*clGetGLTextureInfo_ptr)(mem, CL_GL_TEXTURE_TARGET,
|
|
sizeof(texture_target), &texture_target,
|
|
NULL);
|
|
test_error(error, "clGetGLTextureInfo for CL_GL_TEXTURE_TARGET failed");
|
|
|
|
if (texture_target != expected_cl_gl_texture_target)
|
|
{
|
|
log_error("clGetGLTextureInfo did not return expected texture target: "
|
|
"expected %d, got %d.\n",
|
|
expected_cl_gl_texture_target, texture_target);
|
|
return -1;
|
|
}
|
|
|
|
error = (*clGetGLTextureInfo_ptr)(
|
|
mem, CL_GL_MIPMAP_LEVEL, sizeof(mipmap_level), &mipmap_level, NULL);
|
|
test_error(error, "clGetGLTextureInfo for CL_GL_MIPMAP_LEVEL failed");
|
|
|
|
if (mipmap_level != expected_cl_gl_mipmap_level)
|
|
{
|
|
log_error("clGetGLTextureInfo did not return expected mipmap level: "
|
|
"expected %d, got %d.\n",
|
|
expected_cl_gl_mipmap_level, mipmap_level);
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
bool CheckGLIntegerExtensionSupport()
|
|
{
|
|
// Get the OpenGL version and supported extensions
|
|
const GLubyte *glVersion = glGetString(GL_VERSION);
|
|
const GLubyte *glExtensionList = glGetString(GL_EXTENSIONS);
|
|
|
|
// Check if the OpenGL vrsion is 3.0 or grater or GL_EXT_texture_integer is
|
|
// supported
|
|
return (
|
|
((glVersion[0] - '0') >= 3)
|
|
|| (strstr((const char *)glExtensionList, "GL_EXT_texture_integer")));
|
|
}
|
|
|
|
int is_rgb_101010_supported(cl_context context, GLenum gl_target)
|
|
{
|
|
cl_image_format formatList[128];
|
|
cl_uint formatCount = 0;
|
|
unsigned int i;
|
|
int error;
|
|
|
|
cl_mem_object_type image_type;
|
|
|
|
switch (get_base_gl_target(gl_target))
|
|
{
|
|
case GL_TEXTURE_1D: image_type = CL_MEM_OBJECT_IMAGE1D;
|
|
case GL_TEXTURE_BUFFER:
|
|
image_type = CL_MEM_OBJECT_IMAGE1D_BUFFER;
|
|
break;
|
|
case GL_TEXTURE_RECTANGLE_EXT:
|
|
case GL_TEXTURE_2D:
|
|
case GL_COLOR_ATTACHMENT0:
|
|
case GL_RENDERBUFFER:
|
|
case GL_TEXTURE_CUBE_MAP:
|
|
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
|
|
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
|
|
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
|
|
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
|
|
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
|
|
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
|
|
image_type = CL_MEM_OBJECT_IMAGE2D;
|
|
break;
|
|
case GL_TEXTURE_3D: image_type = CL_MEM_OBJECT_IMAGE3D;
|
|
case GL_TEXTURE_1D_ARRAY: image_type = CL_MEM_OBJECT_IMAGE1D_ARRAY;
|
|
case GL_TEXTURE_2D_ARRAY:
|
|
image_type = CL_MEM_OBJECT_IMAGE2D_ARRAY;
|
|
break;
|
|
default: image_type = CL_MEM_OBJECT_IMAGE2D;
|
|
}
|
|
|
|
if ((error =
|
|
clGetSupportedImageFormats(context, CL_MEM_READ_WRITE, image_type,
|
|
128, formatList, &formatCount)))
|
|
{
|
|
return error;
|
|
}
|
|
|
|
// Check if the RGB 101010 format is supported
|
|
for (i = 0; i < formatCount; i++)
|
|
{
|
|
if (formatList[i].image_channel_data_type == CL_UNORM_INT_101010)
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|