From d6ac9dcac7ddf92ae35acf0d3714b0c456d45d78 Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Mon, 30 Jan 2023 20:11:57 -0600 Subject: [PATCH] nvk: Use MME for clears Part-of: --- src/nouveau/vulkan/nvk_cmd_clear.c | 99 +++++++++++++++++++++--------- src/nouveau/vulkan/nvk_mme.c | 2 + src/nouveau/vulkan/nvk_mme.h | 5 ++ 3 files changed, 76 insertions(+), 30 deletions(-) diff --git a/src/nouveau/vulkan/nvk_cmd_clear.c b/src/nouveau/vulkan/nvk_cmd_clear.c index a4898384174..8ff2dd13185 100644 --- a/src/nouveau/vulkan/nvk_cmd_clear.c +++ b/src/nouveau/vulkan/nvk_cmd_clear.c @@ -3,12 +3,50 @@ #include "nvk_device.h" #include "nvk_image.h" #include "nvk_image_view.h" +#include "nvk_mme.h" #include "nvk_physical_device.h" #include "nil_format.h" #include "vk_format.h" #include "nvk_cl9097.h" +#include "drf.h" + +void nvk_mme_clear_views(struct nvk_device *dev, + struct mme_builder *b) +{ + struct mme_value payload = mme_load(b); + struct mme_value view_mask = mme_load(b); + struct mme_value bit = mme_mov(b, mme_imm(1)); + + const uint32_t arr_idx = 1 << DRF_LO(NV9097_CLEAR_SURFACE_RT_ARRAY_INDEX); + + mme_loop(b, mme_imm(32)) { + mme_if(b, ine, mme_and(b, view_mask, bit), mme_zero()) { + mme_mthd(b, NV9097_CLEAR_SURFACE); + mme_emit(b, payload); + } + + mme_add_to(b, payload, payload, mme_imm(arr_idx)); + mme_sll_to(b, bit, bit, mme_imm(1)); + } +} + +void nvk_mme_clear_layers(struct nvk_device *dev, + struct mme_builder *b) +{ + struct mme_value payload = mme_load(b); + struct mme_value layer_count = mme_load(b); + + const uint32_t arr_idx = 1 << DRF_LO(NV9097_CLEAR_SURFACE_RT_ARRAY_INDEX); + + mme_loop(b, layer_count) { + mme_mthd(b, NV9097_CLEAR_SURFACE); + mme_emit(b, payload); + + mme_add_to(b, payload, payload, mme_imm(arr_idx)); + } +} static void emit_clear_rects(struct nvk_cmd_buffer *cmd, @@ -20,9 +58,9 @@ emit_clear_rects(struct nvk_cmd_buffer *cmd, { struct nvk_rendering_state *render = &cmd->state.gfx.render; - for (uint32_t r = 0; r < rect_count; r++) { - struct nouveau_ws_push_buffer *p = P_SPACE(cmd->push, 3); + struct nouveau_ws_push_buffer *p = P_SPACE(cmd->push, rect_count * 6); + 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, @@ -34,36 +72,37 @@ emit_clear_rects(struct nvk_cmd_buffer *cmd, }); if (render->view_mask) { - assert(rects[r].baseArrayLayer == 0); - assert(rects[r].layerCount == 1); - p = P_SPACE(cmd->push, 64); + uint32_t payload; + V_NV9097_CLEAR_SURFACE(payload, { + .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, + }); - 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, - }); - } + P_1INC(p, NV9097, CALL_MME_MACRO(NVK_MME_CLEAR_LAYERS)); + P_INLINE_DATA(p, payload); + P_INLINE_DATA(p, render->view_mask); } else { - for (uint32_t l = 0; l < rects[r].layerCount; l++) { - p = P_SPACE(cmd->push, 2); - 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, - }); - } + uint32_t payload; + V_NV9097_CLEAR_SURFACE(payload, { + .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, + }); + + P_1INC(p, NV9097, CALL_MME_MACRO(NVK_MME_CLEAR_LAYERS)); + P_INLINE_DATA(p, payload); + P_INLINE_DATA(p, rects[r].layerCount); } } } diff --git a/src/nouveau/vulkan/nvk_mme.c b/src/nouveau/vulkan/nvk_mme.c index 221fa9f03f9..a8de4457611 100644 --- a/src/nouveau/vulkan/nvk_mme.c +++ b/src/nouveau/vulkan/nvk_mme.c @@ -3,6 +3,8 @@ #include "nvk_device.h" static const nvk_mme_builder_func mme_builders[NVK_MME_COUNT] = { + [NVK_MME_CLEAR_VIEWS] = nvk_mme_clear_views, + [NVK_MME_CLEAR_LAYERS] = nvk_mme_clear_layers, }; uint32_t * diff --git a/src/nouveau/vulkan/nvk_mme.h b/src/nouveau/vulkan/nvk_mme.h index 6aeff6c209c..10e325eccf6 100644 --- a/src/nouveau/vulkan/nvk_mme.h +++ b/src/nouveau/vulkan/nvk_mme.h @@ -6,6 +6,8 @@ struct nvk_device; enum nvk_mme { + NVK_MME_CLEAR_VIEWS, + NVK_MME_CLEAR_LAYERS, NVK_MME_COUNT, }; @@ -15,4 +17,7 @@ typedef void (*nvk_mme_builder_func)(struct nvk_device *dev, uint32_t *nvk_build_mme(struct nvk_device *dev, enum nvk_mme mme, size_t *size_out); +void nvk_mme_clear_views(struct nvk_device *dev, struct mme_builder *b); +void nvk_mme_clear_layers(struct nvk_device *dev, struct mme_builder *b); + #endif /* NVK_MME_H */