forked from eden-emu/eden
		
	gl_rasterizer: Fix vertex and index data invalidations
This commit is contained in:
		
							parent
							
								
									32b4a2e093
								
							
						
					
					
						commit
						3a1fafb474
					
				
					 4 changed files with 67 additions and 8 deletions
				
			
		|  | @ -198,8 +198,7 @@ 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) { | ||||||
|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 ReinUsesLisp
						ReinUsesLisp