mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-19 06:09:01 +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;
|
||||
}
|
||||
|
||||
@@ -71,8 +71,10 @@ extern pfnclEnqueueReleaseExternalMemObjectsKHR
|
||||
extern pfnclReleaseSemaphoreKHR clReleaseSemaphoreKHRptr;
|
||||
extern pfnclReImportSemaphoreSyncFdKHR pfnclReImportSemaphoreSyncFdKHRptr;
|
||||
|
||||
cl_int getCLImageInfoFromVkImageInfo(const VkImageCreateInfo *, size_t,
|
||||
cl_image_format *, cl_image_desc *);
|
||||
cl_int
|
||||
getCLImageInfoFromVkImageInfo(const cl_device_id, const VkImageCreateInfo *,
|
||||
cl_image_format *, cl_image_desc *,
|
||||
const VkSubresourceLayout *layout = nullptr);
|
||||
cl_int check_external_memory_handle_type(
|
||||
cl_device_id deviceID,
|
||||
cl_external_memory_handle_type_khr requiredHandleType);
|
||||
|
||||
@@ -1839,7 +1839,13 @@ VulkanImage::VulkanImage(
|
||||
vkImageCreateInfo.pNext = &vkExternalMemoryImageCreateInfo;
|
||||
}
|
||||
|
||||
vkCreateImage(m_device, &vkImageCreateInfo, NULL, &m_vkImage);
|
||||
VkResult vkStatus =
|
||||
vkCreateImage(m_device, &vkImageCreateInfo, NULL, &m_vkImage);
|
||||
if (vkStatus != VK_SUCCESS)
|
||||
{
|
||||
throw std::runtime_error("Error: Failed create image.");
|
||||
}
|
||||
|
||||
VulkanImageCreateInfo = vkImageCreateInfo;
|
||||
|
||||
VkMemoryDedicatedRequirements vkMemoryDedicatedRequirements = {};
|
||||
@@ -1968,7 +1974,7 @@ VulkanExtent3D VulkanImage2D::getExtent3D(uint32_t mipLevel) const
|
||||
return VulkanExtent3D(width, height, depth);
|
||||
}
|
||||
|
||||
VkSubresourceLayout VulkanImage2D::getSubresourceLayout() const
|
||||
VkSubresourceLayout VulkanImage::getSubresourceLayout() const
|
||||
{
|
||||
VkImageSubresource subresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0 };
|
||||
|
||||
|
||||
@@ -491,6 +491,8 @@ public:
|
||||
VulkanSharingMode sharingMode = VULKAN_SHARING_MODE_EXCLUSIVE);
|
||||
virtual ~VulkanImage();
|
||||
virtual VulkanExtent3D getExtent3D(uint32_t mipLevel = 0) const;
|
||||
virtual VkSubresourceLayout getSubresourceLayout() const;
|
||||
|
||||
VulkanFormat getFormat() const;
|
||||
uint32_t getNumMipLevels() const;
|
||||
uint32_t getNumLayers() const;
|
||||
@@ -560,7 +562,6 @@ public:
|
||||
VulkanSharingMode sharingMode = VULKAN_SHARING_MODE_EXCLUSIVE);
|
||||
virtual ~VulkanImage2D();
|
||||
virtual VulkanExtent3D getExtent3D(uint32_t mipLevel = 0) const;
|
||||
virtual VkSubresourceLayout getSubresourceLayout() const;
|
||||
|
||||
VulkanImage2D(const VulkanImage2D &image2D);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user