gl_state_tracker: Add dirty flags for buffers and divisors
This commit is contained in:
		
							parent
							
								
									9b08698a0c
								
							
						
					
					
						commit
						758ad3f75d
					
				@ -164,12 +164,22 @@ void RasterizerOpenGL::SetupVertexFormat() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void RasterizerOpenGL::SetupVertexBuffer() {
 | 
					void RasterizerOpenGL::SetupVertexBuffer() {
 | 
				
			||||||
    auto& gpu = system.GPU().Maxwell3D();
 | 
					    auto& gpu = system.GPU().Maxwell3D();
 | 
				
			||||||
    const auto& regs = gpu.regs;
 | 
					    auto& flags = gpu.dirty.flags;
 | 
				
			||||||
 | 
					    if (!flags[Dirty::VertexBuffers]) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    flags[Dirty::VertexBuffers] = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MICROPROFILE_SCOPE(OpenGL_VB);
 | 
					    MICROPROFILE_SCOPE(OpenGL_VB);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Upload all guest vertex arrays sequentially to our buffer
 | 
					    // Upload all guest vertex arrays sequentially to our buffer
 | 
				
			||||||
    for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) {
 | 
					    const auto& regs = gpu.regs;
 | 
				
			||||||
 | 
					    for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) {
 | 
				
			||||||
 | 
					        if (!flags[Dirty::VertexBuffer0 + index]) {
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        flags[Dirty::VertexBuffer0 + index] = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const auto& vertex_array = regs.vertex_array[index];
 | 
					        const auto& vertex_array = regs.vertex_array[index];
 | 
				
			||||||
        if (!vertex_array.IsEnabled()) {
 | 
					        if (!vertex_array.IsEnabled()) {
 | 
				
			||||||
            continue;
 | 
					            continue;
 | 
				
			||||||
@ -183,33 +193,30 @@ void RasterizerOpenGL::SetupVertexBuffer() {
 | 
				
			|||||||
        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.
 | 
				
			||||||
        vertex_array_pushbuffer.SetVertexBuffer(index, vertex_buffer, vertex_buffer_offset,
 | 
					        vertex_array_pushbuffer.SetVertexBuffer(static_cast<GLuint>(index), vertex_buffer,
 | 
				
			||||||
                                                vertex_array.stride);
 | 
					                                                vertex_buffer_offset, vertex_array.stride);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) {
 | 
					 | 
				
			||||||
            // Enable vertex buffer instancing with the specified divisor.
 | 
					 | 
				
			||||||
            glVertexBindingDivisor(index, vertex_array.divisor);
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            // Disable the vertex buffer instancing.
 | 
					 | 
				
			||||||
            glVertexBindingDivisor(index, 0);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void RasterizerOpenGL::SetupVertexInstances() {
 | 
					void RasterizerOpenGL::SetupVertexInstances() {
 | 
				
			||||||
    auto& gpu = system.GPU().Maxwell3D();
 | 
					    auto& gpu = system.GPU().Maxwell3D();
 | 
				
			||||||
    const auto& regs = gpu.regs;
 | 
					    auto& flags = gpu.dirty.flags;
 | 
				
			||||||
 | 
					    if (!flags[Dirty::VertexInstances]) {
 | 
				
			||||||
    // Upload all guest vertex arrays sequentially to our buffer
 | 
					        return;
 | 
				
			||||||
    for (u32 index = 0; index < 16; ++index) {
 | 
					 | 
				
			||||||
        if (regs.instanced_arrays.IsInstancingEnabled(index) &&
 | 
					 | 
				
			||||||
            regs.vertex_array[index].divisor != 0) {
 | 
					 | 
				
			||||||
            // Enable vertex buffer instancing with the specified divisor.
 | 
					 | 
				
			||||||
            glVertexBindingDivisor(index, regs.vertex_array[index].divisor);
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            // Disable the vertex buffer instancing.
 | 
					 | 
				
			||||||
            glVertexBindingDivisor(index, 0);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    flags[Dirty::VertexInstances] = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const auto& regs = gpu.regs;
 | 
				
			||||||
 | 
					    for (std::size_t index = 0; index < 16; ++index) {
 | 
				
			||||||
 | 
					        if (!flags[Dirty::VertexInstance0 + index]) {
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        flags[Dirty::VertexInstance0 + index] = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const auto gl_index = static_cast<GLuint>(index);
 | 
				
			||||||
 | 
					        const bool instancing_enabled = regs.instanced_arrays.IsInstancingEnabled(gl_index);
 | 
				
			||||||
 | 
					        const GLuint divisor = instancing_enabled ? regs.vertex_array[index].divisor : 0;
 | 
				
			||||||
 | 
					        glVertexBindingDivisor(gl_index, divisor);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -71,6 +71,26 @@ void SetupDirtyColorMasks(Tables& tables) {
 | 
				
			|||||||
    FillBlock(tables[1], OFF(color_mask), NUM(color_mask), ColorMasks);
 | 
					    FillBlock(tables[1], OFF(color_mask), NUM(color_mask), ColorMasks);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SetupDirtyVertexArrays(Tables& tables) {
 | 
				
			||||||
 | 
					    static constexpr std::size_t num_array = 3;
 | 
				
			||||||
 | 
					    static constexpr std::size_t instance_base_offset = 3;
 | 
				
			||||||
 | 
					    for (std::size_t i = 0; i < Regs::NumVertexArrays; ++i) {
 | 
				
			||||||
 | 
					        const std::size_t array_offset = OFF(vertex_array) + i * NUM(vertex_array[0]);
 | 
				
			||||||
 | 
					        const std::size_t limit_offset = OFF(vertex_array_limit) + i * NUM(vertex_array_limit[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        FillBlock(tables, array_offset, num_array, VertexBuffer0 + i, VertexBuffers);
 | 
				
			||||||
 | 
					        FillBlock(tables, limit_offset, NUM(vertex_array_limit), VertexBuffer0 + i, VertexBuffers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const std::size_t instance_array_offset = array_offset + instance_base_offset;
 | 
				
			||||||
 | 
					        tables[0][instance_array_offset] = static_cast<u8>(VertexInstance0 + i);
 | 
				
			||||||
 | 
					        tables[1][instance_array_offset] = VertexInstances;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const std::size_t instance_offset = OFF(instanced_arrays) + i;
 | 
				
			||||||
 | 
					        tables[0][instance_offset] = static_cast<u8>(VertexInstance0 + i);
 | 
				
			||||||
 | 
					        tables[1][instance_offset] = VertexInstances;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SetupDirtyVertexFormat(Tables& tables) {
 | 
					void SetupDirtyVertexFormat(Tables& tables) {
 | 
				
			||||||
    for (std::size_t i = 0; i < Regs::NumVertexAttributes; ++i) {
 | 
					    for (std::size_t i = 0; i < Regs::NumVertexAttributes; ++i) {
 | 
				
			||||||
        const std::size_t offset = OFF(vertex_attrib_format) + i * NUM(vertex_attrib_format[0]);
 | 
					        const std::size_t offset = OFF(vertex_attrib_format) + i * NUM(vertex_attrib_format[0]);
 | 
				
			||||||
@ -115,6 +135,7 @@ void StateTracker::Initialize() {
 | 
				
			|||||||
    SetupDirtyColorMasks(tables);
 | 
					    SetupDirtyColorMasks(tables);
 | 
				
			||||||
    SetupDirtyViewports(tables);
 | 
					    SetupDirtyViewports(tables);
 | 
				
			||||||
    SetupDirtyScissors(tables);
 | 
					    SetupDirtyScissors(tables);
 | 
				
			||||||
 | 
					    SetupDirtyVertexArrays(tables);
 | 
				
			||||||
    SetupDirtyVertexFormat(tables);
 | 
					    SetupDirtyVertexFormat(tables);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto& store = dirty.on_write_stores;
 | 
					    auto& store = dirty.on_write_stores;
 | 
				
			||||||
 | 
				
			|||||||
@ -78,6 +78,10 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        flags[OpenGL::Dirty::VertexBuffers] = true;
 | 
					        flags[OpenGL::Dirty::VertexBuffers] = true;
 | 
				
			||||||
        flags[OpenGL::Dirty::VertexBuffer0] = true;
 | 
					        flags[OpenGL::Dirty::VertexBuffer0] = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        flags[OpenGL::Dirty::VertexInstances] = true;
 | 
				
			||||||
 | 
					        flags[OpenGL::Dirty::VertexInstance0 + 0] = true;
 | 
				
			||||||
 | 
					        flags[OpenGL::Dirty::VertexInstance0 + 1] = true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void NotifyViewport0() {
 | 
					    void NotifyViewport0() {
 | 
				
			||||||
 | 
				
			|||||||
@ -611,6 +611,8 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    glEnableVertexAttribArray(PositionLocation);
 | 
					    glEnableVertexAttribArray(PositionLocation);
 | 
				
			||||||
    glEnableVertexAttribArray(TexCoordLocation);
 | 
					    glEnableVertexAttribArray(TexCoordLocation);
 | 
				
			||||||
 | 
					    glVertexAttribDivisor(PositionLocation, 0);
 | 
				
			||||||
 | 
					    glVertexAttribDivisor(TexCoordLocation, 0);
 | 
				
			||||||
    glVertexAttribFormat(PositionLocation, 2, GL_FLOAT, GL_FALSE,
 | 
					    glVertexAttribFormat(PositionLocation, 2, GL_FLOAT, GL_FALSE,
 | 
				
			||||||
                         offsetof(ScreenRectVertex, position));
 | 
					                         offsetof(ScreenRectVertex, position));
 | 
				
			||||||
    glVertexAttribFormat(TexCoordLocation, 2, GL_FLOAT, GL_FALSE,
 | 
					    glVertexAttribFormat(TexCoordLocation, 2, GL_FLOAT, GL_FALSE,
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user