mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 06:48:06 +02:00
anv: Use blorp for VkCmdFillBuffer
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net> Reviewed-by: Nanley Chery <nanley.g.chery@intel.com>
This commit is contained in:
parent
ca9f26ac6f
commit
f027609a64
2 changed files with 96 additions and 130 deletions
|
|
@ -480,6 +480,20 @@ void anv_CmdBlitImage(
|
||||||
blorp_batch_finish(&batch);
|
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
|
static void
|
||||||
do_buffer_copy(struct blorp_batch *batch,
|
do_buffer_copy(struct blorp_batch *batch,
|
||||||
struct anv_bo *src, uint64_t src_offset,
|
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 actual format we pick doesn't matter as blorp will throw it away.
|
||||||
* The only thing that actually matters is the size.
|
* The only thing that actually matters is the size.
|
||||||
*/
|
*/
|
||||||
enum isl_format format;
|
enum isl_format format = isl_format_for_size(block_size);
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
struct isl_surf surf;
|
struct isl_surf surf;
|
||||||
isl_surf_init(&device->isl_dev, &surf,
|
isl_surf_init(&device->isl_dev, &surf,
|
||||||
|
|
@ -667,6 +672,87 @@ void anv_CmdUpdateBuffer(
|
||||||
blorp_batch_finish(&batch);
|
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(
|
void anv_CmdClearColorImage(
|
||||||
VkCommandBuffer commandBuffer,
|
VkCommandBuffer commandBuffer,
|
||||||
VkImage _image,
|
VkImage _image,
|
||||||
|
|
|
||||||
|
|
@ -944,123 +944,3 @@ void anv_CmdClearAttachments(
|
||||||
|
|
||||||
meta_clear_end(&saved_state, cmd_buffer);
|
meta_clear_end(&saved_state, cmd_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
do_buffer_fill(struct anv_cmd_buffer *cmd_buffer,
|
|
||||||
struct anv_bo *dest, uint64_t dest_offset,
|
|
||||||
int width, int height, VkFormat fill_format, uint32_t data)
|
|
||||||
{
|
|
||||||
VkDevice vk_device = anv_device_to_handle(cmd_buffer->device);
|
|
||||||
|
|
||||||
VkImageCreateInfo image_info = {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
|
||||||
.imageType = VK_IMAGE_TYPE_2D,
|
|
||||||
.format = fill_format,
|
|
||||||
.extent = {
|
|
||||||
.width = width,
|
|
||||||
.height = height,
|
|
||||||
.depth = 1,
|
|
||||||
},
|
|
||||||
.mipLevels = 1,
|
|
||||||
.arrayLayers = 1,
|
|
||||||
.samples = 1,
|
|
||||||
.tiling = VK_IMAGE_TILING_LINEAR,
|
|
||||||
.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
|
||||||
.flags = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
VkImage dest_image;
|
|
||||||
image_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
|
||||||
anv_CreateImage(vk_device, &image_info,
|
|
||||||
&cmd_buffer->pool->alloc, &dest_image);
|
|
||||||
|
|
||||||
/* We could use a vk call to bind memory, but that would require
|
|
||||||
* creating a dummy memory object etc. so there's really no point.
|
|
||||||
*/
|
|
||||||
anv_image_from_handle(dest_image)->bo = dest;
|
|
||||||
anv_image_from_handle(dest_image)->offset = dest_offset;
|
|
||||||
|
|
||||||
const VkClearValue clear_value = {
|
|
||||||
.color = {
|
|
||||||
.uint32 = { data, data, data, data }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const VkImageSubresourceRange range = {
|
|
||||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
|
||||||
.baseMipLevel = 0,
|
|
||||||
.levelCount = 1,
|
|
||||||
.baseArrayLayer = 0,
|
|
||||||
.layerCount = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
anv_cmd_clear_image(cmd_buffer, anv_image_from_handle(dest_image),
|
|
||||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
|
||||||
clear_value, 1, &range);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 anv_meta_saved_state saved_state;
|
|
||||||
|
|
||||||
meta_clear_begin(&saved_state, cmd_buffer);
|
|
||||||
|
|
||||||
if (fillSize == VK_WHOLE_SIZE) {
|
|
||||||
fillSize = dst_buffer->size - dstOffset;
|
|
||||||
/* Make sure fillSize is a multiple of 4 */
|
|
||||||
fillSize -= fillSize & 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkFormat format;
|
|
||||||
int bs;
|
|
||||||
if ((fillSize & 15) == 0 && (dstOffset & 15) == 0) {
|
|
||||||
format = VK_FORMAT_R32G32B32A32_UINT;
|
|
||||||
bs = 16;
|
|
||||||
} else if ((fillSize & 7) == 0 && (dstOffset & 15) == 0) {
|
|
||||||
format = VK_FORMAT_R32G32_UINT;
|
|
||||||
bs = 8;
|
|
||||||
} else {
|
|
||||||
assert((fillSize & 3) == 0 && (dstOffset & 3) == 0);
|
|
||||||
format = VK_FORMAT_R32_UINT;
|
|
||||||
bs = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This is maximum possible width/height our HW can handle */
|
|
||||||
const uint64_t max_surface_dim = 1 << 14;
|
|
||||||
|
|
||||||
/* First, we make a bunch of max-sized copies */
|
|
||||||
const uint64_t max_fill_size = max_surface_dim * max_surface_dim * bs;
|
|
||||||
while (fillSize > max_fill_size) {
|
|
||||||
do_buffer_fill(cmd_buffer, dst_buffer->bo,
|
|
||||||
dst_buffer->offset + dstOffset,
|
|
||||||
max_surface_dim, max_surface_dim, format, data);
|
|
||||||
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;
|
|
||||||
do_buffer_fill(cmd_buffer, dst_buffer->bo,
|
|
||||||
dst_buffer->offset + dstOffset,
|
|
||||||
max_surface_dim, height, format, data);
|
|
||||||
fillSize -= rect_fill_size;
|
|
||||||
dstOffset += rect_fill_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fillSize != 0) {
|
|
||||||
do_buffer_fill(cmd_buffer, dst_buffer->bo,
|
|
||||||
dst_buffer->offset + dstOffset,
|
|
||||||
fillSize / bs, 1, format, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
meta_clear_end(&saved_state, cmd_buffer);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue