renderer_vulkan: Fix null buffer views with wrong format. (#2079)

This commit is contained in:
squidbus 2025-01-06 21:00:07 -08:00 committed by GitHub
parent 39b511070a
commit c08fc85b72
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 16 additions and 26 deletions

View file

@ -537,6 +537,7 @@ void Rasterizer::BindBuffers(const Shader::Info& stage, Shader::Backend::Binding
}
// Second pass to re-bind buffers that were updated after binding
auto& null_buffer = buffer_cache.GetBuffer(VideoCore::NULL_BUFFER_ID);
for (u32 i = 0; i < buffer_bindings.size(); i++) {
const auto& [buffer_id, vsharp] = buffer_bindings[i];
const auto& desc = stage.buffers[i];
@ -548,7 +549,6 @@ void Rasterizer::BindBuffers(const Shader::Info& stage, Shader::Backend::Binding
} else if (instance.IsNullDescriptorSupported()) {
buffer_infos.emplace_back(VK_NULL_HANDLE, 0, VK_WHOLE_SIZE);
} else {
auto& null_buffer = buffer_cache.GetBuffer(VideoCore::NULL_BUFFER_ID);
buffer_infos.emplace_back(null_buffer.Handle(), 0, VK_WHOLE_SIZE);
}
} else {
@ -582,17 +582,19 @@ void Rasterizer::BindBuffers(const Shader::Info& stage, Shader::Backend::Binding
++binding.buffer;
}
const auto null_buffer_view =
instance.IsNullDescriptorSupported() ? VK_NULL_HANDLE : buffer_cache.NullBufferView();
for (u32 i = 0; i < texbuffer_bindings.size(); i++) {
const auto& [buffer_id, vsharp] = texbuffer_bindings[i];
const auto& desc = stage.texture_buffers[i];
vk::BufferView& buffer_view = buffer_views.emplace_back(null_buffer_view);
// Fallback format for null buffer view; never used in valid buffer case.
const auto data_fmt = vsharp.GetDataFmt() != AmdGpu::DataFormat::FormatInvalid
? vsharp.GetDataFmt()
: AmdGpu::DataFormat::Format8;
const u32 fmt_stride = AmdGpu::NumBits(data_fmt) >> 3;
vk::BufferView buffer_view;
if (buffer_id) {
const u32 alignment = instance.TexelBufferMinAlignment();
const auto [vk_buffer, offset] = buffer_cache.ObtainBuffer(
vsharp.base_address, vsharp.GetSize(), desc.is_written, true, buffer_id);
const u32 fmt_stride = AmdGpu::NumBits(vsharp.GetDataFmt()) >> 3;
const u32 buf_stride = vsharp.GetStride();
ASSERT_MSG(buf_stride % fmt_stride == 0,
"Texel buffer stride must match format stride");
@ -600,9 +602,8 @@ void Rasterizer::BindBuffers(const Shader::Info& stage, Shader::Backend::Binding
const u32 adjust = offset - offset_aligned;
ASSERT(adjust % fmt_stride == 0);
push_data.AddTexelOffset(binding.buffer, buf_stride / fmt_stride, adjust / fmt_stride);
buffer_view =
vk_buffer->View(offset_aligned, vsharp.GetSize() + adjust, desc.is_written,
vsharp.GetDataFmt(), vsharp.GetNumberFmt());
buffer_view = vk_buffer->View(offset_aligned, vsharp.GetSize() + adjust,
desc.is_written, data_fmt, vsharp.GetNumberFmt());
if (auto barrier =
vk_buffer->GetBarrier(desc.is_written ? vk::AccessFlagBits2::eShaderWrite
: vk::AccessFlagBits2::eShaderRead,
@ -612,6 +613,11 @@ void Rasterizer::BindBuffers(const Shader::Info& stage, Shader::Backend::Binding
if (desc.is_written) {
texture_cache.InvalidateMemoryFromGPU(vsharp.base_address, vsharp.GetSize());
}
} else if (instance.IsNullDescriptorSupported()) {
buffer_view = VK_NULL_HANDLE;
} else {
buffer_view =
null_buffer.View(0, fmt_stride, desc.is_written, data_fmt, vsharp.GetNumberFmt());
}
set_writes.push_back({
@ -621,7 +627,7 @@ void Rasterizer::BindBuffers(const Shader::Info& stage, Shader::Backend::Binding
.descriptorCount = 1,
.descriptorType = desc.is_written ? vk::DescriptorType::eStorageTexelBuffer
: vk::DescriptorType::eUniformTexelBuffer,
.pTexelBufferView = &buffer_view,
.pTexelBufferView = &buffer_views.emplace_back(buffer_view),
});
++binding.buffer;
}