summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorNiklas Haas <git@haasn.xyz>2017-08-26 05:39:53 +0200
committerNiklas Haas <git@haasn.xyz>2017-08-27 14:36:00 +0200
commit7684fda6ac69265ca21cdf2f1d8ae8483bb36607 (patch)
tree75aa03a8f3e106a4481bc05585a2ad4a99f10ec5 /video
parent45bae90f4d98c64f01ec2fe419a6aa6c068331b2 (diff)
downloadmpv-7684fda6ac69265ca21cdf2f1d8ae8483bb36607.tar.bz2
mpv-7684fda6ac69265ca21cdf2f1d8ae8483bb36607.tar.xz
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.
Diffstat (limited to 'video')
-rw-r--r--video/out/opengl/ra.h4
-rw-r--r--video/out/opengl/ra_gl.c31
-rw-r--r--video/out/opengl/shader_cache.c27
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;