Skip to content

Commit

Permalink
layers: ValidateGraphicsPipelineRenderPassRasterization
Browse files Browse the repository at this point in the history
  • Loading branch information
spencer-lunarg committed Jun 28, 2024
1 parent c6d7352 commit e6678d1
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 91 deletions.
183 changes: 95 additions & 88 deletions layers/core_checks/cc_pipeline_graphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ bool CoreChecks::ValidateGraphicsPipeline(const vvl::Pipeline &pipeline, const L
subpass_desc = &rp_state->create_info.pSubpasses[subpass];
skip |= ValidateGraphicsPipelineExternalFormatResolve(pipeline, *rp_state, *subpass_desc, create_info_loc);
skip |= ValidateGraphicsPipelineMultisampleState(pipeline, *rp_state, *subpass_desc, create_info_loc);
skip |= ValidateGraphicsPipelineRenderPassRasterization(pipeline, *rp_state, *subpass_desc, create_info_loc);

if (subpass_desc->viewMask != 0) {
skip |= ValidateMultiViewShaders(pipeline, create_info_loc.dot(Field::pSubpasses, subpass).dot(Field::viewMask),
subpass_desc->viewMask, false);
}
}

// Check for portability errors
Expand All @@ -106,7 +112,7 @@ bool CoreChecks::ValidateGraphicsPipeline(const vvl::Pipeline &pipeline, const L
skip |= ValidateGraphicsPipelineInputAssemblyState(pipeline, create_info_loc);
skip |= ValidateGraphicsPipelineTessellationState(pipeline, create_info_loc);
skip |= ValidateGraphicsPipelineColorBlendState(pipeline, subpass_desc, create_info_loc);
skip |= ValidateGraphicsPipelineRasterizationState(pipeline, subpass_desc, create_info_loc);
skip |= ValidateGraphicsPipelineRasterizationState(pipeline, create_info_loc);
skip |= ValidateGraphicsPipelineNullState(pipeline, create_info_loc);
skip |= ValidateGraphicsPipelineRasterizationOrderAttachmentAccess(pipeline, subpass_desc, create_info_loc);
skip |= ValidateGraphicsPipelineDynamicState(pipeline, create_info_loc);
Expand Down Expand Up @@ -1764,29 +1770,10 @@ bool CoreChecks::ValidateGraphicsPipelineColorBlendState(const vvl::Pipeline &pi
return skip;
}

bool CoreChecks::ValidateGraphicsPipelineRasterizationState(const vvl::Pipeline &pipeline,
const vku::safe_VkSubpassDescription2 *subpass_desc,
const Location &create_info_loc) const {
bool CoreChecks::ValidateGraphicsPipelineRasterizationState(const vvl::Pipeline &pipeline, const Location &create_info_loc) const {
bool skip = false;
const Location raster_loc = create_info_loc.dot(Field::pRasterizationState);
const auto raster_state = pipeline.RasterizationState();
if (!raster_state) {
const auto &pipeline_ci = pipeline.GraphicsCreateInfo();
if (!pipeline_ci.pRasterizationState && pipeline.OwnsSubState(pipeline.pre_raster_state)) {
if (!IsExtEnabled(device_extensions.vk_ext_extended_dynamic_state3) ||
!pipeline.IsDynamic(CB_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT) ||
!pipeline.IsDynamic(CB_DYNAMIC_STATE_POLYGON_MODE_EXT) ||
!pipeline.IsDynamic(CB_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE) ||
!pipeline.IsDynamic(CB_DYNAMIC_STATE_CULL_MODE) || !pipeline.IsDynamic(CB_DYNAMIC_STATE_FRONT_FACE) ||
!pipeline.IsDynamic(CB_DYNAMIC_STATE_DEPTH_BIAS_ENABLE) || !pipeline.IsDynamic(CB_DYNAMIC_STATE_DEPTH_BIAS) ||
!pipeline.IsDynamic(CB_DYNAMIC_STATE_LINE_WIDTH)) {
skip |=
LogError("VUID-VkGraphicsPipelineCreateInfo-pRasterizationState-06601", device, raster_loc, "is NULL.");
}
}

return skip;
}

if ((raster_state->depthClampEnable == VK_TRUE) && (!enabled_features.depthClamp)) {
skip |= LogError("VUID-VkPipelineRasterizationStateCreateInfo-depthClampEnable-00782", device,
Expand All @@ -1799,11 +1786,6 @@ bool CoreChecks::ValidateGraphicsPipelineRasterizationState(const vvl::Pipeline
"is %f, but the depthBiasClamp feature was not enabled", raster_state->depthBiasClamp);
}

if (subpass_desc && subpass_desc->viewMask != 0) {
skip |= ValidateMultiViewShaders(pipeline, create_info_loc.dot(Field::pSubpasses, pipeline.Subpass()).dot(Field::viewMask),
subpass_desc->viewMask, false);
}

// If rasterization is enabled...
if (raster_state->rasterizerDiscardEnable == VK_FALSE) {
// pMultisampleState can be null for graphics library
Expand All @@ -1819,68 +1801,6 @@ bool CoreChecks::ValidateGraphicsPipelineRasterizationState(const vvl::Pipeline
"is VK_TRUE, but the alphaToOne feature was not enabled.");
}
}

// If subpass uses a depth/stencil attachment, pDepthStencilState must be a pointer to a valid structure
if (pipeline.fragment_shader_state) {
if (subpass_desc && subpass_desc->pDepthStencilAttachment &&
subpass_desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
const Location ds_loc = create_info_loc.dot(Field::pDepthStencilState);
const auto ds_state = pipeline.DepthStencilState();
if (!ds_state) {
if (!pipeline.IsDepthStencilStateDynamic() || !IsExtEnabled(device_extensions.vk_ext_extended_dynamic_state3)) {
skip |= LogError("VUID-VkGraphicsPipelineCreateInfo-renderPass-09028", device, ds_loc,
"is NULL when rasterization is enabled "
"and subpass %" PRIu32 " uses a depth/stencil attachment.",
pipeline.Subpass());
}
} else if (ds_state->depthBoundsTestEnable == VK_TRUE) {
if (!enabled_features.depthBounds) {
skip |= LogError("VUID-VkPipelineDepthStencilStateCreateInfo-depthBoundsTestEnable-00598", device,
ds_loc.dot(Field::depthBoundsTestEnable),
"depthBoundsTestEnable is VK_TRUE, but depthBounds feature was not enabled.");
}

if (!IsExtEnabled(device_extensions.vk_ext_depth_range_unrestricted) &&
!pipeline.IsDynamic(CB_DYNAMIC_STATE_DEPTH_BOUNDS)) {
const float minDepthBounds = ds_state->minDepthBounds;
const float maxDepthBounds = ds_state->maxDepthBounds;
if (!(minDepthBounds >= 0.0) || !(minDepthBounds <= 1.0)) {
skip |= LogError(
"VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-02510", device, ds_loc.dot(Field::minDepthBounds),
"is %f, depthBoundsTestEnable is VK_TRUE, but VK_EXT_depth_range_unrestricted extension "
"is not enabled (and not using VK_DYNAMIC_STATE_DEPTH_BOUNDS).",
minDepthBounds);
}
if (!(maxDepthBounds >= 0.0) || !(maxDepthBounds <= 1.0)) {
skip |= LogError(
"VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-02510", device, ds_loc.dot(Field::minDepthBounds),
"is %f, depthBoundsTestEnable is VK_TRUE, but VK_EXT_depth_range_unrestricted extension "
"is not enabled (and not using VK_DYNAMIC_STATE_DEPTH_BOUNDS).",
maxDepthBounds);
}
}
}
}
}

// If subpass uses color attachments, pColorBlendState must be valid pointer
if (pipeline.fragment_output_state && subpass_desc && !pipeline.fragment_output_state->color_blend_state &&
!pipeline.IsColorBlendStateDynamic()) {
uint32_t color_attachment_count = 0;
for (uint32_t i = 0; i < subpass_desc->colorAttachmentCount; ++i) {
if (subpass_desc->pColorAttachments[i].attachment != VK_ATTACHMENT_UNUSED) {
++color_attachment_count;
}
}

if (color_attachment_count > 0) {
skip |= LogError("VUID-VkGraphicsPipelineCreateInfo-renderPass-09030", device,
create_info_loc.dot(Field::pColorBlendState),
"is NULL when rasterization is enabled and "
"subpass %" PRIu32 " uses color attachments.",
pipeline.Subpass());
}
}
}

if (auto provoking_vertex_state_ci =
Expand Down Expand Up @@ -1981,6 +1901,77 @@ bool CoreChecks::ValidateGraphicsPipelineRasterizationState(const vvl::Pipeline
return skip;
}

bool CoreChecks::ValidateGraphicsPipelineRenderPassRasterization(const vvl::Pipeline &pipeline, const vvl::RenderPass &rp_state,
const vku::safe_VkSubpassDescription2 &subpass_desc,
const Location &create_info_loc) const {
bool skip = false;
const auto raster_state = pipeline.RasterizationState();
if (!raster_state || raster_state->rasterizerDiscardEnable) return skip;

// If subpass uses a depth/stencil attachment, pDepthStencilState must be a pointer to a valid structure
if (pipeline.fragment_shader_state) {
if (subpass_desc.pDepthStencilAttachment && subpass_desc.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
const Location ds_loc = create_info_loc.dot(Field::pDepthStencilState);
const auto ds_state = pipeline.DepthStencilState();
if (!ds_state) {
if (!pipeline.IsDepthStencilStateDynamic() || !IsExtEnabled(device_extensions.vk_ext_extended_dynamic_state3)) {
skip |= LogError("VUID-VkGraphicsPipelineCreateInfo-renderPass-09028", rp_state.Handle(), ds_loc,
"is NULL when rasterization is enabled "
"and subpass %" PRIu32 " uses a depth/stencil attachment.",
pipeline.Subpass());
}
} else if (ds_state->depthBoundsTestEnable == VK_TRUE) {
if (!enabled_features.depthBounds) {
skip |= LogError("VUID-VkPipelineDepthStencilStateCreateInfo-depthBoundsTestEnable-00598", device,
ds_loc.dot(Field::depthBoundsTestEnable),
"depthBoundsTestEnable is VK_TRUE, but depthBounds feature was not enabled.");
}

if (!IsExtEnabled(device_extensions.vk_ext_depth_range_unrestricted) &&
!pipeline.IsDynamic(CB_DYNAMIC_STATE_DEPTH_BOUNDS)) {
const float minDepthBounds = ds_state->minDepthBounds;
const float maxDepthBounds = ds_state->maxDepthBounds;
if (!(minDepthBounds >= 0.0) || !(minDepthBounds <= 1.0)) {
skip |= LogError("VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-02510", device,
ds_loc.dot(Field::minDepthBounds),
"is %f, depthBoundsTestEnable is VK_TRUE, but VK_EXT_depth_range_unrestricted extension "
"is not enabled (and not using VK_DYNAMIC_STATE_DEPTH_BOUNDS).",
minDepthBounds);
}
if (!(maxDepthBounds >= 0.0) || !(maxDepthBounds <= 1.0)) {
skip |= LogError("VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-02510", device,
ds_loc.dot(Field::minDepthBounds),
"is %f, depthBoundsTestEnable is VK_TRUE, but VK_EXT_depth_range_unrestricted extension "
"is not enabled (and not using VK_DYNAMIC_STATE_DEPTH_BOUNDS).",
maxDepthBounds);
}
}
}
}
}

// If subpass uses color attachments, pColorBlendState must be valid pointer
if (pipeline.fragment_output_state && !pipeline.fragment_output_state->color_blend_state &&
!pipeline.IsColorBlendStateDynamic()) {
uint32_t color_attachment_count = 0;
for (uint32_t i = 0; i < subpass_desc.colorAttachmentCount; ++i) {
if (subpass_desc.pColorAttachments[i].attachment != VK_ATTACHMENT_UNUSED) {
++color_attachment_count;
}
}

if (color_attachment_count > 0) {
skip |= LogError("VUID-VkGraphicsPipelineCreateInfo-renderPass-09030", rp_state.Handle(),
create_info_loc.dot(Field::pColorBlendState),
"is NULL when rasterization is enabled and "
"subpass %" PRIu32 " uses color attachments.",
pipeline.Subpass());
}
}

return skip;
}

bool CoreChecks::ValidateSampleLocationsInfo(const VkSampleLocationsInfoEXT &sample_location_info, const Location &loc) const {
bool skip = false;
const VkSampleCountFlagBits sample_count = sample_location_info.sampleLocationsPerPixel;
Expand Down Expand Up @@ -2366,6 +2357,22 @@ bool CoreChecks::ValidateGraphicsPipelineNullState(const vvl::Pipeline &pipeline
create_info_loc.dot(Field::pMultisampleState), "is NULL.");
}
}

if (!pipeline.RasterizationState()) {
if (!pipeline_ci.pRasterizationState && pipeline.OwnsSubState(pipeline.pre_raster_state)) {
if (!IsExtEnabled(device_extensions.vk_ext_extended_dynamic_state3) ||
!pipeline.IsDynamic(CB_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT) ||
!pipeline.IsDynamic(CB_DYNAMIC_STATE_POLYGON_MODE_EXT) ||
!pipeline.IsDynamic(CB_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE) ||
!pipeline.IsDynamic(CB_DYNAMIC_STATE_CULL_MODE) || !pipeline.IsDynamic(CB_DYNAMIC_STATE_FRONT_FACE) ||
!pipeline.IsDynamic(CB_DYNAMIC_STATE_DEPTH_BIAS_ENABLE) || !pipeline.IsDynamic(CB_DYNAMIC_STATE_DEPTH_BIAS) ||
!pipeline.IsDynamic(CB_DYNAMIC_STATE_LINE_WIDTH)) {
skip |= LogError("VUID-VkGraphicsPipelineCreateInfo-pRasterizationState-06601", device,
create_info_loc.dot(Field::pRasterizationState), "is NULL.");
}
}
}

return skip;
}

Expand Down
7 changes: 4 additions & 3 deletions layers/core_checks/core_validation.h
Original file line number Diff line number Diff line change
Expand Up @@ -618,9 +618,10 @@ class CoreChecks : public ValidationStateTracker {
bool IsColorBlendStateAttachmentCountIgnore(const vvl::Pipeline& pipeline) const;
bool ValidateGraphicsPipelineColorBlendState(const vvl::Pipeline& pipeline, const vku::safe_VkSubpassDescription2* subpass_desc,
const Location& create_info_loc) const;
bool ValidateGraphicsPipelineRasterizationState(const vvl::Pipeline& pipeline,
const vku::safe_VkSubpassDescription2* subpass_desc,
const Location& create_info_loc) const;
bool ValidateGraphicsPipelineRasterizationState(const vvl::Pipeline& pipeline, const Location& create_info_loc) const;
bool ValidateGraphicsPipelineRenderPassRasterization(const vvl::Pipeline& pipeline, const vvl::RenderPass& rp_state,
const vku::safe_VkSubpassDescription2& subpass_desc,
const Location& create_info_loc) const;
bool ValidateGraphicsPipelineMultisampleState(const vvl::Pipeline& pipeline, const vvl::RenderPass& rp_state,
const vku::safe_VkSubpassDescription2& subpass_desc,
const Location& create_info_loc) const;
Expand Down

0 comments on commit e6678d1

Please sign in to comment.