Remove dead vs inputs in spir-v, and don't bind corresponding vbo

Fixes a validation error about vkCmdSetVertexInputEXT(). If the V#
corresponding to an input semantic has size 0, BindVertexBuffers() won't
bind any buffer and wont add vulkan BindingInfo/AttributeInfo for that semantic.
Detect and remove dead vs inputs from the vs spirv.
This commit is contained in:
Frodo Baggins 2024-09-22 16:16:54 -07:00
parent fb5bc371cb
commit 5c5f956a90
2 changed files with 20 additions and 8 deletions

View File

@ -238,6 +238,10 @@ void EmitContext::DefineInputs() {
false, input.instance_data_buf, false, input.instance_data_buf,
}; };
} else { } else {
if (!info.loads.GetAny(IR::Attribute::Param0 + input.binding)) {
continue;
}
Id id{DefineInput(type, input.binding)}; Id id{DefineInput(type, input.binding)};
if (input.instance_step_rate == Info::VsInput::InstanceIdType::Plain) { if (input.instance_step_rate == Info::VsInput::InstanceIdType::Plain) {
Name(id, fmt::format("vs_instance_attr{}", input.binding)); Name(id, fmt::format("vs_instance_attr{}", input.binding));

View File

@ -138,7 +138,12 @@ bool BufferCache::BindVertexBuffers(const Shader::Info& vs_info) {
} }
const auto& buffer = vs_info.ReadUd<AmdGpu::Buffer>(input.sgpr_base, input.dword_offset); const auto& buffer = vs_info.ReadUd<AmdGpu::Buffer>(input.sgpr_base, input.dword_offset);
if (buffer.GetSize() == 0) { bool live_input = vs_info.loads.GetAny(Shader::IR::Attribute::Param0 + input.binding);
if (buffer.GetSize() == 0 || !live_input) {
if (buffer.GetSize() == 0 && live_input) {
LOG_WARNING(Render_Vulkan,
"Vertex input looks live but has no corresponding vertex buffer");
}
continue; continue;
} }
guest_buffers.emplace_back(buffer); guest_buffers.emplace_back(buffer);
@ -164,7 +169,9 @@ bool BufferCache::BindVertexBuffers(const Shader::Info& vs_info) {
return lhv.base_address < rhv.base_address; return lhv.base_address < rhv.base_address;
}); });
boost::container::static_vector<BufferRange, NumVertexBuffers> ranges_merged{ranges[0]}; boost::container::static_vector<BufferRange, NumVertexBuffers> ranges_merged;
if (!ranges.empty()) {
ranges_merged.emplace_back(ranges[0]);
for (auto range : ranges) { for (auto range : ranges) {
auto& prev_range = ranges_merged.back(); auto& prev_range = ranges_merged.back();
if (prev_range.end_address < range.base_address) { if (prev_range.end_address < range.base_address) {
@ -173,6 +180,7 @@ bool BufferCache::BindVertexBuffers(const Shader::Info& vs_info) {
prev_range.end_address = std::max(prev_range.end_address, range.end_address); prev_range.end_address = std::max(prev_range.end_address, range.end_address);
} }
} }
}
// Map buffers // Map buffers
for (auto& range : ranges_merged) { for (auto& range : ranges_merged) {