diff options
Diffstat (limited to 'video/out/opengl/utils.c')
-rw-r--r-- | video/out/opengl/utils.c | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/video/out/opengl/utils.c b/video/out/opengl/utils.c index 0026090df9..6ddb333e47 100644 --- a/video/out/opengl/utils.c +++ b/video/out/opengl/utils.c @@ -482,6 +482,7 @@ enum uniform_type { UT_i, UT_f, UT_m, + UT_buffer, }; struct sc_uniform { @@ -493,6 +494,10 @@ struct sc_uniform { union { GLfloat f[9]; GLint i[4]; + struct { + char* text; + GLint binding; + } buffer; } v; }; @@ -535,8 +540,11 @@ void gl_sc_reset(struct gl_shader_cache *sc) { sc->text[0] = '\0'; sc->header_text[0] = '\0'; - for (int n = 0; n < sc->num_uniforms; n++) + for (int n = 0; n < sc->num_uniforms; n++) { talloc_free(sc->uniforms[n].name); + if (sc->uniforms[n].type == UT_buffer) + talloc_free(sc->uniforms[n].v.buffer.text); + } sc->num_uniforms = 0; } @@ -697,6 +705,15 @@ void gl_sc_uniform_mat3(struct gl_shader_cache *sc, char *name, transpose3x3(&u->v.f[0]); } +void gl_sc_uniform_buffer(struct gl_shader_cache *sc, char *name, + const char *text, int binding) +{ + struct sc_uniform *u = find_uniform(sc, name); + u->type = UT_buffer; + u->v.buffer.text = talloc_strdup(sc, text); + u->v.buffer.binding = binding; +} + // This will call glBindAttribLocation() on the shader before it's linked // (OpenGL requires this to happen before linking). Basically, it associates // the input variable names with the fields in the vao. @@ -723,6 +740,11 @@ static const char *vao_glsl_type(const struct gl_vao_entry *e) // Assumes program is current (gl->UseProgram(program)). static void update_uniform(GL *gl, GLuint program, struct sc_uniform *u) { + if (u->type == UT_buffer) { + GLuint idx = gl->GetUniformBlockIndex(program, u->name); + gl->UniformBlockBinding(program, idx, u->v.buffer.binding); + return; + } GLint loc = gl->GetUniformLocation(program, u->name); if (loc < 0) return; @@ -885,7 +907,10 @@ void gl_sc_gen_shader_and_reset(struct gl_shader_cache *sc) ADD(frag, "%s", frag_vaos); for (int n = 0; n < sc->num_uniforms; n++) { struct sc_uniform *u = &sc->uniforms[n]; - ADD(frag, "uniform %s %s;\n", u->glsl_type, u->name); + if (u->type == UT_buffer) + ADD(frag, "uniform %s { %s };\n", u->name, u->v.buffer.text); + else + ADD(frag, "uniform %s %s;\n", u->glsl_type, u->name); } // custom shader header if (sc->header_text[0]) { |