mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-20 22:39:03 +00:00
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.
This commit is contained in:
@@ -428,38 +428,68 @@ size_t GetElementNBytes(const cl_image_format *format)
|
||||
return result;
|
||||
}
|
||||
|
||||
cl_int get2DImageDimensions(const VkImageCreateInfo *VulkanImageCreateInfo,
|
||||
cl_image_format *img_fmt, size_t totalImageSize,
|
||||
size_t &width, size_t &height)
|
||||
cl_int getImageDimensions(const VkImageCreateInfo *VulkanImageCreateInfo,
|
||||
cl_image_format *img_fmt, cl_image_desc *img_desc,
|
||||
VkExtent3D max_ext, const VkSubresourceLayout *layout)
|
||||
{
|
||||
cl_int result = CL_SUCCESS;
|
||||
if (totalImageSize == 0)
|
||||
test_assert_error(
|
||||
VulkanImageCreateInfo != nullptr,
|
||||
"getImageDimensions: invalid VulkanImageCreateInfo pointer!");
|
||||
test_assert_error(img_fmt != nullptr,
|
||||
"getImageDimensions: invalid img_fmt pointer!");
|
||||
test_assert_error(img_desc != nullptr,
|
||||
"getImageDimensions: invalid img_desc pointer!");
|
||||
|
||||
img_desc->image_depth = VulkanImageCreateInfo->extent.depth;
|
||||
img_desc->image_width = VulkanImageCreateInfo->extent.width;
|
||||
img_desc->image_height = VulkanImageCreateInfo->extent.height;
|
||||
|
||||
if (layout != nullptr)
|
||||
{
|
||||
result = CL_INVALID_VALUE;
|
||||
size_t element_size = GetElementNBytes(img_fmt);
|
||||
size_t row_pitch = element_size * VulkanImageCreateInfo->extent.width;
|
||||
row_pitch = row_pitch < layout->rowPitch ? layout->rowPitch : row_pitch;
|
||||
img_desc->image_row_pitch = row_pitch;
|
||||
|
||||
size_t slice_pitch = row_pitch * VulkanImageCreateInfo->extent.height;
|
||||
slice_pitch =
|
||||
slice_pitch < layout->depthPitch ? layout->depthPitch : slice_pitch;
|
||||
img_desc->image_slice_pitch = slice_pitch;
|
||||
}
|
||||
size_t element_size = GetElementNBytes(img_fmt);
|
||||
size_t row_pitch = element_size * VulkanImageCreateInfo->extent.width;
|
||||
row_pitch = row_pitch % 64 == 0 ? row_pitch : ((row_pitch / 64) + 1) * 64;
|
||||
|
||||
width = row_pitch / element_size;
|
||||
height = totalImageSize / row_pitch;
|
||||
switch (img_desc->image_type)
|
||||
{
|
||||
case CL_MEM_OBJECT_IMAGE3D:
|
||||
test_assert_error(img_desc->image_depth >= 1
|
||||
&& img_desc->image_depth <= max_ext.depth,
|
||||
"getImageDimensions: invalid image depth!");
|
||||
case CL_MEM_OBJECT_IMAGE2D:
|
||||
test_assert_error(img_desc->image_height >= 1
|
||||
&& img_desc->image_height <= max_ext.height,
|
||||
"getImageDimensions: invalid image height!");
|
||||
case CL_MEM_OBJECT_IMAGE1D:
|
||||
test_assert_error(img_desc->image_width >= 1
|
||||
&& img_desc->image_width <= max_ext.width,
|
||||
"getImageDimensions: invalid image width!");
|
||||
}
|
||||
|
||||
return result;
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
cl_int
|
||||
getCLImageInfoFromVkImageInfo(const VkImageCreateInfo *VulkanImageCreateInfo,
|
||||
size_t totalImageSize, cl_image_format *img_fmt,
|
||||
cl_image_desc *img_desc)
|
||||
getCLImageInfoFromVkImageInfo(const cl_device_id device,
|
||||
const VkImageCreateInfo *VulkanImageCreateInfo,
|
||||
cl_image_format *img_fmt, cl_image_desc *img_desc,
|
||||
const VkSubresourceLayout *layout)
|
||||
{
|
||||
cl_int result = CL_SUCCESS;
|
||||
cl_int error = CL_SUCCESS;
|
||||
|
||||
cl_image_format clImgFormat = { 0 };
|
||||
result =
|
||||
error =
|
||||
getCLFormatFromVkFormat(VulkanImageCreateInfo->format, &clImgFormat);
|
||||
if (CL_SUCCESS != result)
|
||||
if (CL_SUCCESS != error)
|
||||
{
|
||||
return result;
|
||||
return error;
|
||||
}
|
||||
memcpy(img_fmt, &clImgFormat, sizeof(cl_image_format));
|
||||
|
||||
@@ -469,25 +499,57 @@ getCLImageInfoFromVkImageInfo(const VkImageCreateInfo *VulkanImageCreateInfo,
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
|
||||
result =
|
||||
get2DImageDimensions(VulkanImageCreateInfo, img_fmt, totalImageSize,
|
||||
img_desc->image_width, img_desc->image_height);
|
||||
if (CL_SUCCESS != result)
|
||||
VkExtent3D max_ext = { 0, 0, 0 };
|
||||
|
||||
size_t width = 0, height = 0, depth = 0;
|
||||
if (img_desc->image_type == CL_MEM_OBJECT_IMAGE3D)
|
||||
{
|
||||
throw std::runtime_error("get2DImageDimensions failed!!!");
|
||||
error = clGetDeviceInfo(device, CL_DEVICE_IMAGE3D_MAX_WIDTH,
|
||||
sizeof(width), &width, NULL);
|
||||
test_error(error, "Unable to get CL_DEVICE_IMAGE3D_MAX_WIDTH");
|
||||
error = clGetDeviceInfo(device, CL_DEVICE_IMAGE3D_MAX_HEIGHT,
|
||||
sizeof(height), &height, NULL);
|
||||
test_error(error, "Unable to get CL_DEVICE_IMAGE3D_MAX_HEIGHT");
|
||||
error = clGetDeviceInfo(device, CL_DEVICE_IMAGE3D_MAX_DEPTH,
|
||||
sizeof(depth), &depth, NULL);
|
||||
test_error(error, "Unable to get CL_DEVICE_IMAGE3D_MAX_DEPTH");
|
||||
}
|
||||
else
|
||||
{
|
||||
error = clGetDeviceInfo(device, CL_DEVICE_IMAGE2D_MAX_WIDTH,
|
||||
sizeof(width), &width, NULL);
|
||||
test_error(error, "Unable to get CL_DEVICE_IMAGE2D_MAX_WIDTH");
|
||||
error = clGetDeviceInfo(device, CL_DEVICE_IMAGE2D_MAX_HEIGHT,
|
||||
sizeof(height), &height, NULL);
|
||||
test_error(error, "Unable to get CL_DEVICE_IMAGE2D_MAX_HEIGHT");
|
||||
}
|
||||
|
||||
max_ext.depth = depth;
|
||||
max_ext.height = height;
|
||||
max_ext.width = width;
|
||||
|
||||
// If image_row_pitch is zero and the image is created from an external
|
||||
// memory handle, then the image row pitch is implementation-defined
|
||||
img_desc->image_row_pitch = 0;
|
||||
// If image_slice_pitch is zero and the image is created from an external
|
||||
// memory handle, then the image slice pitch is implementation-defined
|
||||
img_desc->image_slice_pitch = 0;
|
||||
|
||||
error = getImageDimensions(VulkanImageCreateInfo, img_fmt, img_desc,
|
||||
max_ext, layout);
|
||||
if (CL_SUCCESS != error)
|
||||
{
|
||||
throw std::runtime_error("getImageDimensions failed!!!");
|
||||
}
|
||||
|
||||
img_desc->image_depth =
|
||||
static_cast<size_t>(VulkanImageCreateInfo->extent.depth);
|
||||
img_desc->image_array_size = 0;
|
||||
img_desc->image_row_pitch = 0; // Row pitch set to zero as host_ptr is NULL
|
||||
img_desc->image_slice_pitch =
|
||||
img_desc->image_row_pitch * img_desc->image_height;
|
||||
img_desc->num_mip_levels = 0;
|
||||
img_desc->num_samples = 0;
|
||||
img_desc->buffer = NULL;
|
||||
|
||||
return result;
|
||||
return error;
|
||||
}
|
||||
|
||||
cl_int check_external_memory_handle_type(
|
||||
@@ -806,7 +868,7 @@ clExternalMemoryImage::clExternalMemoryImage(
|
||||
image2D.getVkImageCreateInfo();
|
||||
|
||||
errcode_ret = getCLImageInfoFromVkImageInfo(
|
||||
&VulkanImageCreateInfo, image2D.getSize(), &img_format, &image_desc);
|
||||
deviceId, &VulkanImageCreateInfo, &img_format, &image_desc);
|
||||
if (CL_SUCCESS != errcode_ret)
|
||||
{
|
||||
throw std::runtime_error("getCLImageInfoFromVkImageInfo failed\n");
|
||||
@@ -1212,6 +1274,8 @@ cl_external_memory_handle_type_khr vkToOpenCLExternalMemoryHandleType(
|
||||
case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT:
|
||||
case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_NT_KMT:
|
||||
return CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_KMT_KHR;
|
||||
case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_NT_NAME:
|
||||
return CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_NAME_KHR;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user