diff options
author | Jason Ekstrand <[email protected]> | 2016-09-25 08:44:40 -0700 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2016-10-05 09:33:44 -0700 |
commit | f027609a64dffbe09fdf4b24fed4bcdc8e0cafb2 (patch) | |
tree | 89129ce24aa74a721c73297b3c5845ef1465fb0e /src/intel/vulkan/anv_blorp.c | |
parent | ca9f26ac6fcb0afb68101fb3f74fcb3100507c0c (diff) |
anv: Use blorp for VkCmdFillBuffer
Signed-off-by: Jason Ekstrand <[email protected]>
Reviewed-by: Nanley Chery <[email protected]>
Diffstat (limited to 'src/intel/vulkan/anv_blorp.c')
-rw-r--r-- | src/intel/vulkan/anv_blorp.c | 106 |
1 files changed, 96 insertions, 10 deletions
diff --git a/src/intel/vulkan/anv_blorp.c b/src/intel/vulkan/anv_blorp.c index cb610708ab3..f149f849426 100644 --- a/src/intel/vulkan/anv_blorp.c +++ b/src/intel/vulkan/anv_blorp.c @@ -480,6 +480,20 @@ void anv_CmdBlitImage( blorp_batch_finish(&batch); } +static enum isl_format +isl_format_for_size(unsigned size_B) +{ + switch (size_B) { + case 1: return ISL_FORMAT_R8_UINT; + case 2: return ISL_FORMAT_R8G8_UINT; + case 4: return ISL_FORMAT_R8G8B8A8_UINT; + case 8: return ISL_FORMAT_R16G16B16A16_UINT; + case 16: return ISL_FORMAT_R32G32B32A32_UINT; + default: + unreachable("Not a power-of-two format size"); + } +} + static void do_buffer_copy(struct blorp_batch *batch, struct anv_bo *src, uint64_t src_offset, @@ -491,16 +505,7 @@ do_buffer_copy(struct blorp_batch *batch, /* The actual format we pick doesn't matter as blorp will throw it away. * The only thing that actually matters is the size. */ - enum isl_format format; - switch (block_size) { - case 1: format = ISL_FORMAT_R8_UINT; break; - case 2: format = ISL_FORMAT_R8G8_UINT; break; - case 4: format = ISL_FORMAT_R8G8B8A8_UNORM; break; - case 8: format = ISL_FORMAT_R16G16B16A16_UNORM; break; - case 16: format = ISL_FORMAT_R32G32B32A32_UINT; break; - default: - unreachable("Not a power-of-two format size"); - } + enum isl_format format = isl_format_for_size(block_size); struct isl_surf surf; isl_surf_init(&device->isl_dev, &surf, @@ -667,6 +672,87 @@ void anv_CmdUpdateBuffer( blorp_batch_finish(&batch); } +void anv_CmdFillBuffer( + VkCommandBuffer commandBuffer, + VkBuffer dstBuffer, + VkDeviceSize dstOffset, + VkDeviceSize fillSize, + uint32_t data) +{ + ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); + ANV_FROM_HANDLE(anv_buffer, dst_buffer, dstBuffer); + struct blorp_surf surf; + struct isl_surf isl_surf; + + struct blorp_batch batch; + blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer); + + if (fillSize == VK_WHOLE_SIZE) { + fillSize = dst_buffer->size - dstOffset; + /* Make sure fillSize is a multiple of 4 */ + fillSize &= ~3ull; + } + + /* First, we compute the biggest format that can be used with the + * given offsets and size. + */ + int bs = 16; + bs = gcd_pow2_u64(bs, dstOffset); + bs = gcd_pow2_u64(bs, fillSize); + enum isl_format isl_format = isl_format_for_size(bs); + + union isl_color_value color = { + .u32 = { data, data, data, data }, + }; + + const uint64_t max_fill_size = MAX_SURFACE_DIM * MAX_SURFACE_DIM * bs; + while (fillSize >= max_fill_size) { + get_blorp_surf_for_anv_buffer(cmd_buffer->device, + dst_buffer, dstOffset, + MAX_SURFACE_DIM, MAX_SURFACE_DIM, + MAX_SURFACE_DIM * bs, isl_format, + &surf, &isl_surf); + + blorp_clear(&batch, &surf, isl_format, ISL_SWIZZLE_IDENTITY, + 0, 0, 1, 0, 0, MAX_SURFACE_DIM, MAX_SURFACE_DIM, + color, NULL); + fillSize -= max_fill_size; + dstOffset += max_fill_size; + } + + uint64_t height = fillSize / (MAX_SURFACE_DIM * bs); + assert(height < MAX_SURFACE_DIM); + if (height != 0) { + const uint64_t rect_fill_size = height * MAX_SURFACE_DIM * bs; + get_blorp_surf_for_anv_buffer(cmd_buffer->device, + dst_buffer, dstOffset, + MAX_SURFACE_DIM, height, + MAX_SURFACE_DIM * bs, isl_format, + &surf, &isl_surf); + + blorp_clear(&batch, &surf, isl_format, ISL_SWIZZLE_IDENTITY, + 0, 0, 1, 0, 0, MAX_SURFACE_DIM, height, + color, NULL); + fillSize -= rect_fill_size; + dstOffset += rect_fill_size; + } + + if (fillSize != 0) { + const uint32_t width = fillSize / bs; + get_blorp_surf_for_anv_buffer(cmd_buffer->device, + dst_buffer, dstOffset, + width, 1, + width * bs, isl_format, + &surf, &isl_surf); + + blorp_clear(&batch, &surf, isl_format, ISL_SWIZZLE_IDENTITY, + 0, 0, 1, 0, 0, width, 1, + color, NULL); + } + + blorp_batch_finish(&batch); +} + void anv_CmdClearColorImage( VkCommandBuffer commandBuffer, VkImage _image, |