gl_rasterizer: Fix vertex and index data invalidations
This commit is contained in:
parent
1fa21fa192
commit
9cdc576f60
4 changed files with 67 additions and 8 deletions
|
@ -198,9 +198,8 @@ void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) {
|
||||||
const auto [vertex_buffer, vertex_buffer_offset] = buffer_cache.UploadMemory(start, size);
|
const auto [vertex_buffer, vertex_buffer_offset] = buffer_cache.UploadMemory(start, size);
|
||||||
|
|
||||||
// Bind the vertex array to the buffer at the current offset.
|
// Bind the vertex array to the buffer at the current offset.
|
||||||
// FIXME(Rodrigo): This dereferenced pointer might be invalidated in future uploads.
|
vertex_array_pushbuffer.SetVertexBuffer(index, vertex_buffer, vertex_buffer_offset,
|
||||||
glVertexArrayVertexBuffer(vao, index, *vertex_buffer, vertex_buffer_offset,
|
vertex_array.stride);
|
||||||
vertex_array.stride);
|
|
||||||
|
|
||||||
if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) {
|
if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) {
|
||||||
// Enable vertex buffer instancing with the specified divisor.
|
// Enable vertex buffer instancing with the specified divisor.
|
||||||
|
@ -214,7 +213,7 @@ void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) {
|
||||||
gpu.dirty_flags.vertex_array.reset();
|
gpu.dirty_flags.vertex_array.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
GLintptr RasterizerOpenGL::SetupIndexBuffer(GLuint vao) {
|
GLintptr RasterizerOpenGL::SetupIndexBuffer() {
|
||||||
if (accelerate_draw != AccelDraw::Indexed) {
|
if (accelerate_draw != AccelDraw::Indexed) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -222,8 +221,7 @@ GLintptr RasterizerOpenGL::SetupIndexBuffer(GLuint vao) {
|
||||||
const auto& regs = system.GPU().Maxwell3D().regs;
|
const auto& regs = system.GPU().Maxwell3D().regs;
|
||||||
const std::size_t size = CalculateIndexBufferSize();
|
const std::size_t size = CalculateIndexBufferSize();
|
||||||
const auto [buffer, offset] = buffer_cache.UploadMemory(regs.index_array.IndexStart(), size);
|
const auto [buffer, offset] = buffer_cache.UploadMemory(regs.index_array.IndexStart(), size);
|
||||||
// FIXME(Rodrigo): This dereferenced pointer might be invalidated in future uploads.
|
vertex_array_pushbuffer.SetIndexBuffer(buffer);
|
||||||
glVertexArrayElementBuffer(vao, *buffer);
|
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -644,10 +642,11 @@ void RasterizerOpenGL::DrawArrays() {
|
||||||
|
|
||||||
// Prepare vertex array format.
|
// Prepare vertex array format.
|
||||||
const GLuint vao = SetupVertexFormat();
|
const GLuint vao = SetupVertexFormat();
|
||||||
|
vertex_array_pushbuffer.Setup(vao);
|
||||||
|
|
||||||
// Upload vertex and index data.
|
// Upload vertex and index data.
|
||||||
SetupVertexBuffer(vao);
|
SetupVertexBuffer(vao);
|
||||||
const GLintptr index_buffer_offset = SetupIndexBuffer(vao);
|
const GLintptr index_buffer_offset = SetupIndexBuffer();
|
||||||
|
|
||||||
// Setup draw parameters. It will automatically choose what glDraw* method to use.
|
// Setup draw parameters. It will automatically choose what glDraw* method to use.
|
||||||
const DrawParameters params = SetupDraw(index_buffer_offset);
|
const DrawParameters params = SetupDraw(index_buffer_offset);
|
||||||
|
@ -667,6 +666,7 @@ void RasterizerOpenGL::DrawArrays() {
|
||||||
const bool invalidate = buffer_cache.Unmap();
|
const bool invalidate = buffer_cache.Unmap();
|
||||||
|
|
||||||
// Now that we are no longer uploading data, we can safely bind the buffers to OpenGL.
|
// Now that we are no longer uploading data, we can safely bind the buffers to OpenGL.
|
||||||
|
vertex_array_pushbuffer.Bind();
|
||||||
bind_ubo_pushbuffer.Bind();
|
bind_ubo_pushbuffer.Bind();
|
||||||
bind_ssbo_pushbuffer.Bind();
|
bind_ssbo_pushbuffer.Bind();
|
||||||
|
|
||||||
|
|
|
@ -207,6 +207,7 @@ private:
|
||||||
static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024;
|
static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024;
|
||||||
OGLBufferCache buffer_cache;
|
OGLBufferCache buffer_cache;
|
||||||
|
|
||||||
|
VertexArrayPushBuffer vertex_array_pushbuffer;
|
||||||
BindBuffersRangePushBuffer bind_ubo_pushbuffer{GL_UNIFORM_BUFFER};
|
BindBuffersRangePushBuffer bind_ubo_pushbuffer{GL_UNIFORM_BUFFER};
|
||||||
BindBuffersRangePushBuffer bind_ssbo_pushbuffer{GL_SHADER_STORAGE_BUFFER};
|
BindBuffersRangePushBuffer bind_ssbo_pushbuffer{GL_SHADER_STORAGE_BUFFER};
|
||||||
|
|
||||||
|
@ -219,7 +220,7 @@ private:
|
||||||
|
|
||||||
void SetupVertexBuffer(GLuint vao);
|
void SetupVertexBuffer(GLuint vao);
|
||||||
|
|
||||||
GLintptr SetupIndexBuffer(GLuint vao);
|
GLintptr SetupIndexBuffer();
|
||||||
|
|
||||||
DrawParameters SetupDraw(GLintptr index_buffer_offset);
|
DrawParameters SetupDraw(GLintptr index_buffer_offset);
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,37 @@
|
||||||
|
|
||||||
namespace OpenGL {
|
namespace OpenGL {
|
||||||
|
|
||||||
|
VertexArrayPushBuffer::VertexArrayPushBuffer() = default;
|
||||||
|
|
||||||
|
VertexArrayPushBuffer::~VertexArrayPushBuffer() = default;
|
||||||
|
|
||||||
|
void VertexArrayPushBuffer::Setup(GLuint vao_) {
|
||||||
|
vao = vao_;
|
||||||
|
index_buffer = nullptr;
|
||||||
|
vertex_buffers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VertexArrayPushBuffer::SetIndexBuffer(const GLuint* buffer) {
|
||||||
|
index_buffer = buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VertexArrayPushBuffer::SetVertexBuffer(GLuint binding_index, const GLuint* buffer,
|
||||||
|
GLintptr offset, GLsizei stride) {
|
||||||
|
vertex_buffers.push_back(Entry{binding_index, buffer, offset, stride});
|
||||||
|
}
|
||||||
|
|
||||||
|
void VertexArrayPushBuffer::Bind() {
|
||||||
|
if (index_buffer) {
|
||||||
|
glVertexArrayElementBuffer(vao, *index_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(Rodrigo): Find a way to ARB_multi_bind this
|
||||||
|
for (const auto& entry : vertex_buffers) {
|
||||||
|
glVertexArrayVertexBuffer(vao, entry.binding_index, *entry.buffer, entry.offset,
|
||||||
|
entry.stride);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BindBuffersRangePushBuffer::BindBuffersRangePushBuffer(GLenum target) : target{target} {}
|
BindBuffersRangePushBuffer::BindBuffersRangePushBuffer(GLenum target) : target{target} {}
|
||||||
|
|
||||||
BindBuffersRangePushBuffer::~BindBuffersRangePushBuffer() = default;
|
BindBuffersRangePushBuffer::~BindBuffersRangePushBuffer() = default;
|
||||||
|
|
|
@ -11,6 +11,33 @@
|
||||||
|
|
||||||
namespace OpenGL {
|
namespace OpenGL {
|
||||||
|
|
||||||
|
class VertexArrayPushBuffer final {
|
||||||
|
public:
|
||||||
|
explicit VertexArrayPushBuffer();
|
||||||
|
~VertexArrayPushBuffer();
|
||||||
|
|
||||||
|
void Setup(GLuint vao_);
|
||||||
|
|
||||||
|
void SetIndexBuffer(const GLuint* buffer);
|
||||||
|
|
||||||
|
void SetVertexBuffer(GLuint binding_index, const GLuint* buffer, GLintptr offset,
|
||||||
|
GLsizei stride);
|
||||||
|
|
||||||
|
void Bind();
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Entry {
|
||||||
|
GLuint binding_index{};
|
||||||
|
const GLuint* buffer{};
|
||||||
|
GLintptr offset{};
|
||||||
|
GLsizei stride{};
|
||||||
|
};
|
||||||
|
|
||||||
|
GLuint vao{};
|
||||||
|
const GLuint* index_buffer{};
|
||||||
|
std::vector<Entry> vertex_buffers;
|
||||||
|
};
|
||||||
|
|
||||||
class BindBuffersRangePushBuffer final {
|
class BindBuffersRangePushBuffer final {
|
||||||
public:
|
public:
|
||||||
explicit BindBuffersRangePushBuffer(GLenum target);
|
explicit BindBuffersRangePushBuffer(GLenum target);
|
||||||
|
|
Loading…
Reference in a new issue