|
22 | 22 | #include "drawdispatch/drawdispatch_vuids.h"
|
23 | 23 | #include "core_validation.h"
|
24 | 24 | #include "error_message/error_strings.h"
|
| 25 | +#include "error_message/logging.h" |
| 26 | +#include "generated/spirv_grammar_helper.h" |
25 | 27 | #include "generated/vk_extension_helper.h"
|
26 | 28 | #include "state_tracker/buffer_state.h"
|
27 | 29 | #include "state_tracker/image_state.h"
|
@@ -1376,6 +1378,7 @@ bool CoreChecks::ValidateActionState(const LastBound &last_bound_state, const Dr
|
1376 | 1378 | skip |= ValidateDrawAttachmentColorBlend(last_bound_state, vuid);
|
1377 | 1379 | skip |= ValidateDrawAttachmentSampleLocation(last_bound_state, vuid);
|
1378 | 1380 | skip |= ValidateDrawDepthStencilAttachments(last_bound_state, vuid);
|
| 1381 | + skip |= ValidateDrawTessellation(last_bound_state, vuid); |
1379 | 1382 |
|
1380 | 1383 | if (cb_state.active_render_pass && cb_state.active_render_pass->UsesDynamicRendering()) {
|
1381 | 1384 | skip |= ValidateDrawDynamicRenderingFsOutputs(last_bound_state, cb_state, loc);
|
@@ -2136,6 +2139,86 @@ bool CoreChecks::ValidateDrawDepthStencilAttachments(const LastBound &last_bound
|
2136 | 2139 | return skip;
|
2137 | 2140 | }
|
2138 | 2141 |
|
| 2142 | +bool CoreChecks::ValidateDrawTessellation(const LastBound &last_bound_state, const vvl::DrawDispatchVuid &vuid) const { |
| 2143 | + bool skip = false; |
| 2144 | + // Already validation to ensure there is both a Control and Eval |
| 2145 | + if ((last_bound_state.GetAllActiveBoundStages() & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) == 0) { |
| 2146 | + return skip; |
| 2147 | + } |
| 2148 | + |
| 2149 | + const spirv::ExecutionModeSet *tesc_execution_mode = nullptr; |
| 2150 | + const spirv::ExecutionModeSet *tese_execution_mode = nullptr; |
| 2151 | + |
| 2152 | + if (last_bound_state.pipeline_state) { |
| 2153 | + for (auto &stage_state : last_bound_state.pipeline_state->stage_states) { |
| 2154 | + const VkShaderStageFlagBits stage = stage_state.GetStage(); |
| 2155 | + if (stage & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) { |
| 2156 | + if (stage_state.entrypoint) { |
| 2157 | + tesc_execution_mode = &stage_state.entrypoint->execution_mode; |
| 2158 | + } |
| 2159 | + } else if (stage & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) { |
| 2160 | + if (stage_state.entrypoint) { |
| 2161 | + tese_execution_mode = &stage_state.entrypoint->execution_mode; |
| 2162 | + } |
| 2163 | + } |
| 2164 | + } |
| 2165 | + } else { |
| 2166 | + const auto tesc_shader = last_bound_state.GetShaderState(ShaderObjectStage::TESSELLATION_CONTROL); |
| 2167 | + if (tesc_shader && tesc_shader->entrypoint) { |
| 2168 | + tesc_execution_mode = &tesc_shader->entrypoint->execution_mode; |
| 2169 | + } |
| 2170 | + const auto tese_shader = last_bound_state.GetShaderState(ShaderObjectStage::TESSELLATION_EVALUATION); |
| 2171 | + if (tese_shader && tese_shader->entrypoint) { |
| 2172 | + tese_execution_mode = &tese_shader->entrypoint->execution_mode; |
| 2173 | + } |
| 2174 | + } |
| 2175 | + |
| 2176 | + ASSERT_AND_RETURN_SKIP(tesc_execution_mode && tese_execution_mode); |
| 2177 | + |
| 2178 | + // VUID being added in https://gitlab.khronos.org/vulkan/vulkan/-/merge_requests/7694 |
| 2179 | + const uint32_t tesc_subdivision = tesc_execution_mode->GetTessellationSubdivision(); |
| 2180 | + const uint32_t tese_subdivision = tese_execution_mode->GetTessellationSubdivision(); |
| 2181 | + if (tesc_subdivision != 0 && tese_subdivision != 0 && tesc_subdivision != tese_subdivision) { |
| 2182 | + skip |= LogError("UNASSIGNED-vkCmdDraw-tessellation-subdivision", |
| 2183 | + last_bound_state.cb_state.GetObjectList(VK_PIPELINE_BIND_POINT_GRAPHICS), vuid.loc(), |
| 2184 | + "The subdivision specified in tessellation control shader (%s) does not match the subdivision in " |
| 2185 | + "tessellation evaluation shader (%s).", |
| 2186 | + string_SpvExecutionMode(tesc_subdivision), string_SpvExecutionMode(tese_subdivision)); |
| 2187 | + } |
| 2188 | + |
| 2189 | + const uint32_t tesc_orientation = tesc_execution_mode->GetTessellationOrientation(); |
| 2190 | + const uint32_t tese_orientation = tese_execution_mode->GetTessellationOrientation(); |
| 2191 | + if (tesc_orientation != 0 && tese_orientation != 0 && tesc_orientation != tese_orientation) { |
| 2192 | + skip |= LogError("UNASSIGNED-vkCmdDraw-tessellation-orientation", |
| 2193 | + last_bound_state.cb_state.GetObjectList(VK_PIPELINE_BIND_POINT_GRAPHICS), vuid.loc(), |
| 2194 | + "The orientation specified in tessellation control shader (%s) does not match the orientation in " |
| 2195 | + "tessellation evaluation shader (%s).", |
| 2196 | + string_SpvExecutionMode(tesc_orientation), string_SpvExecutionMode(tese_orientation)); |
| 2197 | + } |
| 2198 | + |
| 2199 | + const uint32_t tesc_spacing = tesc_execution_mode->GetTessellationSpacing(); |
| 2200 | + const uint32_t tese_spacing = tese_execution_mode->GetTessellationSpacing(); |
| 2201 | + if (tesc_spacing != 0 && tese_spacing != 0 && tesc_spacing != tese_spacing) { |
| 2202 | + skip |= LogError("UNASSIGNED-vkCmdDraw-tessellation-spacing", |
| 2203 | + last_bound_state.cb_state.GetObjectList(VK_PIPELINE_BIND_POINT_GRAPHICS), vuid.loc(), |
| 2204 | + "The spacing specified in tessellation control shader (%s) does not match the spacing in " |
| 2205 | + "tessellation evaluation shader (%s).", |
| 2206 | + string_SpvExecutionMode(tesc_spacing), string_SpvExecutionMode(tese_spacing)); |
| 2207 | + } |
| 2208 | + const uint32_t tesc_patch_size = tesc_execution_mode->output_vertices; |
| 2209 | + const uint32_t tese_patch_size = tese_execution_mode->output_vertices; |
| 2210 | + if (tesc_patch_size != spirv::kInvalidValue && tese_patch_size != spirv::kInvalidValue && tesc_patch_size != tese_patch_size) { |
| 2211 | + skip |= LogError("UNASSIGNED-vkCmdDraw-tessellation-patch-size", |
| 2212 | + last_bound_state.cb_state.GetObjectList(VK_PIPELINE_BIND_POINT_GRAPHICS), vuid.loc(), |
| 2213 | + "The OutputVertices (patch size) specified in tessellation control shader (%" PRIu32 |
| 2214 | + ") does not match the spacing in " |
| 2215 | + "tessellation evaluation shader (%" PRIu32 ").", |
| 2216 | + tesc_patch_size, tese_patch_size); |
| 2217 | + } |
| 2218 | + |
| 2219 | + return skip; |
| 2220 | +} |
| 2221 | + |
2139 | 2222 | bool CoreChecks::ValidateDrawDynamicRenderpassExternalFormatResolve(const LastBound &last_bound_state,
|
2140 | 2223 | const vvl::RenderPass &rp_state,
|
2141 | 2224 | const vvl::DrawDispatchVuid &vuid) const {
|
|
0 commit comments