Skip to content

Commit f30a191

Browse files
authored
Corrected procedure to collect proper size of image from VkImageCreateInfo (#2289)
Fixes #2155 according to issue description Additional remark: The image size was previously calculated based on the memory size, which seems unusual. Due to Vulkan's configuration capabilities, the size of memory allocated for a specific texture may differ from what would be expected based on the texture dimensions. Thus, calculating the image dimensions back from the memory size of a Vulkan texture can be challenging.
1 parent 3ab4d8a commit f30a191

7 files changed

+128
-84
lines changed

test_conformance/common/vulkan_wrapper/opencl_vulkan_wrapper.cpp

Lines changed: 93 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -428,38 +428,68 @@ size_t GetElementNBytes(const cl_image_format *format)
428428
return result;
429429
}
430430

431-
cl_int get2DImageDimensions(const VkImageCreateInfo *VulkanImageCreateInfo,
432-
cl_image_format *img_fmt, size_t totalImageSize,
433-
size_t &width, size_t &height)
431+
cl_int getImageDimensions(const VkImageCreateInfo *VulkanImageCreateInfo,
432+
cl_image_format *img_fmt, cl_image_desc *img_desc,
433+
VkExtent3D max_ext, const VkSubresourceLayout *layout)
434434
{
435-
cl_int result = CL_SUCCESS;
436-
if (totalImageSize == 0)
435+
test_assert_error(
436+
VulkanImageCreateInfo != nullptr,
437+
"getImageDimensions: invalid VulkanImageCreateInfo pointer!");
438+
test_assert_error(img_fmt != nullptr,
439+
"getImageDimensions: invalid img_fmt pointer!");
440+
test_assert_error(img_desc != nullptr,
441+
"getImageDimensions: invalid img_desc pointer!");
442+
443+
img_desc->image_depth = VulkanImageCreateInfo->extent.depth;
444+
img_desc->image_width = VulkanImageCreateInfo->extent.width;
445+
img_desc->image_height = VulkanImageCreateInfo->extent.height;
446+
447+
if (layout != nullptr)
437448
{
438-
result = CL_INVALID_VALUE;
449+
size_t element_size = GetElementNBytes(img_fmt);
450+
size_t row_pitch = element_size * VulkanImageCreateInfo->extent.width;
451+
row_pitch = row_pitch < layout->rowPitch ? layout->rowPitch : row_pitch;
452+
img_desc->image_row_pitch = row_pitch;
453+
454+
size_t slice_pitch = row_pitch * VulkanImageCreateInfo->extent.height;
455+
slice_pitch =
456+
slice_pitch < layout->depthPitch ? layout->depthPitch : slice_pitch;
457+
img_desc->image_slice_pitch = slice_pitch;
439458
}
440-
size_t element_size = GetElementNBytes(img_fmt);
441-
size_t row_pitch = element_size * VulkanImageCreateInfo->extent.width;
442-
row_pitch = row_pitch % 64 == 0 ? row_pitch : ((row_pitch / 64) + 1) * 64;
443459

444-
width = row_pitch / element_size;
445-
height = totalImageSize / row_pitch;
460+
switch (img_desc->image_type)
461+
{
462+
case CL_MEM_OBJECT_IMAGE3D:
463+
test_assert_error(img_desc->image_depth >= 1
464+
&& img_desc->image_depth <= max_ext.depth,
465+
"getImageDimensions: invalid image depth!");
466+
case CL_MEM_OBJECT_IMAGE2D:
467+
test_assert_error(img_desc->image_height >= 1
468+
&& img_desc->image_height <= max_ext.height,
469+
"getImageDimensions: invalid image height!");
470+
case CL_MEM_OBJECT_IMAGE1D:
471+
test_assert_error(img_desc->image_width >= 1
472+
&& img_desc->image_width <= max_ext.width,
473+
"getImageDimensions: invalid image width!");
474+
}
446475

447-
return result;
476+
return CL_SUCCESS;
448477
}
449478

450479
cl_int
451-
getCLImageInfoFromVkImageInfo(const VkImageCreateInfo *VulkanImageCreateInfo,
452-
size_t totalImageSize, cl_image_format *img_fmt,
453-
cl_image_desc *img_desc)
480+
getCLImageInfoFromVkImageInfo(const cl_device_id device,
481+
const VkImageCreateInfo *VulkanImageCreateInfo,
482+
cl_image_format *img_fmt, cl_image_desc *img_desc,
483+
const VkSubresourceLayout *layout)
454484
{
455-
cl_int result = CL_SUCCESS;
485+
cl_int error = CL_SUCCESS;
456486

457487
cl_image_format clImgFormat = { 0 };
458-
result =
488+
error =
459489
getCLFormatFromVkFormat(VulkanImageCreateInfo->format, &clImgFormat);
460-
if (CL_SUCCESS != result)
490+
if (CL_SUCCESS != error)
461491
{
462-
return result;
492+
return error;
463493
}
464494
memcpy(img_fmt, &clImgFormat, sizeof(cl_image_format));
465495

@@ -469,25 +499,57 @@ getCLImageInfoFromVkImageInfo(const VkImageCreateInfo *VulkanImageCreateInfo,
469499
return CL_INVALID_VALUE;
470500
}
471501

472-
result =
473-
get2DImageDimensions(VulkanImageCreateInfo, img_fmt, totalImageSize,
474-
img_desc->image_width, img_desc->image_height);
475-
if (CL_SUCCESS != result)
502+
VkExtent3D max_ext = { 0, 0, 0 };
503+
504+
size_t width = 0, height = 0, depth = 0;
505+
if (img_desc->image_type == CL_MEM_OBJECT_IMAGE3D)
506+
{
507+
error = clGetDeviceInfo(device, CL_DEVICE_IMAGE3D_MAX_WIDTH,
508+
sizeof(width), &width, NULL);
509+
test_error(error, "Unable to get CL_DEVICE_IMAGE3D_MAX_WIDTH");
510+
error = clGetDeviceInfo(device, CL_DEVICE_IMAGE3D_MAX_HEIGHT,
511+
sizeof(height), &height, NULL);
512+
test_error(error, "Unable to get CL_DEVICE_IMAGE3D_MAX_HEIGHT");
513+
error = clGetDeviceInfo(device, CL_DEVICE_IMAGE3D_MAX_DEPTH,
514+
sizeof(depth), &depth, NULL);
515+
test_error(error, "Unable to get CL_DEVICE_IMAGE3D_MAX_DEPTH");
516+
}
517+
else
518+
{
519+
error = clGetDeviceInfo(device, CL_DEVICE_IMAGE2D_MAX_WIDTH,
520+
sizeof(width), &width, NULL);
521+
test_error(error, "Unable to get CL_DEVICE_IMAGE2D_MAX_WIDTH");
522+
error = clGetDeviceInfo(device, CL_DEVICE_IMAGE2D_MAX_HEIGHT,
523+
sizeof(height), &height, NULL);
524+
test_error(error, "Unable to get CL_DEVICE_IMAGE2D_MAX_HEIGHT");
525+
}
526+
527+
max_ext.depth = depth;
528+
max_ext.height = height;
529+
max_ext.width = width;
530+
531+
// If image_row_pitch is zero and the image is created from an external
532+
// memory handle, then the image row pitch is implementation-defined
533+
img_desc->image_row_pitch = 0;
534+
// If image_slice_pitch is zero and the image is created from an external
535+
// memory handle, then the image slice pitch is implementation-defined
536+
img_desc->image_slice_pitch = 0;
537+
538+
error = getImageDimensions(VulkanImageCreateInfo, img_fmt, img_desc,
539+
max_ext, layout);
540+
if (CL_SUCCESS != error)
476541
{
477-
throw std::runtime_error("get2DImageDimensions failed!!!");
542+
throw std::runtime_error("getImageDimensions failed!!!");
478543
}
479544

480545
img_desc->image_depth =
481546
static_cast<size_t>(VulkanImageCreateInfo->extent.depth);
482547
img_desc->image_array_size = 0;
483-
img_desc->image_row_pitch = 0; // Row pitch set to zero as host_ptr is NULL
484-
img_desc->image_slice_pitch =
485-
img_desc->image_row_pitch * img_desc->image_height;
486548
img_desc->num_mip_levels = 0;
487549
img_desc->num_samples = 0;
488550
img_desc->buffer = NULL;
489551

490-
return result;
552+
return error;
491553
}
492554

493555
cl_int check_external_memory_handle_type(
@@ -806,7 +868,7 @@ clExternalMemoryImage::clExternalMemoryImage(
806868
image2D.getVkImageCreateInfo();
807869

808870
errcode_ret = getCLImageInfoFromVkImageInfo(
809-
&VulkanImageCreateInfo, image2D.getSize(), &img_format, &image_desc);
871+
deviceId, &VulkanImageCreateInfo, &img_format, &image_desc);
810872
if (CL_SUCCESS != errcode_ret)
811873
{
812874
throw std::runtime_error("getCLImageInfoFromVkImageInfo failed\n");
@@ -1212,6 +1274,8 @@ cl_external_memory_handle_type_khr vkToOpenCLExternalMemoryHandleType(
12121274
case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT:
12131275
case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_NT_KMT:
12141276
return CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_KMT_KHR;
1277+
case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_NT_NAME:
1278+
return CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_NAME_KHR;
12151279
}
12161280
return 0;
12171281
}

test_conformance/common/vulkan_wrapper/opencl_vulkan_wrapper.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,10 @@ extern pfnclEnqueueReleaseExternalMemObjectsKHR
7171
extern pfnclReleaseSemaphoreKHR clReleaseSemaphoreKHRptr;
7272
extern pfnclReImportSemaphoreSyncFdKHR pfnclReImportSemaphoreSyncFdKHRptr;
7373

74-
cl_int getCLImageInfoFromVkImageInfo(const VkImageCreateInfo *, size_t,
75-
cl_image_format *, cl_image_desc *);
74+
cl_int
75+
getCLImageInfoFromVkImageInfo(const cl_device_id, const VkImageCreateInfo *,
76+
cl_image_format *, cl_image_desc *,
77+
const VkSubresourceLayout *layout = nullptr);
7678
cl_int check_external_memory_handle_type(
7779
cl_device_id deviceID,
7880
cl_external_memory_handle_type_khr requiredHandleType);

test_conformance/common/vulkan_wrapper/vulkan_wrapper.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1839,7 +1839,13 @@ VulkanImage::VulkanImage(
18391839
vkImageCreateInfo.pNext = &vkExternalMemoryImageCreateInfo;
18401840
}
18411841

1842-
vkCreateImage(m_device, &vkImageCreateInfo, NULL, &m_vkImage);
1842+
VkResult vkStatus =
1843+
vkCreateImage(m_device, &vkImageCreateInfo, NULL, &m_vkImage);
1844+
if (vkStatus != VK_SUCCESS)
1845+
{
1846+
throw std::runtime_error("Error: Failed create image.");
1847+
}
1848+
18431849
VulkanImageCreateInfo = vkImageCreateInfo;
18441850

18451851
VkMemoryDedicatedRequirements vkMemoryDedicatedRequirements = {};
@@ -1968,7 +1974,7 @@ VulkanExtent3D VulkanImage2D::getExtent3D(uint32_t mipLevel) const
19681974
return VulkanExtent3D(width, height, depth);
19691975
}
19701976

1971-
VkSubresourceLayout VulkanImage2D::getSubresourceLayout() const
1977+
VkSubresourceLayout VulkanImage::getSubresourceLayout() const
19721978
{
19731979
VkImageSubresource subresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0 };
19741980

test_conformance/common/vulkan_wrapper/vulkan_wrapper.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,8 @@ class VulkanImage {
491491
VulkanSharingMode sharingMode = VULKAN_SHARING_MODE_EXCLUSIVE);
492492
virtual ~VulkanImage();
493493
virtual VulkanExtent3D getExtent3D(uint32_t mipLevel = 0) const;
494+
virtual VkSubresourceLayout getSubresourceLayout() const;
495+
494496
VulkanFormat getFormat() const;
495497
uint32_t getNumMipLevels() const;
496498
uint32_t getNumLayers() const;
@@ -560,7 +562,6 @@ class VulkanImage2D : public VulkanImage {
560562
VulkanSharingMode sharingMode = VULKAN_SHARING_MODE_EXCLUSIVE);
561563
virtual ~VulkanImage2D();
562564
virtual VulkanExtent3D getExtent3D(uint32_t mipLevel = 0) const;
563-
virtual VkSubresourceLayout getSubresourceLayout() const;
564565

565566
VulkanImage2D(const VulkanImage2D &image2D);
566567
};

test_conformance/vulkan/test_vulkan_api_consistency.cpp

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -232,12 +232,11 @@ struct ConsistencyExternalImageTest : public VulkanTestBase
232232

233233
const VulkanMemoryTypeList& memoryTypeList =
234234
vkImage2D.getMemoryTypeList();
235-
uint64_t totalImageMemSize = vkImage2D.getSize();
236235

237236
log_info("Memory type index: %u\n", (uint32_t)memoryTypeList[0]);
238237
log_info("Memory type property: %d\n",
239238
memoryTypeList[0].getMemoryTypeProperty());
240-
log_info("Image size : %ld\n", totalImageMemSize);
239+
log_info("Image size : %ld\n", vkImage2D.getSize());
241240

242241
VulkanDeviceMemory* vkDeviceMem =
243242
new VulkanDeviceMemory(*vkDevice, vkImage2D, memoryTypeList[0],
@@ -298,14 +297,12 @@ struct ConsistencyExternalImageTest : public VulkanTestBase
298297
const VkImageCreateInfo VulkanImageCreateInfo =
299298
vkImage2D.getVkImageCreateInfo();
300299

301-
errNum = getCLImageInfoFromVkImageInfo(&VulkanImageCreateInfo,
302-
totalImageMemSize, &img_format,
303-
&image_desc);
304-
if (errNum != CL_SUCCESS)
305-
{
306-
log_error("getCLImageInfoFromVkImageInfo failed!!!");
307-
return TEST_FAIL;
308-
}
300+
auto layout = vkImage2D.getSubresourceLayout();
301+
errNum = getCLImageInfoFromVkImageInfo(
302+
device, &VulkanImageCreateInfo, &img_format, &image_desc,
303+
vulkanImageTiling == VULKAN_IMAGE_TILING_LINEAR ? &layout
304+
: nullptr);
305+
test_error_fail(errNum, "getCLImageInfoFromVkImageInfo failed!!!");
309306

310307
clMemWrapper image;
311308

test_conformance/vulkan/test_vulkan_api_consistency_for_1dimages.cpp

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,11 @@ struct ConsistencyExternalImage1DTest : public VulkanTestBase
9090

9191
const VulkanMemoryTypeList& memoryTypeList =
9292
vkImage1D.getMemoryTypeList();
93-
uint64_t totalImageMemSize = vkImage1D.getSize();
9493

9594
log_info("Memory type index: %u\n", (uint32_t)memoryTypeList[0]);
9695
log_info("Memory type property: %d\n",
9796
memoryTypeList[0].getMemoryTypeProperty());
98-
log_info("Image size : %lu\n", totalImageMemSize);
97+
log_info("Image size : %lu\n", vkImage1D.getSize());
9998

10099
VulkanDeviceMemory* vkDeviceMem =
101100
new VulkanDeviceMemory(*vkDevice, vkImage1D, memoryTypeList[0],
@@ -156,14 +155,12 @@ struct ConsistencyExternalImage1DTest : public VulkanTestBase
156155
const VkImageCreateInfo VulkanImageCreateInfo =
157156
vkImage1D.getVkImageCreateInfo();
158157

159-
errNum = getCLImageInfoFromVkImageInfo(&VulkanImageCreateInfo,
160-
totalImageMemSize, &img_format,
161-
&image_desc);
162-
if (errNum != CL_SUCCESS)
163-
{
164-
log_error("getCLImageInfoFromVkImageInfo failed!!!");
165-
return TEST_FAIL;
166-
}
158+
auto layout = vkImage1D.getSubresourceLayout();
159+
errNum = getCLImageInfoFromVkImageInfo(
160+
device, &VulkanImageCreateInfo, &img_format, &image_desc,
161+
vulkanImageTiling == VULKAN_IMAGE_TILING_LINEAR ? &layout
162+
: nullptr);
163+
test_error_fail(errNum, "getCLImageInfoFromVkImageInfo failed!!!");
167164

168165
clMemWrapper image;
169166

@@ -174,16 +171,6 @@ struct ConsistencyExternalImage1DTest : public VulkanTestBase
174171
test_error(errNum, "Unable to create Image with Properties");
175172
image.reset();
176173

177-
// Passing NULL properties and a valid image_format and image_desc
178-
image = clCreateImageWithProperties(context, NULL, CL_MEM_READ_WRITE,
179-
&img_format, &image_desc, NULL,
180-
&errNum);
181-
test_error(errNum,
182-
"Unable to create image with NULL properties "
183-
"with valid image format and image desc");
184-
185-
image.reset();
186-
187174
// Passing image_format as NULL
188175
image = clCreateImageWithProperties(context, extMemProperties.data(),
189176
CL_MEM_READ_WRITE, NULL,

test_conformance/vulkan/test_vulkan_api_consistency_for_3dimages.cpp

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,11 @@ struct ConsistencyExternalImage3DTest : public VulkanTestBase
9292

9393
const VulkanMemoryTypeList& memoryTypeList =
9494
vkImage3D.getMemoryTypeList();
95-
uint64_t totalImageMemSize = vkImage3D.getSize();
9695

9796
log_info("Memory type index: %u\n", (uint32_t)memoryTypeList[0]);
9897
log_info("Memory type property: %d\n",
9998
memoryTypeList[0].getMemoryTypeProperty());
100-
log_info("Image size : %lu\n", totalImageMemSize);
99+
log_info("Image size : %lu\n", vkImage3D.getSize());
101100

102101
VulkanDeviceMemory* vkDeviceMem =
103102
new VulkanDeviceMemory(*vkDevice, vkImage3D, memoryTypeList[0],
@@ -158,14 +157,12 @@ struct ConsistencyExternalImage3DTest : public VulkanTestBase
158157
const VkImageCreateInfo VulkanImageCreateInfo =
159158
vkImage3D.getVkImageCreateInfo();
160159

161-
errNum = getCLImageInfoFromVkImageInfo(&VulkanImageCreateInfo,
162-
totalImageMemSize, &img_format,
163-
&image_desc);
164-
if (errNum != CL_SUCCESS)
165-
{
166-
log_error("getCLImageInfoFromVkImageInfo failed!!!");
167-
return TEST_FAIL;
168-
}
160+
auto layout = vkImage3D.getSubresourceLayout();
161+
errNum = getCLImageInfoFromVkImageInfo(
162+
device, &VulkanImageCreateInfo, &img_format, &image_desc,
163+
vulkanImageTiling == VULKAN_IMAGE_TILING_LINEAR ? &layout
164+
: nullptr);
165+
test_error_fail(errNum, "getCLImageInfoFromVkImageInfo failed!!!");
169166

170167
clMemWrapper image;
171168

@@ -176,16 +173,6 @@ struct ConsistencyExternalImage3DTest : public VulkanTestBase
176173
test_error(errNum, "Unable to create Image with Properties");
177174
image.reset();
178175

179-
// Passing NULL properties and a valid image_format and image_desc
180-
image = clCreateImageWithProperties(context, NULL, CL_MEM_READ_WRITE,
181-
&img_format, &image_desc, NULL,
182-
&errNum);
183-
test_error(errNum,
184-
"Unable to create image with NULL properties "
185-
"with valid image format and image desc");
186-
187-
image.reset();
188-
189176
// Passing image_format as NULL
190177
image = clCreateImageWithProperties(context, extMemProperties.data(),
191178
CL_MEM_READ_WRITE, NULL,

0 commit comments

Comments
 (0)