Barrier vertex/index buffers written by compute (#4611)

* Vertex/Index barriers

* Vert/Index barrier param

* barrrrrrrr

* Add GPU modification checks for buffer barriers
This commit is contained in:
Kravickas 2026-06-27 09:24:19 +02:00 committed by GitHub
parent 59d7c92e45
commit 463fe06dce
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 26 additions and 8 deletions

View File

@ -144,7 +144,9 @@ void BufferCache::DownloadBufferMemory(Buffer& buffer, VAddr device_addr, u64 si
}
}
void BufferCache::BindVertexBuffers(const Vulkan::GraphicsPipeline& pipeline) {
void BufferCache::BindVertexBuffers(
const Vulkan::GraphicsPipeline& pipeline,
boost::container::small_vector<vk::BufferMemoryBarrier2, 16>& barriers) {
const auto& regs = liverpool->regs;
Vulkan::VertexInputs<vk::VertexInputAttributeDescription2EXT> attributes;
Vulkan::VertexInputs<vk::VertexInputBindingDescription2EXT> bindings;
@ -206,6 +208,13 @@ void BufferCache::BindVertexBuffers(const Vulkan::GraphicsPipeline& pipeline) {
const auto [buffer, offset] = ObtainBuffer(range.base_address, size, false);
range.vk_buffer = buffer->buffer;
range.offset = offset;
if (IsRegionGpuModified(range.base_address, size)) {
if (auto barrier =
buffer->GetBarrier(vk::AccessFlagBits2::eVertexAttributeRead,
vk::PipelineStageFlagBits2::eVertexAttributeInput)) {
barriers.emplace_back(*barrier);
}
}
}
// Bind vertex buffers
@ -244,7 +253,8 @@ void BufferCache::BindVertexBuffers(const Vulkan::GraphicsPipeline& pipeline) {
}
}
void BufferCache::BindIndexBuffer(u32 index_offset) {
void BufferCache::BindIndexBuffer(
u32 index_offset, boost::container::small_vector<vk::BufferMemoryBarrier2, 16>& barriers) {
const auto& regs = liverpool->regs;
// Figure out index type and size.
@ -257,6 +267,12 @@ void BufferCache::BindIndexBuffer(u32 index_offset) {
// Bind index buffer.
const u32 index_buffer_size = regs.num_indices * index_size;
const auto [vk_buffer, offset] = ObtainBuffer(index_address, index_buffer_size, false);
if (IsRegionGpuModified(index_address, index_buffer_size)) {
if (auto barrier = vk_buffer->GetBarrier(vk::AccessFlagBits2::eIndexRead,
vk::PipelineStageFlagBits2::eIndexInput)) {
barriers.emplace_back(*barrier);
}
}
const auto cmdbuf = scheduler.CommandBuffer();
cmdbuf.bindIndexBuffer(vk_buffer->Handle(), offset, index_type);
}

View File

@ -112,10 +112,12 @@ public:
void ReadMemory(VAddr device_addr, u64 size, bool is_write = false);
/// Binds host vertex buffers for the current draw.
void BindVertexBuffers(const Vulkan::GraphicsPipeline& pipeline);
void BindVertexBuffers(const Vulkan::GraphicsPipeline& pipeline,
boost::container::small_vector<vk::BufferMemoryBarrier2, 16>& barriers);
/// Bind host index buffer for the current draw.
void BindIndexBuffer(u32 index_offset);
void BindIndexBuffer(u32 index_offset,
boost::container::small_vector<vk::BufferMemoryBarrier2, 16>& barriers);
/// Writes a value to GPU buffer. (uses command buffer to temporarily store the data)
void FillBuffer(VAddr address, u32 num_bytes, u32 value, bool is_gds);

View File

@ -206,9 +206,9 @@ void Rasterizer::Draw(bool is_indexed, u32 index_offset) {
}
const auto state = BeginRendering(pipeline);
buffer_cache.BindVertexBuffers(*pipeline);
buffer_cache.BindVertexBuffers(*pipeline, buffer_barriers);
if (is_indexed) {
buffer_cache.BindIndexBuffer(index_offset);
buffer_cache.BindIndexBuffer(index_offset, buffer_barriers);
}
pipeline->BindResources(set_writes, buffer_barriers, push_data);
@ -254,9 +254,9 @@ void Rasterizer::DrawIndirect(bool is_indexed, VAddr arg_address, u32 offset, u3
}
const auto state = BeginRendering(pipeline);
buffer_cache.BindVertexBuffers(*pipeline);
buffer_cache.BindVertexBuffers(*pipeline, buffer_barriers);
if (is_indexed) {
buffer_cache.BindIndexBuffer(0);
buffer_cache.BindIndexBuffer(0, buffer_barriers);
}
const auto& [buffer, base] =