Mesa (main): lavapipe: implement VK_EXT_color_write_enable

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Jul 19 21:33:57 UTC 2021


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

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Mon Jul 19 16:23:31 2021 -0400

lavapipe: implement VK_EXT_color_write_enable

Reviewed-by: Dave Airlie <airlied at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11961>

---

 src/gallium/frontends/lavapipe/lvp_cmd_buffer.c | 23 ++++++++++++++++
 src/gallium/frontends/lavapipe/lvp_device.c     |  7 +++++
 src/gallium/frontends/lavapipe/lvp_execute.c    | 36 ++++++++++++++++++++++++-
 src/gallium/frontends/lavapipe/lvp_pipeline.c   | 12 +++++++++
 src/gallium/frontends/lavapipe/lvp_private.h    |  6 +++++
 5 files changed, 83 insertions(+), 1 deletion(-)

diff --git a/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c b/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c
index c62765c9d15..a04f7442fd5 100644
--- a/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c
+++ b/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c
@@ -2258,3 +2258,26 @@ VKAPI_ATTR void VKAPI_CALL lvp_CmdSetRasterizerDiscardEnableEXT(
    cmd->u.set_rasterizer_discard_enable.enable = rasterizerDiscardEnable == VK_TRUE;
    cmd_buf_queue(cmd_buffer, cmd);
 }
+
+VKAPI_ATTR void VKAPI_CALL lvp_CmdSetColorWriteEnableEXT(
+    VkCommandBuffer                             commandBuffer,
+    uint32_t                                    attachmentCount,
+    const VkBool32*                             pColorWriteEnables)
+{
+   LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer);
+   struct lvp_cmd_buffer_entry *cmd;
+
+   cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_SET_COLOR_WRITE_ENABLE);
+   if (!cmd)
+      return;
+
+   cmd->u.set_color_write_enable.disable_mask = 0;
+   for (unsigned i = 0; i < attachmentCount; i++) {
+      /* this is inverted because cmdbufs are zero-initialized, meaning only 'true'
+       * can be detected with a bool, and the default is to enable color writes
+       */
+      if (pColorWriteEnables[i] != VK_TRUE)
+         cmd->u.set_color_write_enable.disable_mask |= BITFIELD_BIT(i);
+   }
+   cmd_buf_queue(cmd_buffer, cmd);
+}
diff --git a/src/gallium/frontends/lavapipe/lvp_device.c b/src/gallium/frontends/lavapipe/lvp_device.c
index 58ea8238a5d..e3f41939cd3 100644
--- a/src/gallium/frontends/lavapipe/lvp_device.c
+++ b/src/gallium/frontends/lavapipe/lvp_device.c
@@ -125,6 +125,7 @@ static const struct vk_device_extension_table lvp_device_extensions_supported =
    .KHR_uniform_buffer_standard_layout    = true,
    .KHR_variable_pointers                 = true,
    .EXT_calibrated_timestamps             = true,
+   .EXT_color_write_enable                = true,
    .EXT_conditional_rendering             = true,
    .EXT_extended_dynamic_state            = true,
    .EXT_extended_dynamic_state2           = true,
@@ -639,6 +640,12 @@ VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceFeatures2(
          features->customBorderColorWithoutFormat = true;
          break;
       }
+      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT: {
+         VkPhysicalDeviceColorWriteEnableFeaturesEXT *features =
+            (VkPhysicalDeviceColorWriteEnableFeaturesEXT *)ext;
+         features->colorWriteEnable = true;
+         break;
+      }
       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT: {
          VkPhysicalDeviceProvokingVertexFeaturesEXT *features =
             (VkPhysicalDeviceProvokingVertexFeaturesEXT*)ext;
diff --git a/src/gallium/frontends/lavapipe/lvp_execute.c b/src/gallium/frontends/lavapipe/lvp_execute.c
index 0a9b9f9fa54..5f309c382f7 100644
--- a/src/gallium/frontends/lavapipe/lvp_execute.c
+++ b/src/gallium/frontends/lavapipe/lvp_execute.c
@@ -126,7 +126,9 @@ struct rendering_state {
    bool disable_multisample;
    enum gs_output gs_output_lines : 2;
 
-   uint32_t pad:22;
+   uint32_t color_write_disables:8;
+   bool has_color_write_disables:1;
+   uint32_t pad:13;
 
    void *ss_cso[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
    void *velems_cso;
@@ -220,7 +222,22 @@ static void emit_state(struct rendering_state *state)
 {
    int sh;
    if (state->blend_dirty) {
+      uint32_t mask = 0;
+      /* zero out the colormask values for disabled attachments */
+      if (state->has_color_write_disables && state->color_write_disables) {
+         u_foreach_bit(att, state->color_write_disables) {
+            mask |= state->blend_state.rt[att].colormask << (att * 4);
+            state->blend_state.rt[att].colormask = 0;
+         }
+      }
       cso_set_blend(state->cso, &state->blend_state);
+      /* reset colormasks using saved bitmask */
+      if (state->has_color_write_disables && state->color_write_disables) {
+         const uint32_t att_mask = BITFIELD_MASK(4);
+         u_foreach_bit(att, state->color_write_disables) {
+            state->blend_state.rt[att].colormask = (mask >> (att * 4)) & att_mask;
+         }
+      }
       state->blend_dirty = false;
    }
 
@@ -402,6 +419,8 @@ get_viewport_xform(const VkViewport *viewport,
     VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT
     VK_DYNAMIC_STATE_LOGIC_OP_EXT
     VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT
+
+    VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT
 */
 static int conv_dynamic_state_idx(VkDynamicState dyn_state)
 {
@@ -420,6 +439,10 @@ static int conv_dynamic_state_idx(VkDynamicState dyn_state)
       return dyn_state - VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT +
              VK_DYNAMIC_STATE_STENCIL_OP_EXT - VK_DYNAMIC_STATE_CULL_MODE_EXT +
              VK_DYNAMIC_STATE_STENCIL_REFERENCE + 2 + 1 + 1;
+   if (dyn_state == VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT)
+      return VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT - VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT +
+             VK_DYNAMIC_STATE_STENCIL_OP_EXT - VK_DYNAMIC_STATE_CULL_MODE_EXT +
+             VK_DYNAMIC_STATE_STENCIL_REFERENCE + 2 + 1 + 1 + 1;
    assert(0);
    return -1;
 }
@@ -443,6 +466,7 @@ static void handle_graphics_pipeline(struct lvp_cmd_buffer_entry *cmd,
          dynamic_states[idx] = true;
       }
    }
+   state->has_color_write_disables = dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT)];
 
    bool has_stage[PIPE_SHADER_TYPES] = { false };
 
@@ -3067,6 +3091,13 @@ static void handle_set_rasterizer_discard_enable(struct lvp_cmd_buffer_entry *cm
    state->rs_state.rasterizer_discard = cmd->u.set_rasterizer_discard_enable.enable;
 }
 
+static void handle_set_color_write_enable(struct lvp_cmd_buffer_entry *cmd,
+                                          struct rendering_state *state)
+{
+   state->blend_dirty |= state->color_write_disables != cmd->u.set_color_write_enable.disable_mask;
+   state->color_write_disables = cmd->u.set_color_write_enable.disable_mask;
+}
+
 static void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer,
                                    struct rendering_state *state)
 {
@@ -3297,6 +3328,9 @@ static void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer,
       case LVP_CMD_SET_RASTERIZER_DISCARD_ENABLE:
          handle_set_rasterizer_discard_enable(cmd, state);
          break;
+      case LVP_CMD_SET_COLOR_WRITE_ENABLE:
+         handle_set_color_write_enable(cmd, state);
+         break;
       }
       first = false;
       did_flush = false;
diff --git a/src/gallium/frontends/lavapipe/lvp_pipeline.c b/src/gallium/frontends/lavapipe/lvp_pipeline.c
index 0c1c30315c6..899587baec1 100644
--- a/src/gallium/frontends/lavapipe/lvp_pipeline.c
+++ b/src/gallium/frontends/lavapipe/lvp_pipeline.c
@@ -828,6 +828,18 @@ lvp_graphics_pipeline_init(struct lvp_pipeline *pipeline,
    } else
       pipeline->line_rectangular = true;
 
+   if (!dynamic_state_contains(pipeline->graphics_create_info.pDynamicState, VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT)) {
+      const VkPipelineColorWriteCreateInfoEXT *cw_state =
+         vk_find_struct_const(pCreateInfo->pColorBlendState, PIPELINE_COLOR_WRITE_CREATE_INFO_EXT);
+      if (cw_state) {
+         for (unsigned i = 0; i < cw_state->attachmentCount; i++)
+            if (!cw_state->pColorWriteEnables[i]) {
+               VkPipelineColorBlendAttachmentState *att = (void*)&pipeline->graphics_create_info.pColorBlendState->pAttachments[i];
+               att->colorWriteMask = 0;
+            }
+      }
+   }
+
 
    for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
       VK_FROM_HANDLE(vk_shader_module, module,
diff --git a/src/gallium/frontends/lavapipe/lvp_private.h b/src/gallium/frontends/lavapipe/lvp_private.h
index d1e6b05621c..a56ac3f2e1f 100644
--- a/src/gallium/frontends/lavapipe/lvp_private.h
+++ b/src/gallium/frontends/lavapipe/lvp_private.h
@@ -690,6 +690,7 @@ enum lvp_cmds {
    LVP_CMD_SET_PATCH_CONTROL_POINTS,
    LVP_CMD_SET_PRIMITIVE_RESTART_ENABLE,
    LVP_CMD_SET_RASTERIZER_DISCARD_ENABLE,
+   LVP_CMD_SET_COLOR_WRITE_ENABLE,
 };
 
 struct lvp_cmd_bind_pipeline {
@@ -1096,6 +1097,10 @@ struct lvp_cmd_set_rasterizer_discard_enable {
    bool enable;
 };
 
+struct lvp_cmd_set_color_write_enable {
+   uint8_t disable_mask; //PIPE_MAX_COLOR_BUFS is max attachment count
+};
+
 struct lvp_cmd_buffer_entry {
    struct list_head cmd_link;
    uint32_t cmd_type;
@@ -1159,6 +1164,7 @@ struct lvp_cmd_buffer_entry {
       struct lvp_cmd_set_patch_control_points set_patch_control_points;
       struct lvp_cmd_set_primitive_restart_enable set_primitive_restart_enable;
       struct lvp_cmd_set_rasterizer_discard_enable set_rasterizer_discard_enable;
+      struct lvp_cmd_set_color_write_enable set_color_write_enable;
    } u;
 };
 



More information about the mesa-commit mailing list