summaryrefslogtreecommitdiffstats
path: root/video/out/gpu/shader_cache.c
diff options
context:
space:
mode:
authorNiklas Haas <git@haasn.xyz>2017-09-28 00:07:42 +0200
committerNiklas Haas <git@haasn.xyz>2017-09-28 01:54:38 +0200
commit67fd5882b86bc544e27a9cb0b188d63bdb950623 (patch)
tree7b0cd41803e8432cf2a5124c85cdf96cf73382a9 /video/out/gpu/shader_cache.c
parent002a0ce23200c7044ce744555223e4b884350436 (diff)
downloadmpv-67fd5882b86bc544e27a9cb0b188d63bdb950623.tar.bz2
mpv-67fd5882b86bc544e27a9cb0b188d63bdb950623.tar.xz
vo_gpu: make the vertex attribs dynamic
This has several advantages: 1. no more redundant texcoords when we don't need them 2. no more arbitrary limit on how many textures we can bind 3. (that extends to user shaders as well) 4. no more arbitrary limits on tscale radius To realize this, the VAO was moved from a hacky stateful approach (gl_sc_set_vertex_attribs) - which always bothered me since it was required for compute shaders as well even though they ignored it - to be a proper parameter of gl_sc_dispatch_draw, and internally plumbed into gl_sc_generate, which will make a (properly mangled) deep copy into params.vertex_attribs.
Diffstat (limited to 'video/out/gpu/shader_cache.c')
-rw-r--r--video/out/gpu/shader_cache.c61
1 files changed, 26 insertions, 35 deletions
diff --git a/video/out/gpu/shader_cache.c b/video/out/gpu/shader_cache.c
index 0c09daefab..0aeac8c844 100644
--- a/video/out/gpu/shader_cache.c
+++ b/video/out/gpu/shader_cache.c
@@ -449,20 +449,6 @@ void gl_sc_uniform_mat3(struct gl_shader_cache *sc, char *name,
transpose3x3(&u->v.f[0]);
}
-// Tell the shader generator (and later gl_sc_draw_data()) about the vertex
-// data layout and attribute names. The entries array is terminated with a {0}
-// entry. The array memory must remain valid indefinitely (for now).
-void gl_sc_set_vertex_format(struct gl_shader_cache *sc,
- const struct ra_renderpass_input *entries,
- int vertex_stride)
-{
- sc->params.vertex_attribs = (struct ra_renderpass_input *)entries;
- sc->params.num_vertex_attribs = 0;
- while (entries[sc->params.num_vertex_attribs].name)
- sc->params.num_vertex_attribs++;
- sc->params.vertex_stride = vertex_stride;
-}
-
void gl_sc_blend(struct gl_shader_cache *sc,
enum ra_blend blend_src_rgb,
enum ra_blend blend_dst_rgb,
@@ -577,16 +563,6 @@ static bool create_pass(struct gl_shader_cache *sc, struct sc_entry *entry)
if (sc->text.len)
mp_log_source(sc->log, MSGL_V, sc->text.start);
- // The vertex shader uses mangled names for the vertex attributes, so that
- // the fragment shader can use the "real" names. But the shader is expecting
- // the vertex attribute names (at least with older GLSL targets for GL).
- params.vertex_attribs = talloc_memdup(tmp, params.vertex_attribs,
- params.num_vertex_attribs * sizeof(params.vertex_attribs[0]));
- for (int n = 0; n < params.num_vertex_attribs; n++) {
- struct ra_renderpass_input *attrib = &params.vertex_attribs[n];
- attrib->name = talloc_asprintf(tmp, "vertex_%s", attrib->name);
- }
-
const char *cache_header = "mpv shader cache v1\n";
char *cache_filename = NULL;
char *cache_dir = NULL;
@@ -773,7 +749,9 @@ static void add_uniforms(struct gl_shader_cache *sc, bstr *dst)
// and fragment operations needed for the next program have to be re-added.)
static void gl_sc_generate(struct gl_shader_cache *sc,
enum ra_renderpass_type type,
- const struct ra_format *target_format)
+ const struct ra_format *target_format,
+ const struct ra_renderpass_input *vao,
+ int vao_len, size_t vertex_stride)
{
int glsl_version = sc->ra->glsl_version;
int glsl_es = sc->ra->glsl_es ? glsl_version : 0;
@@ -785,9 +763,6 @@ static void gl_sc_generate(struct gl_shader_cache *sc,
assert(!sc->needs_reset);
sc->needs_reset = true;
- // gl_sc_set_vertex_format() must always be called
- assert(sc->params.vertex_attribs);
-
// If using a UBO, pick a binding (needed for shader generation)
if (sc->ubo_size)
sc->ubo_binding = gl_sc_next_binding(sc, RA_VARTYPE_BUF_RO);
@@ -844,8 +819,8 @@ static void gl_sc_generate(struct gl_shader_cache *sc,
bstr *vert_body = &sc->tmp[2];
ADD(vert_body, "void main() {\n");
bstr *frag_vaos = &sc->tmp[3];
- for (int n = 0; n < sc->params.num_vertex_attribs; n++) {
- const struct ra_renderpass_input *e = &sc->params.vertex_attribs[n];
+ for (int n = 0; n < vao_len; n++) {
+ const struct ra_renderpass_input *e = &vao[n];
const char *glsl_type = vao_glsl_type(e);
char loc[32] = {0};
if (sc->ra->glsl_vulkan)
@@ -956,6 +931,19 @@ static void gl_sc_generate(struct gl_shader_cache *sc,
.total = bstrdup(entry, *hash_total),
.timer = timer_pool_create(sc->ra),
};
+
+ // The vertex shader uses mangled names for the vertex attributes, so
+ // that the fragment shader can use the "real" names. But the shader is
+ // expecting the vertex attribute names (at least with older GLSL
+ // targets for GL).
+ sc->params.vertex_stride = vertex_stride;
+ for (int n = 0; n < vao_len; n++) {
+ struct ra_renderpass_input attrib = vao[n];
+ attrib.name = talloc_asprintf(entry, "vertex_%s", attrib.name);
+ MP_TARRAY_APPEND(sc, sc->params.vertex_attribs,
+ sc->params.num_vertex_attribs, attrib);
+ }
+
for (int n = 0; n < sc->num_uniforms; n++) {
struct sc_cached_uniform u = {0};
if (sc->uniforms[n].type == SC_UNIFORM_TYPE_GLOBAL) {
@@ -997,11 +985,14 @@ static void gl_sc_generate(struct gl_shader_cache *sc,
struct mp_pass_perf gl_sc_dispatch_draw(struct gl_shader_cache *sc,
struct ra_tex *target,
- void *ptr, size_t num)
+ const struct ra_renderpass_input *vao,
+ int vao_len, size_t vertex_stride,
+ void *vertices, size_t num_vertices)
{
struct timer_pool *timer = NULL;
- gl_sc_generate(sc, RA_RENDERPASS_TYPE_RASTER, target->params.format);
+ gl_sc_generate(sc, RA_RENDERPASS_TYPE_RASTER, target->params.format,
+ vao, vao_len, vertex_stride);
if (!sc->current_shader)
goto error;
@@ -1015,8 +1006,8 @@ struct mp_pass_perf gl_sc_dispatch_draw(struct gl_shader_cache *sc,
.num_values = sc->num_values,
.push_constants = sc->current_shader->pushc,
.target = target,
- .vertex_data = ptr,
- .vertex_count = num,
+ .vertex_data = vertices,
+ .vertex_count = num_vertices,
.viewport = full_rc,
.scissors = full_rc,
};
@@ -1035,7 +1026,7 @@ struct mp_pass_perf gl_sc_dispatch_compute(struct gl_shader_cache *sc,
{
struct timer_pool *timer = NULL;
- gl_sc_generate(sc, RA_RENDERPASS_TYPE_COMPUTE, NULL);
+ gl_sc_generate(sc, RA_RENDERPASS_TYPE_COMPUTE, NULL, NULL, 0, 0);
if (!sc->current_shader)
goto error;