Skip to content

Commit

Permalink
glsl: Initial GLSL ES 3.x support (#65)
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnnyonFlame committed Nov 11, 2023
1 parent fef033c commit 2428453
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 15 deletions.
3 changes: 3 additions & 0 deletions CMakeLists.txt
Expand Up @@ -125,6 +125,9 @@ ENDIF(NOT PROFILE_GLSL120)
IF(NOT PROFILE_GLSLES)
ADD_DEFINITIONS(-DSUPPORT_PROFILE_GLSLES=0)
ENDIF(NOT PROFILE_GLSLES)
IF(NOT PROFILE_GLSLES3)
ADD_DEFINITIONS(-DSUPPORT_PROFILE_GLSLES3=0)
ENDIF(NOT PROFILE_GLSLES3)
IF(NOT PROFILE_GLSL)
ADD_DEFINITIONS(-DSUPPORT_PROFILE_GLSL=0)
ENDIF(NOT PROFILE_GLSL)
Expand Down
1 change: 1 addition & 0 deletions mojoshader.c
Expand Up @@ -333,6 +333,7 @@ static const struct { const char *from; const char *to; } profileMap[] =
{
{ MOJOSHADER_PROFILE_GLSPIRV, MOJOSHADER_PROFILE_SPIRV },
{ MOJOSHADER_PROFILE_GLSLES, MOJOSHADER_PROFILE_GLSL },
{ MOJOSHADER_PROFILE_GLSLES3, MOJOSHADER_PROFILE_GLSL },
{ MOJOSHADER_PROFILE_GLSL120, MOJOSHADER_PROFILE_GLSL },
{ MOJOSHADER_PROFILE_NV2, MOJOSHADER_PROFILE_ARB1 },
{ MOJOSHADER_PROFILE_NV3, MOJOSHADER_PROFILE_ARB1 },
Expand Down
5 changes: 5 additions & 0 deletions mojoshader.h
Expand Up @@ -709,6 +709,11 @@ typedef struct MOJOSHADER_parseData
*/
#define MOJOSHADER_PROFILE_GLSLES "glsles"

/*
* Profile string for GLSL ES: changes to GLSL output for ES 3.x compliance.
*/
#define MOJOSHADER_PROFILE_GLSLES3 "glsles3"

/*
* Profile string for OpenGL ARB 1.0 shaders: GL_ARB_(vertex|fragment)_program.
*/
Expand Down
9 changes: 9 additions & 0 deletions mojoshader_internal.h
Expand Up @@ -159,6 +159,10 @@ typedef Uint64 uint64;
#define SUPPORT_PROFILE_GLSLES 1
#endif

#ifndef SUPPORT_PROFILE_GLSLES3
#define SUPPORT_PROFILE_GLSLES3 1
#endif

#ifndef SUPPORT_PROFILE_ARB1
#define SUPPORT_PROFILE_ARB1 1
#endif
Expand Down Expand Up @@ -191,6 +195,11 @@ typedef Uint64 uint64;
#error glsles profile requires glsl profile. Fix your build.
#endif

#if SUPPORT_PROFILE_GLSLES3 && !SUPPORT_PROFILE_GLSLES
#error glsles3 profile requires glsles profile. Fix your build.
#endif


#if SUPPORT_PROFILE_GLSPIRV && !SUPPORT_PROFILE_SPIRV
#error glspirv profile requires spirv profile. Fix your build.
#endif
Expand Down
26 changes: 24 additions & 2 deletions mojoshader_opengl.c
Expand Up @@ -209,6 +209,7 @@ struct MOJOSHADER_glContext
int have_opengl_2; // different entry points than ARB extensions.
int have_opengl_3; // different extension query.
int have_opengl_es; // different extension requirements
int have_opengl_es3; // different shader synxtax and attributes
int have_GL_ARB_vertex_program;
int have_GL_ARB_fragment_program;
int have_GL_NV_vertex_program2_option;
Expand Down Expand Up @@ -1413,6 +1414,11 @@ static void load_extensions(MOJOSHADER_glGetProcAddress lookup, void *d)
}
parse_opengl_version_str(str, &ctx->opengl_major, &ctx->opengl_minor);

if (opengl_version_atleast(3, 0) && ctx->have_opengl_es)
{
ctx->have_opengl_es3 = 1;
}

if ((ctx->have_opengl_3) && (opengl_version_atleast(3, 0)))
{
GLint i;
Expand Down Expand Up @@ -1566,6 +1572,13 @@ static int valid_profile(const char *profile)
} // else if
#endif

#if SUPPORT_PROFILE_GLSLES
else if (strcmp(profile, MOJOSHADER_PROFILE_GLSLES3) == 0)
{
MUST_HAVE_GLSL(MOJOSHADER_PROFILE_GLSLES3, 3, 00);
} // else if
#endif

#if SUPPORT_PROFILE_GLSLES
else if (strcmp(profile, MOJOSHADER_PROFILE_GLSLES) == 0)
{
Expand Down Expand Up @@ -1640,6 +1653,14 @@ int MOJOSHADER_glAvailableProfiles(MOJOSHADER_glGetProcAddress lookup,

load_extensions(lookup, lookup_d);

#if SUPPORT_PROFILE_GLSLES3
if (ctx->have_opengl_es3)
{
profs[0] = MOJOSHADER_PROFILE_GLSLES3;
return 1;
} // if
#endif

#if SUPPORT_PROFILE_GLSLES
if (ctx->have_opengl_es)
{
Expand Down Expand Up @@ -1763,7 +1784,8 @@ MOJOSHADER_glContext *MOJOSHADER_glCreateContext(const char *profile,
#if SUPPORT_PROFILE_GLSL
else if ( (strcmp(profile, MOJOSHADER_PROFILE_GLSL) == 0) ||
(strcmp(profile, MOJOSHADER_PROFILE_GLSL120) == 0) ||
(strcmp(profile, MOJOSHADER_PROFILE_GLSLES) == 0) )
(strcmp(profile, MOJOSHADER_PROFILE_GLSLES) == 0) ||
(strcmp(profile, MOJOSHADER_PROFILE_GLSLES3) == 0) )
{
ctx->profileMaxUniforms = impl_GLSL_MaxUniforms;
ctx->profileCompileShader = impl_GLSL_CompileShader;
Expand All @@ -1780,7 +1802,7 @@ MOJOSHADER_glContext *MOJOSHADER_glCreateContext(const char *profile,
ctx->profilePushSampler = impl_GLSL_PushSampler;
ctx->profileMustPushConstantArrays = impl_GLSL_MustPushConstantArrays;
ctx->profileMustPushSamplers = impl_GLSL_MustPushSamplers;
if (strcmp(profile, MOJOSHADER_PROFILE_GLSLES) == 0)
if (strcmp(profile, MOJOSHADER_PROFILE_GLSLES) == 0 || strcmp(profile, MOJOSHADER_PROFILE_GLSLES3) == 0)
ctx->profileToggleProgramPointSize = impl_NOOP_ToggleProgramPointSize;
else
ctx->profileToggleProgramPointSize = impl_REAL_ToggleProgramPointSize;
Expand Down
11 changes: 10 additions & 1 deletion profiles/mojoshader_profile.h
Expand Up @@ -196,6 +196,9 @@ typedef struct Context
#if SUPPORT_PROFILE_GLSLES
int profile_supports_glsles;
#endif
#if SUPPORT_PROFILE_GLSLES3
int profile_supports_glsles3;
#endif

#if SUPPORT_PROFILE_METAL
int metal_need_header_common;
Expand Down Expand Up @@ -236,8 +239,14 @@ typedef struct Context
#define support_glsl120(ctx) (0)
#endif

#if SUPPORT_PROFILE_GLSLES3
#define support_glsles3(ctx) ((ctx)->profile_supports_glsles3)
#else
#define support_glsles3(ctx) (0)
#endif

#if SUPPORT_PROFILE_GLSLES
#define support_glsles(ctx) ((ctx)->profile_supports_glsles)
#define support_glsles(ctx) ((ctx)->profile_supports_glsles || support_glsles3(ctx))
#else
#define support_glsles(ctx) (0)
#endif
Expand Down
84 changes: 72 additions & 12 deletions profiles/mojoshader_profile_glsl.c
Expand Up @@ -485,7 +485,7 @@ static void prepend_glsl_texlod_extensions(Context *ctx)
// 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)
if (!ctx->glsl_generated_texlod_setup && !support_glsles3(ctx))
{
ctx->glsl_generated_texlod_setup = 1;
push_output(ctx, &ctx->preflight);
Expand Down Expand Up @@ -534,6 +534,33 @@ void emit_GLSL_start(Context *ctx, const char *profilestr)
} // else if
#endif

#if SUPPORT_PROFILE_GLSLES3
else if (strcmp(profilestr, MOJOSHADER_PROFILE_GLSLES3) == 0)
{
ctx->profile_supports_glsles3 = 1;
push_output(ctx, &ctx->preflight);
output_line(ctx, "#version 300 es");
output_line(ctx, "#define texture2D texture");
output_line(ctx, "#define texture2DLod textureLod");
output_line(ctx, "#define texture2DProj textureProj");
output_line(ctx, "#define texture2DGrad textureGrad");
output_line(ctx, "#define texture2DProjGrad textureProjGrad");
output_line(ctx, "#define texture3D texture");
output_line(ctx, "#define texture3DLod textureLod");
output_line(ctx, "#define textureCube texture");
output_line(ctx, "#define textureCubeLod textureLod");
output_line(ctx, "#define texture2DRect texture");
output_line(ctx, "#define texture2DRectProj textureProj");
output_line(ctx, "#define texture2DRectLod textureLod");
if (shader_is_vertex(ctx))
output_line(ctx, "precision highp float;");
else
output_line(ctx, "precision mediump float;");
output_line(ctx, "precision mediump int;");
pop_output(ctx);
} // else if
#endif

#if SUPPORT_PROFILE_GLSLES
else if (strcmp(profilestr, MOJOSHADER_PROFILE_GLSLES) == 0)
{
Expand Down Expand Up @@ -855,6 +882,8 @@ void emit_GLSL_attribute(Context *ctx, RegisterType regtype, int regnum,
int flags)
{
// !!! FIXME: this function doesn't deal with write masks at all yet!
const char *qualifier_in;
const char *qualifier_out;
const char *usage_str = NULL;
const char *arrayleft = "";
const char *arrayright = "";
Expand All @@ -870,6 +899,17 @@ void emit_GLSL_attribute(Context *ctx, RegisterType regtype, int regnum,

if (shader_is_vertex(ctx))
{
if (support_glsles3(ctx))
{
qualifier_in = "in";
qualifier_out = "out";
}
else
{
qualifier_in = "attribute";
qualifier_out = "varying";
}

// pre-vs3 output registers.
// these don't ever happen in DCL opcodes, I think. Map to vs_3_*
// output registers.
Expand Down Expand Up @@ -920,7 +960,7 @@ void emit_GLSL_attribute(Context *ctx, RegisterType regtype, int regnum,
if (regtype == REG_TYPE_INPUT)
{
push_output(ctx, &ctx->globals);
output_line(ctx, "attribute vec4 %s;", var);
output_line(ctx, "%s vec4 %s;", qualifier_in, var);
pop_output(ctx);
} // if

Expand All @@ -944,7 +984,7 @@ void emit_GLSL_attribute(Context *ctx, RegisterType regtype, int regnum,
push_output(ctx, &ctx->globals);
#if SUPPORT_PROFILE_GLSLES
if (support_glsles(ctx))
output_line(ctx, "varying highp float io_%i_%i;", usage, index);
output_line(ctx, "%s highp float io_%i_%i;", qualifier_out, usage, index);
else
#endif
output_line(ctx, "varying float io_%i_%i;", usage, index);
Expand Down Expand Up @@ -982,7 +1022,7 @@ void emit_GLSL_attribute(Context *ctx, RegisterType regtype, int regnum,
push_output(ctx, &ctx->globals);
#if SUPPORT_PROFILE_GLSLES
if (support_glsles(ctx))
output_line(ctx, "varying highp float io_%i_%i;", usage, index);
output_line(ctx, "%s highp float io_%i_%i;", qualifier_out, usage, index);
else
#endif
output_line(ctx, "varying float io_%i_%i;", usage, index);
Expand Down Expand Up @@ -1016,7 +1056,7 @@ void emit_GLSL_attribute(Context *ctx, RegisterType regtype, int regnum,
{
#if SUPPORT_PROFILE_GLSLES
if (support_glsles(ctx))
output_line(ctx, "varying highp vec4 io_%i_%i;", usage, index);
output_line(ctx, "%s highp vec4 io_%i_%i;", qualifier_out, usage, index);
else
#endif
output_line(ctx, "varying vec4 io_%i_%i;", usage, index);
Expand All @@ -1038,6 +1078,11 @@ void emit_GLSL_attribute(Context *ctx, RegisterType regtype, int regnum,

else if (shader_is_pixel(ctx))
{
if (support_glsles3(ctx))
qualifier_in = "in";
else
qualifier_in = "varying";

// samplers DCLs get handled in emit_GLSL_sampler().

if (flags & MOD_CENTROID) // !!! FIXME
Expand All @@ -1048,14 +1093,29 @@ void emit_GLSL_attribute(Context *ctx, RegisterType regtype, int regnum,

if (regtype == REG_TYPE_COLOROUT)
{
if (!ctx->have_multi_color_outputs)
usage_str = "gl_FragColor"; // maybe faster?
// gl_FragColor/FragData were deprecated in favor of manually
// defining your own output variables, GLSL ES 3.x enforces the new
// syntax, so let's use it.
if (support_glsles3(ctx))
{
usage_str = "_gl_FragData";
snprintf(index_str, sizeof (index_str), "_%u", (uint) regnum );

push_output(ctx, &ctx->globals);
output_line(ctx, "layout(location = %u) out highp vec4 %s%s;", regnum, usage_str, index_str);
pop_output(ctx);
}
else
{
snprintf(index_str, sizeof (index_str), "%u", (uint) regnum);
usage_str = "gl_FragData";
arrayleft = "[";
arrayright = "]";
if (!ctx->have_multi_color_outputs)
usage_str = "gl_FragColor"; // maybe faster?
else
{
snprintf(index_str, sizeof (index_str), "%u", (uint) regnum);
usage_str = "gl_FragData";
arrayleft = "[";
arrayright = "]";
} // else
} // else
} // if

Expand Down Expand Up @@ -1145,7 +1205,7 @@ void emit_GLSL_attribute(Context *ctx, RegisterType regtype, int regnum,
{
#if SUPPORT_PROFILE_GLSLES
if (support_glsles(ctx))
output_line(ctx, "varying highp vec4 io_%i_%i;", usage, index);
output_line(ctx, "%s highp vec4 io_%i_%i;", qualifier_in, usage, index);
else
#endif
output_line(ctx, "varying vec4 io_%i_%i;", usage, index);
Expand Down

0 comments on commit 2428453

Please sign in to comment.