v3dv: add paths to handle partial copies of linear images
v2: * Removed unneeded copy_image_linear_buffer * Add tiling/image-type check on copy_image_blit Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19950>
This commit is contained in:

committed by
Marge Bot

parent
b39958a3a1
commit
36ec3d6fe3
@@ -2697,8 +2697,8 @@ v3dv_BindImageMemory2(VkDevice _device,
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
buffer_init(struct v3dv_device *device,
|
||||
void
|
||||
v3dv_buffer_init(struct v3dv_device *device,
|
||||
const VkBufferCreateInfo *pCreateInfo,
|
||||
struct v3dv_buffer *buffer)
|
||||
{
|
||||
@@ -2751,12 +2751,12 @@ v3dv_GetDeviceBufferMemoryRequirementsKHR(
|
||||
V3DV_FROM_HANDLE(v3dv_device, device, _device);
|
||||
|
||||
struct v3dv_buffer buffer = { 0 };
|
||||
buffer_init(device, pInfo->pCreateInfo, &buffer);
|
||||
v3dv_buffer_init(device, pInfo->pCreateInfo, &buffer);
|
||||
get_buffer_memory_requirements(&buffer, pMemoryRequirements);
|
||||
}
|
||||
|
||||
static void
|
||||
bind_buffer_memory(const VkBindBufferMemoryInfo *info)
|
||||
void
|
||||
v3dv_buffer_bind_memory(const VkBindBufferMemoryInfo *info)
|
||||
{
|
||||
V3DV_FROM_HANDLE(v3dv_buffer, buffer, info->buffer);
|
||||
V3DV_FROM_HANDLE(v3dv_device_memory, mem, info->memory);
|
||||
@@ -2781,7 +2781,7 @@ v3dv_BindBufferMemory2(VkDevice device,
|
||||
const VkBindBufferMemoryInfo *pBindInfos)
|
||||
{
|
||||
for (uint32_t i = 0; i < bindInfoCount; i++)
|
||||
bind_buffer_memory(&pBindInfos[i]);
|
||||
v3dv_buffer_bind_memory(&pBindInfos[i]);
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
@@ -2806,7 +2806,7 @@ v3dv_CreateBuffer(VkDevice _device,
|
||||
if (buffer == NULL)
|
||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
||||
buffer_init(device, pCreateInfo, buffer);
|
||||
v3dv_buffer_init(device, pCreateInfo, buffer);
|
||||
|
||||
/* Limit allocations to 32-bit */
|
||||
const VkDeviceSize aligned_size = align64(buffer->size, buffer->alignment);
|
||||
|
@@ -40,6 +40,19 @@ meta_blit_key_compare(const void *key1, const void *key2)
|
||||
return memcmp(key1, key2, V3DV_META_BLIT_CACHE_KEY_SIZE) == 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
texel_buffer_shader_copy(struct v3dv_cmd_buffer *cmd_buffer,
|
||||
VkImageAspectFlags aspect,
|
||||
struct v3dv_image *image,
|
||||
VkFormat dst_format,
|
||||
VkFormat src_format,
|
||||
struct v3dv_buffer *buffer,
|
||||
uint32_t buffer_bpp,
|
||||
VkColorComponentFlags cmask,
|
||||
VkComponentMapping *cswizzle,
|
||||
uint32_t region_count,
|
||||
const VkBufferImageCopy2 *regions);
|
||||
|
||||
static bool
|
||||
create_blit_pipeline_layout(struct v3dv_device *device,
|
||||
VkDescriptorSetLayout *descriptor_set_layout,
|
||||
@@ -1027,6 +1040,10 @@ copy_image_blit(struct v3dv_cmd_buffer *cmd_buffer,
|
||||
struct v3dv_image *src,
|
||||
const VkImageCopy2 *region)
|
||||
{
|
||||
if (src->vk.tiling == VK_IMAGE_TILING_LINEAR &&
|
||||
src->vk.image_type != VK_IMAGE_TYPE_1D)
|
||||
return false;
|
||||
|
||||
const uint32_t src_block_w = vk_format_get_blockwidth(src->vk.format);
|
||||
const uint32_t src_block_h = vk_format_get_blockheight(src->vk.format);
|
||||
const uint32_t dst_block_w = vk_format_get_blockwidth(dst->vk.format);
|
||||
@@ -1163,6 +1180,104 @@ copy_image_blit(struct v3dv_cmd_buffer *cmd_buffer,
|
||||
return handled;
|
||||
}
|
||||
|
||||
static bool
|
||||
copy_image_linear_texel_buffer(struct v3dv_cmd_buffer *cmd_buffer,
|
||||
struct v3dv_image *dst,
|
||||
struct v3dv_image *src,
|
||||
const VkImageCopy2 *region)
|
||||
{
|
||||
if (src->vk.tiling != VK_IMAGE_TILING_LINEAR)
|
||||
return false;
|
||||
|
||||
/* Implementations are allowed to restrict linear images like this */
|
||||
assert(region->srcOffset.z == 0);
|
||||
assert(region->dstOffset.z == 0);
|
||||
assert(region->srcSubresource.mipLevel == 0);
|
||||
assert(region->srcSubresource.baseArrayLayer == 0);
|
||||
assert(region->srcSubresource.layerCount == 1);
|
||||
assert(region->dstSubresource.mipLevel == 0);
|
||||
assert(region->dstSubresource.baseArrayLayer == 0);
|
||||
assert(region->dstSubresource.layerCount == 1);
|
||||
|
||||
const uint32_t bpp = src->cpp;
|
||||
assert(src->cpp == dst->cpp);
|
||||
|
||||
VkFormat format;
|
||||
switch (bpp) {
|
||||
case 16:
|
||||
format = VK_FORMAT_R32G32B32A32_UINT;
|
||||
break;
|
||||
case 8:
|
||||
format = VK_FORMAT_R16G16B16A16_UINT;
|
||||
break;
|
||||
case 4:
|
||||
format = VK_FORMAT_R8G8B8A8_UINT;
|
||||
break;
|
||||
case 2:
|
||||
format = VK_FORMAT_R16_UINT;
|
||||
break;
|
||||
case 1:
|
||||
format = VK_FORMAT_R8_UINT;
|
||||
break;
|
||||
default:
|
||||
unreachable("unsupported bit-size");
|
||||
return false;
|
||||
}
|
||||
|
||||
VkComponentMapping ident_swizzle = {
|
||||
.r = VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
.g = VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
.b = VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
.a = VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
};
|
||||
|
||||
const uint32_t buf_stride = src->slices[0].stride;
|
||||
const VkDeviceSize buf_offset =
|
||||
v3dv_layer_offset(src, 0, 0) +
|
||||
region->srcOffset.y * buf_stride + region->srcOffset.x * bpp;
|
||||
|
||||
struct v3dv_buffer src_buffer;
|
||||
vk_object_base_init(&cmd_buffer->device->vk, &src_buffer.base,
|
||||
VK_OBJECT_TYPE_BUFFER);
|
||||
|
||||
const struct VkBufferCreateInfo buf_create_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.size = src->size,
|
||||
.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT,
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
};
|
||||
v3dv_buffer_init(cmd_buffer->device, &buf_create_info, &src_buffer);
|
||||
|
||||
const VkBindBufferMemoryInfo buf_bind_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO,
|
||||
.buffer = v3dv_buffer_to_handle(&src_buffer),
|
||||
.memory = v3dv_device_memory_to_handle(src->mem),
|
||||
.memoryOffset = src->mem_offset,
|
||||
};
|
||||
v3dv_buffer_bind_memory(&buf_bind_info);
|
||||
|
||||
const VkBufferImageCopy2 copy_region = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2,
|
||||
.pNext = NULL,
|
||||
.bufferOffset = buf_offset,
|
||||
.bufferRowLength = buf_stride / bpp,
|
||||
.bufferImageHeight = src->vk.extent.height,
|
||||
.imageSubresource = region->dstSubresource,
|
||||
.imageOffset = region->dstOffset,
|
||||
.imageExtent = region->extent,
|
||||
};
|
||||
|
||||
return texel_buffer_shader_copy(cmd_buffer,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
dst,
|
||||
format,
|
||||
format,
|
||||
&src_buffer,
|
||||
src->cpp,
|
||||
0 /* color mask: full */, &ident_swizzle,
|
||||
1, ©_region);
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
v3dv_CmdCopyImage2KHR(VkCommandBuffer commandBuffer,
|
||||
const VkCopyImageInfo2 *info)
|
||||
@@ -1183,6 +1298,8 @@ v3dv_CmdCopyImage2KHR(VkCommandBuffer commandBuffer,
|
||||
continue;
|
||||
if (copy_image_blit(cmd_buffer, dst, src, &info->pRegions[i]))
|
||||
continue;
|
||||
if (copy_image_linear_texel_buffer(cmd_buffer, dst, src, &info->pRegions[i]))
|
||||
continue;
|
||||
unreachable("Image copy not supported");
|
||||
}
|
||||
|
||||
|
@@ -733,6 +733,14 @@ struct v3dv_buffer {
|
||||
VkDeviceSize mem_offset;
|
||||
};
|
||||
|
||||
void
|
||||
v3dv_buffer_init(struct v3dv_device *device,
|
||||
const VkBufferCreateInfo *pCreateInfo,
|
||||
struct v3dv_buffer *buffer);
|
||||
|
||||
void
|
||||
v3dv_buffer_bind_memory(const VkBindBufferMemoryInfo *info);
|
||||
|
||||
struct v3dv_buffer_view {
|
||||
struct vk_object_base base;
|
||||
|
||||
|
Reference in New Issue
Block a user