Skip to content

Commit

Permalink
GLSL: Implement texldl instruction
Browse files Browse the repository at this point in the history
  • Loading branch information
kg committed Aug 21, 2019
1 parent 810c038 commit 4d42f68
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 40 deletions.
4 changes: 2 additions & 2 deletions profiles/mojoshader_profile.h
Expand Up @@ -158,7 +158,7 @@ typedef struct Context

// !!! FIXME: move these into SUPPORT_PROFILE sections.
int glsl_generated_lit_helper;
int glsl_generated_texldd_setup;
int glsl_generated_texlod_setup;
int glsl_generated_texm3x3spec_helper;
int arb1_wrote_position;
// !!! FIXME: move these into SUPPORT_PROFILE sections.
Expand Down Expand Up @@ -362,4 +362,4 @@ const char *get_D3D_varname_in_buf(Context *ctx, RegisterType rt,
const size_t len);
const char *get_D3D_varname(Context *ctx, RegisterType rt, int regnum);

#endif
#endif
115 changes: 77 additions & 38 deletions profiles/mojoshader_profile_glsl.c
Expand Up @@ -467,6 +467,45 @@ const char *get_GLSL_comparison_string_vector(Context *ctx)
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)
{
Expand Down Expand Up @@ -1654,8 +1693,11 @@ void emit_GLSL_TEXKILL(Context *ctx)
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;
Expand All @@ -1664,6 +1706,7 @@ static void glsl_texld(Context *ctx, const int texldd)
char code[128] = {0};

assert(!texldd);
assert(!texldl);

RegisterList *sreg;
sreg = reglist_find(&ctx->samplers, REG_TYPE_SAMPLER, info->regnum);
Expand Down Expand Up @@ -1756,13 +1799,18 @@ static void glsl_texld(Context *ctx, const int texldd)
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";
Expand All @@ -1774,10 +1822,13 @@ static void glsl_texld(Context *ctx, const int texldd)
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:
Expand All @@ -1797,6 +1848,24 @@ static void glsl_texld(Context *ctx, const int texldd)
"%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),
Expand All @@ -1810,7 +1879,7 @@ static void glsl_texld(Context *ctx, const int texldd)

void emit_GLSL_TEXLD(Context *ctx)
{
glsl_texld(ctx, 0);
glsl_texld(ctx, 0, 0);
} // emit_GLSL_TEXLD


Expand Down Expand Up @@ -2240,33 +2309,7 @@ void emit_GLSL_DSY(Context *ctx)

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)
Expand Down Expand Up @@ -2295,11 +2338,7 @@ void emit_GLSL_SETP(Context *ctx)

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)
Expand Down

0 comments on commit 4d42f68

Please sign in to comment.