mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 06:58:05 +02:00
panvk/csf: Just issue RUN_FRAGMENT for cmdClearColorImage
The Vulkan meta path issues a full drawcall with a rectangle primitive for cmdClearColorImage. We can instead just issue a RUN_FRAGMENT without any primitives and setting a clear color. This will avoid executing a shader at all in this case and just do a HW clear.
This commit is contained in:
parent
ba35486229
commit
174591a73a
3 changed files with 196 additions and 26 deletions
|
|
@ -540,6 +540,11 @@ panvk_cache_flush_is_nop(const struct panvk_cache_flush_info *cache_flush)
|
|||
extern const struct vk_command_buffer_ops panvk_per_arch(cmd_buffer_ops);
|
||||
|
||||
void panvk_per_arch(cmd_fb_barrier)(struct panvk_cmd_buffer *cmdbuf);
|
||||
void panvk_per_arch(cmd_clear_color_image)(
|
||||
struct panvk_cmd_buffer *cmdbuf, struct panvk_device *dev,
|
||||
struct panvk_image *image, VkImageLayout image_layout,
|
||||
const VkClearColorValue *color_value, uint32_t range_count,
|
||||
const VkImageSubresourceRange *ranges);
|
||||
|
||||
#if PAN_ARCH == 10
|
||||
/* Match against all possible iter_sb values. The constant iter_sb value for
|
||||
|
|
|
|||
|
|
@ -3648,6 +3648,190 @@ handle_deferred_queries(struct panvk_cmd_buffer *cmdbuf)
|
|||
}
|
||||
}
|
||||
|
||||
static struct panvk_image_view *
|
||||
create_internal_panvk_image_view(struct vk_command_buffer *cmdbuf,
|
||||
struct vk_meta_device *meta, VkImage image,
|
||||
uint32_t level, uint32_t base_array_level,
|
||||
uint32_t layer_count)
|
||||
{
|
||||
VK_FROM_HANDLE(panvk_image, pan_image, image);
|
||||
VkImageViewUsageCreateInfo view_usage = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO,
|
||||
};
|
||||
|
||||
if (pan_image->vk.aspects == VK_IMAGE_ASPECT_COLOR_BIT)
|
||||
view_usage.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
if (pan_image->vk.aspects &
|
||||
(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
|
||||
view_usage.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||
|
||||
VkImageViewType view_type;
|
||||
if (pan_image->vk.image_type == VK_IMAGE_TYPE_1D) {
|
||||
view_type =
|
||||
layer_count == 1 ? VK_IMAGE_VIEW_TYPE_1D : VK_IMAGE_VIEW_TYPE_1D_ARRAY;
|
||||
} else {
|
||||
assert((pan_image->vk.image_type == VK_IMAGE_TYPE_2D ||
|
||||
pan_image->vk.image_type == VK_IMAGE_TYPE_3D) &&
|
||||
"Invalid image type");
|
||||
view_type =
|
||||
layer_count == 1 ? VK_IMAGE_VIEW_TYPE_2D : VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
||||
}
|
||||
|
||||
const VkImageViewCreateInfo view_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||
.flags = VK_IMAGE_VIEW_CREATE_DRIVER_INTERNAL_BIT_MESA,
|
||||
.pNext = &view_usage,
|
||||
.image = image,
|
||||
.viewType = view_type,
|
||||
.format = pan_image->vk.format,
|
||||
.subresourceRange = {
|
||||
.aspectMask = pan_image->vk.aspects,
|
||||
.baseMipLevel = level,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = base_array_level,
|
||||
.layerCount = layer_count,
|
||||
}};
|
||||
|
||||
VkImageView image_view;
|
||||
VkResult result =
|
||||
vk_meta_create_image_view(cmdbuf, meta, &view_info, &image_view);
|
||||
|
||||
if (unlikely(result != VK_SUCCESS))
|
||||
return NULL;
|
||||
|
||||
VK_FROM_HANDLE(panvk_image_view, pan_image_view, image_view);
|
||||
return pan_image_view;
|
||||
}
|
||||
|
||||
static void
|
||||
setup_clear_render_state(struct panvk_cmd_buffer *cmdbuf,
|
||||
struct panvk_image_view *clear_image_view,
|
||||
VkImageLayout image_layout,
|
||||
const VkClearValue clear_value, uint32_t layer_count)
|
||||
{
|
||||
const VkRenderingAttachmentInfo color_att = {
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||
.imageView = panvk_image_view_to_handle(clear_image_view),
|
||||
.imageLayout = image_layout,
|
||||
.resolveMode = VK_RESOLVE_MODE_NONE,
|
||||
.resolveImageView = VK_NULL_HANDLE,
|
||||
.resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||
.clearValue = clear_value,
|
||||
};
|
||||
|
||||
const VkRenderingInfo info = {
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
|
||||
.flags = 0,
|
||||
.renderArea =
|
||||
{
|
||||
.offset = {0, 0},
|
||||
.extent =
|
||||
{
|
||||
.width = clear_image_view->vk.extent.width,
|
||||
.height = clear_image_view->vk.extent.height,
|
||||
},
|
||||
},
|
||||
.layerCount = layer_count,
|
||||
.viewMask = 0,
|
||||
.colorAttachmentCount = 1,
|
||||
.pColorAttachments = &color_att,
|
||||
.pDepthAttachment = NULL,
|
||||
.pStencilAttachment = NULL,
|
||||
};
|
||||
|
||||
panvk_per_arch(cmd_init_render_state)(cmdbuf, &info);
|
||||
}
|
||||
|
||||
static void
|
||||
reset_render_state(struct panvk_cmd_buffer *cmdbuf, bool suspending,
|
||||
bool resolve_attachments)
|
||||
{
|
||||
memset(&cmdbuf->state.gfx.render.fbds, 0,
|
||||
sizeof(cmdbuf->state.gfx.render.fbds));
|
||||
memset(&cmdbuf->state.gfx.render.oq, 0, sizeof(cmdbuf->state.gfx.render.oq));
|
||||
|
||||
cmdbuf->state.gfx.render.tiler = 0;
|
||||
|
||||
/* If we're finished with this render pass, make sure we reset the flags
|
||||
* so any barrier encountered after doesn't try to flush
|
||||
* draws. */
|
||||
cmdbuf->state.gfx.render.flags = 0;
|
||||
cmdbuf->state.gfx.render.suspended = suspending;
|
||||
|
||||
if (resolve_attachments)
|
||||
panvk_per_arch(cmd_meta_resolve_attachments)(cmdbuf);
|
||||
|
||||
struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
|
||||
struct panvk_instr_end_args instr_info = {
|
||||
.render = {
|
||||
.flags = cmdbuf->state.gfx.render.flags,
|
||||
.fb = &cmdbuf->state.gfx.render.fb.layout,
|
||||
}};
|
||||
|
||||
panvk_per_arch(panvk_instr_end_work_async)(
|
||||
PANVK_SUBQUEUE_VERTEX_TILER, cmdbuf, PANVK_INSTR_WORK_TYPE_RENDER,
|
||||
&instr_info, cs_defer(dev->csf.sb.all_iters_mask, 0));
|
||||
panvk_per_arch(panvk_instr_end_work_async)(
|
||||
PANVK_SUBQUEUE_FRAGMENT, cmdbuf, PANVK_INSTR_WORK_TYPE_RENDER,
|
||||
&instr_info, cs_defer(dev->csf.sb.all_iters_mask, 0));
|
||||
}
|
||||
|
||||
void
|
||||
panvk_per_arch(cmd_clear_color_image)(struct panvk_cmd_buffer *cmdbuf,
|
||||
struct panvk_device *dev,
|
||||
struct panvk_image *image,
|
||||
VkImageLayout image_layout,
|
||||
const VkClearColorValue *color_value,
|
||||
uint32_t range_count,
|
||||
const VkImageSubresourceRange *ranges)
|
||||
{
|
||||
for (uint32_t r = 0; r < range_count; r++) {
|
||||
const VkImageSubresourceRange *range = &ranges[r];
|
||||
const uint32_t level_count =
|
||||
vk_image_subresource_level_count(&image->vk, range);
|
||||
|
||||
for (uint32_t l = 0; l < level_count; l++) {
|
||||
const uint32_t level = range->baseMipLevel + l;
|
||||
uint32_t base_array_layer, layer_count;
|
||||
|
||||
if (image->vk.image_type == VK_IMAGE_TYPE_3D) {
|
||||
const VkExtent3D level_extent =
|
||||
vk_image_mip_level_extent(&image->vk, level);
|
||||
base_array_layer = 0;
|
||||
layer_count = level_extent.depth;
|
||||
} else {
|
||||
base_array_layer = range->baseArrayLayer;
|
||||
layer_count = vk_image_subresource_layer_count(&image->vk, range);
|
||||
}
|
||||
|
||||
VkImage p_image = panvk_image_to_handle(image);
|
||||
struct panvk_image_view *image_view = create_internal_panvk_image_view(
|
||||
&cmdbuf->vk, &dev->meta, p_image, level, base_array_layer,
|
||||
layer_count);
|
||||
if (unlikely(image_view == NULL)) {
|
||||
reset_render_state(cmdbuf, false, false);
|
||||
return;
|
||||
}
|
||||
|
||||
const VkClearValue clear_value = {
|
||||
.color = *color_value,
|
||||
};
|
||||
|
||||
setup_clear_render_state(cmdbuf, image_view, image_layout, clear_value,
|
||||
layer_count);
|
||||
VkResult result = get_render_ctx(cmdbuf);
|
||||
if (unlikely(result != VK_SUCCESS)) {
|
||||
reset_render_state(cmdbuf, false, false);
|
||||
return;
|
||||
}
|
||||
issue_fragment_jobs(cmdbuf);
|
||||
reset_render_state(cmdbuf, false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
panvk_per_arch(CmdEndRendering)(VkCommandBuffer commandBuffer)
|
||||
{
|
||||
|
|
@ -3697,31 +3881,7 @@ panvk_per_arch(CmdEndRendering)(VkCommandBuffer commandBuffer)
|
|||
return;
|
||||
}
|
||||
|
||||
memset(&cmdbuf->state.gfx.render.fbds, 0,
|
||||
sizeof(cmdbuf->state.gfx.render.fbds));
|
||||
memset(&cmdbuf->state.gfx.render.oq, 0, sizeof(cmdbuf->state.gfx.render.oq));
|
||||
cmdbuf->state.gfx.render.tiler = 0;
|
||||
|
||||
/* If we're finished with this render pass, make sure we reset the flags
|
||||
* so any barrier encountered after EndRendering() doesn't try to flush
|
||||
* draws. */
|
||||
cmdbuf->state.gfx.render.flags = 0;
|
||||
cmdbuf->state.gfx.render.suspended = suspending;
|
||||
|
||||
/* If we're not suspending, we need to resolve attachments. */
|
||||
if (!suspending)
|
||||
panvk_per_arch(cmd_meta_resolve_attachments)(cmdbuf);
|
||||
|
||||
struct panvk_instr_end_args instr_info = {
|
||||
.render = {
|
||||
.flags = cmdbuf->state.gfx.render.flags,
|
||||
.fb = &cmdbuf->state.gfx.render.fb.layout,
|
||||
}};
|
||||
struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
|
||||
panvk_per_arch(panvk_instr_end_work_async)(
|
||||
PANVK_SUBQUEUE_VERTEX_TILER, cmdbuf, PANVK_INSTR_WORK_TYPE_RENDER,
|
||||
&instr_info, cs_defer(dev->csf.sb.all_iters_mask, 0));
|
||||
panvk_per_arch(panvk_instr_end_work_async)(
|
||||
PANVK_SUBQUEUE_FRAGMENT, cmdbuf, PANVK_INSTR_WORK_TYPE_RENDER,
|
||||
&instr_info, cs_defer(dev->csf.sb.all_iters_mask, 0));
|
||||
bool resolve_attachments = !suspending;
|
||||
reset_render_state(cmdbuf, suspending, resolve_attachments);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -318,8 +318,13 @@ panvk_per_arch(CmdClearColorImage)(VkCommandBuffer commandBuffer, VkImage image,
|
|||
struct panvk_cmd_meta_graphics_save_ctx save = {0};
|
||||
|
||||
meta_gfx_start(cmdbuf, &save);
|
||||
#if PAN_ARCH >= 10
|
||||
panvk_per_arch(cmd_clear_color_image)(cmdbuf, dev, img, imageLayout, pColor,
|
||||
rangeCount, pRanges);
|
||||
#else
|
||||
vk_meta_clear_color_image(&cmdbuf->vk, &dev->meta, &img->vk, imageLayout,
|
||||
img->vk.format, pColor, rangeCount, pRanges);
|
||||
#endif
|
||||
meta_gfx_end(cmdbuf, &save);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue