gl_rasterizer: Fix vertex and index data invalidations
This commit is contained in:
		
							parent
							
								
									1fa21fa192
								
							
						
					
					
						commit
						9cdc576f60
					
				@ -198,9 +198,8 @@ void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) {
 | 
			
		||||
        const auto [vertex_buffer, vertex_buffer_offset] = buffer_cache.UploadMemory(start, size);
 | 
			
		||||
 | 
			
		||||
        // Bind the vertex array to the buffer at the current offset.
 | 
			
		||||
        // FIXME(Rodrigo): This dereferenced pointer might be invalidated in future uploads.
 | 
			
		||||
        glVertexArrayVertexBuffer(vao, index, *vertex_buffer, vertex_buffer_offset,
 | 
			
		||||
                                  vertex_array.stride);
 | 
			
		||||
        vertex_array_pushbuffer.SetVertexBuffer(index, vertex_buffer, vertex_buffer_offset,
 | 
			
		||||
                                                vertex_array.stride);
 | 
			
		||||
 | 
			
		||||
        if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) {
 | 
			
		||||
            // Enable vertex buffer instancing with the specified divisor.
 | 
			
		||||
@ -214,7 +213,7 @@ void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) {
 | 
			
		||||
    gpu.dirty_flags.vertex_array.reset();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GLintptr RasterizerOpenGL::SetupIndexBuffer(GLuint vao) {
 | 
			
		||||
GLintptr RasterizerOpenGL::SetupIndexBuffer() {
 | 
			
		||||
    if (accelerate_draw != AccelDraw::Indexed) {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
@ -222,8 +221,7 @@ GLintptr RasterizerOpenGL::SetupIndexBuffer(GLuint vao) {
 | 
			
		||||
    const auto& regs = system.GPU().Maxwell3D().regs;
 | 
			
		||||
    const std::size_t size = CalculateIndexBufferSize();
 | 
			
		||||
    const auto [buffer, offset] = buffer_cache.UploadMemory(regs.index_array.IndexStart(), size);
 | 
			
		||||
    // FIXME(Rodrigo): This dereferenced pointer might be invalidated in future uploads.
 | 
			
		||||
    glVertexArrayElementBuffer(vao, *buffer);
 | 
			
		||||
    vertex_array_pushbuffer.SetIndexBuffer(buffer);
 | 
			
		||||
    return offset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -644,10 +642,11 @@ void RasterizerOpenGL::DrawArrays() {
 | 
			
		||||
 | 
			
		||||
    // Prepare vertex array format.
 | 
			
		||||
    const GLuint vao = SetupVertexFormat();
 | 
			
		||||
    vertex_array_pushbuffer.Setup(vao);
 | 
			
		||||
 | 
			
		||||
    // Upload vertex and index data.
 | 
			
		||||
    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.
 | 
			
		||||
    const DrawParameters params = SetupDraw(index_buffer_offset);
 | 
			
		||||
@ -667,6 +666,7 @@ void RasterizerOpenGL::DrawArrays() {
 | 
			
		||||
    const bool invalidate = buffer_cache.Unmap();
 | 
			
		||||
 | 
			
		||||
    // 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_ssbo_pushbuffer.Bind();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -207,6 +207,7 @@ private:
 | 
			
		||||
    static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024;
 | 
			
		||||
    OGLBufferCache buffer_cache;
 | 
			
		||||
 | 
			
		||||
    VertexArrayPushBuffer vertex_array_pushbuffer;
 | 
			
		||||
    BindBuffersRangePushBuffer bind_ubo_pushbuffer{GL_UNIFORM_BUFFER};
 | 
			
		||||
    BindBuffersRangePushBuffer bind_ssbo_pushbuffer{GL_SHADER_STORAGE_BUFFER};
 | 
			
		||||
 | 
			
		||||
@ -219,7 +220,7 @@ private:
 | 
			
		||||
 | 
			
		||||
    void SetupVertexBuffer(GLuint vao);
 | 
			
		||||
 | 
			
		||||
    GLintptr SetupIndexBuffer(GLuint vao);
 | 
			
		||||
    GLintptr SetupIndexBuffer();
 | 
			
		||||
 | 
			
		||||
    DrawParameters SetupDraw(GLintptr index_buffer_offset);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -13,6 +13,37 @@
 | 
			
		||||
 | 
			
		||||
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() = default;
 | 
			
		||||
 | 
			
		||||
@ -11,6 +11,33 @@
 | 
			
		||||
 | 
			
		||||
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 {
 | 
			
		||||
public:
 | 
			
		||||
    explicit BindBuffersRangePushBuffer(GLenum target);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user