diff --git a/test_common/harness/errorHelpers.cpp b/test_common/harness/errorHelpers.cpp index eaccf64119..d8f3d5d4ba 100644 --- a/test_common/harness/errorHelpers.cpp +++ b/test_common/harness/errorHelpers.cpp @@ -202,6 +202,8 @@ const char *GetChannelTypeName(cl_channel_type type) case CL_SFIXED14_APPLE: return "CL_SFIXED14_APPLE"; #endif case CL_UNORM_INT24: return "CL_UNORM_INT24"; + case CL_UNSIGNED_INT_RAW10_EXT: return "CL_UNSIGNED_INT_RAW10_EXT"; + case CL_UNSIGNED_INT_RAW12_EXT: return "CL_UNSIGNED_INT_RAW12_EXT"; default: return NULL; } } diff --git a/test_common/harness/imageHelpers.cpp b/test_common/harness/imageHelpers.cpp index 52a642383d..2211924d20 100644 --- a/test_common/harness/imageHelpers.cpp +++ b/test_common/harness/imageHelpers.cpp @@ -288,6 +288,9 @@ uint32_t get_pixel_size(const cl_image_format *format) return get_format_channel_count(format) * sizeof(cl_float); case CL_UNORM_INT_101010_2: return 4; + case CL_UNSIGNED_INT_RAW10_EXT: + case CL_UNSIGNED_INT_RAW12_EXT: return 2; + default: return 0; } } diff --git a/test_common/harness/imageHelpers.h b/test_common/harness/imageHelpers.h index 455f0edb4b..d49f358e78 100644 --- a/test_common/harness/imageHelpers.h +++ b/test_common/harness/imageHelpers.h @@ -191,6 +191,42 @@ cl_uint compute_max_mip_levels(size_t width, size_t height, size_t depth); cl_ulong compute_mipmapped_image_size(image_descriptor imageInfo); size_t compute_mip_level_offset(image_descriptor *imageInfo, size_t lod); +constexpr size_t RAW10_EXT_CLUMP_SIZE = 5; +constexpr size_t RAW10_EXT_CLUMP_NUM_PIXELS = 4; +constexpr size_t RAW12_EXT_CLUMP_SIZE = 3; +constexpr size_t RAW12_EXT_CLUMP_NUM_PIXELS = 2; + +inline bool is_width_compatible(image_descriptor imageInfo) +{ + if (imageInfo.format->image_channel_data_type == CL_UNSIGNED_INT_RAW10_EXT + && (imageInfo.width % RAW10_EXT_CLUMP_NUM_PIXELS) != 0) + { + return false; + } + if (imageInfo.format->image_channel_data_type == CL_UNSIGNED_INT_RAW12_EXT + && (imageInfo.width % RAW12_EXT_CLUMP_NUM_PIXELS) != 0) + { + return false; + } + return true; +} + +inline size_t calculate_row_pitch(image_descriptor imageInfo, size_t pixelSize) +{ + if (imageInfo.format->image_channel_data_type == CL_UNSIGNED_INT_RAW10_EXT) + { + return (imageInfo.width * RAW10_EXT_CLUMP_SIZE) + / RAW10_EXT_CLUMP_NUM_PIXELS; + } + if (imageInfo.format->image_channel_data_type == CL_UNSIGNED_INT_RAW12_EXT) + { + return (imageInfo.width * RAW12_EXT_CLUMP_SIZE) + / RAW12_EXT_CLUMP_NUM_PIXELS; + } + + return imageInfo.width * pixelSize; +} + template void read_image_pixel(void *imageData, image_descriptor *imageInfo, int x, int y, int z, T *outData, int lod) @@ -255,10 +291,24 @@ void read_image_pixel(void *imageData, image_descriptor *imageInfo, int x, // Advance to the right spot char *ptr = (char *)imageData; - size_t pixelSize = get_pixel_size(format); - - ptr += z * slice_pitch_lod + y * row_pitch_lod + x * pixelSize; - + switch (format->image_channel_data_type) + { + case CL_UNSIGNED_INT_RAW10_EXT: { + ptr += z * slice_pitch_lod + y * row_pitch_lod + + (x / RAW10_EXT_CLUMP_NUM_PIXELS) * RAW10_EXT_CLUMP_SIZE; + break; + } + case CL_UNSIGNED_INT_RAW12_EXT: { + ptr += z * slice_pitch_lod + y * row_pitch_lod + + (x / RAW12_EXT_CLUMP_NUM_PIXELS) * RAW12_EXT_CLUMP_SIZE; + break; + } + default: { + size_t pixelSize = get_pixel_size(format); + ptr += z * slice_pitch_lod + y * row_pitch_lod + x * pixelSize; + break; + } + } // OpenCL only supports reading floats from certain formats switch (format->image_channel_data_type) { @@ -377,6 +427,26 @@ void read_image_pixel(void *imageData, image_descriptor *imageInfo, int x, break; } #endif + case CL_UNSIGNED_INT_RAW10_EXT: { + cl_uchar *dPtr = (cl_uchar *)ptr; + i = x % RAW10_EXT_CLUMP_NUM_PIXELS; + uint8_t bit_index = i << 1; + uint16_t hi_val = dPtr[i] << 2; + uint16_t lo_val = (dPtr[4] & (0x3 << bit_index)) >> bit_index; + + tempData[0] = (T)(hi_val | lo_val); + break; + } + case CL_UNSIGNED_INT_RAW12_EXT: { + cl_uchar *dPtr = (cl_uchar *)ptr; + i = x % RAW12_EXT_CLUMP_NUM_PIXELS; + uint8_t bit_index = i << 2; + uint16_t hi_val = dPtr[i] << 4; + uint16_t lo_val = (dPtr[2] & (0xF << bit_index)) >> bit_index; + + tempData[0] = (T)(hi_val | lo_val); + break; + } } diff --git a/test_conformance/images/kernel_read_write/CMakeLists.txt b/test_conformance/images/kernel_read_write/CMakeLists.txt index d7e7eded46..9b83f79abe 100644 --- a/test_conformance/images/kernel_read_write/CMakeLists.txt +++ b/test_conformance/images/kernel_read_write/CMakeLists.txt @@ -16,6 +16,7 @@ set(${MODULE_NAME}_SOURCES test_write_3D.cpp test_cl_ext_image_requirements_info.cpp test_cl_ext_image_from_buffer.cpp + test_cl_ext_image_raw10_raw12.cpp ../common.cpp ) diff --git a/test_conformance/images/kernel_read_write/main.cpp b/test_conformance/images/kernel_read_write/main.cpp index debbdf18a4..8c4f555767 100644 --- a/test_conformance/images/kernel_read_write/main.cpp +++ b/test_conformance/images/kernel_read_write/main.cpp @@ -89,6 +89,8 @@ extern int image_from_buffer_fill_positive(cl_device_id device, extern int image_from_buffer_read_positive(cl_device_id device, cl_context context, cl_command_queue queue); +extern int ext_image_raw10_raw12(cl_device_id device, cl_context context, + cl_command_queue queue); /** read_write images only support sampler-less read buildt-ins which require special settings * for some global parameters. This pair of functions temporarily overwrite those global parameters @@ -367,6 +369,12 @@ int test_image_from_buffer_read_positive(cl_device_id device, return image_from_buffer_read_positive(device, context, queue); } +int test_cl_ext_image_raw10_raw12(cl_device_id device, cl_context context, + cl_command_queue queue, int num_elements) +{ + return ext_image_raw10_raw12(device, context, queue); +} + test_definition test_list[] = { ADD_TEST(1D), ADD_TEST(2D), @@ -385,6 +393,7 @@ test_definition test_list[] = { ADD_TEST_VERSION(image_from_small_buffer_negative, Version(3, 0)), ADD_TEST_VERSION(image_from_buffer_fill_positive, Version(3, 0)), ADD_TEST_VERSION(image_from_buffer_read_positive, Version(3, 0)), + ADD_TEST_VERSION(cl_ext_image_raw10_raw12, Version(1, 2)), }; const int test_num = ARRAY_SIZE( test_list ); diff --git a/test_conformance/images/kernel_read_write/test_cl_ext_image_raw10_raw12.cpp b/test_conformance/images/kernel_read_write/test_cl_ext_image_raw10_raw12.cpp new file mode 100644 index 0000000000..c506528e6d --- /dev/null +++ b/test_conformance/images/kernel_read_write/test_cl_ext_image_raw10_raw12.cpp @@ -0,0 +1,78 @@ +// +// Copyright (c) 2023 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" +#include "../common.h" +#include "test_cl_ext_image_buffer.hpp" + +extern int gTypesToTest; +extern int gtestTypesToRun; +extern bool gTestImage2DFromBuffer; +extern cl_mem_flags gMemFlagsToUse; + +static int test_image_set(cl_device_id device, cl_context context, + cl_command_queue queue, cl_mem_object_type imageType) +{ + int ret = 0; + + // Grab the list of supported image formats for integer reads + std::vector formatList = { + { CL_R, CL_UNSIGNED_INT_RAW10_EXT }, { CL_R, CL_UNSIGNED_INT_RAW12_EXT } + }; + + // First time through, we'll go ahead and print the formats supported, + // regardless of type + log_info("---- Supported %s %s formats for this device for " + "cl_ext_image_raw10_raw12---- \n", + convert_image_type_to_string(imageType), "read"); + log_info(" %-7s %-24s %d\n", "CL_R", "CL_UNSIGNED_INT_RAW10_EXT", 0); + log_info(" %-7s %-24s %d\n", "CL_R", "CL_UNSIGNED_INT_RAW12_EXT", 0); + log_info("------------------------------------------- \n"); + + image_sampler_data imageSampler; + ImageTestTypes test{ kTestUInt, kUInt, uintFormats, "uint" }; + if (gTypesToTest & test.type) + { + std::vector filterFlags(formatList.size(), false); + imageSampler.filter_mode = CL_FILTER_NEAREST; + ret = test_read_image_formats(device, context, queue, formatList, + filterFlags, &imageSampler, + test.explicitType, imageType); + } + return ret; +} + +int ext_image_raw10_raw12(cl_device_id device, cl_context context, + cl_command_queue queue) +{ + int ret = 0; + + if (0 == is_extension_available(device, "cl_ext_image_raw10_raw12")) + { + log_info("-----------------------------------------------------\n"); + log_info("This device does not support " + "cl_ext_image_raw10_raw12.\n"); + log_info("Skipping cl_ext_image_raw10_raw12 " + "image test.\n"); + log_info("-----------------------------------------------------\n\n"); + return 0; + } + gtestTypesToRun = kReadTests; + + ret += test_image_set(device, context, queue, CL_MEM_OBJECT_IMAGE2D); + + return ret; +} diff --git a/test_conformance/images/kernel_read_write/test_iterations.cpp b/test_conformance/images/kernel_read_write/test_iterations.cpp index de7ed0fd29..96f8933363 100644 --- a/test_conformance/images/kernel_read_write/test_iterations.cpp +++ b/test_conformance/images/kernel_read_write/test_iterations.cpp @@ -1663,7 +1663,9 @@ int test_read_image_set_2D(cl_device_id device, cl_context context, { for( imageInfo.width = 1; imageInfo.width < 13; imageInfo.width++ ) { - imageInfo.rowPitch = imageInfo.width * pixelSize; + if (!is_width_compatible(imageInfo)) continue; + imageInfo.rowPitch = calculate_row_pitch(imageInfo, pixelSize); + for( imageInfo.height = 1; imageInfo.height < 9; imageInfo.height++ ) { if( gTestMipmaps ) @@ -1688,10 +1690,28 @@ int test_read_image_set_2D(cl_device_id device, cl_context context, for( size_t idx = 0; idx < numbeOfSizes; idx++ ) { - imageInfo.width = sizes[ idx ][ 0 ]; - imageInfo.height = sizes[ idx ][ 1 ]; - imageInfo.rowPitch = imageInfo.width * pixelSize; - log_info("Testing %d x %d\n", (int)sizes[ idx ][ 0 ], (int)sizes[ idx ][ 1 ]); + if (imageInfo.format->image_channel_data_type + == CL_UNSIGNED_INT_RAW10_EXT) + { + imageInfo.width = sizes[idx][0] & ~0x3ULL; + } + else if (imageInfo.format->image_channel_data_type + == CL_UNSIGNED_INT_RAW12_EXT) + { + imageInfo.width = sizes[idx][0] & ~0x1ULL; + } + else + { + imageInfo.width = sizes[idx][0]; + } + + imageInfo.height = sizes[idx][1]; + imageInfo.rowPitch = calculate_row_pitch(imageInfo, pixelSize); + + if (0 == imageInfo.width) continue; + + log_info("Testing %d x %d\n", (int)imageInfo.width, + (int)imageInfo.height); if( gTestMipmaps ) imageInfo.num_mip_levels = (size_t) random_in_range(2, compute_max_mip_levels(imageInfo.width, imageInfo.height, 0)-1, seed); @@ -1759,7 +1779,8 @@ int test_read_image_set_2D(cl_device_id device, cl_context context, imageInfo.width = (size_t)random_log_in_range( 16, maxWidthRange, seed ); imageInfo.height = (size_t)random_log_in_range( 16, maxHeightRange, seed ); - imageInfo.rowPitch = imageInfo.width * pixelSize; + imageInfo.rowPitch = calculate_row_pitch(imageInfo, pixelSize); + if( gTestMipmaps ) { imageInfo.num_mip_levels = (size_t) random_in_range(2, compute_max_mip_levels(imageInfo.width, imageInfo.height, 0)-1, seed); @@ -1782,7 +1803,8 @@ int test_read_image_set_2D(cl_device_id device, cl_context context, size = (size_t)imageInfo.rowPitch * (size_t)imageInfo.height * 4; } - } while( size > maxAllocSize || ( size * 3 ) > memSize ); + } while (size > maxAllocSize || (size * 3) > memSize + || !is_width_compatible(imageInfo)); if( gDebugTrace ) log_info( " at size %d,%d (row pitch %d) out of %d,%d\n", (int)imageInfo.width, (int)imageInfo.height, (int)imageInfo.rowPitch, (int)maxWidth, (int)maxHeight );