From 612dd31d84daefd04e22ca194c20ea78e6edc362 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Fri, 23 Feb 2018 09:11:06 -0800 Subject: layers: Fix miscounting of descriptors for multiple stages Descriptors are not intended to count multiple times against the maxDescriptorSet* limits if they are accessible from multiple stages. Required adjusting various subtests in CreatePipelineLayout*. Also fixed some related issues in those tests: - Input attachments are ONLY accessible to the fragment stage. - Various assumptions about divisibility of the maxDescriptorSet* limits There are still many robustness issues in these tests -- it appears we don't hit them with real implementations, but still wrong. --- layers/core_validation.cpp | 37 +++++++++++-------------------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp index 42e9d3d9..a22a2614 100644 --- a/layers/core_validation.cpp +++ b/layers/core_validation.cpp @@ -5122,31 +5122,16 @@ std::valarray GetDescriptorCountMaxPerStage( return max_sum; } -// Used by PreCallValiateCreatePipelineLayout. -// Returns an array of size VK_DESCRIPTOR_TYPE_RANGE_SIZE of the summed descriptors by type across all pipeline stages -std::valarray GetDescriptorSumAcrossStages( - const layer_data *dev_data, const std::vector> set_layouts) { - // Identify active pipeline stages - std::vector stage_flags = {VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT, - VK_SHADER_STAGE_COMPUTE_BIT}; - if (dev_data->enabled_features.geometryShader) { - stage_flags.push_back(VK_SHADER_STAGE_GEOMETRY_BIT); - } - if (dev_data->enabled_features.tessellationShader) { - stage_flags.push_back(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT); - stage_flags.push_back(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT); - } - - // Sum by descriptor type across all enabled stages +// Used by PreCallValidateCreatePipelineLayout. +// Returns an array of size VK_DESCRIPTOR_TYPE_RANGE_SIZE of the summed descriptors by type. +// Note: descriptors only count against the limit once even if used by multiple stages. +std::valarray GetDescriptorSum( + const layer_data *dev_data, const std::vector> &set_layouts) { std::valarray sum_by_type(0U, VK_DESCRIPTOR_TYPE_RANGE_SIZE); - for (auto stage : stage_flags) { - for (auto dsl : set_layouts) { - for (uint32_t binding_idx = 0; binding_idx < dsl->GetBindingCount(); binding_idx++) { - const VkDescriptorSetLayoutBinding *binding = dsl->GetDescriptorSetLayoutBindingPtrFromIndex(binding_idx); - if (0 != (stage & binding->stageFlags)) { - sum_by_type[binding->descriptorType] += binding->descriptorCount; - } - } + for (auto dsl : set_layouts) { + for (uint32_t binding_idx = 0; binding_idx < dsl->GetBindingCount(); binding_idx++) { + const VkDescriptorSetLayoutBinding *binding = dsl->GetDescriptorSetLayoutBindingPtrFromIndex(binding_idx); + sum_by_type[binding->descriptorType] += binding->descriptorCount; } } return sum_by_type; @@ -5276,9 +5261,9 @@ static bool PreCallValiateCreatePipelineLayout(const layer_data *dev_data, const validation_error_map[VALIDATION_ERROR_0fe00d18]); } - // Total descriptors by type, summed across all pipeline stages + // Total descriptors by type // - std::valarray sum_all_stages = GetDescriptorSumAcrossStages(dev_data, set_layouts); + std::valarray sum_all_stages = GetDescriptorSum(dev_data, set_layouts); // Samplers if ((sum_all_stages[VK_DESCRIPTOR_TYPE_SAMPLER] + sum_all_stages[VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER]) > dev_data->phys_dev_props.limits.maxDescriptorSetSamplers) { -- cgit v1.2.3