From 9935cdd6f9524b1da1e140393fa69a0a1b72125d Mon Sep 17 00:00:00 2001 From: spencer-lunarg Date: Thu, 3 Oct 2024 20:57:52 -0400 Subject: [PATCH] layers: Add DGC Pipline Layout Compatible check --- .../cc_device_generated_commands.cpp | 23 +++++++++ tests/unit/device_generated_commands.cpp | 49 +++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/layers/core_checks/cc_device_generated_commands.cpp b/layers/core_checks/cc_device_generated_commands.cpp index 9196d412e07..bc07508084b 100644 --- a/layers/core_checks/cc_device_generated_commands.cpp +++ b/layers/core_checks/cc_device_generated_commands.cpp @@ -919,6 +919,29 @@ bool CoreChecks::PreCallValidateUpdateIndirectExecutionSetPipelineEXT( "was %screated with StencilExportEXT, but the initialPipeline was %screated with StencilExportEXT.", ies_pipeline_stencil_export ? "" : "not ", initial_pipeline_stencil_export ? "" : "not "); } + + const auto initial_pipeline_layout = initial_pipeline->PipelineLayoutState(); + const auto update_pipeline_layout = update_pipeline->PipelineLayoutState(); + if (initial_pipeline_layout && update_pipeline_layout) { + const uint32_t set_count = (uint32_t)std::min(initial_pipeline_layout->set_compat_ids.size(), + update_pipeline_layout->set_compat_ids.size()); + for (uint32_t set = 0; set < set_count; set++) { + if (!IsPipelineLayoutSetCompatible(set, initial_pipeline_layout.get(), update_pipeline_layout.get())) { + LogObjectList objlist(initial_pipeline->Handle(), initial_pipeline_layout->Handle(), + update_pipeline->Handle(), update_pipeline_layout->Handle()); + LogError( + "VUID-vkUpdateIndirectExecutionSetPipelineEXT-None-11039", objlist, set_write_loc.dot(Field::pipeline), + "%s was created with a layout %s which is not compatible with the initialPipeline layout %s for set " + "%" PRIu32 ".\n%s", + FormatHandle(update_pipeline->VkHandle()).c_str(), + FormatHandle(update_pipeline_layout->VkHandle()).c_str(), + FormatHandle(initial_pipeline_layout->VkHandle()).c_str(), set, + DescribePipelineLayoutSetNonCompatible(set, initial_pipeline_layout.get(), update_pipeline_layout.get()) + .c_str()); + break; + } + } + } } } diff --git a/tests/unit/device_generated_commands.cpp b/tests/unit/device_generated_commands.cpp index 054b2a0c02e..12e7b76f0d4 100644 --- a/tests/unit/device_generated_commands.cpp +++ b/tests/unit/device_generated_commands.cpp @@ -923,6 +923,55 @@ TEST_F(NegativeDeviceGeneratedCommands, UpdateIESPipelineShaderStages) { m_errorMonitor->VerifyFound(); } +TEST_F(NegativeDeviceGeneratedCommands, UpdateIESPipelineCompatible) { + RETURN_IF_SKIP(InitBasicDeviceGeneratedCommands()); + InitRenderTarget(); + + vkt::Buffer uniform_buffer(*m_device, 32, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + OneOffDescriptorSet descriptor_set_vert(m_device, + {{0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT, nullptr}}); + OneOffDescriptorSet descriptor_set_all(m_device, {{0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}}); + descriptor_set_vert.WriteDescriptorBufferInfo(0, uniform_buffer.handle(), 0, VK_WHOLE_SIZE, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); + descriptor_set_vert.UpdateDescriptorSets(); + descriptor_set_all.WriteDescriptorBufferInfo(0, uniform_buffer.handle(), 0, VK_WHOLE_SIZE, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); + descriptor_set_all.UpdateDescriptorSets(); + + const vkt::PipelineLayout pipeline_layout_vert(*m_device, {&descriptor_set_vert.layout_}); + const vkt::PipelineLayout pipeline_layout_all(*m_device, {&descriptor_set_all.layout_}); + + char const *vs_source = R"glsl( + #version 450 + layout(set = 0, binding = 0) buffer StorageBuffer { + uint a; + uint b; + }; + void main() { + a = b; + } + )glsl"; + VkShaderObj vs(this, vs_source, VK_SHADER_STAGE_VERTEX_BIT); + + VkPipelineCreateFlags2CreateInfoKHR pipe_flags2 = vku::InitStructHelper(); + pipe_flags2.flags = VK_PIPELINE_CREATE_2_INDIRECT_BINDABLE_BIT_EXT; + CreatePipelineHelper init_pipe(*this, &pipe_flags2); + init_pipe.gp_ci_.layout = pipeline_layout_vert.handle(); + init_pipe.shader_stages_ = {vs.GetStageCreateInfo(), init_pipe.fs_->GetStageCreateInfo()}; + init_pipe.CreateGraphicsPipeline(); + vkt::IndirectExecutionSet exe_set(*m_device, init_pipe.Handle(), 1); + + CreatePipelineHelper pipe(*this, &pipe_flags2); + pipe.gp_ci_.layout = pipeline_layout_all.handle(); + pipe.shader_stages_ = {vs.GetStageCreateInfo(), pipe.fs_->GetStageCreateInfo()}; + pipe.CreateGraphicsPipeline(); + + VkWriteIndirectExecutionSetPipelineEXT write_exe_sets = vku::InitStructHelper(); + write_exe_sets.index = 0; + write_exe_sets.pipeline = pipe.Handle(); + m_errorMonitor->SetDesiredError("VUID-vkUpdateIndirectExecutionSetPipelineEXT-None-11039"); + vk::UpdateIndirectExecutionSetPipelineEXT(device(), exe_set.handle(), 1, &write_exe_sets); + m_errorMonitor->VerifyFound(); +} + TEST_F(NegativeDeviceGeneratedCommands, UpdateIESMixShaderObjectPipeline) { AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); AddRequiredFeature(vkt::Feature::shaderObject);