--- a/profiles/mojoshader_profile_glsl.c Wed Aug 14 09:33:57 2019 -0400
+++ b/profiles/mojoshader_profile_glsl.c Wed Aug 21 09:30:54 2019 -0400
@@ -467,6 +467,45 @@
return comps[ctx->instruction_controls];
} // get_GLSL_comparison_string_vector
+// special extensions needed for texldd/texldl...
+
+static void prepend_glsl_texlod_extensions(Context *ctx)
+{
+ // !!! FIXME:
+ // GLSL 1.30 introduced textureGrad() for this, but it looks like the
+ // functions are overloaded instead of texture2DGrad() (etc).
+
+ // !!! FIXME:
+ // The spec says we can't use GLSL's texture*Lod() built-ins from fragment
+ // shaders for some inexplicable reason.
+ // For now, you'll just have to suffer with the potentially wrong mipmap
+ // until I can figure something out.
+
+ // ARB_shader_texture_lod and EXT_gpu_shader4 added texture2DLod/Grad*(),
+ // so we'll use them if available. Failing that, we'll just fallback
+ // to a regular texture2D call and hope the mipmap it chooses is close
+ // enough.
+ if (!ctx->glsl_generated_texlod_setup)
+ {
+ ctx->glsl_generated_texlod_setup = 1;
+ push_output(ctx, &ctx->preflight);
+ output_line(ctx, "#if GL_ARB_shader_texture_lod");
+ output_line(ctx, "#extension GL_ARB_shader_texture_lod : enable");
+ output_line(ctx, "#define texture2DGrad texture2DGradARB");
+ output_line(ctx, "#define texture2DProjGrad texture2DProjARB");
+ output_line(ctx, "#define texture2DLod texture2DLodARB");
+ output_line(ctx, "#elif GL_EXT_gpu_shader4");
+ output_line(ctx, "#extension GL_EXT_gpu_shader4 : enable");
+ output_line(ctx, "#else");
+ output_line(ctx, "#define texture2DGrad(a,b,c,d) texture2D(a,b)");
+ output_line(ctx, "#define texture2DProjGrad(a,b,c,d) texture2DProj(a,b)");
+ output_line(ctx, "#define texture2DLod(a,b,c) texture2D(a,b)");
+ output_line(ctx, "#endif");
+ output_blank_line(ctx);
+ pop_output(ctx);
+ } // if
+} // prepend_glsl_texlod_extensions
+
void emit_GLSL_start(Context *ctx, const char *profilestr)
{
@@ -1654,8 +1693,11 @@
output_line(ctx, "if (any(lessThan(%s.xyz, vec3(0.0)))) discard;", dst);
} // emit_GLSL_TEXKILL
-static void glsl_texld(Context *ctx, const int texldd)
+static void glsl_texld(Context *ctx, const int texldd, const int texldl)
{
+ if (texldd || texldl)
+ prepend_glsl_texlod_extensions(ctx);
+
if (!shader_version_atleast(ctx, 1, 4))
{
DestArgInfo *info = &ctx->dest_arg;
@@ -1664,6 +1706,7 @@
char code[128] = {0};
assert(!texldd);
+ assert(!texldl);
RegisterList *sreg;
sreg = reglist_find(&ctx->samplers, REG_TYPE_SAMPLER, info->regnum);
@@ -1756,13 +1799,18 @@
funcname = "texture2DProj";
make_GLSL_srcarg_string_full(ctx, 0, src0, sizeof (src0));
} // if
- else // texld/texldb
+ else // texld/texldb/texldl
{
funcname = "texture2D";
- make_GLSL_srcarg_string_vec2(ctx, 0, src0, sizeof (src0));
+ if (texldl)
+ make_GLSL_srcarg_string_full(ctx, 0, src0, sizeof (src0));
+ else
+ make_GLSL_srcarg_string_vec2(ctx, 0, src0, sizeof (src0));
} // else
break;
case TEXTURE_TYPE_CUBE:
+ assert(!texldl);
+
if (ctx->instruction_controls == CONTROL_TEXLDP)
fail(ctx, "TEXLDP on a cubemap"); // !!! FIXME: is this legal?
funcname = "textureCube";
@@ -1774,10 +1822,13 @@
funcname = "texture3DProj";
make_GLSL_srcarg_string_full(ctx, 0, src0, sizeof (src0));
} // if
- else // texld/texldb
+ else // texld/texldb/texldl
{
funcname = "texture3D";
- make_GLSL_srcarg_string_vec3(ctx, 0, src0, sizeof (src0));
+ if (texldl)
+ make_GLSL_srcarg_string_full(ctx, 0, src0, sizeof (src0));
+ else
+ make_GLSL_srcarg_string_vec3(ctx, 0, src0, sizeof (src0));
} // else
break;
default:
@@ -1797,6 +1848,24 @@
"%sGrad(%s, %s, %s, %s)%s", funcname,
src1, src0, src2, src3, swiz_str);
} // if
+ else if (texldl)
+ {
+ const TextureType texType = (const TextureType) sreg->index;
+ assert(texType != TEXTURE_TYPE_CUBE);
+
+ // HLSL tex2dlod accepts (sampler, uv.xyz, uv.w) where uv.w is the LOD
+ // GLSL seems to want the dimensionality to match the sampler (.xy vs .xyz)
+ // so we vary the swizzle accordingly
+ const char * pattern = 0;
+ if (texType == TEXTURE_TYPE_VOLUME)
+ pattern = "%sLod(%s, %s.xyz, %s.w)%s";
+ else
+ pattern = "%sLod(%s, %s.xy, %s.w)%s";
+
+ make_GLSL_destarg_assign(ctx, code, sizeof(code),
+ pattern, funcname,
+ src1, src0, src0, swiz_str);
+ } // else if
else
{
make_GLSL_destarg_assign(ctx, code, sizeof (code),
@@ -1810,7 +1879,7 @@
void emit_GLSL_TEXLD(Context *ctx)
{
- glsl_texld(ctx, 0);
+ glsl_texld(ctx, 0, 0);
} // emit_GLSL_TEXLD
@@ -2240,33 +2309,7 @@
void emit_GLSL_TEXLDD(Context *ctx)
{
- // !!! FIXME:
- // GLSL 1.30 introduced textureGrad() for this, but it looks like the
- // functions are overloaded instead of texture2DGrad() (etc).
-
- // GL_shader_texture_lod and GL_EXT_gpu_shader4 added texture2DGrad*(),
- // so we'll use them if available. Failing that, we'll just fallback
- // to a regular texture2D call and hope the mipmap it chooses is close
- // enough.
- if (!ctx->glsl_generated_texldd_setup)
- {
- ctx->glsl_generated_texldd_setup = 1;
- push_output(ctx, &ctx->preflight);
- output_line(ctx, "#if GL_ARB_shader_texture_lod");
- output_line(ctx, "#extension GL_ARB_shader_texture_lod : enable");
- output_line(ctx, "#define texture2DGrad texture2DGradARB");
- output_line(ctx, "#define texture2DProjGrad texture2DProjARB");
- output_line(ctx, "#elif GL_EXT_gpu_shader4");
- output_line(ctx, "#extension GL_EXT_gpu_shader4 : enable");
- output_line(ctx, "#else");
- output_line(ctx, "#define texture2DGrad(a,b,c,d) texture2D(a,b)");
- output_line(ctx, "#define texture2DProjGrad(a,b,c,d) texture2DProj(a,b)");
- output_line(ctx, "#endif");
- output_blank_line(ctx);
- pop_output(ctx);
- } // if
-
- glsl_texld(ctx, 1);
+ glsl_texld(ctx, 1, 0);
} // emit_GLSL_TEXLDD
void emit_GLSL_SETP(Context *ctx)
@@ -2295,11 +2338,7 @@
void emit_GLSL_TEXLDL(Context *ctx)
{
- // !!! FIXME: The spec says we can't use GLSL's texture*Lod() built-ins
- // !!! FIXME: from fragment shaders for some inexplicable reason.
- // !!! FIXME: For now, you'll just have to suffer with the potentially
- // !!! FIXME: wrong mipmap until I can figure something out.
- emit_GLSL_TEXLD(ctx);
+ glsl_texld(ctx, 0, 1);
} // emit_GLSL_TEXLDL
void emit_GLSL_BREAKP(Context *ctx)