Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add GLSPIRV profile, to allow for both GL- and VK-friendly SPIR-V output
  • Loading branch information
flibitijibibo committed Dec 31, 2019
1 parent 801b57d commit 3d22cba
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 26 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Expand Up @@ -11,6 +11,7 @@ OPTION(PROFILE_ARB1 "Build MojoShader with support for the ARB1 profile" ON)
OPTION(PROFILE_ARB1_NV "Build MojoShader with support for the ARB1_NV profile" ON)
OPTION(PROFILE_METAL "Build MojoShader with support for the Metal profile" ON)
OPTION(PROFILE_SPIRV "Build MojoShader with support for the SPIR-V profile" ON)
OPTION(PROFILE_GLSPIRV "Build MojoShader with support for the ARB_gl_spirv profile" ON)
OPTION(EFFECT_SUPPORT "Build MojoShader with support for Effect framework files" ON)
OPTION(COMPILER_SUPPORT "Build MojoShader with support for HLSL source files" OFF)
OPTION(FLIP_VIEWPORT "Build MojoShader with the ability to flip the GL viewport" OFF)
Expand Down Expand Up @@ -128,6 +129,9 @@ ENDIF(NOT PROFILE_METAL)
IF(NOT PROFILE_SPIRV)
ADD_DEFINITIONS(-DSUPPORT_PROFILE_SPIRV=0)
ENDIF(NOT PROFILE_SPIRV)
IF(NOT PROFILE_GLSPIRV)
ADD_DEFINITIONS(-DSUPPORT_PROFILE_GLSPIRV=0)
ENDIF(NOT PROFILE_GLSPIRV)

IF(EFFECT_SUPPORT)
IF(UNIX)
Expand Down
7 changes: 5 additions & 2 deletions mojoshader.c
Expand Up @@ -319,6 +319,7 @@ static const Profile profiles[] =
// This is for profiles that extend other profiles...
static const struct { const char *from; const char *to; } profileMap[] =
{
{ MOJOSHADER_PROFILE_GLSPIRV, MOJOSHADER_PROFILE_SPIRV },
{ MOJOSHADER_PROFILE_GLSLES, MOJOSHADER_PROFILE_GLSL },
{ MOJOSHADER_PROFILE_GLSL120, MOJOSHADER_PROFILE_GLSL },
{ MOJOSHADER_PROFILE_NV2, MOJOSHADER_PROFILE_ARB1 },
Expand Down Expand Up @@ -3459,7 +3460,8 @@ static MOJOSHADER_parseData *build_parsedata(Context *ctx)
retval->mainfn = ctx->mainfn;

#if SUPPORT_PROFILE_SPIRV
if (strcmp(retval->profile, "spirv") == 0)
if (strcmp(retval->profile, MOJOSHADER_PROFILE_SPIRV) == 0
|| strcmp(retval->profile, MOJOSHADER_PROFILE_GLSPIRV) == 0)
{
size_t i, max;
int binary_size = retval->output_len - sizeof(SpirvPatchTable);
Expand All @@ -3478,7 +3480,7 @@ static MOJOSHADER_parseData *build_parsedata(Context *ctx)
binary[entry.offset] = entry.location;
} // for
} // if
#endif
#endif // SUPPORT_PROFILE_SPIRV

// we don't own these now, retval does.
ctx->ctab.symbols = NULL;
Expand Down Expand Up @@ -3864,6 +3866,7 @@ int MOJOSHADER_maxShaderModel(const char *profile)
PROFILE_SHADER_MODEL(MOJOSHADER_PROFILE_NV4, 3);
PROFILE_SHADER_MODEL(MOJOSHADER_PROFILE_METAL, 3);
PROFILE_SHADER_MODEL(MOJOSHADER_PROFILE_SPIRV, 3);
PROFILE_SHADER_MODEL(MOJOSHADER_PROFILE_GLSPIRV, 3);
#undef PROFILE_SHADER_MODEL
return -1; // unknown profile?
} // MOJOSHADER_maxShaderModel
Expand Down
5 changes: 5 additions & 0 deletions mojoshader.h
Expand Up @@ -724,6 +724,11 @@ typedef struct MOJOSHADER_parseData
*/
#define MOJOSHADER_PROFILE_SPIRV "spirv"

/*
* Profile string for ARB_gl_spirv-friendly SPIR-V binary output
*/
#define MOJOSHADER_PROFILE_GLSPIRV "glspirv"

/*
* Determine the highest supported Shader Model for a profile.
*/
Expand Down
8 changes: 8 additions & 0 deletions mojoshader_internal.h
Expand Up @@ -68,6 +68,10 @@
#define SUPPORT_PROFILE_SPIRV 1
#endif

#ifndef SUPPORT_PROFILE_GLSPIRV
#define SUPPORT_PROFILE_GLSPIRV 1
#endif

#if SUPPORT_PROFILE_ARB1_NV && !SUPPORT_PROFILE_ARB1
#error nv profiles require arb1 profile. Fix your build.
#endif
Expand All @@ -80,6 +84,10 @@
#error glsles profile requires glsl profile. Fix your build.
#endif

#if SUPPORT_PROFILE_GLSPIRV && !SUPPORT_PROFILE_SPIRV
#error glspirv profile requires spirv profile. Fix your build.
#endif

// Microsoft's preprocessor has some quirks. In some ways, it doesn't work
// like you'd expect a C preprocessor to function.
#ifndef MATCH_MICROSOFT_PREPROCESSOR
Expand Down
28 changes: 14 additions & 14 deletions mojoshader_opengl.c
Expand Up @@ -36,7 +36,7 @@
#include "GL/gl.h"
#include "GL/glext.h"

#if SUPPORT_PROFILE_SPIRV
#if SUPPORT_PROFILE_GLSPIRV
#include "spirv/spirv.h"
#endif

Expand Down Expand Up @@ -402,7 +402,7 @@ static inline void toggle_gl_state(GLenum state, int val)

// profile-specific implementations...

#if SUPPORT_PROFILE_GLSL || SUPPORT_PROFILE_SPIRV
#if SUPPORT_PROFILE_GLSL || SUPPORT_PROFILE_GLSPIRV
static inline GLenum glsl_shader_type(const MOJOSHADER_shaderType t)
{
// these enums match between core 2.0 and the ARB extensions.
Expand Down Expand Up @@ -436,7 +436,7 @@ static int impl_GLSL_MaxUniforms(MOJOSHADER_shaderType shader_type)
return (int) val;
} // impl_GLSL_MaxUniforms

#if SUPPORT_PROFILE_SPIRV
#if SUPPORT_PROFILE_GLSPIRV
static const SpirvPatchTable* spv_getPatchTable(MOJOSHADER_glShader *shader)
{
const MOJOSHADER_parseData *pd = shader->parseData;
Expand Down Expand Up @@ -657,7 +657,7 @@ static void impl_SPIRV_FinalInitProgram(MOJOSHADER_glProgram *program)
if (program->ps_vpos_flip_loc != -1) program->ps_vpos_flip_loc += ps_base_location;
} // if
} // impl_SPIRV_FinalInitProgram
#endif // SUPPORT_PROFILE_SPIRV
#endif // SUPPORT_PROFILE_GLSPIRV

#if SUPPORT_PROFILE_GLSL
static int impl_GLSL_CompileShader(const MOJOSHADER_parseData *pd, GLuint *s)
Expand Down Expand Up @@ -909,7 +909,7 @@ static void impl_GLSL_PushSampler(GLint loc, GLuint sampler)
ctx->glUniform1i(loc, sampler);
} // impl_GLSL_PushSampler

#endif // SUPPORT_PROFILE_GLSL || SUPPORT_PROFILE_SPIRV
#endif // SUPPORT_PROFILE_GLSL || SUPPORT_PROFILE_GLSPIRV


#if SUPPORT_PROFILE_ARB1
Expand Down Expand Up @@ -1553,11 +1553,11 @@ static int valid_profile(const char *profile)
} // else if
#endif

#if SUPPORT_PROFILE_SPIRV
else if (strcmp(profile, MOJOSHADER_PROFILE_SPIRV) == 0)
#if SUPPORT_PROFILE_GLSPIRV
else if (strcmp(profile, MOJOSHADER_PROFILE_GLSPIRV) == 0)
{
MUST_HAVE(MOJOSHADER_PROFILE_SPIRV, GL_ARB_ES2_compatibility);
MUST_HAVE(MOJOSHADER_PROFILE_SPIRV, GL_ARB_gl_spirv);
MUST_HAVE(MOJOSHADER_PROFILE_GLSPIRV, GL_ARB_ES2_compatibility);
MUST_HAVE(MOJOSHADER_PROFILE_GLSPIRV, GL_ARB_gl_spirv);
} // else if
#endif

Expand Down Expand Up @@ -1595,8 +1595,8 @@ static int valid_profile(const char *profile)


static const char *profile_priorities[] = {
#if SUPPORT_PROFILE_SPIRV
MOJOSHADER_PROFILE_SPIRV,
#if SUPPORT_PROFILE_GLSPIRV
MOJOSHADER_PROFILE_GLSPIRV,
#endif
#if SUPPORT_PROFILE_GLSL120
MOJOSHADER_PROFILE_GLSL120,
Expand Down Expand Up @@ -1726,9 +1726,9 @@ MOJOSHADER_glContext *MOJOSHADER_glCreateContext(const char *profile,
// !!! FIXME: generalize this part.
if (profile == NULL) {}

// We don't check SUPPORT_PROFILE_SPIRV here, since valid_profile() does.
#if SUPPORT_PROFILE_SPIRV
else if (strcmp(profile, MOJOSHADER_PROFILE_SPIRV) == 0)
// We don't check SUPPORT_PROFILE_GLSPIRV here, since valid_profile() does.
#if SUPPORT_PROFILE_GLSPIRV
else if (strcmp(profile, MOJOSHADER_PROFILE_GLSPIRV) == 0)
{
ctx->profileMaxUniforms = impl_GLSL_MaxUniforms;
ctx->profileCompileShader = impl_SPIRV_CompileShader;
Expand Down
3 changes: 3 additions & 0 deletions profiles/mojoshader_profile.h
Expand Up @@ -210,6 +210,9 @@ typedef struct Context
int branch_labels_patch_stack[32];
SpirvContext spirv;
#endif
#if SUPPORT_PROFILE_GLSPIRV
int profile_supports_glspirv;
#endif
} Context;

// Use these macros so we can remove all bits of these profiles from the build.
Expand Down
35 changes: 25 additions & 10 deletions profiles/mojoshader_profile_spirv.c
Expand Up @@ -1270,8 +1270,9 @@ static void spv_assign_destarg(Context *ctx, SpirvResult value)

static void spv_emit_vs_main_end(Context* ctx)
{
#if SUPPORT_PROFILE_GLSPIRV
#if defined(MOJOSHADER_DEPTH_CLIPPING) || defined(MOJOSHADER_FLIP_RENDERTARGET)
if (!shader_is_vertex(ctx))
if (!ctx->profile_supports_glspirv || !shader_is_vertex(ctx))
return;

uint32 tid_void = spv_get_type(ctx, STI_VOID);
Expand Down Expand Up @@ -1317,7 +1318,7 @@ static void spv_emit_vs_main_end(Context* ctx)

spv_output_name(ctx, id_pvpflip, "vpFlip");
ctx->spirv.patch_table.vpflip.offset = spv_output_location(ctx, id_pvpflip, ~0u);
#endif
#endif // MOJOSHADER_FLIP_RENDERTARGET

#ifdef MOJOSHADER_DEPTH_CLIPPING
// gl_Position.z = gl_Position.z * 2.0 - gl_Position.w;
Expand All @@ -1334,15 +1335,16 @@ static void spv_emit_vs_main_end(Context* ctx)
spv_emit(ctx, 5, SpvOpFSub, tid_float, id_new_z, id_2z, id_old_w);
spv_emit(ctx, 6, SpvOpCompositeInsert, output.tid, id_new_output, id_new_z, output.id, 2);
output.id = id_new_output;
#endif
#endif // MOJOSHADER_DEPTH_CLIPPING

spv_emit(ctx, 3, SpvOpStore, reg->spirv.iddecl, output.id);
spv_emit(ctx, 1, SpvOpReturn);
spv_emit(ctx, 1, SpvOpFunctionEnd);
pop_output(ctx);

spv_output_name(ctx, id_func, "vs_epilogue");
#endif
#endif // defined(MOJOSHADER_DEPTH_CLIPPING) || defined(MOJOSHADER_FLIP_RENDERTARGET)
#endif // SUPPORT_PROFILE_GLSPIRV
} // spv_emit_vs_main_end

static void spv_emit_func_lit(Context *ctx)
Expand Down Expand Up @@ -1458,8 +1460,11 @@ static void spv_emit_func_end(Context *ctx)
{
push_output(ctx, &ctx->mainline);

#if SUPPORT_PROFILE_GLSPIRV
#if defined(MOJOSHADER_DEPTH_CLIPPING) || defined(MOJOSHADER_FLIP_RENDERTARGET)
if (shader_is_vertex(ctx) && ctx->spirv.id_vs_main_end == 0)
if (ctx->profile_supports_glspirv
&& shader_is_vertex(ctx)
&& ctx->spirv.id_vs_main_end == 0)
{
ctx->spirv.id_vs_main_end = spv_bumpid(ctx);
uint32 tid_void = spv_get_type(ctx, STI_VOID);
Expand All @@ -1469,7 +1474,8 @@ static void spv_emit_func_end(Context *ctx)
spv_emit(ctx, 4, SpvOpFunctionCall, tid_void, id_res, ctx->spirv.id_vs_main_end);
pop_output(ctx);
} // if
#endif
#endif // defined(MOJOSHADER_DEPTH_CLIPPING) || defined(MOJOSHADER_FLIP_RENDERTARGET)
#endif // SUPPORT_PROFILE_GLSPIRV

spv_emit(ctx, 1, SpvOpReturn);
spv_emit(ctx, 1, SpvOpFunctionEnd);
Expand Down Expand Up @@ -1564,8 +1570,10 @@ static void spv_link_ps_attributes(Context *ctx, uint32 id, RegisterType regtype
{
case MISCTYPE_TYPE_POSITION: // vPos
{
// In SM3.0 vPos only has x and y defined, but we should be fine to leave the z and w attributes in
// that SpvBuiltInFragCoord gives
// In SM3.0 vPos only has x and y defined, but we should be
// fine to leave the z and w attributes in that
// SpvBuiltInFragCoord gives.
// FIXME: Is the flip needed for Vulkan?

uint32 tid_float = spv_get_type(ctx, STI_FLOAT);
uint32 tid_vec2 = spv_get_type(ctx, STI_VEC2);
Expand Down Expand Up @@ -1792,8 +1800,15 @@ void emit_SPIRV_start(Context *ctx, const char *profilestr)
return;
} // if

if (strcmp(profilestr, MOJOSHADER_PROFILE_SPIRV) != 0)
failf(ctx, "Profile '%s' unsupported or unknown.", profilestr);
#if SUPPORT_PROFILE_GLSPIRV
if (strcmp(profilestr, MOJOSHADER_PROFILE_GLSPIRV) == 0)
ctx->profile_supports_glspirv = 1;
else
#endif // SUPPORT_PROFILE_GLSPIRV
{
if (strcmp(profilestr, MOJOSHADER_PROFILE_SPIRV) != 0)
failf(ctx, "Profile '%s' unsupported or unknown.", profilestr);
} // else

memset(&(ctx->spirv), '\0', sizeof(ctx->spirv));

Expand Down
2 changes: 2 additions & 0 deletions profiles/mojoshader_profile_spirv.h
Expand Up @@ -147,7 +147,9 @@ typedef struct SpirvResult

typedef struct SpirvContext
{
#if SUPPORT_PROFILE_GLSPIRV
uint32 id_vs_main_end;
#endif // SUPPORT_PROFILE_GLSPIRV
// ext. glsl instructions have been imported
uint32 idext;
uint32 idmax;
Expand Down

0 comments on commit 3d22cba

Please sign in to comment.