Mesa (main): radv: implement dynamic logic op

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jun 22 15:52:02 UTC 2021


Module: Mesa
Branch: main
Commit: 8efa8971683f50a3b9473a0be7d2027f0465a6dd
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=8efa8971683f50a3b9473a0be7d2027f0465a6dd

Author: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Date:   Mon May 17 10:41:24 2021 +0200

radv: implement dynamic logic op

This is part of VK_EXT_extended_dynamic_state2.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10880>

---

 src/amd/vulkan/radv_cmd_buffer.c | 39 ++++++++++++++++++++++-
 src/amd/vulkan/radv_meta.c       |  6 +++-
 src/amd/vulkan/radv_meta.h       |  2 ++
 src/amd/vulkan/radv_pipeline.c   | 68 +++++++++++-----------------------------
 src/amd/vulkan/radv_private.h    | 44 ++++++++++++++++++++++++++
 5 files changed, 107 insertions(+), 52 deletions(-)

diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c
index cb4ca507c02..76f010773e1 100644
--- a/src/amd/vulkan/radv_cmd_buffer.c
+++ b/src/amd/vulkan/radv_cmd_buffer.c
@@ -115,6 +115,7 @@ const struct radv_dynamic_state default_dynamic_state = {
    .depth_bias_enable = 0u,
    .primitive_restart_enable = 0u,
    .rasterizer_discard_enable = 0u,
+   .logic_op = 0u,
 };
 
 static void
@@ -327,6 +328,13 @@ radv_bind_dynamic_state(struct radv_cmd_buffer *cmd_buffer, const struct radv_dy
       }
    }
 
+   if (copy_mask & RADV_DYNAMIC_LOGIC_OP) {
+      if (dest->logic_op != src->logic_op) {
+         dest->logic_op = src->logic_op;
+         dest_mask |= RADV_DYNAMIC_LOGIC_OP;
+      }
+   }
+
    cmd_buffer->state.dirty |= dest_mask;
 }
 
@@ -1282,6 +1290,11 @@ radv_emit_graphics_pipeline(struct radv_cmd_buffer *cmd_buffer)
           pipeline->graphics.pa_cl_clip_cntl)
       cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE;
 
+   if (!cmd_buffer->state.emitted_pipeline ||
+       cmd_buffer->state.emitted_pipeline->graphics.cb_color_control !=
+       pipeline->graphics.cb_color_control)
+      cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_LOGIC_OP;
+
    if (!cmd_buffer->state.emitted_pipeline)
       cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY |
                                  RADV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS |
@@ -1598,6 +1611,18 @@ radv_emit_rasterizer_discard_enable(struct radv_cmd_buffer *cmd_buffer)
    radeon_set_context_reg(cmd_buffer->cs, R_028810_PA_CL_CLIP_CNTL, pa_cl_clip_cntl);
 }
 
+static void
+radv_emit_logic_op(struct radv_cmd_buffer *cmd_buffer)
+{
+   unsigned cb_color_control = cmd_buffer->state.pipeline->graphics.cb_color_control;
+   struct radv_dynamic_state *d = &cmd_buffer->state.dynamic;
+
+   cb_color_control &= C_028808_ROP3;
+   cb_color_control |= S_028808_ROP3(d->logic_op);
+
+   radeon_set_context_reg(cmd_buffer->cs, R_028808_CB_COLOR_CONTROL, cb_color_control);
+}
+
 static void
 radv_emit_fb_color_state(struct radv_cmd_buffer *cmd_buffer, int index,
                          struct radv_color_buffer_info *cb, struct radv_image_view *iview,
@@ -2598,6 +2623,9 @@ radv_cmd_buffer_flush_dynamic_state(struct radv_cmd_buffer *cmd_buffer)
    if (states & RADV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE)
       radv_emit_rasterizer_discard_enable(cmd_buffer);
 
+   if (states & RADV_CMD_DIRTY_DYNAMIC_LOGIC_OP)
+      radv_emit_logic_op(cmd_buffer);
+
    cmd_buffer->state.dirty &= ~states;
 }
 
@@ -4765,7 +4793,16 @@ radv_CmdSetPatchControlPointsEXT(VkCommandBuffer commandBuffer, uint32_t patchCo
 void
 radv_CmdSetLogicOpEXT(VkCommandBuffer commandBuffer, VkLogicOp logicOp)
 {
-   /* not implemented */
+   RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
+   struct radv_cmd_state *state = &cmd_buffer->state;
+   unsigned logic_op = si_translate_blend_logic_op(logicOp);
+
+   if (state->dynamic.logic_op == logic_op)
+      return;
+
+   state->dynamic.logic_op = logic_op;
+
+   state->dirty |= RADV_CMD_DIRTY_DYNAMIC_LOGIC_OP;
 }
 
 void
diff --git a/src/amd/vulkan/radv_meta.c b/src/amd/vulkan/radv_meta.c
index b54e4bd183c..bc3729e32e7 100644
--- a/src/amd/vulkan/radv_meta.c
+++ b/src/amd/vulkan/radv_meta.c
@@ -97,6 +97,8 @@ radv_meta_save(struct radv_meta_saved_state *state, struct radv_cmd_buffer *cmd_
       state->primitive_restart_enable = cmd_buffer->state.dynamic.primitive_restart_enable;
 
       state->rasterizer_discard_enable = cmd_buffer->state.dynamic.rasterizer_discard_enable;
+
+      state->logic_op = cmd_buffer->state.dynamic.logic_op;
    }
 
    if (state->flags & RADV_META_SAVE_SAMPLE_LOCATIONS) {
@@ -186,6 +188,8 @@ radv_meta_restore(const struct radv_meta_saved_state *state, struct radv_cmd_buf
 
       cmd_buffer->state.dynamic.rasterizer_discard_enable = state->rasterizer_discard_enable;
 
+      cmd_buffer->state.dynamic.logic_op = state->logic_op;
+
       cmd_buffer->state.dirty |=
          RADV_CMD_DIRTY_DYNAMIC_VIEWPORT | RADV_CMD_DIRTY_DYNAMIC_SCISSOR |
          RADV_CMD_DIRTY_DYNAMIC_CULL_MODE | RADV_CMD_DIRTY_DYNAMIC_FRONT_FACE |
@@ -195,7 +199,7 @@ radv_meta_restore(const struct radv_meta_saved_state *state, struct radv_cmd_buf
          RADV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE | RADV_CMD_DIRTY_DYNAMIC_STENCIL_OP |
          RADV_CMD_DIRTY_DYNAMIC_FRAGMENT_SHADING_RATE | RADV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE |
          RADV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE |
-         RADV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE;
+         RADV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE | RADV_CMD_DIRTY_DYNAMIC_LOGIC_OP;
    }
 
    if (state->flags & RADV_META_SAVE_SAMPLE_LOCATIONS) {
diff --git a/src/amd/vulkan/radv_meta.h b/src/amd/vulkan/radv_meta.h
index d04da9d3a2b..da9c00441e1 100644
--- a/src/amd/vulkan/radv_meta.h
+++ b/src/amd/vulkan/radv_meta.h
@@ -94,6 +94,8 @@ struct radv_meta_saved_state {
    bool depth_bias_enable;
    bool primitive_restart_enable;
    bool rasterizer_discard_enable;
+
+   unsigned logic_op;
 };
 
 VkResult radv_device_init_meta_clear_state(struct radv_device *device, bool on_demand);
diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c
index a8b028a568a..3ff3161438d 100644
--- a/src/amd/vulkan/radv_pipeline.c
+++ b/src/amd/vulkan/radv_pipeline.c
@@ -51,7 +51,6 @@ struct radv_blend_state {
    uint32_t blend_enable_4bit;
    uint32_t need_src_alpha;
 
-   uint32_t cb_color_control;
    uint32_t cb_target_mask;
    uint32_t cb_target_enabled_4bit;
    uint32_t sx_mrt_blend_opt[8];
@@ -275,47 +274,6 @@ radv_pipeline_init_scratch(const struct radv_device *device, struct radv_pipelin
    pipeline->max_waves = max_waves;
 }
 
-static uint32_t
-si_translate_blend_logic_op(VkLogicOp op)
-{
-   switch (op) {
-   case VK_LOGIC_OP_CLEAR:
-      return V_028808_ROP3_CLEAR;
-   case VK_LOGIC_OP_AND:
-      return V_028808_ROP3_AND;
-   case VK_LOGIC_OP_AND_REVERSE:
-      return V_028808_ROP3_AND_REVERSE;
-   case VK_LOGIC_OP_COPY:
-      return V_028808_ROP3_COPY;
-   case VK_LOGIC_OP_AND_INVERTED:
-      return V_028808_ROP3_AND_INVERTED;
-   case VK_LOGIC_OP_NO_OP:
-      return V_028808_ROP3_NO_OP;
-   case VK_LOGIC_OP_XOR:
-      return V_028808_ROP3_XOR;
-   case VK_LOGIC_OP_OR:
-      return V_028808_ROP3_OR;
-   case VK_LOGIC_OP_NOR:
-      return V_028808_ROP3_NOR;
-   case VK_LOGIC_OP_EQUIVALENT:
-      return V_028808_ROP3_EQUIVALENT;
-   case VK_LOGIC_OP_INVERT:
-      return V_028808_ROP3_INVERT;
-   case VK_LOGIC_OP_OR_REVERSE:
-      return V_028808_ROP3_OR_REVERSE;
-   case VK_LOGIC_OP_COPY_INVERTED:
-      return V_028808_ROP3_COPY_INVERTED;
-   case VK_LOGIC_OP_OR_INVERTED:
-      return V_028808_ROP3_OR_INVERTED;
-   case VK_LOGIC_OP_NAND:
-      return V_028808_ROP3_NAND;
-   case VK_LOGIC_OP_SET:
-      return V_028808_ROP3_SET;
-   default:
-      unreachable("Unhandled logic op");
-   }
-}
-
 static uint32_t
 si_translate_blend_function(VkBlendOp op)
 {
@@ -656,7 +614,7 @@ radv_blend_check_commutativity(struct radv_blend_state *blend, VkBlendOp op, VkB
 }
 
 static struct radv_blend_state
-radv_pipeline_init_blend_state(const struct radv_pipeline *pipeline,
+radv_pipeline_init_blend_state(struct radv_pipeline *pipeline,
                                const VkGraphicsPipelineCreateInfo *pCreateInfo,
                                const struct radv_graphics_pipeline_create_info *extra)
 {
@@ -666,6 +624,7 @@ radv_pipeline_init_blend_state(const struct radv_pipeline *pipeline,
       radv_pipeline_get_multisample_state(pCreateInfo);
    struct radv_blend_state blend = {0};
    unsigned mode = V_028808_CB_NORMAL;
+   unsigned cb_color_control = 0;
    int i;
 
    if (extra && extra->custom_blend_mode) {
@@ -673,12 +632,11 @@ radv_pipeline_init_blend_state(const struct radv_pipeline *pipeline,
       mode = extra->custom_blend_mode;
    }
 
-   blend.cb_color_control = 0;
    if (vkblend) {
       if (vkblend->logicOpEnable)
-         blend.cb_color_control |= S_028808_ROP3(si_translate_blend_logic_op(vkblend->logicOp));
+         cb_color_control |= S_028808_ROP3(si_translate_blend_logic_op(vkblend->logicOp));
       else
-         blend.cb_color_control |= S_028808_ROP3(V_028808_ROP3_COPY);
+         cb_color_control |= S_028808_ROP3(V_028808_ROP3_COPY);
    }
 
    blend.db_alpha_to_mask = S_028B70_ALPHA_TO_MASK_OFFSET0(3) | S_028B70_ALPHA_TO_MASK_OFFSET1(1) |
@@ -819,15 +777,18 @@ radv_pipeline_init_blend_state(const struct radv_pipeline *pipeline,
        */
       if (blend.mrt0_is_dual_src || (vkblend && vkblend->logicOpEnable) ||
           mode == V_028808_CB_RESOLVE)
-         blend.cb_color_control |= S_028808_DISABLE_DUAL_QUAD(1);
+         cb_color_control |= S_028808_DISABLE_DUAL_QUAD(1);
    }
 
    if (blend.cb_target_mask)
-      blend.cb_color_control |= S_028808_MODE(mode);
+      cb_color_control |= S_028808_MODE(mode);
    else
-      blend.cb_color_control |= S_028808_MODE(V_028808_CB_DISABLE);
+      cb_color_control |= S_028808_MODE(V_028808_CB_DISABLE);
 
    radv_pipeline_compute_spi_color_formats(pipeline, pCreateInfo, &blend);
+
+   pipeline->graphics.cb_color_control = cb_color_control;
+
    return blend;
 }
 
@@ -1760,6 +1721,14 @@ radv_pipeline_init_dynamic_state(struct radv_pipeline *pipeline,
          pCreateInfo->pRasterizationState->rasterizerDiscardEnable;
    }
 
+   if (subpass->has_color_att && states & RADV_DYNAMIC_LOGIC_OP) {
+      if (pCreateInfo->pColorBlendState->logicOpEnable) {
+         dynamic->logic_op = si_translate_blend_logic_op(pCreateInfo->pColorBlendState->logicOp);
+      } else {
+         dynamic->logic_op = V_028808_ROP3_COPY;
+      }
+   }
+
    pipeline->dynamic_state.mask = states;
 }
 
@@ -4253,7 +4222,6 @@ radv_pipeline_generate_blend_state(struct radeon_cmdbuf *ctx_cs,
 {
    radeon_set_context_reg_seq(ctx_cs, R_028780_CB_BLEND0_CONTROL, 8);
    radeon_emit_array(ctx_cs, blend->cb_blend_control, 8);
-   radeon_set_context_reg(ctx_cs, R_028808_CB_COLOR_CONTROL, blend->cb_color_control);
    radeon_set_context_reg(ctx_cs, R_028B70_DB_ALPHA_TO_MASK, blend->db_alpha_to_mask);
 
    if (pipeline->device->physical_device->rad_info.has_rbplus) {
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index d9dd39ff3ff..e0917f1b6ec 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -1229,6 +1229,8 @@ struct radv_dynamic_state {
    bool depth_bias_enable;
    bool primitive_restart_enable;
    bool rasterizer_discard_enable;
+
+   unsigned logic_op;
 };
 
 extern const struct radv_dynamic_state default_dynamic_state;
@@ -1750,6 +1752,7 @@ struct radv_pipeline {
          unsigned pa_su_sc_mode_cntl;
          unsigned db_depth_control;
          unsigned pa_cl_clip_cntl;
+         unsigned cb_color_control;
          bool uses_dynamic_stride;
 
          /* Used for rbplus */
@@ -2698,6 +2701,47 @@ si_translate_stencil_op(enum VkStencilOp op)
    }
 }
 
+static inline uint32_t
+si_translate_blend_logic_op(VkLogicOp op)
+{
+   switch (op) {
+   case VK_LOGIC_OP_CLEAR:
+      return V_028808_ROP3_CLEAR;
+   case VK_LOGIC_OP_AND:
+      return V_028808_ROP3_AND;
+   case VK_LOGIC_OP_AND_REVERSE:
+      return V_028808_ROP3_AND_REVERSE;
+   case VK_LOGIC_OP_COPY:
+      return V_028808_ROP3_COPY;
+   case VK_LOGIC_OP_AND_INVERTED:
+      return V_028808_ROP3_AND_INVERTED;
+   case VK_LOGIC_OP_NO_OP:
+      return V_028808_ROP3_NO_OP;
+   case VK_LOGIC_OP_XOR:
+      return V_028808_ROP3_XOR;
+   case VK_LOGIC_OP_OR:
+      return V_028808_ROP3_OR;
+   case VK_LOGIC_OP_NOR:
+      return V_028808_ROP3_NOR;
+   case VK_LOGIC_OP_EQUIVALENT:
+      return V_028808_ROP3_EQUIVALENT;
+   case VK_LOGIC_OP_INVERT:
+      return V_028808_ROP3_INVERT;
+   case VK_LOGIC_OP_OR_REVERSE:
+      return V_028808_ROP3_OR_REVERSE;
+   case VK_LOGIC_OP_COPY_INVERTED:
+      return V_028808_ROP3_COPY_INVERTED;
+   case VK_LOGIC_OP_OR_INVERTED:
+      return V_028808_ROP3_OR_INVERTED;
+   case VK_LOGIC_OP_NAND:
+      return V_028808_ROP3_NAND;
+   case VK_LOGIC_OP_SET:
+      return V_028808_ROP3_SET;
+   default:
+      unreachable("Unhandled logic op");
+   }
+}
+
 /**
  * Helper used for debugging compiler issues by enabling/disabling LLVM for a
  * specific shader stage (developers only).



More information about the mesa-commit mailing list