Validate line width for topology reaching rasterizer rather than input
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index 3850aa3..3484389 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -815,9 +815,8 @@
static bool validate_draw_state_flags(layer_data *dev_data, GLOBAL_CB_NODE *pCB, const PIPELINE_STATE *pPipe, bool indexed,
UNIQUE_VALIDATION_ERROR_CODE const msg_code) {
bool result = false;
- if (pPipe->graphicsPipelineCI.pInputAssemblyState &&
- ((pPipe->graphicsPipelineCI.pInputAssemblyState->topology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST) ||
- (pPipe->graphicsPipelineCI.pInputAssemblyState->topology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP))) {
+ if (pPipe->topology_at_rasterizer == VK_PRIMITIVE_TOPOLOGY_LINE_LIST ||
+ pPipe->topology_at_rasterizer == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP) {
result |= validate_status(dev_data, pCB, CBSTATUS_LINE_WIDTH_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT,
"Dynamic line width state not set for this command buffer", msg_code);
}
diff --git a/layers/core_validation_types.h b/layers/core_validation_types.h
index e4371b8..5e6d310 100644
--- a/layers/core_validation_types.h
+++ b/layers/core_validation_types.h
@@ -608,6 +608,7 @@
std::vector<VkPipelineColorBlendAttachmentState> attachments;
bool blendConstantsEnabled; // Blend constants enabled for any attachments
PIPELINE_LAYOUT_NODE pipeline_layout;
+ VkPrimitiveTopology topology_at_rasterizer;
// Default constructor
PIPELINE_STATE()
@@ -621,7 +622,8 @@
vertexBindingDescriptions(),
attachments(),
blendConstantsEnabled(false),
- pipeline_layout() {}
+ pipeline_layout(),
+ topology_at_rasterizer{} {}
void initGraphicsPipeline(const VkGraphicsPipelineCreateInfo *pCreateInfo, std::shared_ptr<RENDER_PASS_STATE> &&rpstate) {
bool uses_color_attachment = false;
@@ -663,6 +665,9 @@
pCBCI->pAttachments + pCBCI->attachmentCount);
}
}
+ if (graphicsPipelineCI.pInputAssemblyState) {
+ topology_at_rasterizer = graphicsPipelineCI.pInputAssemblyState->topology;
+ }
rp_state = rpstate;
}
diff --git a/layers/shader_validation.cpp b/layers/shader_validation.cpp
index dcae5f9..a9826d9 100644
--- a/layers/shader_validation.cpp
+++ b/layers/shader_validation.cpp
@@ -1373,6 +1373,39 @@
return pipelineLayout->set_layouts[slot.first]->GetDescriptorSetLayoutBindingPtrFromBinding(slot.second);
}
+static void process_execution_modes(shader_module const *src, spirv_inst_iter entrypoint, PIPELINE_STATE *pipeline) {
+ auto entrypoint_id = entrypoint.word(1);
+ bool is_point_mode = false;
+
+ for (auto insn : *src) {
+ if (insn.opcode() == spv::OpExecutionMode && insn.word(1) == entrypoint_id) {
+ switch (insn.word(2)) {
+ case spv::ExecutionModePointMode:
+ // In tessellation shaders, PointMode is separate and trumps the tessellation topology.
+ is_point_mode = true;
+ break;
+
+ case spv::ExecutionModeOutputPoints:
+ pipeline->topology_at_rasterizer = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
+ break;
+
+ case spv::ExecutionModeIsolines:
+ case spv::ExecutionModeOutputLineStrip:
+ pipeline->topology_at_rasterizer = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
+ break;
+
+ case spv::ExecutionModeTriangles:
+ case spv::ExecutionModeQuads:
+ case spv::ExecutionModeOutputTriangleStrip:
+ pipeline->topology_at_rasterizer = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
+ break;
+ }
+ }
+ }
+
+ if (is_point_mode) pipeline->topology_at_rasterizer = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
+}
+
static bool validate_pipeline_shader_stage(layer_data *dev_data, VkPipelineShaderStageCreateInfo const *pStage,
PIPELINE_STATE *pipeline, shader_module const **out_module,
spirv_inst_iter *out_entrypoint) {
@@ -1394,6 +1427,7 @@
// Mark accessible ids
auto accessible_ids = mark_accessible_ids(module, entrypoint);
+ process_execution_modes(module, entrypoint, pipeline);
// Validate descriptor set layout against what the entrypoint actually uses
bool has_writable_descriptor = false;