1
0
mirror of https://github.com/mpv-player/mpv synced 2025-01-18 04:51:52 +00:00

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.
This commit is contained in:
Niklas Haas 2017-08-26 05:39:53 +02:00
parent 45bae90f4d
commit 7684fda6ac
3 changed files with 40 additions and 22 deletions

View File

@ -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;
};

View File

@ -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++) {

View File

@ -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;