mirror of
https://git.h3cjp.net/H3cJP/citra.git
synced 2024-12-25 04:37:09 +00:00
gl_rasterizer: Use buffer_storage for uniform data.
This replaces the glBufferData logic with the shared stream buffer code. The new code doesn't need a temporary staging buffer any more, so the performance should imrpove quite a bit.
This commit is contained in:
parent
7bffd7c1b0
commit
5960282303
|
@ -31,7 +31,8 @@ MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(100, 100, 255));
|
||||||
MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100));
|
MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100));
|
||||||
|
|
||||||
RasterizerOpenGL::RasterizerOpenGL()
|
RasterizerOpenGL::RasterizerOpenGL()
|
||||||
: shader_dirty(true), vertex_buffer(GL_ARRAY_BUFFER, VERTEX_BUFFER_SIZE) {
|
: shader_dirty(true), vertex_buffer(GL_ARRAY_BUFFER, VERTEX_BUFFER_SIZE),
|
||||||
|
uniform_buffer(GL_UNIFORM_BUFFER, UNIFORM_BUFFER_SIZE) {
|
||||||
// Clipping plane 0 is always enabled for PICA fixed clip plane z <= 0
|
// Clipping plane 0 is always enabled for PICA fixed clip plane z <= 0
|
||||||
state.clip_distance[0] = true;
|
state.clip_distance[0] = true;
|
||||||
|
|
||||||
|
@ -48,16 +49,12 @@ RasterizerOpenGL::RasterizerOpenGL()
|
||||||
|
|
||||||
// Generate VBO, VAO and UBO
|
// Generate VBO, VAO and UBO
|
||||||
vertex_array.Create();
|
vertex_array.Create();
|
||||||
uniform_buffer.Create();
|
|
||||||
|
|
||||||
state.draw.vertex_array = vertex_array.handle;
|
state.draw.vertex_array = vertex_array.handle;
|
||||||
state.draw.vertex_buffer = vertex_buffer.GetHandle();
|
state.draw.vertex_buffer = vertex_buffer.GetHandle();
|
||||||
state.draw.uniform_buffer = uniform_buffer.handle;
|
state.draw.uniform_buffer = uniform_buffer.GetHandle();
|
||||||
state.Apply();
|
state.Apply();
|
||||||
|
|
||||||
// Bind the UBO to binding point 0
|
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, 0, uniform_buffer.handle);
|
|
||||||
|
|
||||||
uniform_block_data.dirty = true;
|
uniform_block_data.dirty = true;
|
||||||
|
|
||||||
uniform_block_data.lut_dirty.fill(true);
|
uniform_block_data.lut_dirty.fill(true);
|
||||||
|
@ -70,6 +67,10 @@ RasterizerOpenGL::RasterizerOpenGL()
|
||||||
uniform_block_data.proctex_lut_dirty = true;
|
uniform_block_data.proctex_lut_dirty = true;
|
||||||
uniform_block_data.proctex_diff_lut_dirty = true;
|
uniform_block_data.proctex_diff_lut_dirty = true;
|
||||||
|
|
||||||
|
glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &uniform_buffer_alignment);
|
||||||
|
uniform_size_aligned_fs =
|
||||||
|
Common::AlignUp<size_t>(sizeof(UniformData), uniform_buffer_alignment);
|
||||||
|
|
||||||
// Set vertex attributes
|
// Set vertex attributes
|
||||||
glVertexAttribPointer(GLShader::ATTRIBUTE_POSITION, 4, GL_FLOAT, GL_FALSE,
|
glVertexAttribPointer(GLShader::ATTRIBUTE_POSITION, 4, GL_FLOAT, GL_FALSE,
|
||||||
sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, position));
|
sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, position));
|
||||||
|
@ -475,11 +476,7 @@ void RasterizerOpenGL::DrawTriangles() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sync the uniform data
|
// Sync the uniform data
|
||||||
if (uniform_block_data.dirty) {
|
UploadUniforms();
|
||||||
glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformData), &uniform_block_data.data,
|
|
||||||
GL_STATIC_DRAW);
|
|
||||||
uniform_block_data.dirty = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Viewport can have negative offsets or larger
|
// Viewport can have negative offsets or larger
|
||||||
// dimensions than our framebuffer sub-rect.
|
// dimensions than our framebuffer sub-rect.
|
||||||
|
@ -1652,3 +1649,19 @@ void RasterizerOpenGL::SyncLightDistanceAttenuationScale(int light_index) {
|
||||||
uniform_block_data.dirty = true;
|
uniform_block_data.dirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RasterizerOpenGL::UploadUniforms() {
|
||||||
|
if (!uniform_block_data.dirty)
|
||||||
|
return;
|
||||||
|
|
||||||
|
size_t uniform_size = uniform_size_aligned_fs;
|
||||||
|
u8* uniforms;
|
||||||
|
GLintptr offset;
|
||||||
|
std::tie(uniforms, offset, std::ignore) =
|
||||||
|
uniform_buffer.Map(uniform_size, uniform_buffer_alignment);
|
||||||
|
std::memcpy(uniforms, &uniform_block_data.data, sizeof(UniformData));
|
||||||
|
uniform_buffer.Unmap(uniform_size);
|
||||||
|
glBindBufferRange(GL_UNIFORM_BUFFER, 0, uniform_buffer.GetHandle(), offset,
|
||||||
|
sizeof(UniformData));
|
||||||
|
uniform_block_data.dirty = false;
|
||||||
|
}
|
||||||
|
|
|
@ -215,6 +215,9 @@ private:
|
||||||
/// Syncs the specified light's distance attenuation scale to match the PICA register
|
/// Syncs the specified light's distance attenuation scale to match the PICA register
|
||||||
void SyncLightDistanceAttenuationScale(int light_index);
|
void SyncLightDistanceAttenuationScale(int light_index);
|
||||||
|
|
||||||
|
/// Upload the uniform blocks to the uniform buffer object
|
||||||
|
void UploadUniforms();
|
||||||
|
|
||||||
OpenGLState state;
|
OpenGLState state;
|
||||||
|
|
||||||
RasterizerCacheOpenGL res_cache;
|
RasterizerCacheOpenGL res_cache;
|
||||||
|
@ -237,12 +240,17 @@ private:
|
||||||
|
|
||||||
std::unique_ptr<ShaderProgramManager> shader_program_manager;
|
std::unique_ptr<ShaderProgramManager> shader_program_manager;
|
||||||
|
|
||||||
|
// They shall be big enough for about one frame.
|
||||||
|
static constexpr size_t VERTEX_BUFFER_SIZE = 32 * 1024 * 1024;
|
||||||
|
static constexpr size_t UNIFORM_BUFFER_SIZE = 2 * 1024 * 1024;
|
||||||
|
|
||||||
std::array<SamplerInfo, 3> texture_samplers;
|
std::array<SamplerInfo, 3> texture_samplers;
|
||||||
OGLVertexArray vertex_array;
|
OGLVertexArray vertex_array;
|
||||||
static constexpr size_t VERTEX_BUFFER_SIZE = 32 * 1024 * 1024;
|
|
||||||
OGLStreamBuffer vertex_buffer;
|
OGLStreamBuffer vertex_buffer;
|
||||||
OGLBuffer uniform_buffer;
|
OGLStreamBuffer uniform_buffer;
|
||||||
OGLFramebuffer framebuffer;
|
OGLFramebuffer framebuffer;
|
||||||
|
GLint uniform_buffer_alignment;
|
||||||
|
size_t uniform_size_aligned_fs;
|
||||||
|
|
||||||
// TODO (wwylele): consider caching texture cube in the rasterizer cache
|
// TODO (wwylele): consider caching texture cube in the rasterizer cache
|
||||||
OGLTexture texture_cube;
|
OGLTexture texture_cube;
|
||||||
|
|
Loading…
Reference in a new issue