anv/pipeline: Add support for dynamic state in pipelines
authorJason Ekstrand <jason.ekstrand@intel.com>
Wed, 7 Oct 2015 16:28:21 +0000 (09:28 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Wed, 7 Oct 2015 16:40:49 +0000 (09:40 -0700)
src/vulkan/anv_cmd_buffer.c
src/vulkan/anv_pipeline.c
src/vulkan/anv_private.h

index 8486bd05a2c33391288cb7db04c68da394fbb700..28d9dd9d69426e64dbf45643d27857b4505b1e8e 100644 (file)
@@ -319,6 +319,12 @@ void anv_CmdBindPipeline(
       cmd_buffer->state.vb_dirty |= pipeline->vb_used;
       cmd_buffer->state.dirty |= ANV_CMD_BUFFER_PIPELINE_DIRTY;
       cmd_buffer->state.push_constants_dirty |= pipeline->active_stages;
+
+      /* Apply the dynamic state from the pipeline */
+      cmd_buffer->state.dirty |= pipeline->dynamic_state_mask;
+      anv_dynamic_state_copy(&cmd_buffer->state.dynamic,
+                             &pipeline->dynamic_state,
+                             pipeline->dynamic_state_mask);
       break;
 
    default:
index 192a4b17ae0fb11cdf11738fb4a21e4a4d492229..75f640154cc50307c175076b46374592df21ed88 100644 (file)
@@ -177,6 +177,98 @@ static const uint32_t vk_to_gen_primitive_type[] = {
    [VK_PRIMITIVE_TOPOLOGY_PATCH]                = _3DPRIM_PATCHLIST_1
 };
 
+static void
+anv_pipeline_init_dynamic_state(struct anv_pipeline *pipeline,
+                                const VkGraphicsPipelineCreateInfo *pCreateInfo)
+{
+   pipeline->dynamic_state_mask = 0;
+
+   if (pCreateInfo->pDynamicState == NULL)
+      return;
+
+   uint32_t count = pCreateInfo->pDynamicState->dynamicStateCount;
+   struct anv_dynamic_state *dynamic = &pipeline->dynamic_state;
+
+   for (uint32_t s = 0; s < count; s++) {
+      VkDynamicState state = pCreateInfo->pDynamicState->pDynamicStates[s];
+
+      assert(state < 32);
+      pipeline->dynamic_state_mask |= (1u << state);
+
+      switch (state) {
+      case VK_DYNAMIC_STATE_VIEWPORT:
+         assert(pCreateInfo->pViewportState);
+         dynamic->viewport.count = pCreateInfo->pViewportState->viewportCount;
+         typed_memcpy(dynamic->viewport.viewports,
+                      pCreateInfo->pViewportState->pViewports,
+                      pCreateInfo->pViewportState->viewportCount);
+         break;
+
+      case VK_DYNAMIC_STATE_SCISSOR:
+         assert(pCreateInfo->pViewportState);
+         dynamic->scissor.count = pCreateInfo->pViewportState->scissorCount;
+         typed_memcpy(dynamic->scissor.scissors,
+                      pCreateInfo->pViewportState->pScissors,
+                      pCreateInfo->pViewportState->scissorCount);
+         break;
+
+      case VK_DYNAMIC_STATE_LINE_WIDTH:
+         assert(pCreateInfo->pRasterState);
+         dynamic->line_width = pCreateInfo->pRasterState->lineWidth;
+         break;
+
+      case VK_DYNAMIC_STATE_DEPTH_BIAS:
+         assert(pCreateInfo->pRasterState);
+         dynamic->depth_bias.bias = pCreateInfo->pRasterState->depthBias;
+         dynamic->depth_bias.clamp = pCreateInfo->pRasterState->depthBiasClamp;
+         dynamic->depth_bias.slope_scaled =
+            pCreateInfo->pRasterState->slopeScaledDepthBias;
+         break;
+
+      case VK_DYNAMIC_STATE_BLEND_CONSTANTS:
+         assert(pCreateInfo->pColorBlendState);
+         typed_memcpy(dynamic->blend_constants,
+                      pCreateInfo->pColorBlendState->blendConst, 4);
+         break;
+
+      case VK_DYNAMIC_STATE_DEPTH_BOUNDS:
+         assert(pCreateInfo->pDepthStencilState);
+         dynamic->depth_bounds.min =
+            pCreateInfo->pDepthStencilState->minDepthBounds;
+         dynamic->depth_bounds.max =
+            pCreateInfo->pDepthStencilState->maxDepthBounds;
+         break;
+
+      case VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK:
+         assert(pCreateInfo->pDepthStencilState);
+         dynamic->stencil_compare_mask.front =
+            pCreateInfo->pDepthStencilState->front.stencilCompareMask;
+         dynamic->stencil_compare_mask.back =
+            pCreateInfo->pDepthStencilState->back.stencilCompareMask;
+         break;
+
+      case VK_DYNAMIC_STATE_STENCIL_WRITE_MASK:
+         assert(pCreateInfo->pDepthStencilState);
+         dynamic->stencil_write_mask.front =
+            pCreateInfo->pDepthStencilState->front.stencilWriteMask;
+         dynamic->stencil_write_mask.back =
+            pCreateInfo->pDepthStencilState->back.stencilWriteMask;
+         break;
+
+      case VK_DYNAMIC_STATE_STENCIL_REFERENCE:
+         assert(pCreateInfo->pDepthStencilState);
+         dynamic->stencil_reference.front =
+            pCreateInfo->pDepthStencilState->front.stencilReference;
+         dynamic->stencil_reference.back =
+            pCreateInfo->pDepthStencilState->back.stencilReference;
+         break;
+
+      default:
+         assert(!"Invalid dynamic state");
+      }
+   }
+}
+
 VkResult
 anv_pipeline_init(struct anv_pipeline *pipeline, struct anv_device *device,
                   const VkGraphicsPipelineCreateInfo *pCreateInfo,
@@ -205,6 +297,8 @@ anv_pipeline_init(struct anv_pipeline *pipeline, struct anv_device *device,
          anv_shader_from_handle(pCreateInfo->pStages[i].shader);
    }
 
+   anv_pipeline_init_dynamic_state(pipeline, pCreateInfo);
+
    if (pCreateInfo->pTessellationState)
       anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO");
    if (pCreateInfo->pViewportState)
index 3d47739aae7421e97db25bbca712cd38d5b84481..0d1998d659ca30b48652a6a541c055fe1a7af080 100644 (file)
@@ -1046,6 +1046,9 @@ struct anv_pipeline {
    struct anv_batch                             batch;
    uint32_t                                     batch_data[256];
    struct anv_reloc_list                        batch_relocs;
+   uint32_t                                     dynamic_state_mask;
+   struct anv_dynamic_state                     dynamic_state;
+
    struct anv_shader *                          shaders[VK_SHADER_STAGE_NUM];
    struct anv_pipeline_layout *                 layout;
    bool                                         use_repclear;