layers: Insist on each shader's stage being unique in a pipeline
authorChris Forbes <chrisforbes@google.com>
Tue, 5 Apr 2016 23:21:28 +0000 (11:21 +1200)
committerTobin Ehlis <tobine@google.com>
Wed, 6 Apr 2016 15:41:53 +0000 (09:41 -0600)
Signed-off-by: Chris Forbes <chrisforbes@google.com>
layers/core_validation.cpp
layers/core_validation.h

index 0f49d20..c3768da 100644 (file)
@@ -3133,6 +3133,17 @@ static bool verifyPipelineCreateState(layer_data *my_data, const VkDevice device
     if (!validate_and_capture_pipeline_shader_state(my_data, pPipeline)) {
         skipCall = true;
     }
+    // Each shader's stage must be unique
+    if (pPipeline->duplicate_shaders) {
+        for (uint32_t stage = VK_SHADER_STAGE_VERTEX_BIT; stage & VK_SHADER_STAGE_ALL_GRAPHICS; stage <<= 1) {
+            if (pPipeline->duplicate_shaders & stage) {
+                skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0,
+                                    __LINE__, DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS",
+                                    "Invalid Pipeline CreateInfo State: Multiple shaders provided for stage %s",
+                                    string_VkShaderStageFlagBits(VkShaderStageFlagBits(stage)));
+            }
+        }
+    }
     // VS is required
     if (!(pPipeline->active_shaders & VK_SHADER_STAGE_VERTEX_BIT)) {
         skipCall |=
index ff9144d..e4db2f7 100644 (file)
@@ -445,6 +445,7 @@ class PIPELINE_NODE {
     safe_VkComputePipelineCreateInfo computePipelineCI;
     // Flag of which shader stages are active for this pipeline
     uint32_t active_shaders;
+    uint32_t duplicate_shaders;
     // Capture which slots (set#->bindings) are actually used by the shaders of this pipeline
     unordered_map<uint32_t, unordered_set<uint32_t>> active_slots;
     // Vtx input info (if any)
@@ -454,7 +455,7 @@ class PIPELINE_NODE {
     bool blendConstantsEnabled; // Blend constants enabled for any attachments
     // Default constructor
     PIPELINE_NODE()
-        : pipeline{}, graphicsPipelineCI{}, computePipelineCI{}, active_shaders(0), active_slots(), vertexBindingDescriptions(),
+        : pipeline{}, graphicsPipelineCI{}, computePipelineCI{}, active_shaders(0), duplicate_shaders(0), active_slots(), vertexBindingDescriptions(),
           vertexAttributeDescriptions(), attachments(), blendConstantsEnabled(false) {}
 
     void initGraphicsPipeline(const VkGraphicsPipelineCreateInfo *pCreateInfo) {
@@ -464,31 +465,8 @@ class PIPELINE_NODE {
         computePipelineCI.initialize(&emptyComputeCI);
         for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
             const VkPipelineShaderStageCreateInfo *pPSSCI = &pCreateInfo->pStages[i];
-
-            switch (pPSSCI->stage) {
-            case VK_SHADER_STAGE_VERTEX_BIT:
-                this->active_shaders |= VK_SHADER_STAGE_VERTEX_BIT;
-                break;
-            case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
-                this->active_shaders |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
-                break;
-            case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
-                this->active_shaders |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
-                break;
-            case VK_SHADER_STAGE_GEOMETRY_BIT:
-                this->active_shaders |= VK_SHADER_STAGE_GEOMETRY_BIT;
-                break;
-            case VK_SHADER_STAGE_FRAGMENT_BIT:
-                this->active_shaders |= VK_SHADER_STAGE_FRAGMENT_BIT;
-                break;
-            case VK_SHADER_STAGE_COMPUTE_BIT:
-                // TODO : Flag error, CS is specified through VkComputePipelineCreateInfo
-                this->active_shaders |= VK_SHADER_STAGE_COMPUTE_BIT;
-                break;
-            default:
-                // TODO : Flag error
-                break;
-            }
+            this->duplicate_shaders |= this->active_shaders & pPSSCI->stage;
+            this->active_shaders |= pPSSCI->stage;
         }
         if (pCreateInfo->pVertexInputState) {
             const VkPipelineVertexInputStateCreateInfo *pVICI = pCreateInfo->pVertexInputState;