Skip to content

Commit 7deecbe

Browse files
authored
Extend scanline comparisons for image padding (#2619)
Extend compare_scanlines to handle INT10X6/12X4/14X2 padding and per-channel SNORM INT8/INT16 comparisons, and switch pixel loads to memcpy to avoid unaligned access. Rework image_from_buffer_fill_check to compare rows via compare_scanlines. Signed-off-by: Xin Jin <xin.jin@arm.com>
1 parent 5dbe48e commit 7deecbe

File tree

4 files changed

+137
-49
lines changed

4 files changed

+137
-49
lines changed

test_common/harness/imageHelpers.cpp

Lines changed: 107 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -493,43 +493,119 @@ size_t compare_scanlines(const image_descriptor *imageInfo, const char *aPtr,
493493
// If the data type is 101010, then ignore bits 31 and 32 when
494494
// comparing the row
495495
case CL_UNORM_INT_101010: {
496-
cl_uint aPixel = *(cl_uint *)aPtr;
497-
cl_uint bPixel = *(cl_uint *)bPtr;
496+
cl_uint aPixel = 0;
497+
cl_uint bPixel = 0;
498+
memcpy(&aPixel, aPtr, sizeof(aPixel));
499+
memcpy(&bPixel, bPtr, sizeof(bPixel));
498500
if ((aPixel & 0x3fffffff) != (bPixel & 0x3fffffff))
499501
return column;
500502
}
501503
break;
502504

503505
// If the data type is 555, ignore bit 15 when comparing the row
504506
case CL_UNORM_SHORT_555: {
505-
cl_ushort aPixel = *(cl_ushort *)aPtr;
506-
cl_ushort bPixel = *(cl_ushort *)bPtr;
507+
cl_ushort aPixel = 0;
508+
cl_ushort bPixel = 0;
509+
memcpy(&aPixel, aPtr, sizeof(aPixel));
510+
memcpy(&bPixel, bPtr, sizeof(bPixel));
507511
if ((aPixel & 0x7fff) != (bPixel & 0x7fff)) return column;
508512
}
509513
break;
510514

515+
// 16-bit per-channel formats with LSB padding (per spec); compare
516+
// defined bits only.
517+
case CL_UNSIGNED_INT10X6_EXT:
518+
case CL_UNORM_INT10X6_EXT: {
519+
const size_t channel_count =
520+
get_format_channel_count(imageInfo->format);
521+
for (size_t chan = 0; chan < channel_count; ++chan)
522+
{
523+
cl_ushort aChanVal = 0;
524+
cl_ushort bChanVal = 0;
525+
const char *aChan = aPtr + chan * sizeof(cl_ushort);
526+
const char *bChan = bPtr + chan * sizeof(cl_ushort);
527+
memcpy(&aChanVal, aChan, sizeof(aChanVal));
528+
memcpy(&bChanVal, bChan, sizeof(bChanVal));
529+
if ((aChanVal & 0xffc0) != (bChanVal & 0xffc0))
530+
return column;
531+
}
532+
}
533+
break;
534+
case CL_UNSIGNED_INT12X4_EXT:
535+
case CL_UNORM_INT12X4_EXT: {
536+
const size_t channel_count =
537+
get_format_channel_count(imageInfo->format);
538+
for (size_t chan = 0; chan < channel_count; ++chan)
539+
{
540+
cl_ushort aChanVal = 0;
541+
cl_ushort bChanVal = 0;
542+
const char *aChan = aPtr + chan * sizeof(cl_ushort);
543+
const char *bChan = bPtr + chan * sizeof(cl_ushort);
544+
memcpy(&aChanVal, aChan, sizeof(aChanVal));
545+
memcpy(&bChanVal, bChan, sizeof(bChanVal));
546+
if ((aChanVal & 0xfff0) != (bChanVal & 0xfff0))
547+
return column;
548+
}
549+
}
550+
break;
551+
case CL_UNSIGNED_INT14X2_EXT:
552+
case CL_UNORM_INT14X2_EXT: {
553+
const size_t channel_count =
554+
get_format_channel_count(imageInfo->format);
555+
for (size_t chan = 0; chan < channel_count; ++chan)
556+
{
557+
cl_ushort aChanVal = 0;
558+
cl_ushort bChanVal = 0;
559+
const char *aChan = aPtr + chan * sizeof(cl_ushort);
560+
const char *bChan = bPtr + chan * sizeof(cl_ushort);
561+
memcpy(&aChanVal, aChan, sizeof(aChanVal));
562+
memcpy(&bChanVal, bChan, sizeof(bChanVal));
563+
if ((aChanVal & 0xfffc) != (bChanVal & 0xfffc))
564+
return column;
565+
}
566+
}
567+
break;
568+
511569
case CL_SNORM_INT8: {
512-
cl_uchar aPixel = *(cl_uchar *)aPtr;
513-
cl_uchar bPixel = *(cl_uchar *)bPtr;
514-
// -1.0 is defined as 0x80 and 0x81
515-
aPixel = (aPixel == 0x80) ? 0x81 : aPixel;
516-
bPixel = (bPixel == 0x80) ? 0x81 : bPixel;
517-
if (aPixel != bPixel)
570+
const size_t channel_count =
571+
get_format_channel_count(imageInfo->format);
572+
for (size_t chan = 0; chan < channel_count; ++chan)
518573
{
519-
return column;
574+
cl_uchar aChanVal = 0;
575+
cl_uchar bChanVal = 0;
576+
const char *aChan = aPtr + chan * sizeof(cl_uchar);
577+
const char *bChan = bPtr + chan * sizeof(cl_uchar);
578+
memcpy(&aChanVal, aChan, sizeof(aChanVal));
579+
memcpy(&bChanVal, bChan, sizeof(bChanVal));
580+
// -1.0 is defined as 0x80 and 0x81
581+
aChanVal = (aChanVal == 0x80) ? 0x81 : aChanVal;
582+
bChanVal = (bChanVal == 0x80) ? 0x81 : bChanVal;
583+
if (aChanVal != bChanVal)
584+
{
585+
return column;
586+
}
520587
}
521588
}
522589
break;
523590

524591
case CL_SNORM_INT16: {
525-
cl_ushort aPixel = *(cl_ushort *)aPtr;
526-
cl_ushort bPixel = *(cl_ushort *)bPtr;
527-
// -1.0 is defined as 0x8000 and 0x8001
528-
aPixel = (aPixel == 0x8000) ? 0x8001 : aPixel;
529-
bPixel = (bPixel == 0x8000) ? 0x8001 : bPixel;
530-
if (aPixel != bPixel)
592+
const size_t channel_count =
593+
get_format_channel_count(imageInfo->format);
594+
for (size_t chan = 0; chan < channel_count; ++chan)
531595
{
532-
return column;
596+
cl_ushort aChanVal = 0;
597+
cl_ushort bChanVal = 0;
598+
const char *aChan = aPtr + chan * sizeof(cl_ushort);
599+
const char *bChan = bPtr + chan * sizeof(cl_ushort);
600+
memcpy(&aChanVal, aChan, sizeof(aChanVal));
601+
memcpy(&bChanVal, bChan, sizeof(bChanVal));
602+
// -1.0 is defined as 0x8000 and 0x8001
603+
aChanVal = (aChanVal == 0x8000) ? 0x8001 : aChanVal;
604+
bChanVal = (bChanVal == 0x8000) ? 0x8001 : bChanVal;
605+
if (aChanVal != bChanVal)
606+
{
607+
return column;
608+
}
533609
}
534610
}
535611
break;
@@ -544,6 +620,7 @@ size_t compare_scanlines(const image_descriptor *imageInfo, const char *aPtr,
544620
}
545621

546622
// If we didn't find a difference, return the width of the image
623+
assert(column == imageInfo->width);
547624
return column;
548625
}
549626

@@ -1208,19 +1285,21 @@ void escape_inf_nan_subnormal_values(char *data, size_t allocSize)
12081285
{
12091286
// filter values with 8 not-quite-highest bits
12101287
unsigned int *intPtr = (unsigned int *)data;
1211-
for (size_t i = 0; i<allocSize>> 2; i++)
1288+
for (size_t i = 0; i < (allocSize >> 2); i++)
12121289
{
1213-
if ((intPtr[i] & 0x7F800000) == 0x7F800000) intPtr[i] ^= 0x40000000;
1290+
if ((intPtr[i] & 0x7F800000) == 0x7F800000)
1291+
intPtr[i] ^= 0x40000000;
12141292
else if ((intPtr[i] & 0x7F800000) == 0)
12151293
intPtr[i] ^= 0x40000000;
12161294
}
12171295

12181296
// Ditto with half floats (16-bit numbers with the 5 not-quite-highest bits
12191297
// = 0x7C00 are special)
12201298
unsigned short *shortPtr = (unsigned short *)data;
1221-
for (size_t i = 0; i<allocSize>> 1; i++)
1299+
for (size_t i = 0; i < (allocSize >> 1); i++)
12221300
{
1223-
if ((shortPtr[i] & 0x7C00) == 0x7C00) shortPtr[i] ^= 0x4000;
1301+
if ((shortPtr[i] & 0x7C00) == 0x7C00)
1302+
shortPtr[i] ^= 0x4000;
12241303
else if ((shortPtr[i] & 0x7C00) == 0)
12251304
shortPtr[i] ^= 0x4000;
12261305
}
@@ -3191,12 +3270,12 @@ void pack_image_pixel_error(const float *srcVector,
31913270
case CL_UNSIGNED_INT32: {
31923271
const cl_uint *ptr = (const cl_uint *)results;
31933272
for (unsigned int i = 0; i < channelCount; i++)
3194-
errors[i] = (cl_float)(
3195-
(cl_long)ptr[i]
3196-
- (cl_long)CONVERT_UINT(
3197-
srcVector[i],
3198-
MAKE_HEX_FLOAT(0x1.fffffep31f, 0x1fffffe, 31 - 23),
3199-
CL_UINT_MAX));
3273+
errors[i] = (cl_float)((cl_long)ptr[i]
3274+
- (cl_long)CONVERT_UINT(
3275+
srcVector[i],
3276+
MAKE_HEX_FLOAT(0x1.fffffep31f,
3277+
0x1fffffe, 31 - 23),
3278+
CL_UINT_MAX));
32003279
break;
32013280
}
32023281
case CL_UNSIGNED_INT10X6_EXT: {

test_conformance/extensions/cl_khr_external_memory_ahb/debug_ahb.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ ahardwareBufferDecodeUsageFlagsToString(const AHardwareBuffer_UsageFlags flags)
6060

6161
return std::accumulate(active_flags.begin() + 1, active_flags.end(),
6262
active_flags.front(),
63-
[](std::string acc, const std::string& flag) {
63+
[](std::string acc, const std::string &flag) {
6464
return std::move(acc) + "|" + flag;
6565
});
6666
}

test_conformance/extensions/cl_khr_external_semaphore/test_external_semaphore.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
} \
5353
} while (false)
5454

55-
static const char *source = "__kernel void empty() {}";
55+
static const char* source = "__kernel void empty() {}";
5656

5757
static void log_info_semaphore_type(
5858
VulkanExternalSemaphoreHandleType vkExternalSemaphoreHandleType)
@@ -64,7 +64,7 @@ static void log_info_semaphore_type(
6464
log_info("%s", semaphore_type_description.str().c_str());
6565
}
6666

67-
static int init_vulkan_device(cl_uint num_devices, cl_device_id *deviceIds)
67+
static int init_vulkan_device(cl_uint num_devices, cl_device_id* deviceIds)
6868
{
6969
cl_platform_id platform = nullptr;
7070

@@ -84,7 +84,7 @@ static int init_vulkan_device(cl_uint num_devices, cl_device_id *deviceIds)
8484

8585
static cl_int get_device_semaphore_handle_types(
8686
cl_device_id deviceID, cl_device_info param,
87-
std::vector<cl_external_semaphore_handle_type_khr> &handle_types)
87+
std::vector<cl_external_semaphore_handle_type_khr>& handle_types)
8888
{
8989
int err = CL_SUCCESS;
9090
// Query for export support

test_conformance/images/kernel_read_write/test_cl_ext_image_from_buffer.cpp

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -642,11 +642,12 @@ int image_from_small_buffer_negative(cl_device_id device, cl_context context,
642642
}
643643

644644
static int image_from_buffer_fill_check(cl_command_queue queue, cl_mem image,
645-
size_t* region, size_t element_size,
646-
char pattern)
645+
const cl_image_format& format,
646+
size_t* region, char pattern)
647647
{
648648
/* read the image from buffer and check the pattern */
649-
const size_t image_size = region[0] * region[1] * region[2] * element_size;
649+
const size_t pixel_size = get_pixel_size(&format);
650+
const size_t image_size = region[0] * region[1] * region[2] * pixel_size;
650651
size_t origin[3] = { 0, 0, 0 };
651652
std::vector<char> read_buffer(image_size);
652653

@@ -655,21 +656,29 @@ static int image_from_buffer_fill_check(cl_command_queue queue, cl_mem image,
655656
read_buffer.data(), 0, nullptr, nullptr);
656657
test_error(error, "Error clEnqueueReadImage");
657658

658-
for (size_t line = 0; line < region[0]; line++)
659+
const size_t row_pitch = region[0] * pixel_size;
660+
const size_t slice_pitch = row_pitch * region[1];
661+
662+
image_descriptor image_info = {};
663+
image_info.width = region[0];
664+
image_info.format = &format;
665+
666+
std::vector<char> expected_row(row_pitch, pattern);
667+
668+
for (size_t depth = 0; depth < region[2]; depth++)
659669
{
660670
for (size_t row = 0; row < region[1]; row++)
661671
{
662-
for (size_t depth = 0; depth < region[2]; depth++)
672+
const char* actual_ptr =
673+
read_buffer.data() + depth * slice_pitch + row * row_pitch;
674+
size_t where =
675+
compare_scanlines(&image_info, expected_row.data(), actual_ptr);
676+
// compare_scanlines returns width when rows match; < width
677+
// indicates mismatch.
678+
if (where < region[0])
663679
{
664-
for (size_t elmt = 0; elmt < element_size; elmt++)
665-
{
666-
size_t index = line * row * depth * elmt;
667-
668-
if (read_buffer[index] != pattern)
669-
{
670-
test_fail("Image pattern check failed\n");
671-
}
672-
}
680+
test_fail("Image pattern check failed (z=%zu, y=%zu, x=%zu)\n",
681+
depth, row, where);
673682
}
674683
}
675684
}
@@ -827,14 +836,14 @@ int image_from_buffer_fill_positive(cl_device_id device, cl_context context,
827836
test_error(err, "Error clFinish");
828837

829838
int fill_error = image_from_buffer_fill_check(
830-
queue, image_from_buffer, region, element_size, pattern);
839+
queue, image_from_buffer, format, region, pattern);
831840
if (TEST_PASS != fill_error)
832841
{
833842
return fill_error;
834843
}
835844

836-
fill_error = image_from_buffer_fill_check(
837-
queue, image, region, element_size, pattern);
845+
fill_error = image_from_buffer_fill_check(queue, image, format,
846+
region, pattern);
838847
if (TEST_PASS != fill_error)
839848
{
840849
return fill_error;

0 commit comments

Comments
 (0)