From 7684fda6ac69265ca21cdf2f1d8ae8483bb36607 Mon Sep 17 00:00:00 2001 From: Niklas Haas Date: Sat, 26 Aug 2017 05:39:53 +0200 Subject: vo_opengl: refactor shader_cache binding There's no reason to be needlessly wasteful with our binding points here. Just add a CAP for it. --- video/out/opengl/ra.h | 4 ++++ video/out/opengl/ra_gl.c | 31 ++++++++++++++++++------------- video/out/opengl/shader_cache.c | 27 ++++++++++++++++++--------- 3 files changed, 40 insertions(+), 22 deletions(-) diff --git a/video/out/opengl/ra.h b/video/out/opengl/ra.h index f09fa6c861..6d77255180 100644 --- a/video/out/opengl/ra.h +++ b/video/out/opengl/ra.h @@ -45,6 +45,7 @@ enum { RA_CAP_DIRECT_UPLOAD = 1 << 4, // supports tex_upload without ra_buf RA_CAP_BUF_RW = 1 << 5, // supports RA_VARTYPE_BUF_RW RA_CAP_NESTED_ARRAY = 1 << 6, // supports nested arrays + RA_CAP_SHARED_BINDING = 1 << 7, // sampler/image/buffer namespaces are disjoint }; enum ra_ctype { @@ -174,6 +175,7 @@ enum ra_vartype { // ra_tex.params.storage_dst must be true RA_VARTYPE_BYTE_UNORM, // C: uint8_t, GLSL: int, vec* (vertex data only) RA_VARTYPE_BUF_RW, // C: ra_buf*, GLSL: buffer block + RA_VARTYPE_COUNT }; // Represents a uniform, texture input parameter, and similar things. @@ -189,6 +191,8 @@ struct ra_renderpass_input { // RA_VARTYPE_IMG_W: image unit // RA_VARTYPE_BUF_* buffer binding point // Other uniforms: unused + // If RA_CAP_SHARED_BINDING is set, these may only be unique per input type. + // Otherwise, these must be unique for all input values. int binding; }; diff --git a/video/out/opengl/ra_gl.c b/video/out/opengl/ra_gl.c index d9c7205815..1726980615 100644 --- a/video/out/opengl/ra_gl.c +++ b/video/out/opengl/ra_gl.c @@ -91,22 +91,27 @@ static int ra_init_gl(struct ra *ra, GL *gl) ra_gl_set_debug(ra, true); ra->fns = &ra_fns_gl; - ra->caps = RA_CAP_DIRECT_UPLOAD; - if (gl->mpgl_caps & MPGL_CAP_1D_TEX) - ra->caps |= RA_CAP_TEX_1D; - if (gl->mpgl_caps & MPGL_CAP_3D_TEX) - ra->caps |= RA_CAP_TEX_3D; - if (gl->BlitFramebuffer) - ra->caps |= RA_CAP_BLIT; - if (gl->mpgl_caps & MPGL_CAP_COMPUTE_SHADER) - ra->caps |= RA_CAP_COMPUTE; - if (gl->mpgl_caps & MPGL_CAP_NESTED_ARRAY) - ra->caps |= RA_CAP_NESTED_ARRAY; - if (gl->mpgl_caps & MPGL_CAP_SSBO) - ra->caps |= RA_CAP_BUF_RW; ra->glsl_version = gl->glsl_version; ra->glsl_es = gl->es > 0; + static const int caps_map[][2] = { + {RA_CAP_DIRECT_UPLOAD, 0}, + {RA_CAP_SHARED_BINDING, 0}, + {RA_CAP_TEX_1D, MPGL_CAP_1D_TEX}, + {RA_CAP_TEX_3D, MPGL_CAP_3D_TEX}, + {RA_CAP_COMPUTE, MPGL_CAP_COMPUTE_SHADER}, + {RA_CAP_NESTED_ARRAY, MPGL_CAP_NESTED_ARRAY}, + {RA_CAP_BUF_RW, MPGL_CAP_SSBO}, + }; + + for (int i = 0; i < MP_ARRAY_SIZE(caps_map); i++) { + if ((gl->mpgl_caps & caps_map[i][1]) == caps_map[i][1]) + ra->caps |= caps_map[i][0]; + } + + if (gl->BlitFramebuffer) + ra->caps |= RA_CAP_BLIT; + int gl_fmt_features = gl_format_feature_flags(gl); for (int n = 0; gl_formats[n].internal_format; n++) { diff --git a/video/out/opengl/shader_cache.c b/video/out/opengl/shader_cache.c index 050d01d36d..97374e781b 100644 --- a/video/out/opengl/shader_cache.c +++ b/video/out/opengl/shader_cache.c @@ -58,9 +58,10 @@ struct gl_shader_cache { bstr prelude_text; bstr header_text; bstr text; - int next_texture_unit; - int next_image_unit; - int next_buffer_binding; + + // Next binding point (texture unit, image unit, buffer binding, etc.) + // In OpenGL these are separate for each input type + int next_binding[RA_VARTYPE_COUNT]; struct ra_renderpass_params params; @@ -113,9 +114,8 @@ static void gl_sc_reset(struct gl_shader_cache *sc) for (int n = 0; n < sc->num_uniforms; n++) talloc_free((void *)sc->uniforms[n].input.name); sc->num_uniforms = 0; - sc->next_texture_unit = 1; // not 0, as 0 is "free for use" - sc->next_image_unit = 1; - sc->next_buffer_binding = 1; + for (int i = 0; i < RA_VARTYPE_COUNT; i++) + sc->next_binding[i] = 0; sc->current_shader = NULL; sc->params = (struct ra_renderpass_params){0}; sc->needs_reset = false; @@ -230,6 +230,15 @@ static struct sc_uniform *find_uniform(struct gl_shader_cache *sc, return &sc->uniforms[sc->num_uniforms - 1]; } +static int gl_sc_next_binding(struct gl_shader_cache *sc, enum ra_vartype type) +{ + if (sc->ra->caps & RA_CAP_SHARED_BINDING) { + return sc->next_binding[type]++; + } else { + return sc->next_binding[0]++; + } +} + void gl_sc_uniform_texture(struct gl_shader_cache *sc, char *name, struct ra_tex *tex) { @@ -249,7 +258,7 @@ void gl_sc_uniform_texture(struct gl_shader_cache *sc, char *name, struct sc_uniform *u = find_uniform(sc, name); u->input.type = RA_VARTYPE_TEX; u->glsl_type = glsl_type; - u->input.binding = sc->next_texture_unit++; + u->input.binding = gl_sc_next_binding(sc, u->input.type); u->v.tex = tex; } @@ -261,7 +270,7 @@ void gl_sc_uniform_image2D_wo(struct gl_shader_cache *sc, const char *name, struct sc_uniform *u = find_uniform(sc, name); u->input.type = RA_VARTYPE_IMG_W; u->glsl_type = "writeonly image2D"; - u->input.binding = sc->next_image_unit++; + u->input.binding = gl_sc_next_binding(sc, u->input.type); u->v.tex = tex; } @@ -273,7 +282,7 @@ void gl_sc_ssbo(struct gl_shader_cache *sc, char *name, struct ra_buf *buf, struct sc_uniform *u = find_uniform(sc, name); u->input.type = RA_VARTYPE_BUF_RW; u->glsl_type = ""; - u->input.binding = sc->next_buffer_binding++; + u->input.binding = gl_sc_next_binding(sc, u->input.type); u->v.buf = buf; va_list ap; -- cgit v1.2.3