anv: add support for dynamic cull mode and winding order
authorTapani Pälli <tapani.palli@intel.com>
Fri, 29 May 2020 07:20:18 +0000 (10:20 +0300)
committerMarge Bot <eric+marge@anholt.net>
Sun, 2 Aug 2020 17:44:54 +0000 (17:44 +0000)
v2: cleanup, white space issues (Lionel)

Signed-off-by: Tapani Pälli <tapani.palli@intel.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5604>

src/intel/vulkan/anv_cmd_buffer.c
src/intel/vulkan/anv_pipeline.c
src/intel/vulkan/anv_private.h
src/intel/vulkan/gen7_cmd_buffer.c
src/intel/vulkan/gen8_cmd_buffer.c

index 1ca33f206aa82f41cbb877af7bf976f98d8f3362..6cc2d3f3d3631c089cbbf2d5e5da9ad3f0cc71f8 100644 (file)
@@ -76,6 +76,8 @@ const struct anv_dynamic_state default_dynamic_state = {
       .factor = 0u,
       .pattern = 0u,
    },
+   .cull_mode = 0,
+   .front_face = 0,
 };
 
 /**
@@ -141,6 +143,9 @@ anv_dynamic_state_copy(struct anv_dynamic_state *dest,
    ANV_CMP_COPY(line_stipple.factor, ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE);
    ANV_CMP_COPY(line_stipple.pattern, ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE);
 
+   ANV_CMP_COPY(cull_mode, ANV_CMD_DIRTY_DYNAMIC_CULL_MODE);
+   ANV_CMP_COPY(front_face, ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE);
+
 #undef ANV_CMP_COPY
 
    return changed;
@@ -610,6 +615,28 @@ void anv_CmdSetLineStippleEXT(
    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE;
 }
 
+void anv_CmdSetCullModeEXT(
+   VkCommandBuffer                              commandBuffer,
+   VkCullModeFlags                              cullMode)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
+
+   cmd_buffer->state.gfx.dynamic.cull_mode = cullMode;
+
+   cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_CULL_MODE;
+}
+
+void anv_CmdSetFrontFaceEXT(
+   VkCommandBuffer                              commandBuffer,
+   VkFrontFace                                  frontFace)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
+
+   cmd_buffer->state.gfx.dynamic.front_face = frontFace;
+
+   cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE;
+}
+
 static void
 anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
                                    VkPipelineBindPoint bind_point,
index ca265056d70c1499de02ff46d21ae05144a12b0a..3d04fa3f62a9f29c7b3f195285921a2d140a9532 100644 (file)
@@ -1871,6 +1871,18 @@ copy_non_dynamic_state(struct anv_graphics_pipeline *pipeline,
          pCreateInfo->pRasterizationState->depthBiasSlopeFactor;
    }
 
+   if (states & ANV_CMD_DIRTY_DYNAMIC_CULL_MODE) {
+      assert(pCreateInfo->pRasterizationState);
+      dynamic->cull_mode =
+         pCreateInfo->pRasterizationState->cullMode;
+   }
+
+   if (states & ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE) {
+      assert(pCreateInfo->pRasterizationState);
+      dynamic->front_face =
+         pCreateInfo->pRasterizationState->frontFace;
+   }
+
    /* Section 9.2 of the Vulkan 1.0.15 spec says:
     *
     *    pColorBlendState is [...] NULL if the pipeline has rasterization
index 957fa3d7b4a9ee95f92f7238bb23c3f33fc1dbda..fb885d1199904bb8af670153b9c1c1605940620b 100644 (file)
@@ -2688,6 +2688,9 @@ struct anv_dynamic_state {
       uint32_t                                  factor;
       uint16_t                                  pattern;
    } line_stipple;
+
+   VkCullModeFlags                              cull_mode;
+   VkFrontFace                                  front_face;
 };
 
 extern const struct anv_dynamic_state default_dynamic_state;
index 4977cc97aae5ed1a5690b907fee3ae106c3063ae..0d713d339195e99d252c355a00bd88fea04333b2 100644 (file)
@@ -198,10 +198,23 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
    struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
    struct anv_dynamic_state *d = &cmd_buffer->state.gfx.dynamic;
 
+   static const uint32_t vk_to_gen_cullmode[] = {
+      [VK_CULL_MODE_NONE]                       = CULLMODE_NONE,
+      [VK_CULL_MODE_FRONT_BIT]                  = CULLMODE_FRONT,
+      [VK_CULL_MODE_BACK_BIT]                   = CULLMODE_BACK,
+      [VK_CULL_MODE_FRONT_AND_BACK]             = CULLMODE_BOTH
+   };
+   static const uint32_t vk_to_gen_front_face[] = {
+      [VK_FRONT_FACE_COUNTER_CLOCKWISE]         = 1,
+      [VK_FRONT_FACE_CLOCKWISE]                 = 0
+   };
+
    if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
                                       ANV_CMD_DIRTY_RENDER_TARGETS |
                                       ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH |
-                                      ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS)) {
+                                      ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS |
+                                      ANV_CMD_DIRTY_DYNAMIC_CULL_MODE |
+                                      ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE)) {
       uint32_t sf_dw[GENX(3DSTATE_SF_length)];
       struct GENX(3DSTATE_SF) sf = {
          GENX(3DSTATE_SF_header),
@@ -209,7 +222,9 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
          .LineWidth = d->line_width,
          .GlobalDepthOffsetConstant = d->depth_bias.bias,
          .GlobalDepthOffsetScale = d->depth_bias.slope,
-         .GlobalDepthOffsetClamp = d->depth_bias.clamp
+         .GlobalDepthOffsetClamp = d->depth_bias.clamp,
+         .FrontWinding            = vk_to_gen_front_face[d->front_face],
+         .CullMode                = vk_to_gen_cullmode[d->cull_mode],
       };
       GENX(3DSTATE_SF_pack)(NULL, sf_dw, &sf);
 
index f2497231fea86715e78162b6272bfe27860a8e8f..1e7b746ee17780a1dca4c6244665363729f0f13b 100644 (file)
@@ -439,14 +439,29 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
       anv_batch_emit_merge(&cmd_buffer->batch, sf_dw, pipeline->gen8.sf);
    }
 
+   static const uint32_t vk_to_gen_cullmode[] = {
+      [VK_CULL_MODE_NONE]                       = CULLMODE_NONE,
+      [VK_CULL_MODE_FRONT_BIT]                  = CULLMODE_FRONT,
+      [VK_CULL_MODE_BACK_BIT]                   = CULLMODE_BACK,
+      [VK_CULL_MODE_FRONT_AND_BACK]             = CULLMODE_BOTH
+   };
+   static const uint32_t vk_to_gen_front_face[] = {
+      [VK_FRONT_FACE_COUNTER_CLOCKWISE]         = 1,
+      [VK_FRONT_FACE_CLOCKWISE]                 = 0
+   };
+
    if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
-                                      ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS)){
+                                      ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS |
+                                      ANV_CMD_DIRTY_DYNAMIC_CULL_MODE |
+                                      ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE)) {
       uint32_t raster_dw[GENX(3DSTATE_RASTER_length)];
       struct GENX(3DSTATE_RASTER) raster = {
          GENX(3DSTATE_RASTER_header),
          .GlobalDepthOffsetConstant = d->depth_bias.bias,
          .GlobalDepthOffsetScale = d->depth_bias.slope,
-         .GlobalDepthOffsetClamp = d->depth_bias.clamp
+         .GlobalDepthOffsetClamp = d->depth_bias.clamp,
+         .CullMode = vk_to_gen_cullmode[d->cull_mode],
+         .FrontWinding = vk_to_gen_front_face[d->front_face],
       };
       GENX(3DSTATE_RASTER_pack)(NULL, raster_dw, &raster);
       anv_batch_emit_merge(&cmd_buffer->batch, raster_dw,