From 4646ba9c482d1f914a4fcdd29eeb8cdb4848acc3 Mon Sep 17 00:00:00 2001 From: Jannik Vogel Date: Tue, 25 Aug 2015 06:44:06 +0200 Subject: [PATCH] Use uniform buffer objects --- hw/xbox/nv2a.c | 45 +++++++++++++++++++++++++++++++----------- hw/xbox/nv2a_shaders.c | 10 ++-------- hw/xbox/nv2a_shaders.h | 2 +- hw/xbox/nv2a_vsh.c | 4 +++- 4 files changed, 39 insertions(+), 22 deletions(-) diff --git a/hw/xbox/nv2a.c b/hw/xbox/nv2a.c index c277c4d926..5cc6a23911 100644 --- a/hw/xbox/nv2a.c +++ b/hw/xbox/nv2a.c @@ -1553,6 +1553,8 @@ typedef struct PGRAPHState { GLuint gl_element_buffer; GLuint gl_memory_buffer; + GLuint gl_vertex_constants_buffer; + GLuint gl_vertex_array; uint32_t regs[0x2000]; @@ -2902,6 +2904,13 @@ static void pgraph_bind_shaders(PGRAPHState *pg) } else { pg->shader_binding = generate_shaders(state); + /* Bind uniform blocks */ + if (pg->shader_binding->gl_constants_loc != GL_INVALID_INDEX) { + glUniformBlockBinding(pg->shader_binding->gl_program, + pg->shader_binding->gl_constants_loc, + 0 /* FIXME: Use #define */); + } + /* cache it */ ShaderState *cache_state = g_malloc(sizeof(*cache_state)); memcpy(cache_state, &state, sizeof(*cache_state)); @@ -3097,18 +3106,6 @@ static void pgraph_bind_shaders(PGRAPHState *pg) } else if (vertex_program) { /* update vertex program constants */ - for (i=0; iconstants[i]; - if (!constant->dirty && !binding_changed) continue; - - GLint loc = pg->shader_binding->vsh_constant_loc[i]; - //assert(loc != -1); - if (loc != -1) { - glUniform4fv(loc, 1, (const GLfloat*)constant->data); - } - constant->dirty = false; - } - GLint loc = glGetUniformLocation(pg->shader_binding->gl_program, "surfaceSize"); if (loc != -1) { @@ -3123,6 +3120,23 @@ static void pgraph_bind_shaders(PGRAPHState *pg) } } + + /* Update constants */ + if (pg->shader_binding->gl_constants_loc != GL_INVALID_INDEX) { + /* FIXME: Can be done on buffer creation? */ + glBindBufferBase(GL_UNIFORM_BUFFER, 0 /* FIXME: Use def */, + pg->gl_vertex_constants_buffer); + for (i=0; iconstants[i]; + if (!constant->dirty) continue; + + /* FIXME: Query GL_UNIFORM_ARRAY_STRIDE instead of assuming 16 */ + + glBufferSubData(GL_UNIFORM_BUFFER, i * 16, 16, constant->data); + constant->dirty = false; + } + } + NV2A_GL_DGROUP_END(); } @@ -3532,6 +3546,13 @@ static void pgraph_init(NV2AState *d) glGenBuffers(1, &pg->gl_inline_array_buffer); glGenBuffers(1, &pg->gl_element_buffer); + glGenBuffers(1, &pg->gl_vertex_constants_buffer); + glBindBuffer(GL_UNIFORM_BUFFER, pg->gl_vertex_constants_buffer); + glBufferData(GL_UNIFORM_BUFFER, + 16 * NV2A_VERTEXSHADER_CONSTANTS, + NULL, + GL_DYNAMIC_DRAW); + glGenBuffers(1, &pg->gl_memory_buffer); glBindBuffer(GL_ARRAY_BUFFER, pg->gl_memory_buffer); glBufferData(GL_ARRAY_BUFFER, diff --git a/hw/xbox/nv2a_shaders.c b/hw/xbox/nv2a_shaders.c index e6cdc02321..3ee35610db 100644 --- a/hw/xbox/nv2a_shaders.c +++ b/hw/xbox/nv2a_shaders.c @@ -593,14 +593,8 @@ ShaderBinding* generate_shaders(const ShaderState state) ret->psh_constant_loc[i][j] = glGetUniformLocation(program, tmp); } } - if (state.vertex_program) { - /* lookup vertex shader bindings */ - for(i = 0; i < NV2A_VERTEXSHADER_CONSTANTS; i++) { - char tmp[8]; - snprintf(tmp, sizeof(tmp), "c[%d]", i); - ret->vsh_constant_loc[i] = glGetUniformLocation(program, tmp); - } - } + + ret->gl_constants_loc = glGetUniformBlockIndex(program, "VertexConstants"); return ret; } diff --git a/hw/xbox/nv2a_shaders.h b/hw/xbox/nv2a_shaders.h index 3271cb5415..c26c85d9b4 100644 --- a/hw/xbox/nv2a_shaders.h +++ b/hw/xbox/nv2a_shaders.h @@ -87,7 +87,7 @@ typedef struct ShaderState { typedef struct ShaderBinding { GLuint gl_program; GLint psh_constant_loc[9][2]; - GLint vsh_constant_loc[NV2A_VERTEXSHADER_CONSTANTS]; + GLint gl_constants_loc; } ShaderBinding; ShaderBinding* generate_shaders(const ShaderState state); diff --git a/hw/xbox/nv2a_vsh.c b/hw/xbox/nv2a_vsh.c index 3e43a284cc..90316817cd 100644 --- a/hw/xbox/nv2a_vsh.c +++ b/hw/xbox/nv2a_vsh.c @@ -567,7 +567,9 @@ static const char* vsh_header = /* All constants in 1 array declaration */ - "uniform vec4 c[192];\n" + "layout(shared) uniform VertexConstants {\n" + " uniform vec4 c[192];\n" + "};" "\n" "uniform vec2 clipRange;\n" "uniform vec2 surfaceSize;\n"