From: Faith Ekstrand Date: Tue, 31 Jan 2023 02:11:55 +0000 (-0600) Subject: nvk: Use hardware clears for attachment clears X-Git-Tag: upstream/23.3.3~4325 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7b7bfbcc61dceba891f9c89184877acd7918d8ec;p=platform%2Fupstream%2Fmesa.git nvk: Use hardware clears for attachment clears Part-of: --- diff --git a/src/nouveau/vulkan/meson.build b/src/nouveau/vulkan/meson.build index cdcaf4c..82dfa3f 100644 --- a/src/nouveau/vulkan/meson.build +++ b/src/nouveau/vulkan/meson.build @@ -9,6 +9,7 @@ nvk_files = files( 'nvk_cmd_blit.c', 'nvk_cmd_buffer.c', 'nvk_cmd_buffer.h', + 'nvk_cmd_clear.c', 'nvk_cmd_copy.c', 'nvk_cmd_dispatch.c', 'nvk_cmd_draw.c', diff --git a/src/nouveau/vulkan/nvk_cmd_clear.c b/src/nouveau/vulkan/nvk_cmd_clear.c new file mode 100644 index 0000000..6019771 --- /dev/null +++ b/src/nouveau/vulkan/nvk_cmd_clear.c @@ -0,0 +1,116 @@ +#include "nvk_cmd_buffer.h" + +#include "nvk_cl9097.h" + +static void +emit_clear_rects(struct nvk_cmd_buffer *cmd, + int color_att, + bool clear_depth, + bool clear_stencil, + uint32_t rect_count, + const VkClearRect *rects) +{ + struct nvk_rendering_state *render = &cmd->state.gfx.render; + struct nouveau_ws_push *p = cmd->push; + + for (uint32_t r = 0; r < rect_count; r++) { + P_MTHD(p, NV9097, SET_CLEAR_RECT_HORIZONTAL); + P_NV9097_SET_CLEAR_RECT_HORIZONTAL(p, { + .xmin = rects[r].rect.offset.x, + .xmax = rects[r].rect.offset.x + rects[r].rect.extent.width, + }); + P_NV9097_SET_CLEAR_RECT_VERTICAL(p, { + .ymin = rects[r].rect.offset.y, + .ymax = rects[r].rect.offset.y + rects[r].rect.extent.height, + }); + + if (render->view_mask) { + assert(rects[r].baseArrayLayer == 0); + assert(rects[r].layerCount == 1); + u_foreach_bit(view, render->view_mask) { + P_IMMD(p, NV9097, CLEAR_SURFACE, { + .z_enable = clear_depth, + .stencil_enable = clear_stencil, + .r_enable = color_att >= 0, + .g_enable = color_att >= 0, + .b_enable = color_att >= 0, + .a_enable = color_att >= 0, + .mrt_select = color_att >= 0 ? color_att : 0, + .rt_array_index = view, + }); + } + } else { + for (uint32_t l = 0; l < rects[r].layerCount; l++) { + P_IMMD(p, NV9097, CLEAR_SURFACE, { + .z_enable = clear_depth, + .stencil_enable = clear_stencil, + .r_enable = color_att >= 0, + .g_enable = color_att >= 0, + .b_enable = color_att >= 0, + .a_enable = color_att >= 0, + .mrt_select = color_att >= 0 ? color_att : 0, + .rt_array_index = rects[r].baseArrayLayer + l, + }); + } + } + } +} + +VKAPI_ATTR void VKAPI_CALL +nvk_CmdClearAttachments(VkCommandBuffer commandBuffer, + uint32_t attachmentCount, + const VkClearAttachment *pAttachments, + uint32_t rectCount, + const VkClearRect *pRects) +{ + VK_FROM_HANDLE(nvk_cmd_buffer, cmd, commandBuffer); + struct nouveau_ws_push *p = cmd->push; + + P_IMMD(p, NV9097, SET_CLEAR_SURFACE_CONTROL, { + .respect_stencil_mask = RESPECT_STENCIL_MASK_FALSE, + .use_clear_rect = USE_CLEAR_RECT_TRUE, + .use_scissor0 = USE_SCISSOR0_FALSE, + .use_viewport_clip0 = USE_VIEWPORT_CLIP0_FALSE, + }); + + bool clear_depth = false, clear_stencil = false; + for (uint32_t i = 0; i < attachmentCount; i++) { + if (pAttachments[i].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) { + P_IMMD(p, NV9097, SET_Z_CLEAR_VALUE, + fui(pAttachments[i].clearValue.depthStencil.depth)); + clear_depth = true; + } + + if (pAttachments[i].aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) { + P_IMMD(p, NV9097, SET_STENCIL_CLEAR_VALUE, + pAttachments[i].clearValue.depthStencil.stencil & 0xff); + clear_stencil = true; + } + } + + for (uint32_t i = 0; i < attachmentCount; i++) { + if (pAttachments[i].aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) + continue; + + if (pAttachments[i].colorAttachment == VK_ATTACHMENT_UNUSED) + continue; + + VkClearColorValue color = pAttachments[i].clearValue.color; + + P_MTHD(p, NV9097, SET_COLOR_CLEAR_VALUE(0)); + P_NV9097_SET_COLOR_CLEAR_VALUE(p, 0, color.uint32[0]); + P_NV9097_SET_COLOR_CLEAR_VALUE(p, 1, color.uint32[1]); + P_NV9097_SET_COLOR_CLEAR_VALUE(p, 2, color.uint32[2]); + P_NV9097_SET_COLOR_CLEAR_VALUE(p, 3, color.uint32[3]); + + emit_clear_rects(cmd, pAttachments[i].colorAttachment, + clear_depth, clear_stencil, rectCount, pRects); + + /* We only need to clear depth/stencil once */ + clear_depth = clear_stencil = false; + } + + /* No color clears */ + if (clear_depth || clear_stencil) + emit_clear_rects(cmd, -1, clear_depth, clear_stencil, rectCount, pRects); +} diff --git a/src/nouveau/vulkan/nvk_cmd_meta.c b/src/nouveau/vulkan/nvk_cmd_meta.c index a8be8ba..a18cdab 100644 --- a/src/nouveau/vulkan/nvk_cmd_meta.c +++ b/src/nouveau/vulkan/nvk_cmd_meta.c @@ -102,29 +102,6 @@ nvk_meta_end(struct nvk_cmd_buffer *cmd, } VKAPI_ATTR void VKAPI_CALL -nvk_CmdClearAttachments(VkCommandBuffer commandBuffer, - uint32_t attachmentCount, - const VkClearAttachment *pAttachments, - uint32_t rectCount, - const VkClearRect *pRects) -{ - VK_FROM_HANDLE(nvk_cmd_buffer, cmd, commandBuffer); - struct nvk_device *dev = nvk_cmd_buffer_device(cmd); - - struct nvk_meta_save save; - nvk_meta_begin(cmd, &save); - - struct vk_meta_rendering_info render; - nvk_meta_init_render(cmd, &render); - - vk_meta_clear_attachments(&cmd->vk, &dev->meta, &render, - attachmentCount, pAttachments, - rectCount, pRects); - - nvk_meta_end(cmd, &save); -} - -VKAPI_ATTR void VKAPI_CALL nvk_CmdClearColorImage(VkCommandBuffer commandBuffer, VkImage _image, VkImageLayout imageLayout,