Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Implement HLSL emitter, MOJOSHADER_d3d11 API
  • Loading branch information
TheSpydog committed May 21, 2020
1 parent 9b41cfc commit 6766661
Show file tree
Hide file tree
Showing 8 changed files with 3,423 additions and 4 deletions.
6 changes: 6 additions & 0 deletions CMakeLists.txt
Expand Up @@ -4,6 +4,7 @@ PROJECT(MojoShader)
OPTION(BUILD_SHARED_LIBS "Build MojoShader as a shared library" OFF)
OPTION(PROFILE_D3D "Build MojoShader with support for the D3D profile" ON)
OPTION(PROFILE_BYTECODE "Build MojoShader with support for the BYTECODE profile" ON)
OPTION(PROFILE_HLSL "Build MojoShader with support for the HLSL profile" ON)
OPTION(PROFILE_GLSL120 "Build MojoShader with support for the GLSL120 profile" ON)
OPTION(PROFILE_GLSLES "Build MojoShader with support for the GLSLES profile" ON)
OPTION(PROFILE_GLSL "Build MojoShader with support for the GLSL profile" ON)
Expand Down Expand Up @@ -108,6 +109,9 @@ ENDIF(NOT PROFILE_D3D)
IF(NOT PROFILE_BYTECODE)
ADD_DEFINITIONS(-DSUPPORT_PROFILE_BYTECODE=0)
ENDIF(NOT PROFILE_BYTECODE)
IF(NOT PROFILE_HLSL)
ADD_DEFINITIONS(-DSUPPORT_PROFILE_HLSL=0)
ENDIF(NOT PROFILE_HLSL)
IF(NOT PROFILE_GLSL120)
ADD_DEFINITIONS(-DSUPPORT_PROFILE_GLSL120=0)
ENDIF(NOT PROFILE_GLSL120)
Expand Down Expand Up @@ -159,9 +163,11 @@ ADD_LIBRARY(mojoshader
mojoshader_common.c
mojoshader_opengl.c
mojoshader_metal.c
mojoshader_d3d11.c
profiles/mojoshader_profile_arb1.c
profiles/mojoshader_profile_bytecode.c
profiles/mojoshader_profile_d3d.c
profiles/mojoshader_profile_hlsl.c
profiles/mojoshader_profile_glsl.c
profiles/mojoshader_profile_metal.c
profiles/mojoshader_profile_spirv.c
Expand Down
14 changes: 14 additions & 0 deletions mojoshader.c
Expand Up @@ -236,6 +236,15 @@ PREDECLARE_PROFILE(BYTECODE)
PREDECLARE_PROFILE(D3D)
#endif

#if !SUPPORT_PROFILE_HLSL
#define PROFILE_EMITTER_HLSL(op)
#else
#undef AT_LEAST_ONE_PROFILE
#define AT_LEAST_ONE_PROFILE 1
#define PROFILE_EMITTER_HLSL(op) emit_HLSL_##op,
PREDECLARE_PROFILE(HLSL)
#endif

#if !SUPPORT_PROFILE_GLSL
#define PROFILE_EMITTER_GLSL(op)
#else
Expand Down Expand Up @@ -300,6 +309,9 @@ static const Profile profiles[] =
#if SUPPORT_PROFILE_BYTECODE
DEFINE_PROFILE(BYTECODE)
#endif
#if SUPPORT_PROFILE_HLSL
DEFINE_PROFILE(HLSL)
#endif
#if SUPPORT_PROFILE_GLSL
DEFINE_PROFILE(GLSL)
#endif
Expand Down Expand Up @@ -331,6 +343,7 @@ static const struct { const char *from; const char *to; } profileMap[] =
#define PROFILE_EMITTERS(op) { \
PROFILE_EMITTER_D3D(op) \
PROFILE_EMITTER_BYTECODE(op) \
PROFILE_EMITTER_HLSL(op) \
PROFILE_EMITTER_GLSL(op) \
PROFILE_EMITTER_ARB1(op) \
PROFILE_EMITTER_METAL(op) \
Expand Down Expand Up @@ -3866,6 +3879,7 @@ int MOJOSHADER_maxShaderModel(const char *profile)
#define PROFILE_SHADER_MODEL(p,v) if (strcmp(profile, p) == 0) return v;
PROFILE_SHADER_MODEL(MOJOSHADER_PROFILE_D3D, 3);
PROFILE_SHADER_MODEL(MOJOSHADER_PROFILE_BYTECODE, 3);
PROFILE_SHADER_MODEL(MOJOSHADER_PROFILE_HLSL, 3);
PROFILE_SHADER_MODEL(MOJOSHADER_PROFILE_GLSL, 3);
PROFILE_SHADER_MODEL(MOJOSHADER_PROFILE_GLSL120, 3);
PROFILE_SHADER_MODEL(MOJOSHADER_PROFILE_GLSLES, 3);
Expand Down
208 changes: 208 additions & 0 deletions mojoshader.h
Expand Up @@ -685,6 +685,11 @@ typedef struct MOJOSHADER_parseData
*/
#define MOJOSHADER_PROFILE_BYTECODE "bytecode"

/*
* Profile string for HLSL Shader Model 4 output.
*/
#define MOJOSHADER_PROFILE_HLSL "hlsl"

/*
* Profile string for GLSL: OpenGL high-level shader language output.
*/
Expand Down Expand Up @@ -3528,6 +3533,209 @@ DECLSPEC void MOJOSHADER_mtlEndFrame(void);
DECLSPEC void MOJOSHADER_mtlDestroyContext(void);


/* D3D11 interface... */

typedef struct MOJOSHADER_d3d11Shader MOJOSHADER_d3d11Shader;

/*
* Prepare MojoShader to manage Direct3D 11 shaders.
*
* You do not need to call this if all you want is MOJOSHADER_parse().
*
* You must call this once AFTER you have successfully built your D3D11 context.
*
* As MojoShader requires some memory to be allocated, you may provide a
* custom allocator to this function, which will be used to allocate/free
* memory. They function just like malloc() and free(). We do not use
* realloc(). If you don't care, pass NULL in for the allocator functions.
* If your allocator needs instance-specific data, you may supply it with the
* (malloc_d) parameter. This pointer is passed as-is to your (m) and (f)
* functions.
*
* This call is only as thread safe as your D3D11 context! If you call your
* context from multiple threads, you must protect this call with whatever
* thread synchronization technique you have for your other D3D calls.
*/
DECLSPEC int MOJOSHADER_d3d11CreateContext(void *device, void *deviceContext,
MOJOSHADER_malloc m, MOJOSHADER_free f,
void *malloc_d);

/*
* Get any error state we might have picked up, such as failed shader
* compilation.
*
* Returns a human-readable string. This string is for debugging purposes, and
* not guaranteed to be localized, coherent, or user-friendly in any way.
* It's for programmers!
*
* The latest error may remain between calls. New errors replace any existing
* error. Don't check this string for a sign that an error happened, check
* return codes instead and use this for explanation when debugging.
*
* Do not free the returned string: it's a pointer to a static internal
* buffer. Do not keep the pointer around, either, as it's likely to become
* invalid as soon as you call into MojoShader again.
*/
DECLSPEC const char *MOJOSHADER_d3d11GetError(void);

/*
* Compile a buffer of Direct3D 9 shader bytecode into a Direct3D 11 shader.
* You still need to link the shader before you may render with it.
*
* (mainfn) is the name of the shader's main function.
* (tokenbuf) is a buffer of Direct3D shader bytecode.
* (bufsize) is the size, in bytes, of the bytecode buffer.
* (swiz), (swizcount), (smap), and (smapcount) are passed to
* MOJOSHADER_parse() unmolested.
*
* Returns NULL on error, or a shader handle on success.
*
* This call is only as thread safe as your D3D11 context! If you call your
* context from multiple threads, you must protect this call with whatever
* thread synchronization technique you have for your other D3D calls.
*/
DECLSPEC MOJOSHADER_d3d11Shader *MOJOSHADER_d3d11CompileShader(const char *mainfn,
const unsigned char *tokenbuf,
const unsigned int bufsize,
const MOJOSHADER_swizzle *swiz,
const unsigned int swizcount,
const MOJOSHADER_samplerMap *smap,
const unsigned int smapcount);

/*
* Increments a shader's internal refcount. To decrement the refcount, call
* MOJOSHADER_glDeleteShader().
*
* This call is only as thread safe as your D3D11 context! If you call your
* context from multiple threads, you must protect this call with whatever
* thread synchronization technique you have for your other D3D calls.
*/
DECLSPEC void MOJOSHADER_d3d11ShaderAddRef(MOJOSHADER_d3d11Shader *shader);

/*
* Get the MOJOSHADER_parseData structure that was produced from the
* call to MOJOSHADER_d3d11CompileShader().
*
* This data is read-only, and you should NOT attempt to free it. This
* pointer remains valid until the shader is deleted.
*/
DECLSPEC const MOJOSHADER_parseData *MOJOSHADER_d3d11GetShaderParseData(
MOJOSHADER_d3d11Shader *shader);

/*
* This binds individual shaders together, to be linked into a single working
* program once MOJOSHADER_d3d11ProgramReady is called.
*
* This call is only as thread safe as your D3D11 context! If you call your
* context from multiple threads, you must protect this call with whatever
* thread synchronization technique you have for your other D3D calls.
*/
DECLSPEC void MOJOSHADER_d3d11BindShaders(MOJOSHADER_d3d11Shader *vshader,
MOJOSHADER_d3d11Shader *pshader);

/*
* This queries for the shaders currently bound to the active context.
*
* This function is only for convenience, specifically for compatibility with
* the effects API.
*
* This call is only as thread safe as your D3D11 context! If you call your
* context from multiple threads, you must protect this call with whatever
* thread synchronization technique you have for your other D3D calls.
*/
DECLSPEC void MOJOSHADER_d3d11GetBoundShaders(MOJOSHADER_d3d11Shader **vshader,
MOJOSHADER_d3d11Shader **pshader);

/*
* Fills register pointers with pointers that are directly used to push uniform
* data to the D3D11 shader context.
*
* This function is really just for the effects API, you should NOT be using
* this unless you know every single line of MojoShader from memory.
*
* This call is only as thread safe as your D3D11 context! If you call your
* context from multiple threads, you must protect this call with whatever
* thread synchronization technique you have for your other D3D calls.
*/
DECLSPEC void MOJOSHADER_d3d11MapUniformBufferMemory(float **vsf, int **vsi, unsigned char **vsb,
float **psf, int **psi, unsigned char **psb);

/*
* Tells the context that you are done with the memory mapped by
* MOJOSHADER_d3d11MapUniformBufferMemory().
*
* This call is only as thread safe as your D3D11 context! If you call your
* context from multiple threads, you must protect this call with whatever
* thread synchronization technique you have for your other D3D calls.
*/
DECLSPEC void MOJOSHADER_d3d11UnmapUniformBufferMemory();

/*
* Return the location of a vertex attribute for the given vertex shader.
*
* (usage) and (index) map to Direct3D vertex declaration values: COLOR1 would
* be MOJOSHADER_USAGE_COLOR and 1.
*
* The return value is the index of the attribute to be used when building the
* input layout object.
*/
DECLSPEC int MOJOSHADER_d3d11GetVertexAttribLocation(MOJOSHADER_d3d11Shader *vert,
MOJOSHADER_usage usage,
int index);

/*
* Using the given input layout, compiles the vertex shader with input
* parameters that will be compatible with the incoming vertex data.
*
* (inputLayoutHash) is an application-defined value to differentiate unique
* vertex declarations that will be passed to the vertex shader.
* (elements) is an array of D3D11_INPUT_ELEMENT_DESCs, with (elementCount)
* entries. (bytecode) and (bytecodeLength) will be filled with the final
* compiled D3D11 vertex shader.
*
* This call is only as thread safe as your D3D11 context! If you call your
* context from multiple threads, you must protect this call with whatever
* thread synchronization technique you have for your other D3D calls.
*/
DECLSPEC void MOJOSHADER_d3d11CompileVertexShader(unsigned long long inputLayoutHash,
void *elements, int elementCount,
void **bytecode, int *bytecodeLength);

/*
* Inform MojoShader that it should commit any pending state and prepare the
* final shader program object, linking the input/output parameter data to
* be compatible with the more-struct Shader Model 4 rule set. This must be

This comment has been minimized.

Copy link
@TheSpydog

TheSpydog May 21, 2020

Author Contributor

Should "struct" be "strict"?

This comment has been minimized.

Copy link
@flibitijibibo

flibitijibibo May 21, 2020

Collaborator

Yup, that's on me...

* called after you bind shaders and update any inputs, right before you start
* drawing, so any outstanding changes made to the shared constants array (etc)
* can propagate to the shader during this call.
*
* This call is only as thread safe as your D3D11 context! If you call your
* context from multiple threads, you must protect this call with whatever
* thread synchronization technique you have for your other D3D calls.
*/
DECLSPEC void MOJOSHADER_d3d11ProgramReady(unsigned long long inputLayoutHash);

/*
* Free the resources of a compiled shader. This will delete the shader object
* and free memory.
*
* This call is only as thread safe as your D3D11 context! If you call your
* context from multiple threads, you must protect this call with whatever
* thread synchronization technique you have for your other D3D calls.
*/
DECLSPEC void MOJOSHADER_d3d11DeleteShader(MOJOSHADER_d3d11Shader *shader);

/*
* Deinitialize MojoShader's D3D11 shader management.
*
* This will clean up resources previously allocated for the active context.
*
* This will NOT clean up shaders you created! Please destroy all shaders
* before calling this function.
*/
DECLSPEC void MOJOSHADER_d3d11DestroyContext(void);


/* Effects interface... */
#include "mojoshader_effects.h"

Expand Down

0 comments on commit 6766661

Please sign in to comment.