anv/pipeline: Validate VkGraphicsPipelineCreateInfo
authorChad Versace <chad.versace@intel.com>
Sat, 17 Oct 2015 03:31:39 +0000 (20:31 -0700)
committerChad Versace <chad.versace@intel.com>
Tue, 20 Oct 2015 17:55:54 +0000 (10:55 -0700)
The Vulkan spec (20 Oct 2015, git-aa308cb) states that some fields of
VkGraphicsPipelineCreateInfo are required under certain conditions.
Add a new function, anv_pipeline_validate_create_info() that asserts the
requirements hold.

The assertions helped me discover bugs in Crucible and anv_meta.c.

src/vulkan/anv_pipeline.c

index 7fd8c1005683de185ec86467197a3eafec50e2d5..28cccaa3d25cf076eb3c79a6bb15fdb8476962a4 100644 (file)
@@ -260,6 +260,51 @@ anv_pipeline_init_dynamic_state(struct anv_pipeline *pipeline,
    pipeline->dynamic_state_mask = states;
 }
 
+static void
+anv_pipeline_validate_create_info(const VkGraphicsPipelineCreateInfo *info)
+{
+   struct anv_render_pass *renderpass = NULL;
+   struct anv_subpass *subpass = NULL;
+
+   /* Assert that all required members of VkGraphicsPipelineCreateInfo are
+    * present, as explained by the Vulkan (20 Oct 2015, git-aa308cb), Section
+    * 4.2 Graphics Pipeline.
+    */
+   assert(info->sType == VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO);
+
+   renderpass = anv_render_pass_from_handle(info->renderPass);
+   assert(renderpass);
+
+   if (renderpass != &anv_meta_dummy_renderpass) {
+      assert(info->subpass < renderpass->subpass_count);
+      subpass = &renderpass->subpasses[info->subpass];
+   }
+
+   assert(info->stageCount >= 1);
+   assert(info->pVertexInputState);
+   assert(info->pInputAssemblyState);
+   assert(info->pViewportState);
+   assert(info->pRasterState);
+   assert(info->pMultisampleState);
+
+   if (subpass && subpass->depth_stencil_attachment != VK_ATTACHMENT_UNUSED)
+      assert(info->pDepthStencilState);
+
+   if (subpass && subpass->color_count > 0)
+      assert(info->pColorBlendState);
+
+   for (uint32_t i = 0; i < info->stageCount; ++i) {
+      switch (info->pStages[i].stage) {
+      case VK_SHADER_STAGE_TESS_CONTROL:
+      case VK_SHADER_STAGE_TESS_EVALUATION:
+         assert(info->pTessellationState);
+         break;
+      default:
+         break;
+      }
+   }
+}
+
 VkResult
 anv_pipeline_init(struct anv_pipeline *pipeline, struct anv_device *device,
                   const VkGraphicsPipelineCreateInfo *pCreateInfo,
@@ -267,6 +312,10 @@ anv_pipeline_init(struct anv_pipeline *pipeline, struct anv_device *device,
 {
    VkResult result;
 
+   anv_validate {
+      anv_pipeline_validate_create_info(pCreateInfo);
+   }
+
    pipeline->device = device;
    pipeline->layout = anv_pipeline_layout_from_handle(pCreateInfo->layout);
    memset(pipeline->shaders, 0, sizeof(pipeline->shaders));