Skip to content

Commit

Permalink
layers: Fix multiple calls to CmdSetVertexInputEXT
Browse files Browse the repository at this point in the history
  • Loading branch information
spencer-lunarg committed Sep 12, 2024
1 parent f939e68 commit 884762a
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 4 deletions.
4 changes: 2 additions & 2 deletions layers/core_checks/cc_cmd_buffer_dynamic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1018,8 +1018,8 @@ bool CoreChecks::ValidateDrawDynamicState(const LastBound& last_bound_state, con
continue;
}
bool location_provided = false;
for (const auto& binding_state : cb_state.dynamic_state_value.vertex_bindings) {
const auto* attrib = vvl::Find(binding_state.second.locations, variable_ptr->decorations.location);
for (const auto& vertex_binding : cb_state.dynamic_state_value.vertex_bindings) {
const auto* attrib = vvl::Find(vertex_binding.second.locations, variable_ptr->decorations.location);
if (!attrib) continue;
location_provided = true;

Expand Down
4 changes: 2 additions & 2 deletions layers/state_tracker/state_tracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5241,14 +5241,14 @@ void ValidationStateTracker::PostCallRecordCmdSetVertexInputEXT(
}
auto &vertex_bindings = cb_state->dynamic_state_value.vertex_bindings;
for (const auto [i, bd] : vvl::enumerate(pVertexBindingDescriptions, vertexBindingDescriptionCount)) {
vertex_bindings.emplace(bd->binding, VertexBindingState(i, bd));
vertex_bindings.insert_or_assign(bd->binding, VertexBindingState(i, bd));

cb_state->current_vertex_buffer_binding_info[bd->binding].stride = bd->stride;
}

for (const auto [i, ad] : vvl::enumerate(pVertexAttributeDescriptions, vertexAttributeDescriptionCount)) {
if (auto *binding_state = vvl::Find(vertex_bindings, ad->binding)) {
binding_state->locations.emplace(ad->location, VertexAttrState(i, ad));
binding_state->locations.insert_or_assign(ad->location, VertexAttrState(i, ad));
}
}
}
Expand Down
48 changes: 48 additions & 0 deletions tests/unit/vertex_input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1764,3 +1764,51 @@ TEST_F(NegativeVertexInput, VertextBufferDestroyed) {
vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
m_errorMonitor->VerifyFound();
}

TEST_F(NegativeVertexInput, ResetCmdSetVertexInput) {
TEST_DESCRIPTION("https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/8523");
AddRequiredExtensions(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME);
AddRequiredFeature(vkt::Feature::vertexInputDynamicState);
RETURN_IF_SKIP(Init());
InitRenderTarget();

char const *vs_source = R"glsl(
#version 450
layout(location=0) in uvec4 x;
void main(){}
)glsl";
VkShaderObj vs(this, vs_source, VK_SHADER_STAGE_VERTEX_BIT);

CreatePipelineHelper pipe(*this);
pipe.AddDynamicState(VK_DYNAMIC_STATE_VERTEX_INPUT_EXT);
pipe.shader_stages_ = {vs.GetStageCreateInfo(), pipe.fs_->GetStageCreateInfo()};
pipe.CreateGraphicsPipeline();

vkt::Buffer vertex_buffer(*m_device, 1024, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
VkDeviceSize offset = 0;

VkVertexInputBindingDescription2EXT bindings = vku::InitStructHelper();
bindings.binding = 0;
bindings.divisor = 1;
bindings.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;

VkVertexInputAttributeDescription2EXT attributes = vku::InitStructHelper();
attributes.location = 0;
attributes.binding = 0;
attributes.format = VK_FORMAT_R8G8B8A8_UINT;

m_commandBuffer->begin();
m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0u, 1u, &vertex_buffer.handle(), &offset);
vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.Handle());
vk::CmdSetVertexInputEXT(m_commandBuffer->handle(), 1, &bindings, 1, &attributes);
vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 1);

attributes.format = VK_FORMAT_R8G8B8A8_UNORM;
vk::CmdSetVertexInputEXT(m_commandBuffer->handle(), 1, &bindings, 1, &attributes);
m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-Input-08734");
vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 1);
m_errorMonitor->VerifyFound();
m_commandBuffer->EndRenderPass();
m_commandBuffer->end();
}
62 changes: 62 additions & 0 deletions tests/unit/vertex_input_positive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
* http://www.apache.org/licenses/LICENSE-2.0
*/

#include <vulkan/vulkan_core.h>
#include "../framework/layer_validation_tests.h"
#include "../framework/pipeline_helper.h"
#include "../framework/render_pass_helper.h"
Expand Down Expand Up @@ -902,4 +903,65 @@ TEST_F(PositiveVertexInput, LegacyVertexAttributes) {
vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
m_commandBuffer->EndRenderPass();
m_commandBuffer->end();
}

TEST_F(PositiveVertexInput, ResetCmdSetVertexInput) {
TEST_DESCRIPTION("https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/8523");
AddRequiredExtensions(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME);
AddRequiredFeature(vkt::Feature::vertexInputDynamicState);
RETURN_IF_SKIP(Init());
InitRenderTarget();

char const *vs_source_int = R"glsl(
#version 450
layout(location=0) in uvec4 x;
void main(){}
)glsl";
VkShaderObj vs_int(this, vs_source_int, VK_SHADER_STAGE_VERTEX_BIT);

char const *vs_source_float = R"glsl(
#version 450
layout(location=0) in vec4 x;
void main(){}
)glsl";
VkShaderObj vs_float(this, vs_source_float, VK_SHADER_STAGE_VERTEX_BIT);

CreatePipelineHelper pipe_int(*this);
pipe_int.AddDynamicState(VK_DYNAMIC_STATE_VERTEX_INPUT_EXT);
pipe_int.shader_stages_ = {vs_int.GetStageCreateInfo(), pipe_int.fs_->GetStageCreateInfo()};
pipe_int.CreateGraphicsPipeline();

CreatePipelineHelper pipe_float(*this);
pipe_float.AddDynamicState(VK_DYNAMIC_STATE_VERTEX_INPUT_EXT);
pipe_float.shader_stages_ = {vs_float.GetStageCreateInfo(), pipe_float.fs_->GetStageCreateInfo()};
pipe_float.CreateGraphicsPipeline();

vkt::Buffer vertex_buffer(*m_device, 1024, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
VkDeviceSize offset = 0;

VkVertexInputBindingDescription2EXT bindings = vku::InitStructHelper();
bindings.binding = 0;
bindings.divisor = 1;
bindings.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;

VkVertexInputAttributeDescription2EXT attributes = vku::InitStructHelper();
attributes.location = 0;
attributes.binding = 0;
attributes.format = VK_FORMAT_R8G8B8A8_UINT;

m_commandBuffer->begin();
m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0u, 1u, &vertex_buffer.handle(), &offset);
vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_int.Handle());
vk::CmdSetVertexInputEXT(m_commandBuffer->handle(), 1, &bindings, 1, &attributes);
vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 1);
m_commandBuffer->EndRenderPass();

attributes.format = VK_FORMAT_R8G8B8A8_UNORM;
m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_float.Handle());
vk::CmdSetVertexInputEXT(m_commandBuffer->handle(), 1, &bindings, 1, &attributes);
vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 1);
m_commandBuffer->EndRenderPass();
m_commandBuffer->end();
}

0 comments on commit 884762a

Please sign in to comment.