From 5771f7abf48282fe847137845f17eec5a5af245f Mon Sep 17 00:00:00 2001 From: Niklas Haas Date: Sun, 20 Aug 2017 04:27:42 +0200 Subject: [PATCH] vo_opengl: add support for vulkan GLSL dialect Redefining texture1D / texture3D seems to be illegal, they are already built-in macros or something. So just use tex1D and tex3D instead. Additionally, GL_KHR_vulkan_glsl requires using explicit vertex locations and bindings, so make some changes to facilitate this. (It also requires explicitly setting location=0 for the color attachment output) --- video/out/opengl/ra.h | 4 +++- video/out/opengl/shader_cache.c | 35 ++++++++++++++++++++++++-------- video/out/opengl/video.c | 2 +- video/out/opengl/video_shaders.c | 2 +- 4 files changed, 31 insertions(+), 12 deletions(-) diff --git a/video/out/opengl/ra.h b/video/out/opengl/ra.h index 0f1f98c6f0..81078da41f 100644 --- a/video/out/opengl/ra.h +++ b/video/out/opengl/ra.h @@ -10,6 +10,7 @@ struct ra { int glsl_version; // GLSL version (e.g. 300 => 3.0) bool glsl_es; // use ES dialect + bool glsl_vulkan; // use vulkan dialect struct mp_log *log; @@ -240,7 +241,8 @@ struct ra_renderpass_params { // --- type==RA_RENDERPASS_TYPE_RASTER only - // Describes the format of the vertex data. + // Describes the format of the vertex data. When using ra.glsl_vulkan, + // the order of this array must match the vertex attribute locations. struct ra_renderpass_input *vertex_attribs; int num_vertex_attribs; int vertex_stride; diff --git a/video/out/opengl/shader_cache.c b/video/out/opengl/shader_cache.c index f150bd7e44..0a722b8492 100644 --- a/video/out/opengl/shader_cache.c +++ b/video/out/opengl/shader_cache.c @@ -660,6 +660,12 @@ static void add_uniforms(struct gl_shader_cache *sc, bstr *dst) // fall through case RA_VARTYPE_TEX: case RA_VARTYPE_IMG_W: + // Vulkan requires explicitly assigning the bindings in the shader + // source. For OpenGL it's optional, but requires higher GL version + // so we don't do it (and instead have ra_gl update the bindings + // after program creation). + if (sc->ra->glsl_vulkan) + ADD(dst, "layout(binding=%d) ", u->input.binding); ADD(dst, "uniform %s %s;\n", u->glsl_type, u->input.name); break; case RA_VARTYPE_BUF_RO: @@ -670,7 +676,6 @@ static void add_uniforms(struct gl_shader_cache *sc, bstr *dst) ADD(dst, "layout(std430, binding=%d) buffer %s { %s };\n", u->input.binding, u->input.name, u->buffer_format); break; - default: abort(); } } } @@ -726,12 +731,19 @@ static void gl_sc_generate(struct gl_shader_cache *sc, } if (glsl_version >= 130) { - ADD(header, "#define texture1D texture\n"); - ADD(header, "#define texture3D texture\n"); + ADD(header, "#define tex1D texture\n"); + ADD(header, "#define tex3D texture\n"); } else { + ADD(header, "#define tex1D texture1D\n"); + ADD(header, "#define tex3D texture3D\n"); ADD(header, "#define texture texture2D\n"); } + if (sc->ra->glsl_vulkan && type == RA_RENDERPASS_TYPE_COMPUTE) { + ADD(header, "#define gl_GlobalInvocationIndex " + "(gl_WorkGroupID * gl_WorkGroupSize + gl_LocalInvocationID)\n"); + } + // Additional helpers. ADD(header, "#define LUT_POS(x, lut_size)" " mix(0.5 / (lut_size), 1.0 - 0.5 / (lut_size), (x))\n"); @@ -753,16 +765,19 @@ static void gl_sc_generate(struct gl_shader_cache *sc, for (int n = 0; n < sc->params.num_vertex_attribs; n++) { const struct ra_renderpass_input *e = &sc->params.vertex_attribs[n]; const char *glsl_type = vao_glsl_type(e); + char loc[32] = {0}; + if (sc->ra->glsl_vulkan) + snprintf(loc, sizeof(loc), "layout(location=%d) ", n); if (strcmp(e->name, "position") == 0) { // setting raster pos. requires setting gl_Position magic variable assert(e->dim_v == 2 && e->type == RA_VARTYPE_FLOAT); - ADD(vert_head, "%s vec2 vertex_position;\n", vert_in); + ADD(vert_head, "%s%s vec2 vertex_position;\n", loc, vert_in); ADD(vert_body, "gl_Position = vec4(vertex_position, 1.0, 1.0);\n"); } else { - ADD(vert_head, "%s %s vertex_%s;\n", vert_in, glsl_type, e->name); - ADD(vert_head, "%s %s %s;\n", vert_out, glsl_type, e->name); + ADD(vert_head, "%s%s %s vertex_%s;\n", loc, vert_in, glsl_type, e->name); + ADD(vert_head, "%s%s %s %s;\n", loc, vert_out, glsl_type, e->name); ADD(vert_body, "%s = vertex_%s;\n", e->name, e->name); - ADD(frag_vaos, "%s %s %s;\n", frag_in, glsl_type, e->name); + ADD(frag_vaos, "%s%s %s %s;\n", loc, frag_in, glsl_type, e->name); } } ADD(vert_body, "}\n"); @@ -772,8 +787,10 @@ static void gl_sc_generate(struct gl_shader_cache *sc, // fragment shader; still requires adding used uniforms and VAO elements frag = &sc->tmp[4]; ADD_BSTR(frag, *header); - if (glsl_version >= 130) - ADD(frag, "out vec4 out_color;\n"); + if (glsl_version >= 130) { + ADD(frag, "%sout vec4 out_color;\n", + sc->ra->glsl_vulkan ? "layout(location=0) " : ""); + } ADD_BSTR(frag, *frag_vaos); add_uniforms(sc, frag); diff --git a/video/out/opengl/video.c b/video/out/opengl/video.c index 1378872838..8d90c2bcaa 100644 --- a/video/out/opengl/video.c +++ b/video/out/opengl/video.c @@ -2467,7 +2467,7 @@ static void pass_colormanage(struct gl_video *p, struct mp_colorspace src, bool GLSL(vec3 cpos;) for (int i = 0; i < 3; i++) GLSLF("cpos[%d] = LUT_POS(color[%d], %d.0);\n", i, i, p->lut_3d_size[i]); - GLSL(color.rgb = texture3D(lut_3d, cpos).rgb;) + GLSL(color.rgb = tex3D(lut_3d, cpos).rgb;) } } diff --git a/video/out/opengl/video_shaders.c b/video/out/opengl/video_shaders.c index b73f13434b..10edc0563d 100644 --- a/video/out/opengl/video_shaders.c +++ b/video/out/opengl/video_shaders.c @@ -122,7 +122,7 @@ static void polar_sample(struct gl_shader_cache *sc, struct scaler *scaler, // get the weight for this pixel if (scaler->lut->params.dimensions == 1) { - GLSLF("w = texture1D(lut, LUT_POS(d * 1.0/%f, %d.0)).r;\n", + GLSLF("w = tex1D(lut, LUT_POS(d * 1.0/%f, %d.0)).r;\n", radius, scaler->lut_size); } else { GLSLF("w = texture(lut, vec2(0.5, LUT_POS(d * 1.0/%f, %d.0))).r;\n",