vk: Implement dynamic and pipeline ds state
authorKristian Høgsberg <kristian.h.kristensen@intel.com>
Mon, 25 May 2015 04:19:26 +0000 (21:19 -0700)
committerKristian Høgsberg <kristian.h.kristensen@intel.com>
Tue, 26 May 2015 03:20:31 +0000 (20:20 -0700)
src/vulkan/device.c
src/vulkan/pipeline.c
src/vulkan/private.h

index 0c35d503ab089c942770771c43493e37af21c2c7..a64772ae1bcb7c306ff5689111fbee1324a306d3 100644 (file)
@@ -2083,11 +2083,44 @@ VkResult anv_CreateDynamicColorBlendState(
 }
 
 VkResult anv_CreateDynamicDepthStencilState(
-    VkDevice                                    device,
+    VkDevice                                    _device,
     const VkDynamicDsStateCreateInfo*           pCreateInfo,
     VkDynamicDsState*                           pState)
 {
-   stub_return(VK_UNSUPPORTED);
+   struct anv_device *device = (struct anv_device *) _device;
+   struct anv_dynamic_ds_state *state;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_DS_STATE_CREATE_INFO);
+
+   state = anv_device_alloc(device, sizeof(*state), 8,
+                            VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (state == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   struct GEN8_3DSTATE_WM_DEPTH_STENCIL wm_depth_stencil = {
+      GEN8_3DSTATE_WM_DEPTH_STENCIL_header,
+
+      /* pCreateInfo->stencilFrontRef,
+       * pCreateInfo->stencilBackRef,
+       * go in cc state
+       */
+
+      /* Is this what we need to do? */
+      .StencilBufferWriteEnable = pCreateInfo->stencilWriteMask != 0,
+
+      .StencilTestMask = pCreateInfo->stencilReadMask,
+      .StencilWriteMask = pCreateInfo->stencilWriteMask,
+
+      .BackfaceStencilTestMask = pCreateInfo->stencilReadMask,
+      .BackfaceStencilWriteMask = pCreateInfo->stencilWriteMask,
+   };
+
+   GEN8_3DSTATE_WM_DEPTH_STENCIL_pack(NULL, state->state_wm_depth_stencil,
+                                      &wm_depth_stencil);
+
+   *pState = (VkDynamicDsState) state;
+
+   return VK_SUCCESS;
 }
 
 // Command buffer functions
@@ -2260,10 +2293,6 @@ VkResult anv_BeginCommandBuffer(
    anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_SBE_SWIZ);
    anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_AA_LINE_PARAMETERS);
 
-   anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_WM_DEPTH_STENCIL,
-                  .DepthTestEnable = false,
-                  .DepthBufferWriteEnable = false);
-
    return VK_SUCCESS;
 }
 
@@ -2440,7 +2469,10 @@ void anv_CmdBindDynamicStateObject(
       cmd_buffer->dirty |= ANV_CMD_BUFFER_RS_DIRTY;
       break;
    case VK_STATE_BIND_POINT_COLOR_BLEND:
+      break;
    case VK_STATE_BIND_POINT_DEPTH_STENCIL:
+      cmd_buffer->ds_state = (struct anv_dynamic_ds_state *) dynamicState;
+      cmd_buffer->dirty |= ANV_CMD_BUFFER_DS_DIRTY;
       break;
    default:
       break;
@@ -2680,6 +2712,12 @@ anv_cmd_buffer_flush_state(struct anv_cmd_buffer *cmd_buffer)
       anv_batch_emit_merge(&cmd_buffer->batch,
                            cmd_buffer->rs_state->state_sf, pipeline->state_sf);
 
+   if (cmd_buffer->ds_state &&
+       (cmd_buffer->dirty & (ANV_CMD_BUFFER_PIPELINE_DIRTY | ANV_CMD_BUFFER_DS_DIRTY)))
+      anv_batch_emit_merge(&cmd_buffer->batch,
+                           cmd_buffer->ds_state->state_wm_depth_stencil,
+                           pipeline->state_wm_depth_stencil);
+
    cmd_buffer->vb_dirty &= ~vb_emit;
    cmd_buffer->dirty = 0;
 }
index a9594a71c95ce0bd5d7eeae7fcdaf95864736fc4..3e0dc15c1aed465bc3ab7f94ff96ff23ae72349e 100644 (file)
@@ -156,7 +156,6 @@ emit_ia_state(struct anv_pipeline *pipeline,
 static void
 emit_rs_state(struct anv_pipeline *pipeline, VkPipelineRsStateCreateInfo *info,
               const struct anv_pipeline_create_info *extra)
-
 {
    static const uint32_t vk_to_gen_cullmode[] = {
       [VK_CULL_MODE_NONE] = CULLMODE_NONE,
@@ -216,6 +215,53 @@ emit_rs_state(struct anv_pipeline *pipeline, VkPipelineRsStateCreateInfo *info,
 
 }
 
+static const uint32_t vk_to_gen_compare_op[] = {
+   [VK_COMPARE_OP_NEVER] = COMPAREFUNCTION_NEVER,
+   [VK_COMPARE_OP_LESS] = COMPAREFUNCTION_LESS,
+   [VK_COMPARE_OP_EQUAL] = COMPAREFUNCTION_EQUAL,
+   [VK_COMPARE_OP_LESS_EQUAL] = COMPAREFUNCTION_LEQUAL,
+   [VK_COMPARE_OP_GREATER] = COMPAREFUNCTION_GREATER,
+   [VK_COMPARE_OP_NOT_EQUAL] = COMPAREFUNCTION_NOTEQUAL,
+   [VK_COMPARE_OP_GREATER_EQUAL] = COMPAREFUNCTION_GEQUAL,
+   [VK_COMPARE_OP_ALWAYS] = COMPAREFUNCTION_ALWAYS,
+};
+
+static const uint32_t vk_to_gen_stencil_op[] = {
+   [VK_STENCIL_OP_KEEP] = 0,
+   [VK_STENCIL_OP_ZERO] = 0,
+   [VK_STENCIL_OP_REPLACE] = 0,
+   [VK_STENCIL_OP_INC_CLAMP] = 0,
+   [VK_STENCIL_OP_DEC_CLAMP] = 0,
+   [VK_STENCIL_OP_INVERT] = 0,
+   [VK_STENCIL_OP_INC_WRAP] = 0,
+   [VK_STENCIL_OP_DEC_WRAP] = 0
+};
+
+static void
+emit_ds_state(struct anv_pipeline *pipeline, VkPipelineDsStateCreateInfo *info)
+{
+   /* bool32_t depthBoundsEnable;          // optional (depth_bounds_test) */
+
+   struct GEN8_3DSTATE_WM_DEPTH_STENCIL wm_depth_stencil = {
+      .DepthTestEnable = info->depthTestEnable,
+      .DepthBufferWriteEnable = info->depthWriteEnable,
+      .DepthTestFunction = vk_to_gen_compare_op[info->depthCompareOp],
+      .DoubleSidedStencilEnable = true,
+
+      .StencilTestEnable = info->stencilTestEnable,
+      .StencilFailOp = vk_to_gen_stencil_op[info->front.stencilFailOp],
+      .StencilPassDepthPassOp = vk_to_gen_stencil_op[info->front.stencilPassOp],
+      .StencilPassDepthFailOp = vk_to_gen_stencil_op[info->front.stencilDepthFailOp],
+      .StencilTestFunction = vk_to_gen_compare_op[info->front.stencilCompareOp],
+      .BackfaceStencilFailOp = vk_to_gen_stencil_op[info->back.stencilFailOp],
+      .BackfaceStencilPassDepthPassOp = vk_to_gen_stencil_op[info->back.stencilPassOp],
+      .BackfaceStencilPassDepthFailOp =vk_to_gen_stencil_op[info->back.stencilDepthFailOp],
+      .BackfaceStencilTestFunction = vk_to_gen_compare_op[info->back.stencilCompareOp],
+   };
+
+   GEN8_3DSTATE_WM_DEPTH_STENCIL_pack(NULL, pipeline->state_wm_depth_stencil, &wm_depth_stencil);
+}
+
 VkResult anv_CreateGraphicsPipeline(
     VkDevice                                    device,
     const VkGraphicsPipelineCreateInfo*         pCreateInfo,
@@ -249,8 +295,9 @@ anv_pipeline_create(
    struct anv_pipeline *pipeline;
    const struct anv_common *common;
    VkPipelineShaderStageCreateInfo *shader_create_info;
-   VkPipelineIaStateCreateInfo *ia_info;
-   VkPipelineRsStateCreateInfo *rs_info;
+   VkPipelineIaStateCreateInfo *ia_info = NULL;
+   VkPipelineRsStateCreateInfo *rs_info = NULL;
+   VkPipelineDsStateCreateInfo *ds_info = NULL;
    VkPipelineVertexInputCreateInfo *vi_info;
    VkResult result;
    uint32_t offset, length;
@@ -282,14 +329,23 @@ anv_pipeline_create(
          ia_info = (VkPipelineIaStateCreateInfo *) common;
          break;
       case VK_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO:
+         anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO");
+         break;
       case VK_STRUCTURE_TYPE_PIPELINE_VP_STATE_CREATE_INFO:
+         anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_VP_STATE_CREATE_INFO");
          break;
       case VK_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO:
          rs_info = (VkPipelineRsStateCreateInfo *) common;
          break;
       case VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO:
+         anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO");
+         break;
       case VK_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO:
+         anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO");
+         break;
       case VK_STRUCTURE_TYPE_PIPELINE_DS_STATE_CREATE_INFO:
+         ds_info = (VkPipelineDsStateCreateInfo *) common;
+         break;
       case VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO:
          shader_create_info = (VkPipelineShaderStageCreateInfo *) common;
          pipeline->shaders[shader_create_info->shader.stage] =
@@ -311,9 +367,16 @@ anv_pipeline_create(
    if (pipeline->vs_simd8 == NO_KERNEL)
       pipeline->wm_prog_data.num_varying_inputs = vi_info->attributeCount - 2;
 
+   assert(vi_info);
    emit_vertex_input(pipeline, vi_info);
+   assert(ia_info);
    emit_ia_state(pipeline, ia_info, extra);
+   assert(rs_info);
    emit_rs_state(pipeline, rs_info, extra);
+   /* ds_info is optional if we're not using depth or stencil buffers, ps is
+    * optional for depth-only rendering. */
+   if (ds_info)
+      emit_ds_state(pipeline, ds_info);
 
    anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_CLIP,
                   .ClipEnable = true,
index f75e03c85984d54d61feb4b34ef0f5eb2a95f406..ec7ffb49dc71fba317f582df87482c2dae381515 100644 (file)
@@ -470,6 +470,10 @@ struct anv_dynamic_rs_state {
    uint32_t state_sf[GEN8_3DSTATE_SF_length];
 };
 
+struct anv_dynamic_ds_state {
+   uint32_t state_wm_depth_stencil[GEN8_3DSTATE_WM_DEPTH_STENCIL_length];
+};
+
 struct anv_dynamic_cb_state {
    uint32_t blend_offset;
 };
@@ -540,6 +544,7 @@ struct anv_buffer {
 #define ANV_CMD_BUFFER_PIPELINE_DIRTY           (1 << 0)
 #define ANV_CMD_BUFFER_DESCRIPTOR_SET_DIRTY     (1 << 1)
 #define ANV_CMD_BUFFER_RS_DIRTY                 (1 << 2)
+#define ANV_CMD_BUFFER_DS_DIRTY                 (1 << 3)
    
 struct anv_bindings {
    struct {
@@ -578,6 +583,7 @@ struct anv_cmd_buffer {
    struct anv_pipeline *                        pipeline;
    struct anv_framebuffer *                     framebuffer;
    struct anv_dynamic_rs_state *                rs_state;
+   struct anv_dynamic_ds_state *                ds_state;
    struct anv_dynamic_vp_state *                vp_state;
    struct anv_bindings *                        bindings;
    struct anv_bindings                          default_bindings;
@@ -637,6 +643,7 @@ struct anv_pipeline {
 
    uint32_t                                     state_sf[GEN8_3DSTATE_SF_length];
    uint32_t                                     state_raster[GEN8_3DSTATE_RASTER_length];
+   uint32_t                                     state_wm_depth_stencil[GEN8_3DSTATE_WM_DEPTH_STENCIL_length];
 };
 
 struct anv_pipeline_create_info {