OpenGL: refactor all of our StreamBuffers

The old way was to use big switch/case statements based on a type of buffer.
The new one is to use inheritance.

This change prohibits us to change the buffer type while running, but I doubt we'll ever do so.
Performance should also be a bit better. Also a nice cleanup.

Added some comments about this different kind of buffers.
This commit is contained in:
degasus
2014-01-23 15:12:31 +01:00
parent be1fee6d74
commit 128fcdac26
4 changed files with 373 additions and 256 deletions
@@ -193,18 +193,18 @@ void ProgramShaderCache::UploadConstants()
{
if(PixelShaderManager::dirty || VertexShaderManager::dirty)
{
u8* buffer = s_buffer->Map(s_ubo_buffer_size, s_ubo_align);
auto buffer = s_buffer->Map(s_ubo_buffer_size, s_ubo_align);
memcpy(buffer,
memcpy(buffer.first,
&PixelShaderManager::constants, sizeof(PixelShaderConstants));
memcpy(buffer + ROUND_UP(sizeof(PixelShaderConstants), s_ubo_align),
memcpy(buffer.first + ROUND_UP(sizeof(PixelShaderConstants), s_ubo_align),
&VertexShaderManager::constants, sizeof(VertexShaderConstants));
size_t offset = s_buffer->Unmap(s_ubo_buffer_size);
glBindBufferRange(GL_UNIFORM_BUFFER, 1, s_buffer->getBuffer(), offset,
s_buffer->Unmap(s_ubo_buffer_size);
glBindBufferRange(GL_UNIFORM_BUFFER, 1, s_buffer->m_buffer, buffer.second,
sizeof(PixelShaderConstants));
glBindBufferRange(GL_UNIFORM_BUFFER, 2, s_buffer->getBuffer(), offset + ROUND_UP(sizeof(PixelShaderConstants), s_ubo_align),
glBindBufferRange(GL_UNIFORM_BUFFER, 2, s_buffer->m_buffer, buffer.second + ROUND_UP(sizeof(PixelShaderConstants), s_ubo_align),
sizeof(VertexShaderConstants));
PixelShaderManager::dirty = false;
@@ -471,7 +471,7 @@ void ProgramShaderCache::Init(void)
// We multiply by *4*4 because we need to get down to basic machine units.
// So multiply by four to get how many floats we have from vec4s
// Then once more to get bytes
s_buffer = new StreamBuffer(GL_UNIFORM_BUFFER, UBO_LENGTH);
s_buffer = StreamBuffer::Create(GL_UNIFORM_BUFFER, UBO_LENGTH);
}
// Read our shader cache, only if supported
File diff suppressed because it is too large Load Diff
+26 -23
View File
@@ -5,6 +5,7 @@
#ifndef STREAMBUFFER_H
#define STREAMBUFFER_H
#include <utility>
#include "VideoCommon.h"
#include "FramebufferManager.h"
#include "GLUtil.h"
@@ -17,39 +18,41 @@
namespace OGL
{
enum StreamType {
MAP_AND_ORPHAN = (1 << 1),
MAP_AND_SYNC = (1 << 2),
PINNED_MEMORY = (1 << 3),
BUFFERSUBDATA = (1 << 4),
BUFFERDATA = (1 << 5),
BUFFERSTORAGE = (1 << 6),
};
class StreamBuffer {
public:
static StreamBuffer* Create(u32 type, size_t size);
virtual ~StreamBuffer();
/* This mapping function will return a pair of:
* - the pointer to the mapped buffer
* - the offset into the real gpu buffer (always multiple of stride)
* On mapping, the maximum of size for allocation has to be set.
* The size really pushed into this fifo only has to be known on Unmapping.
* Mapping invalidates the current buffer content,
* so it isn't allowed to access the old content any more.
*/
virtual std::pair<u8*, size_t> Map(size_t size, u32 stride = 0) = 0;
virtual void Unmap(size_t used_size) = 0;
const u32 m_buffer;
protected:
StreamBuffer(u32 type, size_t size);
~StreamBuffer();
u8* Map(size_t size, u32 stride = 0);
size_t Unmap(size_t used_size); // returns the offset of the beginning of the uploaded block
inline u32 getBuffer() { return m_buffer; }
private:
void Init();
void Shutdown();
void CreateFences();
void DeleteFences();
void AllocMemory(size_t size);
void Align(u32 stride);
StreamType m_uploadtype;
u32 m_buffer;
u32 m_buffertype;
size_t m_size;
u8 *pointer;
const u32 m_buffertype;
const size_t m_size;
size_t m_iterator;
size_t m_used_iterator;
size_t m_free_iterator;
private:
GLsync *fences;
};
+11 -10
View File
@@ -58,11 +58,11 @@ VertexManager::~VertexManager()
void VertexManager::CreateDeviceObjects()
{
s_vertexBuffer = new StreamBuffer(GL_ARRAY_BUFFER, MAX_VBUFFER_SIZE);
m_vertex_buffers = s_vertexBuffer->getBuffer();
s_vertexBuffer = StreamBuffer::Create(GL_ARRAY_BUFFER, MAX_VBUFFER_SIZE);
m_vertex_buffers = s_vertexBuffer->m_buffer;
s_indexBuffer = new StreamBuffer(GL_ELEMENT_ARRAY_BUFFER, MAX_IBUFFER_SIZE);
m_index_buffers = s_indexBuffer->getBuffer();
s_indexBuffer = StreamBuffer::Create(GL_ELEMENT_ARRAY_BUFFER, MAX_IBUFFER_SIZE);
m_index_buffers = s_indexBuffer->m_buffer;
m_CurrentVertexFmt = NULL;
m_last_vao = 0;
@@ -85,14 +85,15 @@ void VertexManager::PrepareDrawBuffers(u32 stride)
u32 vertex_data_size = IndexGenerator::GetNumVerts() * stride;
u32 index_data_size = IndexGenerator::GetIndexLen() * sizeof(u16);
u8* buffer = s_vertexBuffer->Map(vertex_data_size, stride);
memcpy(buffer, GetVertexBuffer(), vertex_data_size);
size_t offset = s_vertexBuffer->Unmap(vertex_data_size);
s_baseVertex = offset / stride;
auto buffer = s_vertexBuffer->Map(vertex_data_size, stride);
memcpy(buffer.first, GetVertexBuffer(), vertex_data_size);
s_vertexBuffer->Unmap(vertex_data_size);
s_baseVertex = buffer.second / stride;
buffer = s_indexBuffer->Map(index_data_size);
memcpy(buffer, GetIndexBuffer(), index_data_size);
s_index_offset = s_indexBuffer->Unmap(index_data_size);
memcpy(buffer.first, GetIndexBuffer(), index_data_size);
s_indexBuffer->Unmap(index_data_size);
s_index_offset = buffer.second;
ADDSTAT(stats.thisFrame.bytesVertexStreamed, vertex_data_size);
ADDSTAT(stats.thisFrame.bytesIndexStreamed, index_data_size);