mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-15 22:21:25 +00:00
gl: Implement scratch ring buffer with memory barriers
This commit is contained in:
parent
3fd846687e
commit
764fb57fdc
@ -238,4 +238,73 @@ namespace gl
|
||||
{
|
||||
flush();
|
||||
}
|
||||
|
||||
scratch_ring_buffer::~scratch_ring_buffer()
|
||||
{
|
||||
if (m_storage)
|
||||
{
|
||||
remove();
|
||||
}
|
||||
}
|
||||
|
||||
void scratch_ring_buffer::create(buffer::target target_, u64 size)
|
||||
{
|
||||
if (m_storage)
|
||||
{
|
||||
remove();
|
||||
}
|
||||
|
||||
m_storage.create(target_, size, nullptr, gl::buffer::memory_type::local, GL_STATIC_COPY);
|
||||
}
|
||||
|
||||
void scratch_ring_buffer::remove()
|
||||
{
|
||||
if (m_storage)
|
||||
{
|
||||
m_storage.remove();
|
||||
}
|
||||
|
||||
m_barriers.clear();
|
||||
m_alloc_pointer = 0;
|
||||
}
|
||||
|
||||
u32 scratch_ring_buffer::alloc(u32 size, u32 alignment)
|
||||
{
|
||||
u64 start = utils::align(m_alloc_pointer, alignment);
|
||||
m_alloc_pointer = (start + size);
|
||||
|
||||
if (m_alloc_pointer > m_storage.size())
|
||||
{
|
||||
start = 0;
|
||||
m_alloc_pointer = size;
|
||||
}
|
||||
|
||||
pop_barrier(start, size);
|
||||
return start;
|
||||
}
|
||||
|
||||
void scratch_ring_buffer::pop_barrier(u32 start, u32 length)
|
||||
{
|
||||
const auto range = utils::address_range::start_length(start, length);
|
||||
m_barriers.erase(std::remove_if(m_barriers.begin(), m_barriers.end(), [&range](auto& barrier_)
|
||||
{
|
||||
if (barrier_.range.overlaps(range))
|
||||
{
|
||||
barrier_.signal.wait_for_signal();
|
||||
}
|
||||
}), m_barriers.end());
|
||||
}
|
||||
|
||||
void scratch_ring_buffer::push_barrier(u32 start, u32 length)
|
||||
{
|
||||
if (!length)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
barrier barrier_;
|
||||
barrier_.range = utils::address_range::start_length(start, length);
|
||||
barrier_.signal.create();
|
||||
m_barriers.emplace_back(barrier_);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "buffer_object.h"
|
||||
#include "Utilities/address_range.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
@ -78,4 +79,32 @@ namespace gl
|
||||
|
||||
void unmap() override;
|
||||
};
|
||||
|
||||
// Simple GPU-side ring buffer with no map/unmap semantics
|
||||
class scratch_ring_buffer
|
||||
{
|
||||
struct barrier
|
||||
{
|
||||
fence signal;
|
||||
utils::address_range range;
|
||||
};
|
||||
|
||||
buffer m_storage;
|
||||
std::vector<barrier> m_barriers;
|
||||
u64 m_alloc_pointer = 0;
|
||||
|
||||
void pop_barrier(u32 start, u32 length);
|
||||
|
||||
public:
|
||||
|
||||
scratch_ring_buffer() = default;
|
||||
scratch_ring_buffer(const scratch_ring_buffer&) = delete;
|
||||
~scratch_ring_buffer();
|
||||
|
||||
void create(buffer::target _target, u64 size);
|
||||
void remove();
|
||||
|
||||
u32 alloc(u32 size, u32 alignment);
|
||||
void push_barrier(u32 start, u32 length);
|
||||
};
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user