/** * MojoShader; generate shader programs from bytecode of compiled * Direct3D shaders. * * Please see the file LICENSE.txt in the source's root directory. * * This file written by Ryan C. Gordon. */ #ifndef _INCL_MOJOSHADER_H_ #define _INCL_MOJOSHADER_H_ #ifdef __cplusplus extern "C" { #endif /* You can define this if you aren't generating mojoshader_version.h */ #ifndef MOJOSHADER_NO_VERSION_INCLUDE #include "mojoshader_version.h" #endif #ifndef MOJOSHADER_VERSION #define MOJOSHADER_VERSION -1 #endif #ifndef MOJOSHADER_CHANGESET #define MOJOSHADER_CHANGESET "???" #endif #ifndef DECLSPEC #ifdef _WIN32 #define DECLSPEC __declspec(dllexport) #else #define DECLSPEC #endif #endif #ifndef MOJOSHADERCALL #ifdef _WIN32 #define MOJOSHADERCALL __cdecl #else #define MOJOSHADERCALL #endif #endif /* -Wpedantic nameless union/struct silencing */ #ifndef MOJOSHADERNAMELESS #ifdef __GNUC__ #define MOJOSHADERNAMELESS __extension__ #else #define MOJOSHADERNAMELESS #endif /* __GNUC__ */ #endif /* MOJOSHADERNAMELESS */ /* * For determining the version of MojoShader you are using: * const int compiled_against = MOJOSHADER_VERSION; * const int linked_against = MOJOSHADER_version(); * * The version is a single integer that increments, not a major/minor value. */ DECLSPEC int MOJOSHADER_version(void); /* * For determining the revision control changeset of MojoShader you are using: * const char *compiled_against = MOJOSHADER_CHANGESET; * const char *linked_against = MOJOSHADER_changeset(); * * The version is an arbitrary, null-terminated ASCII string. It is probably * a hash that represents a revision control changeset, and can't be * compared to any other string to determine chronology. * * Do not attempt to free this string; it's statically allocated. */ DECLSPEC const char *MOJOSHADER_changeset(void); /* * These allocators work just like the C runtime's malloc() and free() * (in fact, they probably use malloc() and free() internally if you don't * specify your own allocator, but don't rely on that behaviour). * (data) is the pointer you supplied when specifying these allocator * callbacks, in case you need instance-specific data...it is passed through * to your allocator unmolested, and can be NULL if you like. */ typedef void *(MOJOSHADERCALL *MOJOSHADER_malloc)(int bytes, void *data); typedef void (MOJOSHADERCALL *MOJOSHADER_free)(void *ptr, void *data); /* * These are enum values, but they also can be used in bitmasks, so we can * test if an opcode is acceptable: if (op->shader_types & ourtype) {} ... */ typedef enum { MOJOSHADER_TYPE_UNKNOWN = 0, MOJOSHADER_TYPE_PIXEL = (1 << 0), MOJOSHADER_TYPE_VERTEX = (1 << 1), MOJOSHADER_TYPE_GEOMETRY = (1 << 2), /* (not supported yet.) */ MOJOSHADER_TYPE_ANY = 0x7FFFFFFF /* used for bitmasks */ } MOJOSHADER_shaderType; /* * Data types for vertex attribute streams. */ typedef enum { MOJOSHADER_ATTRIBUTE_UNKNOWN = -1, /* housekeeping; not returned. */ MOJOSHADER_ATTRIBUTE_BYTE, MOJOSHADER_ATTRIBUTE_UBYTE, MOJOSHADER_ATTRIBUTE_SHORT, MOJOSHADER_ATTRIBUTE_USHORT, MOJOSHADER_ATTRIBUTE_INT, MOJOSHADER_ATTRIBUTE_UINT, MOJOSHADER_ATTRIBUTE_FLOAT, MOJOSHADER_ATTRIBUTE_DOUBLE, MOJOSHADER_ATTRIBUTE_HALF_FLOAT /* MAYBE available in your OpenGL! */ } MOJOSHADER_attributeType; /* * Data types for uniforms. See MOJOSHADER_uniform for more information. */ typedef enum { MOJOSHADER_UNIFORM_UNKNOWN = -1, /* housekeeping value; never returned. */ MOJOSHADER_UNIFORM_FLOAT, MOJOSHADER_UNIFORM_INT, MOJOSHADER_UNIFORM_BOOL } MOJOSHADER_uniformType; /* * These are the uniforms to be set for a shader. "Uniforms" are what Direct3D * calls "Constants" ... IDirect3DDevice::SetVertexShaderConstantF() would * need this data, for example. These integers are register indexes. So if * index==6 and type==MOJOSHADER_UNIFORM_FLOAT, that means we'd expect a * 4-float vector to be specified for what would be register "c6" in D3D * assembly language, before drawing with the shader. * (array_count) means this is an array of uniforms...this happens in some * profiles when we see a relative address ("c0[a0.x]", not the usual "c0"). * In those cases, the shader was built to set some range of constant * registers as an array. You should set this array with (array_count) * elements from the constant register file, starting at (index) instead of * just a single uniform. To be extra difficult, you'll need to fill in the * correct values from the MOJOSHADER_constant data into the appropriate * parts of the array, overriding the constant register file. Fun! * (constant) says whether this is a constant array; these need to be loaded * once at creation time, from the constant list and not ever updated from * the constant register file. This is a workaround for limitations in some * profiles. * (name) is a profile-specific variable name; it may be NULL if it isn't * applicable to the requested profile. */ typedef struct MOJOSHADER_uniform { MOJOSHADER_uniformType type; int index; int array_count; int constant; const char *name; } MOJOSHADER_uniform; /* * These are the constants defined in a shader. These are data values * hardcoded in a shader (with the DEF, DEFI, DEFB instructions), which * override your Uniforms. This data is largely for informational purposes, * since they are compiled in and can't be changed, like Uniforms can be. * These integers are register indexes. So if index==6 and * type==MOJOSHADER_UNIFORM_FLOAT, that means we'd expect a 4-float vector * to be specified for what would be register "c6" in D3D assembly language, * before drawing with the shader. * (value) is the value of the constant, unioned by type. */ typedef struct MOJOSHADER_constant { MOJOSHADER_uniformType type; int index; union { float f[4]; /* if type==MOJOSHADER_UNIFORM_FLOAT */ int i[4]; /* if type==MOJOSHADER_UNIFORM_INT */ int b; /* if type==MOJOSHADER_UNIFORM_BOOL */ } value; } MOJOSHADER_constant; /* * Data types for samplers. See MOJOSHADER_sampler for more information. */ typedef enum { MOJOSHADER_SAMPLER_UNKNOWN = -1, /* housekeeping value; never returned. */ MOJOSHADER_SAMPLER_2D, MOJOSHADER_SAMPLER_CUBE, MOJOSHADER_SAMPLER_VOLUME } MOJOSHADER_samplerType; /* * These are the samplers to be set for a shader. ... * IDirect3DDevice::SetTexture() would need this data, for example. * These integers are the sampler "stage". So if index==6 and * type==MOJOSHADER_SAMPLER_2D, that means we'd expect a regular 2D texture * to be specified for what would be register "s6" in D3D assembly language, * before drawing with the shader. * (name) is a profile-specific variable name; it may be NULL if it isn't * applicable to the requested profile. * (texbem) will be non-zero if a TEXBEM opcode references this sampler. This * is only used in legacy shaders (ps_1_1 through ps_1_3), but it needs some * special support to work, as we have to load a magic uniform behind the * scenes to support it. Most code can ignore this field in general, and no * one has to touch it unless they really know what they're doing. */ typedef struct MOJOSHADER_sampler { MOJOSHADER_samplerType type; int index; const char *name; int texbem; } MOJOSHADER_sampler; /* * This struct is used if you have to force a sampler to a specific type. * Generally, you can ignore this, but if you have, say, a ps_1_1 * shader, you might need to specify what the samplers are meant to be * to get correct results, as Shader Model 1 samples textures according * to what is bound to a sampler at the moment instead of what the shader * is hardcoded to expect. */ typedef struct MOJOSHADER_samplerMap { int index; MOJOSHADER_samplerType type; } MOJOSHADER_samplerMap; /* * Data types for attributes. See MOJOSHADER_attribute for more information. */ typedef enum { MOJOSHADER_USAGE_UNKNOWN = -1, /* housekeeping value; never returned. */ MOJOSHADER_USAGE_POSITION, /* 0-15 for Vertex, 1-15 for Pixel */ MOJOSHADER_USAGE_BLENDWEIGHT, /* 0-15 */ MOJOSHADER_USAGE_BLENDINDICES, /* 0-15 */ MOJOSHADER_USAGE_NORMAL, /* 0-15 */ MOJOSHADER_USAGE_POINTSIZE, /* 0-15 */ MOJOSHADER_USAGE_TEXCOORD, /* 0-15 */ MOJOSHADER_USAGE_TANGENT, /* 0-15 */ MOJOSHADER_USAGE_BINORMAL, /* 0-15 */ MOJOSHADER_USAGE_TESSFACTOR, /* 0 only */ MOJOSHADER_USAGE_POSITIONT, /* 0-15 for Vertex, 1-15 for Pixel */ MOJOSHADER_USAGE_COLOR, /* 0-15 but depends on MRT support */ MOJOSHADER_USAGE_FOG, /* 0-15 */ MOJOSHADER_USAGE_DEPTH, /* 0-15 */ MOJOSHADER_USAGE_SAMPLE, MOJOSHADER_USAGE_TOTAL /* housekeeping value; never returned. */ } MOJOSHADER_usage; /* * These are the attributes to be set for a shader. "Attributes" are what * Direct3D calls "Vertex Declarations Usages" ... * IDirect3DDevice::CreateVertexDeclaration() would need this data, for * example. Each attribute is associated with an array of data that uses one * element per-vertex. So if usage==MOJOSHADER_USAGE_COLOR and index==1, that * means we'd expect a secondary color array to be bound to this shader * before drawing. * (name) is a profile-specific variable name; it may be NULL if it isn't * applicable to the requested profile. */ typedef struct MOJOSHADER_attribute { MOJOSHADER_usage usage; int index; const char *name; } MOJOSHADER_attribute; /* * Use this if you want to specify newly-parsed code to swizzle incoming * data. This can be useful if you know, at parse time, that a shader * will be processing data on COLOR0 that should be RGBA, but you'll * be passing it a vertex array full of ARGB instead. */ typedef struct MOJOSHADER_swizzle { MOJOSHADER_usage usage; unsigned int index; unsigned char swizzles[4]; /* {0,1,2,3} == .xyzw, {2,2,2,2} == .zzzz */ } MOJOSHADER_swizzle; /* * MOJOSHADER_symbol data. * * These are used to expose high-level information in shader bytecode. * They associate HLSL variables with registers. This data is used for both * debugging and optimization. */ typedef enum { MOJOSHADER_SYMREGSET_BOOL=0, MOJOSHADER_SYMREGSET_INT4, MOJOSHADER_SYMREGSET_FLOAT4, MOJOSHADER_SYMREGSET_SAMPLER, MOJOSHADER_SYMREGSET_TOTAL /* housekeeping value; never returned. */ } MOJOSHADER_symbolRegisterSet; typedef enum { MOJOSHADER_SYMCLASS_SCALAR=0, MOJOSHADER_SYMCLASS_VECTOR, MOJOSHADER_SYMCLASS_MATRIX_ROWS, MOJOSHADER_SYMCLASS_MATRIX_COLUMNS, MOJOSHADER_SYMCLASS_OBJECT, MOJOSHADER_SYMCLASS_STRUCT, MOJOSHADER_SYMCLASS_TOTAL /* housekeeping value; never returned. */ } MOJOSHADER_symbolClass; typedef enum { MOJOSHADER_SYMTYPE_VOID=0, MOJOSHADER_SYMTYPE_BOOL, MOJOSHADER_SYMTYPE_INT, MOJOSHADER_SYMTYPE_FLOAT, MOJOSHADER_SYMTYPE_STRING, MOJOSHADER_SYMTYPE_TEXTURE, MOJOSHADER_SYMTYPE_TEXTURE1D, MOJOSHADER_SYMTYPE_TEXTURE2D, MOJOSHADER_SYMTYPE_TEXTURE3D, MOJOSHADER_SYMTYPE_TEXTURECUBE, MOJOSHADER_SYMTYPE_SAMPLER, MOJOSHADER_SYMTYPE_SAMPLER1D, MOJOSHADER_SYMTYPE_SAMPLER2D, MOJOSHADER_SYMTYPE_SAMPLER3D, MOJOSHADER_SYMTYPE_SAMPLERCUBE, MOJOSHADER_SYMTYPE_PIXELSHADER, MOJOSHADER_SYMTYPE_VERTEXSHADER, MOJOSHADER_SYMTYPE_PIXELFRAGMENT, MOJOSHADER_SYMTYPE_VERTEXFRAGMENT, MOJOSHADER_SYMTYPE_UNSUPPORTED, MOJOSHADER_SYMTYPE_TOTAL /* housekeeping value; never returned. */ } MOJOSHADER_symbolType; typedef struct MOJOSHADER_symbolStructMember MOJOSHADER_symbolStructMember; typedef struct MOJOSHADER_symbolTypeInfo { MOJOSHADER_symbolClass parameter_class; MOJOSHADER_symbolType parameter_type; unsigned int rows; unsigned int columns; unsigned int elements; unsigned int member_count; MOJOSHADER_symbolStructMember *members; } MOJOSHADER_symbolTypeInfo; struct MOJOSHADER_symbolStructMember { const char *name; MOJOSHADER_symbolTypeInfo info; }; typedef struct MOJOSHADER_symbol { const char *name; MOJOSHADER_symbolRegisterSet register_set; unsigned int register_index; unsigned int register_count; MOJOSHADER_symbolTypeInfo info; } MOJOSHADER_symbol; /* * These are used with MOJOSHADER_error as special case positions. */ #define MOJOSHADER_POSITION_NONE (-3) #define MOJOSHADER_POSITION_BEFORE (-2) #define MOJOSHADER_POSITION_AFTER (-1) typedef struct MOJOSHADER_error { /* * Human-readable error, if there is one. Will be NULL if there was no * error. The string will be UTF-8 encoded, and English only. Most of * these shouldn't be shown to the end-user anyhow. */ const char *error; /* * Filename where error happened. This can be NULL if the information * isn't available. */ const char *filename; /* * Position of error, if there is one. Will be MOJOSHADER_POSITION_NONE if * there was no error, MOJOSHADER_POSITION_BEFORE if there was an error * before processing started, and MOJOSHADER_POSITION_AFTER if there was * an error during final processing. If >= 0, MOJOSHADER_parse() sets * this to the byte offset (starting at zero) into the bytecode you * supplied, and MOJOSHADER_assemble(), MOJOSHADER_parseAst(), and * MOJOSHADER_compile() sets this to a a line number in the source code * you supplied (starting at one). */ int error_position; } MOJOSHADER_error; /* !!! FIXME: document me. */ typedef enum MOJOSHADER_preshaderOpcode { MOJOSHADER_PRESHADEROP_NOP, MOJOSHADER_PRESHADEROP_MOV, MOJOSHADER_PRESHADEROP_NEG, MOJOSHADER_PRESHADEROP_RCP, MOJOSHADER_PRESHADEROP_FRC, MOJOSHADER_PRESHADEROP_EXP, MOJOSHADER_PRESHADEROP_LOG, MOJOSHADER_PRESHADEROP_RSQ, MOJOSHADER_PRESHADEROP_SIN, MOJOSHADER_PRESHADEROP_COS, MOJOSHADER_PRESHADEROP_ASIN, MOJOSHADER_PRESHADEROP_ACOS, MOJOSHADER_PRESHADEROP_ATAN, MOJOSHADER_PRESHADEROP_MIN, MOJOSHADER_PRESHADEROP_MAX, MOJOSHADER_PRESHADEROP_LT, MOJOSHADER_PRESHADEROP_GE, MOJOSHADER_PRESHADEROP_ADD, MOJOSHADER_PRESHADEROP_MUL, MOJOSHADER_PRESHADEROP_ATAN2, MOJOSHADER_PRESHADEROP_DIV, MOJOSHADER_PRESHADEROP_CMP, MOJOSHADER_PRESHADEROP_MOVC, MOJOSHADER_PRESHADEROP_DOT, MOJOSHADER_PRESHADEROP_NOISE, MOJOSHADER_PRESHADEROP_SCALAR_OPS, MOJOSHADER_PRESHADEROP_MIN_SCALAR = MOJOSHADER_PRESHADEROP_SCALAR_OPS, MOJOSHADER_PRESHADEROP_MAX_SCALAR, MOJOSHADER_PRESHADEROP_LT_SCALAR, MOJOSHADER_PRESHADEROP_GE_SCALAR, MOJOSHADER_PRESHADEROP_ADD_SCALAR, MOJOSHADER_PRESHADEROP_MUL_SCALAR, MOJOSHADER_PRESHADEROP_ATAN2_SCALAR, MOJOSHADER_PRESHADEROP_DIV_SCALAR, MOJOSHADER_PRESHADEROP_DOT_SCALAR, MOJOSHADER_PRESHADEROP_NOISE_SCALAR } MOJOSHADER_preshaderOpcode; typedef enum MOJOSHADER_preshaderOperandType { MOJOSHADER_PRESHADEROPERAND_INPUT, MOJOSHADER_PRESHADEROPERAND_OUTPUT, MOJOSHADER_PRESHADEROPERAND_LITERAL, MOJOSHADER_PRESHADEROPERAND_TEMP } MOJOSHADER_preshaderOperandType; typedef struct MOJOSHADER_preshaderOperand { MOJOSHADER_preshaderOperandType type; unsigned int index; unsigned int array_register_count; unsigned int *array_registers; } MOJOSHADER_preshaderOperand; typedef struct MOJOSHADER_preshaderInstruction { MOJOSHADER_preshaderOpcode opcode; unsigned int element_count; unsigned int operand_count; MOJOSHADER_preshaderOperand operands[4]; } MOJOSHADER_preshaderInstruction; typedef struct MOJOSHADER_preshader { unsigned int literal_count; double *literals; unsigned int temp_count; /* scalar, not vector! */ unsigned int symbol_count; MOJOSHADER_symbol *symbols; unsigned int instruction_count; MOJOSHADER_preshaderInstruction *instructions; unsigned int register_count; float *registers; MOJOSHADER_malloc malloc; MOJOSHADER_free free; void *malloc_data; } MOJOSHADER_preshader; /* * Structure used to return data from parsing of a shader... */ /* !!! FIXME: most of these ints should be unsigned. */ typedef struct MOJOSHADER_parseData { /* * The number of elements pointed to by (errors). */ int error_count; /* * (error_count) elements of data that specify errors that were generated * by parsing this shader. * This can be NULL if there were no errors or if (error_count) is zero. */ MOJOSHADER_error *errors; /* * The name of the profile used to parse the shader. Will be NULL on error. */ const char *profile; /* * Bytes of output from parsing. Most profiles produce a string of source * code, but profiles that do binary output may not be text at all. * Will be NULL on error. */ const char *output; /* * Byte count for output, not counting any null terminator. Most profiles * produce an ASCII string of source code (which will be null-terminated * even though that null char isn't included in output_len), but profiles * that do binary output may not be text at all. Will be 0 on error. */ int output_len; /* * Count of Direct3D instruction slots used. This is meaningless in terms * of the actual output, as the profile will probably grow or reduce * the count (or for high-level languages, not have that information at * all). Also, as with Microsoft's own assembler, this value is just a * rough estimate, as unpredicable real-world factors make the actual * value vary at least a little from this count. Still, it can give you * a rough idea of the size of your shader. Will be zero on error. */ int instruction_count; /* * The type of shader we parsed. Will be MOJOSHADER_TYPE_UNKNOWN on error. */ MOJOSHADER_shaderType shader_type; /* * The shader's major version. If this was a "vs_3_0", this would be 3. */ int major_ver; /* * The shader's minor version. If this was a "ps_1_4", this would be 4. * Two notes: for "vs_2_x", this is 1, and for "vs_3_sw", this is 255. */ int minor_ver; /* * This is the main function name of the shader. This will be the * caller-supplied string even if a given profile ignores it (GLSL, * for example, always uses "main" in the shader output out of necessity, * and Direct3D assembly has no concept of a "main function", etc). * Otherwise, it'll be a default name chosen by the profile ("main") or * whatnot. */ const char *mainfn; /* * The number of elements pointed to by (uniforms). */ int uniform_count; /* * (uniform_count) elements of data that specify Uniforms to be set for * this shader. See discussion on MOJOSHADER_uniform for details. * This can be NULL on error or if (uniform_count) is zero. */ MOJOSHADER_uniform *uniforms; /* * The number of elements pointed to by (constants). */ int constant_count; /* * (constant_count) elements of data that specify constants used in * this shader. See discussion on MOJOSHADER_constant for details. * This can be NULL on error or if (constant_count) is zero. * This is largely informational: constants are hardcoded into a shader. * The constants that you can set like parameters are in the "uniforms" * list. */ MOJOSHADER_constant *constants; /* * The number of elements pointed to by (samplers). */ int sampler_count; /* * (sampler_count) elements of data that specify Samplers to be set for * this shader. See discussion on MOJOSHADER_sampler for details. * This can be NULL on error or if (sampler_count) is zero. */ MOJOSHADER_sampler *samplers; /* !!! FIXME: this should probably be "input" and not "attribute" */ /* * The number of elements pointed to by (attributes). */ int attribute_count; /* !!! FIXME: this should probably be "input" and not "attribute" */ /* * (attribute_count) elements of data that specify Attributes to be set * for this shader. See discussion on MOJOSHADER_attribute for details. * This can be NULL on error or if (attribute_count) is zero. */ MOJOSHADER_attribute *attributes; /* * The number of elements pointed to by (outputs). */ int output_count; /* * (output_count) elements of data that specify outputs this shader * writes to. See discussion on MOJOSHADER_attribute for details. * This can be NULL on error or if (output_count) is zero. */ MOJOSHADER_attribute *outputs; /* * The number of elements pointed to by (swizzles). */ int swizzle_count; /* !!! FIXME: this should probably be "input" and not "attribute" */ /* * (swizzle_count) elements of data that specify swizzles the shader will * apply to incoming attributes. This is a copy of what was passed to * MOJOSHADER_parseData(). * This can be NULL on error or if (swizzle_count) is zero. */ MOJOSHADER_swizzle *swizzles; /* * The number of elements pointed to by (symbols). */ int symbol_count; /* * (symbol_count) elements of data that specify high-level symbol data * for the shader. This will be parsed from the CTAB section * in bytecode, and will be a copy of what you provide to * MOJOSHADER_assemble(). This data is optional. * This can be NULL on error or if (symbol_count) is zero. */ MOJOSHADER_symbol *symbols; /* * !!! FIXME: document me. * This can be NULL on error or if no preshader was available. */ MOJOSHADER_preshader *preshader; /* * This is the malloc implementation you passed to MOJOSHADER_parse(). */ MOJOSHADER_malloc malloc; /* * This is the free implementation you passed to MOJOSHADER_parse(). */ MOJOSHADER_free free; /* * This is the pointer you passed as opaque data for your allocator. */ void *malloc_data; } MOJOSHADER_parseData; /* * Profile string for Direct3D assembly language output. */ #define MOJOSHADER_PROFILE_D3D "d3d" /* * Profile string for passthrough of the original bytecode, unchanged. */ #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. */ #define MOJOSHADER_PROFILE_GLSL "glsl" /* * Profile string for GLSL 1.20: minor improvements to base GLSL spec. */ #define MOJOSHADER_PROFILE_GLSL120 "glsl120" /* * Profile string for GLSL ES: minor changes to GLSL output for ES compliance. */ #define MOJOSHADER_PROFILE_GLSLES "glsles" /* * Profile string for OpenGL ARB 1.0 shaders: GL_ARB_(vertex|fragment)_program. */ #define MOJOSHADER_PROFILE_ARB1 "arb1" /* * Profile string for OpenGL ARB 1.0 shaders with Nvidia 2.0 extensions: * GL_NV_vertex_program2_option and GL_NV_fragment_program2 */ #define MOJOSHADER_PROFILE_NV2 "nv2" /* * Profile string for OpenGL ARB 1.0 shaders with Nvidia 3.0 extensions: * GL_NV_vertex_program3 and GL_NV_fragment_program2 */ #define MOJOSHADER_PROFILE_NV3 "nv3" /* * Profile string for OpenGL ARB 1.0 shaders with Nvidia 4.0 extensions: * GL_NV_gpu_program4 */ #define MOJOSHADER_PROFILE_NV4 "nv4" /* * Profile string for Metal: Apple's lowlevel API's high-level shader language. */ #define MOJOSHADER_PROFILE_METAL "metal" /* * Profile string for SPIR-V binary output */ #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. */ DECLSPEC int MOJOSHADER_maxShaderModel(const char *profile); /* * Parse a compiled Direct3D shader's bytecode. * * This is your primary entry point into MojoShader. You need to pass it * a compiled D3D shader and tell it which "profile" you want to use to * convert it into useful data. * * The available profiles are the set of MOJOSHADER_PROFILE_* defines. * Note that MojoShader may be built without support for all listed * profiles (in which case using one here will return with an error). * * As parsing 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 * (d) parameter. This pointer is passed as-is to your (m) and (f) functions. * * This function returns a MOJOSHADER_parseData. * * This function will never return NULL, even if the system is completely * out of memory upon entry (in which case, this function returns a static * MOJOSHADER_parseData object, which is still safe to pass to * MOJOSHADER_freeParseData()). * * You can tell the generated program to swizzle certain inputs. If you know * that COLOR0 should be RGBA but you're passing in ARGB, you can specify * a swizzle of { MOJOSHADER_USAGE_COLOR, 0, {1,2,3,0} } to (swiz). If the * input register in the code would produce reg.ywzx, that swizzle would * change it to reg.wzxy ... (swiz) can be NULL. * * You can force the shader to expect samplers of certain types. Generally * you don't need this, as Shader Model 2 and later always specify what they * expect samplers to be (2D, cubemap, etc). Shader Model 1, however, just * uses whatever is bound to a given sampler at draw time, but this doesn't * work in OpenGL, etc. In these cases, MojoShader will default to * 2D texture sampling (or cubemap sampling, in cases where it makes sense, * like the TEXM3X3TEX opcode), which works 75% of the time, but if you * really needed something else, you'll need to specify it here. This can * also be used, at your own risk, to override DCL opcodes in shaders: if * the shader explicit says 2D, but you want Cubemap, for example, you can * use this to override. If you aren't sure about any of this stuff, you can * (and should) almost certainly ignore it: (smap) can be NULL. * * (bufsize) is the size in bytes of (tokenbuf). If (bufsize) is zero, * MojoShader will attempt to figure out the size of the buffer, but you * risk a buffer overflow if you have corrupt data, etc. Supply the value * if you can. * * You should pass a name for your shader's main function in here, via the * (mainfn) param. Some profiles need this name to be unique. Passing a NULL * here will pick a reasonable default, and most profiles will ignore it * anyhow. As the name of the shader's main function, etc, so make it a * simple name that would match C's identifier rules. Keep it simple! * * This function is thread safe, so long as (m) and (f) are too, and that * (tokenbuf) remains intact for the duration of the call. This allows you * to parse several shaders on separate CPU cores at the same time. */ DECLSPEC const MOJOSHADER_parseData *MOJOSHADER_parse(const char *profile, 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, MOJOSHADER_malloc m, MOJOSHADER_free f, void *d); /* * Call this to dispose of parsing results when you are done with them. * This will call the MOJOSHADER_free function you provided to * MOJOSHADER_parse multiple times, if you provided one. * Passing a NULL here is a safe no-op. * * This function is thread safe, so long as any allocator you passed into * MOJOSHADER_parse() is, too. */ DECLSPEC void MOJOSHADER_freeParseData(const MOJOSHADER_parseData *data); /* * You almost certainly don't need this function, unless you absolutely know * why you need it without hesitation. This is useful if you're doing * extremely low-level shader work or building specialized tools. * * Parse a preshader structure. This expects a buffer of bytes that represents * the preshader data starting with its magic number token and ending at * the end of the comment tokens that contain this preshader. Note that it * does _not_ start at the beginning of the comment tokens. * * On success, this will return a MOJOSHADER_preshader. This can be * deallocated later by calling MOJOSHADER_freePreshader(). On failure, * this will return NULL. Unlike other MojoShader APIs, this assumes you * either have a complete and valid buffer of preshader tokens or you have * incomplete/corrupted data, so there is no explicit error reporting. Please * note that if the system runs out of memory, this function will also return * NULL without distinction. * * This function is thread safe, so long as any allocator you passed into * MOJOSHADER_parsePreshader() is, too. */ DECLSPEC const MOJOSHADER_preshader *MOJOSHADER_parsePreshader(const unsigned char *buf, const unsigned int len, MOJOSHADER_malloc m, MOJOSHADER_free f, void *d); /* * You almost certainly don't need this function, unless you absolutely know * why you need it without hesitation. This is useful if you're doing * extremely low-level shader work or building specialized tools. * * Call this to dispose of preshader parsing results when you are done with * them. This will call the MOJOSHADER_free function you provided to * MOJOSHADER_parsePreshader() multiple times, if you provided one. * Passing a NULL here is a safe no-op. * * You only need to call this function for results from a call to * MOJOSHADER_parsePreshader(). Other MojoShader structures with a preshader * field, such as MOJOSHADER_parseData(), should not use this function, as * the preshader will be deallocated with everything else in * MOJOSHADER_freeParseData(), etc. * * This function is thread safe, so long as any allocator you passed into * MOJOSHADER_parsePreshader() is, too. */ DECLSPEC void MOJOSHADER_freePreshader(const MOJOSHADER_preshader *preshader); /* Preprocessor interface... */ /* * Structure used to pass predefined macros. Maps to D3DXMACRO. * You can have macro arguments: set identifier to "a(b, c)" or whatever. */ typedef struct MOJOSHADER_preprocessorDefine { const char *identifier; const char *definition; } MOJOSHADER_preprocessorDefine; /* * Used with the MOJOSHADER_includeOpen callback. Maps to D3DXINCLUDE_TYPE. */ typedef enum { MOJOSHADER_INCLUDETYPE_LOCAL, /* local header: #include "blah.h" */ MOJOSHADER_INCLUDETYPE_SYSTEM /* system header: #include */ } MOJOSHADER_includeType; /* * Structure used to return data from preprocessing of a shader... */ /* !!! FIXME: most of these ints should be unsigned. */ typedef struct MOJOSHADER_preprocessData { /* * The number of elements pointed to by (errors). */ int error_count; /* * (error_count) elements of data that specify errors that were generated * by parsing this shader. * This can be NULL if there were no errors or if (error_count) is zero. */ MOJOSHADER_error *errors; /* * Bytes of output from preprocessing. This is a UTF-8 string. We * guarantee it to be NULL-terminated. Will be NULL on error. */ const char *output; /* * Byte count for output, not counting any null terminator. * Will be 0 on error. */ int output_len; /* * This is the malloc implementation you passed to MOJOSHADER_parse(). */ MOJOSHADER_malloc malloc; /* * This is the free implementation you passed to MOJOSHADER_parse(). */ MOJOSHADER_free free; /* * This is the pointer you passed as opaque data for your allocator. */ void *malloc_data; } MOJOSHADER_preprocessData; /* * This callback allows an app to handle #include statements for the * preprocessor. When the preprocessor sees an #include, it will call this * function to obtain the contents of the requested file. This is optional; * the preprocessor will open files directly if no callback is supplied, but * this allows an app to retrieve data from something other than the * traditional filesystem (for example, headers packed in a .zip file or * headers generated on-the-fly). * * This function maps to ID3DXInclude::Open() * * (inctype) specifies the type of header we wish to include. * (fname) specifies the name of the file specified on the #include line. * (parent) is a string of the entire source file containing the include, in * its original, not-yet-preprocessed state. Note that this is just the * contents of the specific file, not all source code that the preprocessor * has seen through other includes, etc. * (outdata) will be set by the callback to a pointer to the included file's * contents. The callback is responsible for allocating this however they * see fit (we provide allocator functions, but you may ignore them). This * pointer must remain valid until the includeClose callback runs. This * string does not need to be NULL-terminated. * (outbytes) will be set by the callback to the number of bytes pointed to * by (outdata). * (m),(f), and (d) are the allocator details that the application passed to * MojoShader. If these were NULL, MojoShader may have replaced them with its * own internal allocators. * * The callback returns zero on error, non-zero on success. * * If you supply an includeOpen callback, you must supply includeClose, too. */ typedef int (MOJOSHADERCALL *MOJOSHADER_includeOpen)(MOJOSHADER_includeType inctype, const char *fname, const char *parent, const char **outdata, unsigned int *outbytes, MOJOSHADER_malloc m, MOJOSHADER_free f, void *d); /* * This callback allows an app to clean up the results of a previous * includeOpen callback. * * This function maps to ID3DXInclude::Close() * * (data) is the data that was returned from a previous call to includeOpen. * It is now safe to deallocate this data. * (m),(f), and (d) are the same allocator details that were passed to your * includeOpen callback. * * If you supply an includeClose callback, you must supply includeOpen, too. */ typedef void (MOJOSHADERCALL *MOJOSHADER_includeClose)(const char *data, MOJOSHADER_malloc m, MOJOSHADER_free f, void *d); /* * This function is optional. Even if you are dealing with shader source * code, you don't need to explicitly use the preprocessor, as the compiler * and assembler will use it behind the scenes. In fact, you probably never * need this function unless you are debugging a custom tool (or debugging * MojoShader itself). * * Preprocessing roughly follows the syntax of an ANSI C preprocessor, as * Microsoft's Direct3D assembler and HLSL compiler use this syntax. Please * note that we try to match the output you'd get from Direct3D's * preprocessor, which has some quirks if you're expecting output that matches * a generic C preprocessor. * * This function maps to D3DXPreprocessShader(). * * (filename) is a NULL-terminated UTF-8 filename. It can be NULL. We do not * actually access this file, as we obtain our data from (source). This * string is copied when we need to report errors while processing (source), * as opposed to errors in a file referenced via the #include directive in * (source). If this is NULL, then errors will report the filename as NULL, * too. * * (source) is an string of UTF-8 text to preprocess. It does not need to be * NULL-terminated. * * (sourcelen) is the length of the string pointed to by (source), in bytes. * * (defines) points to (define_count) preprocessor definitions, and can be * NULL. These are treated by the preprocessor as if the source code started * with one #define for each entry you pass in here. * * (include_open) and (include_close) let the app control the preprocessor's * behaviour for #include statements. Both are optional and can be NULL, but * both must be specified if either is specified. * * This will return a MOJOSHADER_preprocessorData. You should pass this * return value to MOJOSHADER_freePreprocessData() when you are done with * it. * * This function will never return NULL, even if the system is completely * out of memory upon entry (in which case, this function returns a static * MOJOSHADER_preprocessData object, which is still safe to pass to * MOJOSHADER_freePreprocessData()). * * As preprocessing 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 * (d) parameter. This pointer is passed as-is to your (m) and (f) functions. * * This function is thread safe, so long as the various callback functions * are, too, and that the parameters remains intact for the duration of the * call. This allows you to preprocess several shaders on separate CPU cores * at the same time. */ DECLSPEC const MOJOSHADER_preprocessData *MOJOSHADER_preprocess(const char *filename, const char *source, unsigned int sourcelen, const MOJOSHADER_preprocessorDefine *defines, unsigned int define_count, MOJOSHADER_includeOpen include_open, MOJOSHADER_includeClose include_close, MOJOSHADER_malloc m, MOJOSHADER_free f, void *d); /* * Call this to dispose of preprocessing results when you are done with them. * This will call the MOJOSHADER_free function you provided to * MOJOSHADER_preprocess() multiple times, if you provided one. * Passing a NULL here is a safe no-op. * * This function is thread safe, so long as any allocator you passed into * MOJOSHADER_preprocess() is, too. */ DECLSPEC void MOJOSHADER_freePreprocessData(const MOJOSHADER_preprocessData *data); /* Assembler interface... */ /* * This function is optional. Use this to convert Direct3D shader assembly * language into bytecode, which can be handled by MOJOSHADER_parse(). * * (filename) is a NULL-terminated UTF-8 filename. It can be NULL. We do not * actually access this file, as we obtain our data from (source). This * string is copied when we need to report errors while processing (source), * as opposed to errors in a file referenced via the #include directive in * (source). If this is NULL, then errors will report the filename as NULL, * too. * * (source) is an UTF-8 string of valid Direct3D shader assembly source code. * It does not need to be NULL-terminated. * * (sourcelen) is the length of the string pointed to by (source), in bytes. * * (comments) points to (comment_count) NULL-terminated UTF-8 strings, and * can be NULL. These strings are inserted as comments in the bytecode. * * (symbols) points to (symbol_count) symbol structs, and can be NULL. These * become a CTAB field in the bytecode. This is optional, but * MOJOSHADER_parse() needs CTAB data for all arrays used in a program, or * relative addressing will not be permitted, so you'll want to at least * provide symbol information for those. The symbol data is 100% trusted * at this time; it will not be checked to see if it matches what was * assembled in any way whatsoever. * * (defines) points to (define_count) preprocessor definitions, and can be * NULL. These are treated by the preprocessor as if the source code started * with one #define for each entry you pass in here. * * (include_open) and (include_close) let the app control the preprocessor's * behaviour for #include statements. Both are optional and can be NULL, but * both must be specified if either is specified. * * This will return a MOJOSHADER_parseData, like MOJOSHADER_parse() would, * except the profile will be MOJOSHADER_PROFILE_BYTECODE and the output * will be the assembled bytecode instead of some other language. This output * can be pushed back through MOJOSHADER_parseData() with a different profile. * * This function will never return NULL, even if the system is completely * out of memory upon entry (in which case, this function returns a static * MOJOSHADER_parseData object, which is still safe to pass to * MOJOSHADER_freeParseData()). * * As assembling 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 * (d) parameter. This pointer is passed as-is to your (m) and (f) functions. * * This function is thread safe, so long as the various callback functions * are, too, and that the parameters remains intact for the duration of the * call. This allows you to assemble several shaders on separate CPU cores * at the same time. */ DECLSPEC const MOJOSHADER_parseData *MOJOSHADER_assemble(const char *filename, const char *source, unsigned int sourcelen, const char **comments, unsigned int comment_count, const MOJOSHADER_symbol *symbols, unsigned int symbol_count, const MOJOSHADER_preprocessorDefine *defines, unsigned int define_count, MOJOSHADER_includeOpen include_open, MOJOSHADER_includeClose include_close, MOJOSHADER_malloc m, MOJOSHADER_free f, void *d); /* High level shading language support... */ /* * Source profile strings for HLSL: Direct3D High Level Shading Language. */ #define MOJOSHADER_SRC_PROFILE_HLSL_VS_1_1 "hlsl_vs_1_1" #define MOJOSHADER_SRC_PROFILE_HLSL_VS_2_0 "hlsl_vs_2_0" #define MOJOSHADER_SRC_PROFILE_HLSL_VS_3_0 "hlsl_vs_3_0" #define MOJOSHADER_SRC_PROFILE_HLSL_PS_1_1 "hlsl_ps_1_1" #define MOJOSHADER_SRC_PROFILE_HLSL_PS_1_2 "hlsl_ps_1_2" #define MOJOSHADER_SRC_PROFILE_HLSL_PS_1_3 "hlsl_ps_1_3" #define MOJOSHADER_SRC_PROFILE_HLSL_PS_1_4 "hlsl_ps_1_4" #define MOJOSHADER_SRC_PROFILE_HLSL_PS_2_0 "hlsl_ps_2_0" #define MOJOSHADER_SRC_PROFILE_HLSL_PS_3_0 "hlsl_ps_3_0" /* Abstract Syntax Tree interface... */ /* * ATTENTION: This adds a lot of stuff to the API, but almost everyone can * ignore this section. Seriously, go ahead and skip over anything that has * "AST" in it, unless you know why you'd want to use it. * * ALSO: This API is still evolving! We make no promises at this time to keep * source or binary compatibility for the AST pieces. * * Important notes: * - ASTs are the result of parsing the source code: a program that fails to * compile will often parse successfully. Undeclared variables, * type incompatibilities, etc, aren't detected at this point. * - Vector swizzles (the ".xyzw" part of "MyVec4.xyzw") will look like * structure dereferences. We don't realize these are actually swizzles * until semantic analysis. * - MOJOSHADER_astDataType info is not reliable when returned from * MOJOSHADER_parseAst()! Most of the datatype info will be missing or have * inaccurate data types. We sort these out during semantic analysis, which * happens after the AST parsing is complete. A few are filled in, or can * be deduced fairly trivially by processing several pieces into one. * It's enough that you can reproduce the original source code, more or * less, from the AST. */ /* High-level datatypes for AST nodes. */ typedef enum MOJOSHADER_astDataTypeType { MOJOSHADER_AST_DATATYPE_NONE, MOJOSHADER_AST_DATATYPE_BOOL, MOJOSHADER_AST_DATATYPE_INT, MOJOSHADER_AST_DATATYPE_UINT, MOJOSHADER_AST_DATATYPE_FLOAT, MOJOSHADER_AST_DATATYPE_FLOAT_SNORM, MOJOSHADER_AST_DATATYPE_FLOAT_UNORM, MOJOSHADER_AST_DATATYPE_HALF, MOJOSHADER_AST_DATATYPE_DOUBLE, MOJOSHADER_AST_DATATYPE_STRING, MOJOSHADER_AST_DATATYPE_SAMPLER_1D, MOJOSHADER_AST_DATATYPE_SAMPLER_2D, MOJOSHADER_AST_DATATYPE_SAMPLER_3D, MOJOSHADER_AST_DATATYPE_SAMPLER_CUBE, MOJOSHADER_AST_DATATYPE_SAMPLER_STATE, MOJOSHADER_AST_DATATYPE_SAMPLER_COMPARISON_STATE, MOJOSHADER_AST_DATATYPE_STRUCT, MOJOSHADER_AST_DATATYPE_ARRAY, MOJOSHADER_AST_DATATYPE_VECTOR, MOJOSHADER_AST_DATATYPE_MATRIX, MOJOSHADER_AST_DATATYPE_BUFFER, MOJOSHADER_AST_DATATYPE_FUNCTION, MOJOSHADER_AST_DATATYPE_USER } MOJOSHADER_astDataTypeType; #define MOJOSHADER_AST_DATATYPE_CONST (1 << 31) typedef union MOJOSHADER_astDataType MOJOSHADER_astDataType; /* This is just part of DataTypeStruct, never appears outside of it. */ typedef struct MOJOSHADER_astDataTypeStructMember { const MOJOSHADER_astDataType *datatype; const char *identifier; } MOJOSHADER_astDataTypeStructMember; typedef struct MOJOSHADER_astDataTypeStruct { MOJOSHADER_astDataTypeType type; const MOJOSHADER_astDataTypeStructMember *members; int member_count; } MOJOSHADER_astDataTypeStruct; typedef struct MOJOSHADER_astDataTypeArray { MOJOSHADER_astDataTypeType type; const MOJOSHADER_astDataType *base; int elements; } MOJOSHADER_astDataTypeArray; typedef MOJOSHADER_astDataTypeArray MOJOSHADER_astDataTypeVector; typedef struct MOJOSHADER_astDataTypeMatrix { MOJOSHADER_astDataTypeType type; const MOJOSHADER_astDataType *base; int rows; int columns; } MOJOSHADER_astDataTypeMatrix; typedef struct MOJOSHADER_astDataTypeBuffer { MOJOSHADER_astDataTypeType type; const MOJOSHADER_astDataType *base; } MOJOSHADER_astDataTypeBuffer; typedef struct MOJOSHADER_astDataTypeFunction { MOJOSHADER_astDataTypeType type; const MOJOSHADER_astDataType *retval; const MOJOSHADER_astDataType **params; int num_params; int intrinsic; /* non-zero for built-in functions */ } MOJOSHADER_astDataTypeFunction; typedef struct MOJOSHADER_astDataTypeUser { MOJOSHADER_astDataTypeType type; const MOJOSHADER_astDataType *details; const char *name; } MOJOSHADER_astDataTypeUser; union MOJOSHADER_astDataType { MOJOSHADER_astDataTypeType type; MOJOSHADER_astDataTypeArray array; MOJOSHADER_astDataTypeStruct structure; MOJOSHADER_astDataTypeVector vector; MOJOSHADER_astDataTypeMatrix matrix; MOJOSHADER_astDataTypeBuffer buffer; MOJOSHADER_astDataTypeUser user; MOJOSHADER_astDataTypeFunction function; }; /* Structures that make up the parse tree... */ typedef enum MOJOSHADER_astNodeType { MOJOSHADER_AST_OP_START_RANGE, /* expression operators. */ MOJOSHADER_AST_OP_START_RANGE_UNARY, /* unary operators. */ MOJOSHADER_AST_OP_PREINCREMENT, MOJOSHADER_AST_OP_PREDECREMENT, MOJOSHADER_AST_OP_NEGATE, MOJOSHADER_AST_OP_COMPLEMENT, MOJOSHADER_AST_OP_NOT, MOJOSHADER_AST_OP_POSTINCREMENT, MOJOSHADER_AST_OP_POSTDECREMENT, MOJOSHADER_AST_OP_CAST, MOJOSHADER_AST_OP_END_RANGE_UNARY, MOJOSHADER_AST_OP_START_RANGE_BINARY, /* binary operators. */ MOJOSHADER_AST_OP_COMMA, MOJOSHADER_AST_OP_MULTIPLY, MOJOSHADER_AST_OP_DIVIDE, MOJOSHADER_AST_OP_MODULO, MOJOSHADER_AST_OP_ADD, MOJOSHADER_AST_OP_SUBTRACT, MOJOSHADER_AST_OP_LSHIFT, MOJOSHADER_AST_OP_RSHIFT, MOJOSHADER_AST_OP_LESSTHAN, MOJOSHADER_AST_OP_GREATERTHAN, MOJOSHADER_AST_OP_LESSTHANOREQUAL, MOJOSHADER_AST_OP_GREATERTHANOREQUAL, MOJOSHADER_AST_OP_EQUAL, MOJOSHADER_AST_OP_NOTEQUAL, MOJOSHADER_AST_OP_BINARYAND, MOJOSHADER_AST_OP_BINARYXOR, MOJOSHADER_AST_OP_BINARYOR, MOJOSHADER_AST_OP_LOGICALAND, MOJOSHADER_AST_OP_LOGICALOR, MOJOSHADER_AST_OP_ASSIGN, MOJOSHADER_AST_OP_MULASSIGN, MOJOSHADER_AST_OP_DIVASSIGN, MOJOSHADER_AST_OP_MODASSIGN, MOJOSHADER_AST_OP_ADDASSIGN, MOJOSHADER_AST_OP_SUBASSIGN, MOJOSHADER_AST_OP_LSHIFTASSIGN, MOJOSHADER_AST_OP_RSHIFTASSIGN, MOJOSHADER_AST_OP_ANDASSIGN, MOJOSHADER_AST_OP_XORASSIGN, MOJOSHADER_AST_OP_ORASSIGN, MOJOSHADER_AST_OP_DEREF_ARRAY, MOJOSHADER_AST_OP_END_RANGE_BINARY, MOJOSHADER_AST_OP_START_RANGE_TERNARY, /* ternary operators. */ MOJOSHADER_AST_OP_CONDITIONAL, MOJOSHADER_AST_OP_END_RANGE_TERNARY, MOJOSHADER_AST_OP_START_RANGE_DATA, /* expression operands. */ MOJOSHADER_AST_OP_IDENTIFIER, MOJOSHADER_AST_OP_INT_LITERAL, MOJOSHADER_AST_OP_FLOAT_LITERAL, MOJOSHADER_AST_OP_STRING_LITERAL, MOJOSHADER_AST_OP_BOOLEAN_LITERAL, MOJOSHADER_AST_OP_END_RANGE_DATA, MOJOSHADER_AST_OP_START_RANGE_MISC, /* other expression things. */ MOJOSHADER_AST_OP_DEREF_STRUCT, MOJOSHADER_AST_OP_CALLFUNC, MOJOSHADER_AST_OP_CONSTRUCTOR, MOJOSHADER_AST_OP_END_RANGE_MISC, MOJOSHADER_AST_OP_END_RANGE, MOJOSHADER_AST_COMPUNIT_START_RANGE, /* things in global scope. */ MOJOSHADER_AST_COMPUNIT_FUNCTION, MOJOSHADER_AST_COMPUNIT_TYPEDEF, MOJOSHADER_AST_COMPUNIT_STRUCT, MOJOSHADER_AST_COMPUNIT_VARIABLE, MOJOSHADER_AST_COMPUNIT_END_RANGE, MOJOSHADER_AST_STATEMENT_START_RANGE, /* statements in function scope. */ MOJOSHADER_AST_STATEMENT_EMPTY, MOJOSHADER_AST_STATEMENT_BREAK, MOJOSHADER_AST_STATEMENT_CONTINUE, MOJOSHADER_AST_STATEMENT_DISCARD, MOJOSHADER_AST_STATEMENT_BLOCK, MOJOSHADER_AST_STATEMENT_EXPRESSION, MOJOSHADER_AST_STATEMENT_IF, MOJOSHADER_AST_STATEMENT_SWITCH, MOJOSHADER_AST_STATEMENT_FOR, MOJOSHADER_AST_STATEMENT_DO, MOJOSHADER_AST_STATEMENT_WHILE, MOJOSHADER_AST_STATEMENT_RETURN, MOJOSHADER_AST_STATEMENT_TYPEDEF, MOJOSHADER_AST_STATEMENT_STRUCT, MOJOSHADER_AST_STATEMENT_VARDECL, MOJOSHADER_AST_STATEMENT_END_RANGE, MOJOSHADER_AST_MISC_START_RANGE, /* misc. syntactic glue. */ MOJOSHADER_AST_FUNCTION_PARAMS, MOJOSHADER_AST_FUNCTION_SIGNATURE, MOJOSHADER_AST_SCALAR_OR_ARRAY, MOJOSHADER_AST_TYPEDEF, MOJOSHADER_AST_PACK_OFFSET, MOJOSHADER_AST_VARIABLE_LOWLEVEL, MOJOSHADER_AST_ANNOTATION, MOJOSHADER_AST_VARIABLE_DECLARATION, MOJOSHADER_AST_STRUCT_DECLARATION, MOJOSHADER_AST_STRUCT_MEMBER, MOJOSHADER_AST_SWITCH_CASE, MOJOSHADER_AST_ARGUMENTS, MOJOSHADER_AST_MISC_END_RANGE, MOJOSHADER_AST_END_RANGE } MOJOSHADER_astNodeType; typedef struct MOJOSHADER_astNodeInfo { MOJOSHADER_astNodeType type; const char *filename; unsigned int line; } MOJOSHADER_astNodeInfo; typedef enum MOJOSHADER_astVariableAttributes { MOJOSHADER_AST_VARATTR_EXTERN = (1 << 0), MOJOSHADER_AST_VARATTR_NOINTERPOLATION = (1 << 1), MOJOSHADER_AST_VARATTR_SHARED = (1 << 2), MOJOSHADER_AST_VARATTR_STATIC = (1 << 3), MOJOSHADER_AST_VARATTR_UNIFORM = (1 << 4), MOJOSHADER_AST_VARATTR_VOLATILE = (1 << 5), MOJOSHADER_AST_VARATTR_CONST = (1 << 6), MOJOSHADER_AST_VARATTR_ROWMAJOR = (1 << 7), MOJOSHADER_AST_VARATTR_COLUMNMAJOR = (1 << 8) } MOJOSHADER_astVariableAttributes; typedef enum MOJOSHADER_astIfAttributes { MOJOSHADER_AST_IFATTR_NONE, MOJOSHADER_AST_IFATTR_BRANCH, MOJOSHADER_AST_IFATTR_FLATTEN, MOJOSHADER_AST_IFATTR_IFALL, MOJOSHADER_AST_IFATTR_IFANY, MOJOSHADER_AST_IFATTR_PREDICATE, MOJOSHADER_AST_IFATTR_PREDICATEBLOCK } MOJOSHADER_astIfAttributes; typedef enum MOJOSHADER_astSwitchAttributes { MOJOSHADER_AST_SWITCHATTR_NONE, MOJOSHADER_AST_SWITCHATTR_FLATTEN, MOJOSHADER_AST_SWITCHATTR_BRANCH, MOJOSHADER_AST_SWITCHATTR_FORCECASE, MOJOSHADER_AST_SWITCHATTR_CALL } MOJOSHADER_astSwitchAttributes; /* You can cast any AST node pointer to this. */ typedef struct MOJOSHADER_astGeneric { MOJOSHADER_astNodeInfo ast; } MOJOSHADER_astGeneric; typedef struct MOJOSHADER_astExpression { MOJOSHADER_astNodeInfo ast; const MOJOSHADER_astDataType *datatype; } MOJOSHADER_astExpression; typedef struct MOJOSHADER_astArguments { MOJOSHADER_astNodeInfo ast; /* Always MOJOSHADER_AST_ARGUMENTS */ MOJOSHADER_astExpression *argument; struct MOJOSHADER_astArguments *next; } MOJOSHADER_astArguments; typedef struct MOJOSHADER_astExpressionUnary { MOJOSHADER_astNodeInfo ast; const MOJOSHADER_astDataType *datatype; MOJOSHADER_astExpression *operand; } MOJOSHADER_astExpressionUnary; typedef struct MOJOSHADER_astExpressionBinary { MOJOSHADER_astNodeInfo ast; const MOJOSHADER_astDataType *datatype; MOJOSHADER_astExpression *left; MOJOSHADER_astExpression *right; } MOJOSHADER_astExpressionBinary; typedef struct MOJOSHADER_astExpressionTernary { MOJOSHADER_astNodeInfo ast; const MOJOSHADER_astDataType *datatype; MOJOSHADER_astExpression *left; MOJOSHADER_astExpression *center; MOJOSHADER_astExpression *right; } MOJOSHADER_astExpressionTernary; /* Identifier indexes aren't available until semantic analysis phase completes. * It provides a unique id for this identifier's variable. * It will be negative for global scope, positive for function scope * (global values are globally unique, function values are only * unique within the scope of the given function). There's a different * set of indices if this identifier is a function (positive for * user-defined functions, negative for intrinsics). * May be zero for various reasons (unknown identifier, etc). */ typedef struct MOJOSHADER_astExpressionIdentifier { MOJOSHADER_astNodeInfo ast; /* Always MOJOSHADER_AST_OP_IDENTIFIER */ const MOJOSHADER_astDataType *datatype; const char *identifier; int index; } MOJOSHADER_astExpressionIdentifier; typedef struct MOJOSHADER_astExpressionIntLiteral { MOJOSHADER_astNodeInfo ast; /* Always MOJOSHADER_AST_OP_INT_LITERAL */ const MOJOSHADER_astDataType *datatype; /* always AST_DATATYPE_INT */ int value; } MOJOSHADER_astExpressionIntLiteral; typedef struct MOJOSHADER_astExpressionFloatLiteral { MOJOSHADER_astNodeInfo ast; /* Always MOJOSHADER_AST_OP_FLOAT_LITERAL */ const MOJOSHADER_astDataType *datatype; /* always AST_DATATYPE_FLOAT */ double value; } MOJOSHADER_astExpressionFloatLiteral; typedef struct MOJOSHADER_astExpressionStringLiteral { MOJOSHADER_astNodeInfo ast; /* Always MOJOSHADER_AST_OP_STRING_LITERAL */ const MOJOSHADER_astDataType *datatype; /* always AST_DATATYPE_STRING */ const char *string; } MOJOSHADER_astExpressionStringLiteral; typedef struct MOJOSHADER_astExpressionBooleanLiteral { MOJOSHADER_astNodeInfo ast; /* Always MOJOSHADER_AST_OP_BOOLEAN_LITERAL */ const MOJOSHADER_astDataType *datatype; /* always AST_DATATYPE_BOOL */ int value; /* Always 1 or 0. */ } MOJOSHADER_astExpressionBooleanLiteral; typedef struct MOJOSHADER_astExpressionConstructor { MOJOSHADER_astNodeInfo ast; /* Always MOJOSHADER_AST_OP_CONSTRUCTOR */ const MOJOSHADER_astDataType *datatype; MOJOSHADER_astArguments *args; } MOJOSHADER_astExpressionConstructor; typedef struct MOJOSHADER_astExpressionDerefStruct { MOJOSHADER_astNodeInfo ast; /* Always MOJOSHADER_AST_OP_DEREF_STRUCT */ const MOJOSHADER_astDataType *datatype; /* !!! FIXME: * "identifier" is misnamed; this might not be an identifier at all: * x = FunctionThatReturnsAStruct().SomeMember; */ MOJOSHADER_astExpression *identifier; const char *member; int isswizzle; /* Always 1 or 0. Never set by parseAst()! */ int member_index; /* Never set by parseAst()! */ } MOJOSHADER_astExpressionDerefStruct; typedef struct MOJOSHADER_astExpressionCallFunction { MOJOSHADER_astNodeInfo ast; /* Always MOJOSHADER_AST_OP_CALLFUNC */ const MOJOSHADER_astDataType *datatype; MOJOSHADER_astExpressionIdentifier *identifier; MOJOSHADER_astArguments *args; } MOJOSHADER_astExpressionCallFunction; typedef struct MOJOSHADER_astExpressionCast { MOJOSHADER_astNodeInfo ast; /* Always MOJOSHADER_AST_OP_CAST */ const MOJOSHADER_astDataType *datatype; MOJOSHADER_astExpression *operand; } MOJOSHADER_astExpressionCast; typedef struct MOJOSHADER_astCompilationUnit { MOJOSHADER_astNodeInfo ast; struct MOJOSHADER_astCompilationUnit *next; } MOJOSHADER_astCompilationUnit; typedef enum MOJOSHADER_astFunctionStorageClass { MOJOSHADER_AST_FNSTORECLS_NONE, MOJOSHADER_AST_FNSTORECLS_INLINE } MOJOSHADER_astFunctionStorageClass; typedef enum MOJOSHADER_astInputModifier { MOJOSHADER_AST_INPUTMOD_NONE, MOJOSHADER_AST_INPUTMOD_IN, MOJOSHADER_AST_INPUTMOD_OUT, MOJOSHADER_AST_INPUTMOD_INOUT, MOJOSHADER_AST_INPUTMOD_UNIFORM } MOJOSHADER_astInputModifier; typedef enum MOJOSHADER_astInterpolationModifier { MOJOSHADER_AST_INTERPMOD_NONE, MOJOSHADER_AST_INTERPMOD_LINEAR, MOJOSHADER_AST_INTERPMOD_CENTROID, MOJOSHADER_AST_INTERPMOD_NOINTERPOLATION, MOJOSHADER_AST_INTERPMOD_NOPERSPECTIVE, MOJOSHADER_AST_INTERPMOD_SAMPLE } MOJOSHADER_astInterpolationModifier; typedef struct MOJOSHADER_astFunctionParameters { MOJOSHADER_astNodeInfo ast; const MOJOSHADER_astDataType *datatype; MOJOSHADER_astInputModifier input_modifier; const char *identifier; const char *semantic; MOJOSHADER_astInterpolationModifier interpolation_modifier; MOJOSHADER_astExpression *initializer; struct MOJOSHADER_astFunctionParameters *next; } MOJOSHADER_astFunctionParameters; typedef struct MOJOSHADER_astFunctionSignature { MOJOSHADER_astNodeInfo ast; const MOJOSHADER_astDataType *datatype; const char *identifier; MOJOSHADER_astFunctionParameters *params; MOJOSHADER_astFunctionStorageClass storage_class; const char *semantic; } MOJOSHADER_astFunctionSignature; typedef struct MOJOSHADER_astScalarOrArray { MOJOSHADER_astNodeInfo ast; const char *identifier; int isarray; /* boolean: 1 or 0 */ MOJOSHADER_astExpression *dimension; } MOJOSHADER_astScalarOrArray; typedef struct MOJOSHADER_astAnnotations { MOJOSHADER_astNodeInfo ast; const MOJOSHADER_astDataType *datatype; MOJOSHADER_astExpression *initializer; struct MOJOSHADER_astAnnotations *next; } MOJOSHADER_astAnnotations; typedef struct MOJOSHADER_astPackOffset { MOJOSHADER_astNodeInfo ast; const char *ident1; /* !!! FIXME: rename this. */ const char *ident2; } MOJOSHADER_astPackOffset; typedef struct MOJOSHADER_astVariableLowLevel { MOJOSHADER_astNodeInfo ast; MOJOSHADER_astPackOffset *packoffset; const char *register_name; } MOJOSHADER_astVariableLowLevel; typedef struct MOJOSHADER_astStructMembers { MOJOSHADER_astNodeInfo ast; const MOJOSHADER_astDataType *datatype; const char *semantic; MOJOSHADER_astScalarOrArray *details; MOJOSHADER_astInterpolationModifier interpolation_mod; struct MOJOSHADER_astStructMembers *next; } MOJOSHADER_astStructMembers; typedef struct MOJOSHADER_astStructDeclaration { MOJOSHADER_astNodeInfo ast; const MOJOSHADER_astDataType *datatype; const char *name; MOJOSHADER_astStructMembers *members; } MOJOSHADER_astStructDeclaration; typedef struct MOJOSHADER_astVariableDeclaration { MOJOSHADER_astNodeInfo ast; int attributes; const MOJOSHADER_astDataType *datatype; MOJOSHADER_astStructDeclaration *anonymous_datatype; MOJOSHADER_astScalarOrArray *details; const char *semantic; MOJOSHADER_astAnnotations *annotations; MOJOSHADER_astExpression *initializer; MOJOSHADER_astVariableLowLevel *lowlevel; struct MOJOSHADER_astVariableDeclaration *next; } MOJOSHADER_astVariableDeclaration; typedef struct MOJOSHADER_astStatement { MOJOSHADER_astNodeInfo ast; struct MOJOSHADER_astStatement *next; } MOJOSHADER_astStatement; typedef MOJOSHADER_astStatement MOJOSHADER_astEmptyStatement; typedef MOJOSHADER_astStatement MOJOSHADER_astBreakStatement; typedef MOJOSHADER_astStatement MOJOSHADER_astContinueStatement; typedef MOJOSHADER_astStatement MOJOSHADER_astDiscardStatement; /* something enclosed in "{}" braces. */ typedef struct MOJOSHADER_astBlockStatement { MOJOSHADER_astNodeInfo ast; MOJOSHADER_astStatement *next; MOJOSHADER_astStatement *statements; /* list of child statements. */ } MOJOSHADER_astBlockStatement; typedef struct MOJOSHADER_astReturnStatement { MOJOSHADER_astNodeInfo ast; MOJOSHADER_astStatement *next; MOJOSHADER_astExpression *expr; } MOJOSHADER_astReturnStatement; typedef struct MOJOSHADER_astExpressionStatement { MOJOSHADER_astNodeInfo ast; MOJOSHADER_astStatement *next; MOJOSHADER_astExpression *expr; } MOJOSHADER_astExpressionStatement; typedef struct MOJOSHADER_astIfStatement { MOJOSHADER_astNodeInfo ast; MOJOSHADER_astStatement *next; int attributes; MOJOSHADER_astExpression *expr; MOJOSHADER_astStatement *statement; MOJOSHADER_astStatement *else_statement; } MOJOSHADER_astIfStatement; typedef struct MOJOSHADER_astSwitchCases { MOJOSHADER_astNodeInfo ast; MOJOSHADER_astExpression *expr; MOJOSHADER_astStatement *statement; struct MOJOSHADER_astSwitchCases *next; } MOJOSHADER_astSwitchCases; typedef struct MOJOSHADER_astSwitchStatement { MOJOSHADER_astNodeInfo ast; MOJOSHADER_astStatement *next; int attributes; MOJOSHADER_astExpression *expr; MOJOSHADER_astSwitchCases *cases; } MOJOSHADER_astSwitchStatement; typedef struct MOJOSHADER_astWhileStatement { MOJOSHADER_astNodeInfo ast; MOJOSHADER_astStatement *next; int unroll; /* # times to unroll, 0 to loop, < 0 == compiler's choice. */ MOJOSHADER_astExpression *expr; MOJOSHADER_astStatement *statement; } MOJOSHADER_astWhileStatement; typedef MOJOSHADER_astWhileStatement MOJOSHADER_astDoStatement; typedef struct MOJOSHADER_astForStatement { MOJOSHADER_astNodeInfo ast; MOJOSHADER_astStatement *next; int unroll; /* # times to unroll, 0 to loop, < 0 == compiler's choice. */ MOJOSHADER_astVariableDeclaration *var_decl; /* either this ... */ MOJOSHADER_astExpression *initializer; /* ... or this will used. */ MOJOSHADER_astExpression *looptest; MOJOSHADER_astExpression *counter; MOJOSHADER_astStatement *statement; } MOJOSHADER_astForStatement; typedef struct MOJOSHADER_astTypedef { MOJOSHADER_astNodeInfo ast; const MOJOSHADER_astDataType *datatype; int isconst; /* boolean: 1 or 0 */ MOJOSHADER_astScalarOrArray *details; } MOJOSHADER_astTypedef; typedef struct MOJOSHADER_astTypedefStatement { MOJOSHADER_astNodeInfo ast; MOJOSHADER_astStatement *next; MOJOSHADER_astTypedef *type_info; } MOJOSHADER_astTypedefStatement; typedef struct MOJOSHADER_astVarDeclStatement { MOJOSHADER_astNodeInfo ast; MOJOSHADER_astStatement *next; MOJOSHADER_astVariableDeclaration *declaration; } MOJOSHADER_astVarDeclStatement; typedef struct MOJOSHADER_astStructStatement { MOJOSHADER_astNodeInfo ast; MOJOSHADER_astStatement *next; MOJOSHADER_astStructDeclaration *struct_info; } MOJOSHADER_astStructStatement; typedef struct MOJOSHADER_astCompilationUnitFunction { MOJOSHADER_astNodeInfo ast; MOJOSHADER_astCompilationUnit *next; MOJOSHADER_astFunctionSignature *declaration; MOJOSHADER_astStatement *definition; int index; /* unique id. Will be 0 until semantic analysis runs. */ } MOJOSHADER_astCompilationUnitFunction; typedef struct MOJOSHADER_astCompilationUnitTypedef { MOJOSHADER_astNodeInfo ast; MOJOSHADER_astCompilationUnit *next; MOJOSHADER_astTypedef *type_info; } MOJOSHADER_astCompilationUnitTypedef; typedef struct MOJOSHADER_astCompilationUnitStruct { MOJOSHADER_astNodeInfo ast; MOJOSHADER_astCompilationUnit *next; MOJOSHADER_astStructDeclaration *struct_info; } MOJOSHADER_astCompilationUnitStruct; typedef struct MOJOSHADER_astCompilationUnitVariable { MOJOSHADER_astNodeInfo ast; MOJOSHADER_astCompilationUnit *next; MOJOSHADER_astVariableDeclaration *declaration; } MOJOSHADER_astCompilationUnitVariable; /* this is way cleaner than all the nasty typecasting. */ typedef union MOJOSHADER_astNode { MOJOSHADER_astNodeInfo ast; MOJOSHADER_astGeneric generic; MOJOSHADER_astExpression expression; MOJOSHADER_astArguments arguments; MOJOSHADER_astExpressionUnary unary; MOJOSHADER_astExpressionBinary binary; MOJOSHADER_astExpressionTernary ternary; MOJOSHADER_astExpressionIdentifier identifier; MOJOSHADER_astExpressionIntLiteral intliteral; MOJOSHADER_astExpressionFloatLiteral floatliteral; MOJOSHADER_astExpressionStringLiteral stringliteral; MOJOSHADER_astExpressionBooleanLiteral boolliteral; MOJOSHADER_astExpressionConstructor constructor; MOJOSHADER_astExpressionDerefStruct derefstruct; MOJOSHADER_astExpressionCallFunction callfunc; MOJOSHADER_astExpressionCast cast; MOJOSHADER_astCompilationUnit compunit; MOJOSHADER_astFunctionParameters params; MOJOSHADER_astFunctionSignature funcsig; MOJOSHADER_astScalarOrArray soa; MOJOSHADER_astAnnotations annotations; MOJOSHADER_astPackOffset packoffset; MOJOSHADER_astVariableLowLevel varlowlevel; MOJOSHADER_astStructMembers structmembers; MOJOSHADER_astStructDeclaration structdecl; MOJOSHADER_astVariableDeclaration vardecl; MOJOSHADER_astStatement stmt; MOJOSHADER_astEmptyStatement emptystmt; MOJOSHADER_astBreakStatement breakstmt; MOJOSHADER_astContinueStatement contstmt; MOJOSHADER_astDiscardStatement discardstmt; MOJOSHADER_astBlockStatement blockstmt; MOJOSHADER_astReturnStatement returnstmt; MOJOSHADER_astExpressionStatement exprstmt; MOJOSHADER_astIfStatement ifstmt; MOJOSHADER_astSwitchCases cases; MOJOSHADER_astSwitchStatement switchstmt; MOJOSHADER_astWhileStatement whilestmt; MOJOSHADER_astDoStatement dostmt; MOJOSHADER_astForStatement forstmt; MOJOSHADER_astTypedef typdef; MOJOSHADER_astTypedefStatement typedefstmt; MOJOSHADER_astVarDeclStatement vardeclstmt; MOJOSHADER_astStructStatement structstmt; MOJOSHADER_astCompilationUnitFunction funcunit; MOJOSHADER_astCompilationUnitTypedef typedefunit; MOJOSHADER_astCompilationUnitStruct structunit; MOJOSHADER_astCompilationUnitVariable varunit; } MOJOSHADER_astNode; /* * Structure used to return data from parsing of a shader into an AST... */ /* !!! FIXME: most of these ints should be unsigned. */ typedef struct MOJOSHADER_astData { /* * The number of elements pointed to by (errors). */ int error_count; /* * (error_count) elements of data that specify errors that were generated * by parsing this shader. * This can be NULL if there were no errors or if (error_count) is zero. * Note that this will only produce errors for syntax problems. Most of * the things we expect a compiler to produce errors for--incompatible * types, unknown identifiers, etc--are not checked at all during * initial generation of the syntax tree...bogus programs that would * fail to compile will pass here without error, if they are syntactically * correct! */ MOJOSHADER_error *errors; /* * The name of the source profile used to parse the shader. Will be NULL * on error. */ const char *source_profile; /* * The actual syntax tree. You are responsible for walking it yourself. * CompilationUnits are always the top of the tree (functions, typedefs, * global variables, etc). Will be NULL on error. */ const MOJOSHADER_astNode *ast; /* * This is the malloc implementation you passed to MOJOSHADER_parse(). */ MOJOSHADER_malloc malloc; /* * This is the free implementation you passed to MOJOSHADER_parse(). */ MOJOSHADER_free free; /* * This is the pointer you passed as opaque data for your allocator. */ void *malloc_data; /* * This is internal data, and not for the application to touch. */ void *opaque; } MOJOSHADER_astData; /* * You almost certainly don't need this function, unless you absolutely know * why you need it without hesitation. This is almost certainly only good for * building code analysis tools on top of. * * This is intended to parse HLSL source code, turning it into an abstract * syntax tree. * * (srcprofile) specifies the source language of the shader. You can specify * a shader model with this, too. See MOJOSHADER_SRC_PROFILE_* constants. * * (filename) is a NULL-terminated UTF-8 filename. It can be NULL. We do not * actually access this file, as we obtain our data from (source). This * string is copied when we need to report errors while processing (source), * as opposed to errors in a file referenced via the #include directive in * (source). If this is NULL, then errors will report the filename as NULL, * too. * * (source) is an UTF-8 string of valid high-level shader source code. * It does not need to be NULL-terminated. * * (sourcelen) is the length of the string pointed to by (source), in bytes. * * (defines) points to (define_count) preprocessor definitions, and can be * NULL. These are treated by the preprocessor as if the source code started * with one #define for each entry you pass in here. * * (include_open) and (include_close) let the app control the preprocessor's * behaviour for #include statements. Both are optional and can be NULL, but * both must be specified if either is specified. * * This will return a MOJOSHADER_astData. The data supplied here gives the * application a tree-like structure they can walk to see the layout of * a given program. When you are done with this data, pass it to * MOJOSHADER_freeCompileData() to deallocate resources. * * This function will never return NULL, even if the system is completely * out of memory upon entry (in which case, this function returns a static * MOJOSHADER_astData object, which is still safe to pass to * MOJOSHADER_freeAstData()). * * As parsing 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 * (d) parameter. This pointer is passed as-is to your (m) and (f) functions. * * This function is thread safe, so long as the various callback functions * are, too, and that the parameters remains intact for the duration of the * call. This allows you to parse several shaders on separate CPU cores * at the same time. */ DECLSPEC const MOJOSHADER_astData *MOJOSHADER_parseAst(const char *srcprofile, const char *filename, const char *source, unsigned int sourcelen, const MOJOSHADER_preprocessorDefine *defs, unsigned int define_count, MOJOSHADER_includeOpen include_open, MOJOSHADER_includeClose include_close, MOJOSHADER_malloc m, MOJOSHADER_free f, void *d); /* !!! FIXME: expose semantic analysis to the public API? */ /* * Call this to dispose of AST parsing results when you are done with them. * This will call the MOJOSHADER_free function you provided to * MOJOSHADER_parseAst() multiple times, if you provided one. * Passing a NULL here is a safe no-op. * * This function is thread safe, so long as any allocator you passed into * MOJOSHADER_parseAst() is, too. */ DECLSPEC void MOJOSHADER_freeAstData(const MOJOSHADER_astData *data); /* Intermediate Representation interface... */ /* !!! FIXME: there is currently no way to access the IR via the public API. */ typedef enum MOJOSHADER_irNodeType { MOJOSHADER_IR_START_RANGE_EXPR, MOJOSHADER_IR_CONSTANT, MOJOSHADER_IR_TEMP, MOJOSHADER_IR_BINOP, MOJOSHADER_IR_MEMORY, MOJOSHADER_IR_CALL, MOJOSHADER_IR_ESEQ, MOJOSHADER_IR_ARRAY, MOJOSHADER_IR_CONVERT, MOJOSHADER_IR_SWIZZLE, MOJOSHADER_IR_CONSTRUCT, MOJOSHADER_IR_END_RANGE_EXPR, MOJOSHADER_IR_START_RANGE_STMT, MOJOSHADER_IR_MOVE, MOJOSHADER_IR_EXPR_STMT, MOJOSHADER_IR_JUMP, MOJOSHADER_IR_CJUMP, MOJOSHADER_IR_SEQ, MOJOSHADER_IR_LABEL, MOJOSHADER_IR_DISCARD, MOJOSHADER_IR_END_RANGE_STMT, MOJOSHADER_IR_START_RANGE_MISC, MOJOSHADER_IR_EXPRLIST, MOJOSHADER_IR_END_RANGE_MISC, MOJOSHADER_IR_END_RANGE } MOJOSHADER_irNodeType; typedef struct MOJOSHADER_irNodeInfo { MOJOSHADER_irNodeType type; const char *filename; unsigned int line; } MOJOSHADER_irNodeInfo; typedef struct MOJOSHADER_irExprList MOJOSHADER_irExprList; /* * IR nodes are categorized into Expressions, Statements, and Everything Else. * You can cast any of them to MOJOSHADER_irGeneric, but this split is * useful for slightly better type-checking (you can't cleanly assign * something that doesn't return a value to something that wants one, etc). * These broader categories are just unions of the simpler types, so the * real definitions are below all the things they contain (but these * predeclarations are because the simpler types refer to the broader * categories). */ typedef union MOJOSHADER_irExpression MOJOSHADER_irExpression; /* returns a value. */ typedef union MOJOSHADER_irStatement MOJOSHADER_irStatement; /* no returned value. */ typedef union MOJOSHADER_irMisc MOJOSHADER_irMisc; /* Everything Else. */ typedef union MOJOSHADER_irNode MOJOSHADER_irNode; /* Generic uber-wrapper. */ /* You can cast any IR node pointer to this. */ typedef struct MOJOSHADER_irGeneric { MOJOSHADER_irNodeInfo ir; } MOJOSHADER_irGeneric; /* These are used for MOJOSHADER_irBinOp */ typedef enum MOJOSHADER_irBinOpType { MOJOSHADER_IR_BINOP_ADD, MOJOSHADER_IR_BINOP_SUBTRACT, MOJOSHADER_IR_BINOP_MULTIPLY, MOJOSHADER_IR_BINOP_DIVIDE, MOJOSHADER_IR_BINOP_MODULO, MOJOSHADER_IR_BINOP_AND, MOJOSHADER_IR_BINOP_OR, MOJOSHADER_IR_BINOP_XOR, MOJOSHADER_IR_BINOP_LSHIFT, MOJOSHADER_IR_BINOP_RSHIFT, MOJOSHADER_IR_BINOP_UNKNOWN } MOJOSHADER_irBinOpType; typedef enum MOJOSHADER_irConditionType { MOJOSHADER_IR_COND_EQL, MOJOSHADER_IR_COND_NEQ, MOJOSHADER_IR_COND_LT, MOJOSHADER_IR_COND_GT, MOJOSHADER_IR_COND_LEQ, MOJOSHADER_IR_COND_GEQ, MOJOSHADER_IR_COND_UNKNOWN } MOJOSHADER_irConditionType; /* MOJOSHADER_irExpression types... */ typedef struct MOJOSHADER_irExprInfo { MOJOSHADER_irNodeInfo ir; MOJOSHADER_astDataTypeType type; int elements; } MOJOSHADER_irExprInfo; typedef struct MOJOSHADER_irConstant /* Constant value */ { MOJOSHADER_irExprInfo info; /* Always MOJOSHADER_IR_CONSTANT */ union { int ival[16]; float fval[16]; } value; } MOJOSHADER_irConstant; typedef struct MOJOSHADER_irTemp /* temp value (not necessarily a register). */ { MOJOSHADER_irExprInfo info; /* Always MOJOSHADER_IR_TEMP */ int index; } MOJOSHADER_irTemp; typedef struct MOJOSHADER_irBinOp /* binary operator (+, -, etc) */ { MOJOSHADER_irExprInfo info; /* Always MOJOSHADER_IR_BINOP */ MOJOSHADER_irBinOpType op; MOJOSHADER_irExpression *left; MOJOSHADER_irExpression *right; } MOJOSHADER_irBinOp; typedef struct MOJOSHADER_irMemory { MOJOSHADER_irExprInfo info; /* Always MOJOSHADER_IR_MEMORY */ int index; /* not final addresses, just a unique identifier. */ } MOJOSHADER_irMemory; typedef struct MOJOSHADER_irCall { MOJOSHADER_irExprInfo info; /* Always MOJOSHADER_IR_CALL */ int index; MOJOSHADER_irExprList *args; } MOJOSHADER_irCall; typedef struct MOJOSHADER_irESeq /* statement with result */ { MOJOSHADER_irExprInfo info; /* Always MOJOSHADER_IR_ESEQ */ MOJOSHADER_irStatement *stmt; /* execute this for side-effects, then... */ MOJOSHADER_irExpression *expr; /* ...use this for the result. */ } MOJOSHADER_irESeq; typedef struct MOJOSHADER_irArray /* Array dereference. */ { MOJOSHADER_irExprInfo info; /* Always MOJOSHADER_IR_ARRAY */ MOJOSHADER_irExpression *array; MOJOSHADER_irExpression *element; } MOJOSHADER_irArray; typedef struct MOJOSHADER_irConvert /* casting between datatypes */ { MOJOSHADER_irExprInfo info; /* Always MOJOSHADER_IR_CONVERT */ MOJOSHADER_irExpression *expr; } MOJOSHADER_irConvert; typedef struct MOJOSHADER_irSwizzle /* vector swizzle */ { MOJOSHADER_irExprInfo info; /* Always MOJOSHADER_IR_SWIZZLE */ MOJOSHADER_irExpression *expr; char channels[4]; } MOJOSHADER_irSwizzle; typedef struct MOJOSHADER_irConstruct /* vector construct from discrete items */ { MOJOSHADER_irExprInfo info; /* Always MOJOSHADER_IR_CONTSTRUCT */ MOJOSHADER_irExprList *args; } MOJOSHADER_irConstruct; /* Wrap the whole category in a union for type "safety." */ union MOJOSHADER_irExpression { MOJOSHADER_irNodeInfo ir; MOJOSHADER_irExprInfo info; MOJOSHADER_irConstant constant; MOJOSHADER_irTemp temp; MOJOSHADER_irBinOp binop; MOJOSHADER_irMemory memory; MOJOSHADER_irCall call; MOJOSHADER_irESeq eseq; MOJOSHADER_irArray array; MOJOSHADER_irConvert convert; MOJOSHADER_irSwizzle swizzle; MOJOSHADER_irConstruct construct; }; /* MOJOSHADER_irStatement types. */ typedef struct MOJOSHADER_irMove /* load/store. */ { MOJOSHADER_irNodeInfo ir; /* Always MOJOSHADER_IR_MOVE */ MOJOSHADER_irExpression *dst; /* must result in a temp or mem! */ MOJOSHADER_irExpression *src; int writemask; /* for write-masking vector channels. */ } MOJOSHADER_irMove; typedef struct MOJOSHADER_irExprStmt /* evaluate expression, throw it away. */ { MOJOSHADER_irNodeInfo ir; /* Always MOJOSHADER_IR_EXPR_STMT */ MOJOSHADER_irExpression *expr; } MOJOSHADER_irExprStmt; typedef struct MOJOSHADER_irJump /* unconditional jump */ { MOJOSHADER_irNodeInfo ir; /* Always MOJOSHADER_IR_JUMP */ int label; /* !!! FIXME: possible label list, for further optimization passes. */ } MOJOSHADER_irJump; typedef struct MOJOSHADER_irCJump /* conditional jump */ { MOJOSHADER_irNodeInfo ir; /* Always MOJOSHADER_IR_CJUMP */ MOJOSHADER_irConditionType cond; MOJOSHADER_irExpression *left; /* if (left cond right) */ MOJOSHADER_irExpression *right; int iftrue; /* label id for true case. */ int iffalse; /* label id for false case. */ } MOJOSHADER_irCJump; typedef struct MOJOSHADER_irSeq /* statement without side effects */ { MOJOSHADER_irNodeInfo ir; /* Always MOJOSHADER_IR_SEQ */ MOJOSHADER_irStatement *first; MOJOSHADER_irStatement *next; } MOJOSHADER_irSeq; typedef struct MOJOSHADER_irLabel /* like a label in assembly language. */ { MOJOSHADER_irNodeInfo ir; /* Always MOJOSHADER_IR_LABEL */ int index; } MOJOSHADER_irLabel; typedef MOJOSHADER_irGeneric MOJOSHADER_irDiscard; /* discard statement. */ /* Wrap the whole category in a union for type "safety." */ union MOJOSHADER_irStatement { MOJOSHADER_irNodeInfo ir; MOJOSHADER_irGeneric generic; MOJOSHADER_irMove move; MOJOSHADER_irExprStmt expr; MOJOSHADER_irJump jump; MOJOSHADER_irCJump cjump; MOJOSHADER_irSeq seq; MOJOSHADER_irLabel label; MOJOSHADER_irDiscard discard; }; /* MOJOSHADER_irMisc types. */ struct MOJOSHADER_irExprList { MOJOSHADER_irNodeInfo ir; /* Always MOJOSHADER_IR_EXPRLIST */ MOJOSHADER_irExpression *expr; MOJOSHADER_irExprList *next; }; /* Wrap the whole category in a union for type "safety." */ union MOJOSHADER_irMisc { MOJOSHADER_irNodeInfo ir; MOJOSHADER_irGeneric generic; MOJOSHADER_irExprList exprlist; }; /* This is a catchall for all your needs. :) */ union MOJOSHADER_irNode { MOJOSHADER_irNodeInfo ir; MOJOSHADER_irGeneric generic; MOJOSHADER_irExpression expr; MOJOSHADER_irStatement stmt; MOJOSHADER_irMisc misc; }; /* Compiler interface... */ /* * Structure used to return data from parsing of a shader... */ /* !!! FIXME: most of these ints should be unsigned. */ typedef struct MOJOSHADER_compileData { /* * The number of elements pointed to by (errors). */ int error_count; /* * (error_count) elements of data that specify errors that were generated * by compiling this shader. * This can be NULL if there were no errors or if (error_count) is zero. */ MOJOSHADER_error *errors; /* * The number of elements pointed to by (warnings). */ int warning_count; /* * (warning_count) elements of data that specify errors that were * generated by compiling this shader. * This can be NULL if there were no errors or if (warning_count) is zero. */ MOJOSHADER_error *warnings; /* * The name of the source profile used to compile the shader. Will be NULL * on error. */ const char *source_profile; /* * Bytes of output from compiling. This will be a null-terminated ASCII * string of D3D assembly source code. */ const char *output; /* * Byte count for output, not counting any null terminator. * Will be 0 on error. */ int output_len; /* * The number of elements pointed to by (symbols). */ int symbol_count; /* * (symbol_count) elements of data that specify high-level symbol data * for the shader. This can be used by MOJOSHADER_assemble() to * generate a CTAB section in bytecode, which is needed by * MOJOSHADER_parseData() to handle some shaders. This can be NULL on * error or if (symbol_count) is zero. */ MOJOSHADER_symbol *symbols; /* * This is the malloc implementation you passed to MOJOSHADER_parse(). */ MOJOSHADER_malloc malloc; /* * This is the free implementation you passed to MOJOSHADER_parse(). */ MOJOSHADER_free free; /* * This is the pointer you passed as opaque data for your allocator. */ void *malloc_data; } MOJOSHADER_compileData; /* * This function is optional. Use this to compile high-level shader programs. * * This is intended to turn HLSL source code into D3D assembly code, which * can then be passed to MOJOSHADER_assemble() to convert it to D3D bytecode * (which can then be used with MOJOSHADER_parseData() to support other * shading targets). * * (srcprofile) specifies the source language of the shader. You can specify * a shader model with this, too. See MOJOSHADER_SRC_PROFILE_* constants. * * (filename) is a NULL-terminated UTF-8 filename. It can be NULL. We do not * actually access this file, as we obtain our data from (source). This * string is copied when we need to report errors while processing (source), * as opposed to errors in a file referenced via the #include directive in * (source). If this is NULL, then errors will report the filename as NULL, * too. * * (source) is an UTF-8 string of valid high-level shader source code. * It does not need to be NULL-terminated. * * (sourcelen) is the length of the string pointed to by (source), in bytes. * * (defines) points to (define_count) preprocessor definitions, and can be * NULL. These are treated by the preprocessor as if the source code started * with one #define for each entry you pass in here. * * (include_open) and (include_close) let the app control the preprocessor's * behaviour for #include statements. Both are optional and can be NULL, but * both must be specified if either is specified. * * This will return a MOJOSHADER_compileData. The data supplied here is * sufficient to supply to MOJOSHADER_assemble() for further processing. * When you are done with this data, pass it to MOJOSHADER_freeCompileData() * to deallocate resources. * * This function will never return NULL, even if the system is completely * out of memory upon entry (in which case, this function returns a static * MOJOSHADER_compileData object, which is still safe to pass to * MOJOSHADER_freeCompileData()). * * As compiling 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 * (d) parameter. This pointer is passed as-is to your (m) and (f) functions. * * This function is thread safe, so long as the various callback functions * are, too, and that the parameters remains intact for the duration of the * call. This allows you to compile several shaders on separate CPU cores * at the same time. */ DECLSPEC const MOJOSHADER_compileData *MOJOSHADER_compile(const char *srcprofile, const char *filename, const char *source, unsigned int sourcelen, const MOJOSHADER_preprocessorDefine *defs, unsigned int define_count, MOJOSHADER_includeOpen include_open, MOJOSHADER_includeClose include_close, MOJOSHADER_malloc m, MOJOSHADER_free f, void *d); /* * Call this to dispose of compile results when you are done with them. * This will call the MOJOSHADER_free function you provided to * MOJOSHADER_compile() multiple times, if you provided one. * Passing a NULL here is a safe no-op. * * This function is thread safe, so long as any allocator you passed into * MOJOSHADER_compile() is, too. */ DECLSPEC void MOJOSHADER_freeCompileData(const MOJOSHADER_compileData *data); /* OpenGL interface... */ /* * Signature for function lookup callbacks. MojoShader will call a function * you provide to get OpenGL entry points (both standard functions and * extensions). Through this, MojoShader never links directly to OpenGL, * but relies on you to provide the implementation. This means you can * swap in different drivers, or hook functions (log every GL call MojoShader * makes, etc). * * (fnname) is the function name we want the address for ("glBegin" or * whatever. (data) is a void pointer you provide, if this callback needs * extra information. If you don't need it, you may specify NULL. * * Return the entry point on success, NULL if it couldn't be found. * Note that this could ask for standard entry points like glEnable(), or * extensions like glProgramLocalParameterI4ivNV(), so you might need * to check two places to find the desired entry point, depending on your * platform (Windows might need to look in OpenGL32.dll and use WGL, etc). */ typedef void *(MOJOSHADERCALL *MOJOSHADER_glGetProcAddress)(const char *fnname, void *data); /* * "Contexts" map to OpenGL contexts...you need one per window, or whatever, * and need to inform MojoShader when you make a new one current. * * "Shaders" refer to individual vertex or pixel programs, and are created * by "compiling" Direct3D shader bytecode. A vertex and pixel shader are * "linked" into a "Program" before you can use them to render. * * To the calling application, these are all opaque handles. */ typedef struct MOJOSHADER_glContext MOJOSHADER_glContext; typedef struct MOJOSHADER_glShader MOJOSHADER_glShader; typedef struct MOJOSHADER_glProgram MOJOSHADER_glProgram; /* * Get a list of available profiles. This will fill in the array (profs) * with up to (size) pointers of profiles that the current system can handle; * that is, the profiles are built into MojoShader and the OpenGL extensions * required for them exist at runtime. This function returns the number of * available profiles, which may be more, less, or equal to (size). * * If there are more than (size) profiles, the (profs) buffer will not * overflow. You can check the return value for the total number of * available profiles, allocate more space, and try again if necessary. * Calling this function with (size) == 0 is legal. * * You can only call this AFTER you have successfully built your GL context * and made it current. This function will lookup the GL functions it needs * through the callback you supply, via (lookup) and (lookup_d). The lookup * function is neither stored nor used by MojoShader after this function * returns, nor are the functions it might look up. * * 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. * * You should not free any strings returned from this function; they are * pointers to internal, probably static, memory. * * This call is NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. */ DECLSPEC int MOJOSHADER_glAvailableProfiles(MOJOSHADER_glGetProcAddress lookup, void *lookup_d, const char **profs, const int size, MOJOSHADER_malloc m, MOJOSHADER_free f, void *malloc_d); /* * Determine the best profile to use for the current system. * * You can only call this AFTER you have successfully built your GL context * and made it current. This function will lookup the GL functions it needs * through the callback you supply via (lookup) and (lookup_d). The lookup * function is neither stored nor used by MojoShader after this function * returns, nor are the functions it might look up. * * Returns the name of the "best" profile on success, NULL if none of the * available profiles will work on this system. "Best" is a relative term, * but it generally means the best trade off between feature set and * performance. The selection algorithm may be arbitrary and complex. * * 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. * * The returned value is an internal static string, and should not be free()'d * by the caller. If you get a NULL, calling MOJOSHADER_glGetError() might * shed some light on why. * * This call is NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. */ DECLSPEC const char *MOJOSHADER_glBestProfile(MOJOSHADER_glGetProcAddress lookup, void *lookup_d, MOJOSHADER_malloc m, MOJOSHADER_free f, void *malloc_d); /* * Prepare MojoShader to manage OpenGL 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 GL context * and made it current. This function will lookup the GL functions it needs * through the callback you supply via (lookup) and (lookup_d), after which * it may call them at any time up until you call * MOJOSHADER_glDestroyContext(). The lookup function is neither stored nor * used by MojoShader after this function returns. * * (profile) is an OpenGL-specific MojoShader profile, which decides how * Direct3D bytecode shaders get turned into OpenGL programs, and how they * are fed to the GL. * * (lookup) is a callback that is used to load GL entry points. This callback * has to look up base GL functions and extension entry points. The pointer * you supply in (lookup_d) is passed as-is to the callback. * * 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. * * Returns a new context on success, NULL on error. If you get a new context, * you need to make it current before using it with * MOJOSHADER_glMakeContextCurrent(). * * This call is NOT thread safe! It must return success before you may call * any other MOJOSHADER_gl* function. Also, as most OpenGL implementations * are not thread safe, you should probably only call this from the same * thread that created the GL context. */ DECLSPEC MOJOSHADER_glContext *MOJOSHADER_glCreateContext(const char *profile, MOJOSHADER_glGetProcAddress lookup, void *lookup_d, MOJOSHADER_malloc m, MOJOSHADER_free f, void *malloc_d); /* * You must call this before using the context that you got from * MOJOSHADER_glCreateContext(), and must use it when you switch to a new GL * context. * * You can only have one MOJOSHADER_glContext per actual GL context, or * undefined behaviour will result. * * It is legal to call this with a NULL pointer to make no context current, * but you need a valid context to be current to use most of MojoShader. */ DECLSPEC void MOJOSHADER_glMakeContextCurrent(MOJOSHADER_glContext *ctx); /* * Get any error state we might have picked up. MojoShader will NOT call * glGetError() internally, but there are other errors we can pick up, * such as failed shader compilation, etc. * * 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. * * This call is NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call does NOT require a valid MOJOSHADER_glContext to have been made * current. The error buffer is shared between contexts, so you can get * error results from a failed MOJOSHADER_glCreateContext(). */ DECLSPEC const char *MOJOSHADER_glGetError(void); /* * Get the maximum uniforms a shader can support for the current GL context, * MojoShader profile, and shader type. You can use this to make decisions * about what shaders you want to use (for example, a less complicated * shader may be swapped in for lower-end systems). * * Returns the number, or -1 on error. * * This call is NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). */ DECLSPEC int MOJOSHADER_glMaxUniforms(MOJOSHADER_shaderType shader_type); /* * Compile a buffer of Direct3D shader bytecode into an OpenGL shader. * You still need to link the shader before you may render with it. * * (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 NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). * * Compiled shaders from this function may not be shared between contexts. */ DECLSPEC MOJOSHADER_glShader *MOJOSHADER_glCompileShader(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 NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). */ DECLSPEC void MOJOSHADER_glShaderAddRef(MOJOSHADER_glShader *shader); /* * Get the MOJOSHADER_parseData structure that was produced from the * call to MOJOSHADER_glCompileShader(). * * 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_glGetShaderParseData( MOJOSHADER_glShader *shader); /* * Link a vertex and pixel shader into an OpenGL program. * (vshader) or (pshader) can be NULL, to specify that the GL should use the * fixed-function pipeline instead of the programmable pipeline for that * portion of the work. You can reuse shaders in various combinations across * multiple programs, by relinking different pairs. * * It is illegal to give a vertex shader for (pshader) or a pixel shader * for (vshader). * * Once you have successfully linked a program, you may render with it. * * Returns NULL on error, or a program handle on success. * * This call is NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). * * Linked programs from this function may not be shared between contexts. */ DECLSPEC MOJOSHADER_glProgram *MOJOSHADER_glLinkProgram(MOJOSHADER_glShader *vshader, MOJOSHADER_glShader *pshader); /* * This binds the program (using, for example, glUseProgramObjectARB()), and * disables all the client-side arrays so we can reset them with new values * if appropriate. * * Call with NULL to disable the programmable pipeline and all enabled * client-side arrays. * * After binding a program, you should update any uniforms you care about * with MOJOSHADER_glSetVertexShaderUniformF() (etc), set any vertex arrays * you want to use with MOJOSHADER_glSetVertexAttribute(), and finally call * MOJOSHADER_glProgramReady() to commit everything to the GL. Then you may * begin drawing through standard GL entry points. * * This call is NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). */ DECLSPEC void MOJOSHADER_glBindProgram(MOJOSHADER_glProgram *program); /* * This binds individual shaders as if you had linked them with * MOJOSHADER_glLinkProgram(), and used MOJOSHADER_glBindProgram() on the * linked result. * * MojoShader will handle linking behind the scenes, and keep a cache of * programs linked here. Programs are removed from this cache when one of the * invidual shaders in it is deleted, otherwise they remain cached so future * calls to this function don't need to relink a previously-used shader * grouping. * * This function is for convenience, as the API is closer to how Direct3D * works, and retrofitting linking into your app can be difficult; * frequently, you just end up building your own cache, anyhow. * * Calling with all shaders set to NULL is equivalent to calling * MOJOSHADER_glBindProgram(NULL). * * This call is NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). */ DECLSPEC void MOJOSHADER_glBindShaders(MOJOSHADER_glShader *vshader, MOJOSHADER_glShader *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 NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). */ DECLSPEC void MOJOSHADER_glGetBoundShaders(MOJOSHADER_glShader **vshader, MOJOSHADER_glShader **pshader); /* * Set a floating-point uniform value (what Direct3D calls a "constant"). * * There is a single array of 4-float "registers" shared by all vertex shaders. * This is the "c" register file in Direct3D (c0, c1, c2, etc...) * MojoShader will take care of synchronizing this internal array with the * appropriate variables in the GL shaders. * * (idx) is the index into the internal array: 0 is the first four floats, * 1 is the next four, etc. * (data) is a pointer to (vec4count*4) floats. * * This call is NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). * * Uniforms are not shared between contexts. */ DECLSPEC void MOJOSHADER_glSetVertexShaderUniformF(unsigned int idx, const float *data, unsigned int vec4count); /* * Retrieve a floating-point uniform value (what Direct3D calls a "constant"). * * There is a single array of 4-float "registers" shared by all vertex shaders. * This is the "c" register file in Direct3D (c0, c1, c2, etc...) * MojoShader will take care of synchronizing this internal array with the * appropriate variables in the GL shaders. * * (idx) is the index into the internal array: 0 is the first four floats, * 1 is the next four, etc. * (data) is a pointer to space for (vec4count*4) floats. * (data) will be filled will current values in the register file. Results * are undefined if you request data past the end of the register file or * previously uninitialized registers. * * This is a "fast" call; we're just reading from internal memory. We do not * query the GPU or the GL for this information. * * This call is NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). * * Uniforms are not shared between contexts. */ DECLSPEC void MOJOSHADER_glGetVertexShaderUniformF(unsigned int idx, float *data, unsigned int vec4count); /* * Set an integer uniform value (what Direct3D calls a "constant"). * * There is a single array of 4-int "registers" shared by all vertex shaders. * This is the "i" register file in Direct3D (i0, i1, i2, etc...) * MojoShader will take care of synchronizing this internal array with the * appropriate variables in the GL shaders. * * (idx) is the index into the internal array: 0 is the first four ints, * 1 is the next four, etc. * (data) is a pointer to (ivec4count*4) ints. * * This call is NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). * * Uniforms are not shared between contexts. */ DECLSPEC void MOJOSHADER_glSetVertexShaderUniformI(unsigned int idx, const int *data, unsigned int ivec4count); /* * Retrieve an integer uniform value (what Direct3D calls a "constant"). * * There is a single array of 4-int "registers" shared by all vertex shaders. * This is the "i" register file in Direct3D (i0, i1, i2, etc...) * MojoShader will take care of synchronizing this internal array with the * appropriate variables in the GL shaders. * * (idx) is the index into the internal array: 0 is the first four ints, * 1 is the next four, etc. * (data) is a pointer to space for (ivec4count*4) ints. * (data) will be filled will current values in the register file. Results * are undefined if you request data past the end of the register file or * previously uninitialized registers. * * This is a "fast" call; we're just reading from internal memory. We do not * query the GPU or the GL for this information. * * This call is NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). * * Uniforms are not shared between contexts. */ DECLSPEC void MOJOSHADER_glGetVertexShaderUniformI(unsigned int idx, int *data, unsigned int ivec4count); /* * Set a boolean uniform value (what Direct3D calls a "constant"). * * There is a single array of "registers" shared by all vertex shaders. * This is the "b" register file in Direct3D (b0, b1, b2, etc...) * MojoShader will take care of synchronizing this internal array with the * appropriate variables in the GL shaders. * * Unlike the float and int counterparts, booleans are single values, not * four-element vectors...so idx==1 is the second boolean in the internal * array, not the fifth. * * Non-zero values are considered "true" and zero is considered "false". * * (idx) is the index into the internal array. * (data) is a pointer to (bcount) ints. * * This call is NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). * * Uniforms are not shared between contexts. */ DECLSPEC void MOJOSHADER_glSetVertexShaderUniformB(unsigned int idx, const int *data, unsigned int bcount); /* * Retrieve a boolean uniform value (what Direct3D calls a "constant"). * * There is a single array of "registers" shared by all vertex shaders. * This is the "b" register file in Direct3D (b0, b1, b2, etc...) * MojoShader will take care of synchronizing this internal array with the * appropriate variables in the GL shaders. * * Unlike the float and int counterparts, booleans are single values, not * four-element vectors...so idx==1 is the second boolean in the internal * array, not the fifth. * * Non-zero values are considered "true" and zero is considered "false". * This function will always return true values as 1, regardless of what * non-zero integer you originally used to set the registers. * * (idx) is the index into the internal array. * (data) is a pointer to space for (bcount) ints. * (data) will be filled will current values in the register file. Results * are undefined if you request data past the end of the register file or * previously uninitialized registers. * * This is a "fast" call; we're just reading from internal memory. We do not * query the GPU or the GL for this information. * * This call is NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). * * Uniforms are not shared between contexts. */ DECLSPEC void MOJOSHADER_glGetVertexShaderUniformB(unsigned int idx, int *data, unsigned int bcount); /* * The equivalent of MOJOSHADER_glSetVertexShaderUniformF() for pixel * shaders. Other than using a different internal array that is specific * to pixel shaders, this functions just like its vertex array equivalent. * * This call is NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). * * Uniforms are not shared between contexts. */ DECLSPEC void MOJOSHADER_glSetPixelShaderUniformF(unsigned int idx, const float *data, unsigned int vec4count); /* * The equivalent of MOJOSHADER_glGetVertexShaderUniformF() for pixel * shaders. Other than using a different internal array that is specific * to pixel shaders, this functions just like its vertex array equivalent. * * This call is NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). * * Uniforms are not shared between contexts. */ DECLSPEC void MOJOSHADER_glGetPixelShaderUniformF(unsigned int idx, float *data, unsigned int vec4count); /* * The equivalent of MOJOSHADER_glSetVertexShaderUniformI() for pixel * shaders. Other than using a different internal array that is specific * to pixel shaders, this functions just like its vertex array equivalent. * * This call is NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). * * Uniforms are not shared between contexts. */ DECLSPEC void MOJOSHADER_glSetPixelShaderUniformI(unsigned int idx, const int *data, unsigned int ivec4count); /* * The equivalent of MOJOSHADER_glGetVertexShaderUniformI() for pixel * shaders. Other than using a different internal array that is specific * to pixel shaders, this functions just like its vertex array equivalent. * * This call is NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). * * Uniforms are not shared between contexts. */ DECLSPEC void MOJOSHADER_glGetPixelShaderUniformI(unsigned int idx, int *data, unsigned int ivec4count); /* * The equivalent of MOJOSHADER_glSetVertexShaderUniformB() for pixel * shaders. Other than using a different internal array that is specific * to pixel shaders, this functions just like its vertex array equivalent. * * This call is NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). * * Uniforms are not shared between contexts. */ DECLSPEC void MOJOSHADER_glSetPixelShaderUniformB(unsigned int idx, const int *data, unsigned int bcount); /* * The equivalent of MOJOSHADER_glGetVertexShaderUniformB() for pixel * shaders. Other than using a different internal array that is specific * to pixel shaders, this functions just like its vertex array equivalent. * * This call is NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). * * Uniforms are not shared between contexts. */ DECLSPEC void MOJOSHADER_glGetPixelShaderUniformB(unsigned int idx, int *data, unsigned int bcount); /* * Fills register pointers with pointers that are directly used to push uniform * data to the GL 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 NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). */ DECLSPEC void MOJOSHADER_glMapUniformBufferMemory(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_glMapUniformBufferMemory(). * * This call is NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). */ DECLSPEC void MOJOSHADER_glUnmapUniformBufferMemory(); /* * Set up the vector for the TEXBEM opcode. Most apps can ignore this API. * * Shader Model 1.1 through 1.3 had an instruction for "fake bump mapping" * called TEXBEM. To use it, you had to set some sampler states, * D3DTSS_BUMPENVMATxx, which would be referenced by the opcode. * * This functionality was removed from Shader Model 1.4 and later, because * it was special-purpose and limited. The functionality could be built on * more general opcodes, and the sampler state could be supplied in a more * general uniform. * * However, to support this opcode, we supply a way to specify that sampler * state, and the OpenGL glue code does the right thing to pass that * information to the shader. * * This call maps to IDirect3DDevice::SetTextureStageState() with the * D3DTSS_BUMPENVMAT00, D3DTSS_BUMPENVMAT01, D3DTSS_BUMPENVMAT10, * D3DTSS_BUMPENVMAT11, D3DTSS_BUMPENVLSCALE, and D3DTSS_BUMPENVLOFFSET * targets. This is only useful for Shader Model < 1.4 pixel shaders, if * they use the TEXBEM or TEXBEML opcode. If you aren't sure, you don't need * this function. * * Like the rest of your uniforms, you must call MOJOSHADER_glProgramReady() * between setting new values and drawing with them. * * This call is NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). * * These values are not shared between contexts. */ DECLSPEC void MOJOSHADER_glSetLegacyBumpMapEnv(unsigned int sampler, float mat00, float mat01, float mat10, float mat11, float lscale, float loffset); /* * Return the location of a vertex attribute for the currently-bound program. * * (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 sent to * glVertexAttribPointer, or -1 if the stream is not used. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). */ DECLSPEC int MOJOSHADER_glGetVertexAttribLocation(MOJOSHADER_usage usage, int index); /* * Connect a client-side array to the currently-bound program. * * (usage) and (index) map to Direct3D vertex declaration values: COLOR1 would * be MOJOSHADER_USAGE_COLOR and 1. * * The caller should bind VBOs before this call and treat (ptr) as an offset, * if appropriate. * * MojoShader will figure out where to plug this stream into the * currently-bound program, and enable the appropriate client-side array. * * (size), (type), (normalized), (stride), and (ptr) correspond to * glVertexAttribPointer()'s parameters (in most cases, these get passed * unmolested to that very entry point during this function). * * This call is NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). * * Vertex attributes are not shared between contexts. */ /* !!! FIXME: this should probably be "input" and not "attribute" */ /* !!! FIXME: or maybe "vertex array" or something. */ DECLSPEC void MOJOSHADER_glSetVertexAttribute(MOJOSHADER_usage usage, int index, unsigned int size, MOJOSHADER_attributeType type, int normalized, unsigned int stride, const void *ptr); /* * Modify the rate at which this vertex attribute advances during instanced * rendering. * * This should be called alongside glSetVertexAttribute, as this does not flag * the vertex array as being in use. This just calls glVertexAttribDivisorARB. * * This call is NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). * * Vertex attributes are not shared between contexts. */ DECLSPEC void MOJOSHADER_glSetVertexAttribDivisor(MOJOSHADER_usage usage, int index, unsigned int divisor); /* * Inform MojoShader that it should commit any pending state to the GL. This * must be called after you bind a program 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 NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). */ DECLSPEC void MOJOSHADER_glProgramReady(void); /* * Provide information about the current viewport to the prepared shader * program. * * There are numerous components of OpenGL and Direct3D where the coordinate * systems do not match, and so the vertex/pixel shaders have to be modified to * compensate for these mismatches (for example, gl_FragCoord requires some * additional math on the Y coordinate to match vPos when rendering to the * backbuffer). Call this after MOJOSHADER_glProgramReady to apply all of the * relevant coordinate fixups at once. * * This call is NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). */ DECLSPEC void MOJOSHADER_glProgramViewportInfo(int viewportW, int viewportH, int backbufferW, int backbufferH, int renderTargetBound); /* * Free the resources of a linked program. This will delete the GL object * and free memory. * * If the program is currently bound by MOJOSHADER_glBindProgram(), it will * be deleted as soon as it becomes unbound. * * This call is NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). */ DECLSPEC void MOJOSHADER_glDeleteProgram(MOJOSHADER_glProgram *program); /* * Free the resources of a compiled shader. This will delete the GL object * and free memory. * * If the shader is currently referenced by a linked program (or is currently * bound with MOJOSHADER_glBindShaders()), it will be deleted as soon as all * referencing programs are deleted and it is no longer bound, too. * * This call is NOT thread safe! As most OpenGL implementations are not thread * safe, you should probably only call this from the same thread that created * the GL context. * * This call requires a valid MOJOSHADER_glContext to have been made current, * or it will crash your program. See MOJOSHADER_glMakeContextCurrent(). */ DECLSPEC void MOJOSHADER_glDeleteShader(MOJOSHADER_glShader *shader); /* * Deinitialize MojoShader's OpenGL shader management. * * You must call this once, while your GL context (not MojoShader context) is * still current, if you previously had a successful call to * MOJOSHADER_glCreateContext(). This should be the last MOJOSHADER_gl* * function you call until you've prepared a context again. * * This will clean up resources previously allocated, and may call into the GL. * * This will not clean up shaders and programs you created! Please call * MOJOSHADER_glDeleteShader() and MOJOSHADER_glDeleteProgram() to clean * those up before calling this function! * * This function destroys the MOJOSHADER_glContext you pass it. If it's the * current context, then no context will be current upon return. * * This call is NOT thread safe! There must not be any other MOJOSHADER_gl* * functions running when this is called. Also, as most OpenGL implementations * are not thread safe, you should probably only call this from the same * thread that created the GL context. */ DECLSPEC void MOJOSHADER_glDestroyContext(MOJOSHADER_glContext *ctx); /* Metal interface... */ typedef struct MOJOSHADER_mtlContext MOJOSHADER_mtlContext; typedef struct MOJOSHADER_mtlShader MOJOSHADER_mtlShader; /* * Prepare MojoShader to manage Metal shaders. * * This is really just for the effects framework. Don't call this unless * you know for sure that you need it. * * You must call this only once, AFTER you have created your MTLDevice. * This function will lookup the Objective-C selectors it needs, after which * it may call them at any time until you call MOJOSHADER_mtlDestroyContext(). * * (device) refers to the active MTLDevice, cast from id to void*. * * 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. * * Returns a new context on success, NULL on error. If you get a new context, * you need to make it current before using it with * MOJOSHADER_mtlMakeContextCurrent(). */ DECLSPEC MOJOSHADER_mtlContext *MOJOSHADER_mtlCreateContext(void *mtlDevice, MOJOSHADER_malloc m, MOJOSHADER_free f, void *malloc_d); /* * You must call this before using the context that you got from * MOJOSHADER_mtlCreateContext(), and must use it when you switch to a new * context. * * It is legal to call this with a NULL pointer to make no context current, * but you need a valid context to be current to use most of MojoShader. */ DECLSPEC void MOJOSHADER_mtlMakeContextCurrent(MOJOSHADER_mtlContext *ctx); /* * Transform a buffer of Direct3D shader bytecode into a struct containing * Metal shader metadata. * * This function is only for convenience, specifically for compatibility with * the effects API. * * Despite the name, this does NOT compile a shader! The actual compilation * happens inside MOJOSHADER_mtlCompileLibrary, which batch-compiles an effect * into a single MTLLibrary. * * (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 requires a valid MOJOSHADER_mtlContext to have been made current, * or it will crash your program. See MOJOSHADER_mtlMakeContextCurrent(). */ DECLSPEC MOJOSHADER_mtlShader *MOJOSHADER_mtlCompileShader(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_mtlDeleteShader(). */ DECLSPEC void MOJOSHADER_mtlShaderAddRef(MOJOSHADER_mtlShader *shader); /* * Get the MOJOSHADER_parseData structure that was produced from the * call to MOJOSHADER_mtlCompileShader(). * * 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_mtlGetShaderParseData( MOJOSHADER_mtlShader *shader); /* * This "binds" individual shaders, which effectively means the context * will store these shaders for later retrieval. No actual binding or * pipeline creation is performed. * * This function is only for convenience, specifically for compatibility with * the effects API. * * This call requires a valid MOJOSHADER_mtlContext to have been made current, * or it will crash your program. See MOJOSHADER_mtlMakeContextCurrent(). */ DECLSPEC void MOJOSHADER_mtlBindShaders(MOJOSHADER_mtlShader *vshader, MOJOSHADER_mtlShader *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 requires a valid MOJOSHADER_mtlContext to have been created, * or it will crash your program. See MOJOSHADER_mtlMakeContextCurrent(). */ DECLSPEC void MOJOSHADER_mtlGetBoundShaders(MOJOSHADER_mtlShader **vshader, MOJOSHADER_mtlShader **pshader); /* * Fills register pointers with pointers that are directly used to push uniform * data to the Metal 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 requires a valid MOJOSHADER_mtlContext to have been made current, * or it will crash your program. See MOJOSHADER_mtlMakeContextCurrent(). */ DECLSPEC void MOJOSHADER_mtlMapUniformBufferMemory(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_mtlMapUniformBufferMemory(). * * This call requires a valid MOJOSHADER_mtlContext to have been made current, * or it will crash your program. See MOJOSHADER_mtlMakeContextCurrent(). */ DECLSPEC void MOJOSHADER_mtlUnmapUniformBufferMemory(); /* * This queries for the uniform buffer and byte offsets for each of the * currently bound shaders. * * This function is only for convenience, specifically for compatibility with * the effects API. * * This call requires a valid MOJOSHADER_mtlContext to have been made current, * or it will crash your program. See MOJOSHADER_mtlMakeContextCurrent(). */ DECLSPEC void MOJOSHADER_mtlGetUniformData(void **buf, int *voff, int *poff); /* * Get the MTLFunction* from the given MOJOSHADER_mtlShader. */ DECLSPEC void *MOJOSHADER_mtlGetFunctionHandle(MOJOSHADER_mtlShader *shader); /* * Resets buffer offsets to prepare for the next frame. * * Always call this after submitting the final command buffer for a frame! */ DECLSPEC void MOJOSHADER_mtlEndFrame(void); /* * Return the location of a vertex attribute for the given 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 to create * a MTLVertexAttributeDescriptor, or -1 if the stream is not used. */ DECLSPEC int MOJOSHADER_mtlGetVertexAttribLocation(MOJOSHADER_mtlShader *vert, MOJOSHADER_usage usage, int index); /* * 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. * * This call does NOT require a valid MOJOSHADER_mtlContext to have been made * current. The error buffer is shared between contexts, so you can get * error results from a failed MOJOSHADER_mtlCreateContext(). * * 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_mtlGetError(void); /* * Release the given MTLLibrary and all MTLFunctions it contains. * * This does NOT free MOJOSHADER_mtlShaders! Call MOJOSHADER_mtlDeleteShader() * on all the shaders of the library before you call this. * * This call requires a valid MOJOSHADER_mtlContext to have been made current, * or it will crash your program. See MOJOSHADER_mtlMakeContextCurrent(). */ DECLSPEC void MOJOSHADER_mtlDeleteLibrary(void *library); /* * Free the resources of a compiled shader. This will delete the MojoShader * shader struct and free memory. * * This does NOT release the actual shader! The shader data belongs to an * MTLLibrary that must be deleted with MOJOSHADER_mtlDeleteLibrary(). * * This call requires a valid MOJOSHADER_mtlContext to have been made current, * or it will crash your program. See MOJOSHADER_mtlMakeContextCurrent(). */ DECLSPEC void MOJOSHADER_mtlDeleteShader(MOJOSHADER_mtlShader *shader); /* * Deinitialize MojoShader's Metal shader management. * * This should be the last MOJOSHADER_mtl* function you call until you've * prepared a context again. * * This will clean up resources previously allocated, and may call into Metal. * * This will not clean up shaders and libraries you created! Please call * MOJOSHADER_mtlDeleteShader() and MOJOSHADER_mtlDeleteLibrary() to clean * those up before calling this function! * * This function destroys the MOJOSHADER_mtlContext you pass it. If it's the * current context, then no context will be current upon return. */ DECLSPEC void MOJOSHADER_mtlDestroyContext(MOJOSHADER_mtlContext *_ctx); /* Vulkan interface */ /* Avoid including vulkan.h, don't define handles if it's already included */ #ifdef VULKAN_H_ #define NO_MOJOSHADER_VULKAN_TYPEDEFS #endif #ifndef NO_MOJOSHADER_VULKAN_TYPEDEFS #ifdef _WIN32 #define VKAPI_CALL __stdcall #define VKAPI_PTR VKAPI_CALL #else #define VKAPI_CALL #define VKAPI_PTR #endif #define VK_DEFINE_HANDLE(object) typedef struct object##_T* object; #if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object; #else #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef unsigned long long object; #endif VK_DEFINE_HANDLE(VkInstance) VK_DEFINE_HANDLE(VkDevice) VK_DEFINE_HANDLE(VkPhysicalDevice) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBuffer) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkShaderModule) #endif /* !NO_MOJOSHADER_VULKAN_TYPEDEFS */ typedef void (VKAPI_PTR *PFN_MOJOSHADER_vkVoidFunction)(void); typedef PFN_MOJOSHADER_vkVoidFunction (VKAPI_PTR *PFN_MOJOSHADER_vkGetDeviceProcAddr)( VkDevice device, const char* pName ); typedef PFN_MOJOSHADER_vkVoidFunction (VKAPI_PTR *PFN_MOJOSHADER_vkGetInstanceProcAddr)( VkInstance instance, const char* pName ); typedef struct MOJOSHADER_vkContext MOJOSHADER_vkContext; typedef struct MOJOSHADER_vkShader MOJOSHADER_vkShader; typedef struct MOJOSHADER_vkProgram MOJOSHADER_vkProgram; /* * Prepares a context to manage Vulkan shaders. * * Don't call this unless you know for sure that you need it. * * You must call this after creating VkDevice and VkInstance. * * (instance) refers to VkInstance, cast to void*. * * (device) refers to VkDevice, cast to void*. * * (frames_in_flight) refers to the maximum number of frames that can be * processed simultaneously. * * (lookup) refers to PFN_vkGetDeviceProcAddr, a function pointer that * is used to dynamically link required Vulkan functions. * * You must pass in the graphics queue family index and the memory type index * you will be using with your Vulkan instance. * * 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. * * The context created by this function will automatically become the current * context. No further action is needed by the caller. * * Returns 0 on success or -1 on failure. */ DECLSPEC MOJOSHADER_vkContext *MOJOSHADER_vkCreateContext(VkInstance *instance, VkPhysicalDevice *physical_device, VkDevice *logical_device, int frames_in_flight, PFN_MOJOSHADER_vkGetInstanceProcAddr instance_lookup, PFN_MOJOSHADER_vkGetDeviceProcAddr lookup, unsigned int graphics_queue_family_index, unsigned int max_uniform_buffer_range, unsigned int min_uniform_buffer_offset_alignment, MOJOSHADER_malloc m, MOJOSHADER_free f, void *malloc_d); /* * You must call this before using the context that you got from * MOJOSHADER_vkCreateContext(), and must use it when you switch to a new GL * context. * * You can only have one MOJOSHADER_vkContext per actual Vulkan context, or * undefined behaviour will result. * * It is legal to call this with a NULL pointer to make no context current, * but you need a valid context to be current to use most of MojoShader. */ DECLSPEC void MOJOSHADER_vkMakeContextCurrent(MOJOSHADER_vkContext *_ctx); /* * Get any error state we might have picked up. * * 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. * * This call does NOT require a valid MOJOSHADER_vkContext to have been made * current. The error buffer is shared between contexts, so you can get * error results from a failed MOJOSHADER_vkCreateContext(). */ DECLSPEC const char *MOJOSHADER_vkGetError(); /* * Deinitialize MojoShader's Vulkan shader management. * * You must call this once, while your Vulkan context (not MojoShader context) is * still current, if you previously had a successful call to * MOJOSHADER_vkCreateContext(). This should be the last MOJOSHADER_vk* * function you call until you've prepared a context again. * * This will clean up resources previously allocated, and may call into Vulkan. * * This will not clean up shaders and programs you created! Please call * MOJOSHADER_vkDeleteShader() and MOJOSHADER_vkDeleteProgram() to clean * those up before calling this function! * * This function destroys the MOJOSHADER_vkContext you pass it. If it's the * current context, then no context will be current upon return. */ DECLSPEC void MOJOSHADER_vkDestroyContext(MOJOSHADER_vkContext *ctx); /* * Compile a buffer of Direct3D shader bytecode into a Vulkan shader module. * * (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 requires a valid MOJOSHADER_vkContext to have been made current, * or it will crash your program. See MOJOSHADER_vkMakeContextCurrent(). * * Compiled shaders from this function may not be shared between contexts. */ DECLSPEC MOJOSHADER_vkShader *MOJOSHADER_vkCompileShader(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_vkDeleteShader(). * * This call requires a valid MOJOSHADER_vkContext to have been made current, * or it will crash your program. See MOJOSHADER_vkMakeContextCurrent(). */ DECLSPEC void MOJOSHADER_vkShaderAddRef(MOJOSHADER_vkShader *shader); /* * Increments a shader's internal refcount. * * To decrement the refcount, call MOJOSHADER_vkDeleteShader(). * * This call requires a valid MOJOSHADER_vkContext to have been made current, * or it will crash your program. See MOJOSHADER_vkMakeContextCurrent(). */ DECLSPEC void MOJOSHADER_vkDeleteShader(MOJOSHADER_vkShader *shader); /* * Get the MOJOSHADER_parseData structure that was produced from the * call to MOJOSHADER_vkCompileShader(). * * 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_vkGetShaderParseData( MOJOSHADER_vkShader *shader); /* * Link a vertex and pixel shader into a working Vulkan shader program. * (vshader) or (pshader) can NOT be NULL, unlike OpenGL. * * You can reuse shaders in various combinations across * multiple programs, by relinking different pairs. * * It is illegal to give a vertex shader for (pshader) or a pixel shader * for (vshader). * * Once you have successfully linked a program, you may render with it. * * Returns NULL on error, or a program handle on success. * * This call requires a valid MOJOSHADER_vkContext to have been made current, * or it will crash your program. See MOJOSHADER_vkMakeContextCurrent(). */ DECLSPEC MOJOSHADER_vkProgram *MOJOSHADER_vkLinkProgram(MOJOSHADER_vkShader *vshader, MOJOSHADER_vkShader *pshader); /* * This binds the program to the active context, and does nothing particularly * special until you start working with uniform buffers or shader modules. * * After binding a program, you should update any uniforms you care about * with MOJOSHADER_vkMapUniformBufferMemory() (etc), set any vertex arrays * using MOJOSHADER_vkGetVertexAttribLocation(), and finally call * MOJOSHADER_vkGetShaderModules() to get the final modules. Then you may * begin building your pipeline state objects. * * This call requires a valid MOJOSHADER_vkContext to have been made current, * or it will crash your program. See MOJOSHADER_vkMakeContextCurrent(). */ DECLSPEC void MOJOSHADER_vkBindProgram(MOJOSHADER_vkProgram *program); /* * Free the resources of a linked program. This will delete the shader modules * and free memory. * * If the program is currently bound by MOJOSHADER_vkBindProgram(), it will * be deleted as soon as it becomes unbound. * * This call requires a valid MOJOSHADER_vkContext to have been made current, * or it will crash your program. See MOJOSHADER_vkMakeContextCurrent(). */ DECLSPEC void MOJOSHADER_vkDeleteProgram(MOJOSHADER_vkProgram *program); /* * This "binds" individual shaders, which effectively means the context * will store these shaders for later retrieval. No actual binding or * pipeline creation is performed. * * This function is only for convenience, specifically for compatibility * with the effects API. * * This call requires a valid MOJOSHADER_vkContext to have been made current, * or it will crash your program. See MOJOSHADER_vkMakeContextCurrent(). */ DECLSPEC void MOJOSHADER_vkBindShaders(MOJOSHADER_vkShader *vshader, MOJOSHADER_vkShader *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 requires a valid MOJOSHADER_vkContext to have been made current, * or it will crash your program. See MOJOSHADER_vkMakeContextCurrent(). */ DECLSPEC void MOJOSHADER_vkGetBoundShaders(MOJOSHADER_vkShader **vshader, MOJOSHADER_vkShader **pshader); /* * Fills register pointers with pointers that are directly used to push uniform * data to the Vulkan 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 requires a valid MOJOSHADER_vkContext to have been made current, * or it will crash your program. See MOJOSHADER_vkMakeContextCurrent(). */ DECLSPEC void MOJOSHADER_vkMapUniformBufferMemory(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_vkMapUniformBufferMemory(). * * This call requires a valid MOJOSHADER_vkContext to have been made current, * or it will crash your program. See MOJOSHADER_vkMakeContextCurrent(). */ DECLSPEC void MOJOSHADER_vkUnmapUniformBufferMemory(); /* * This queries for the uniform buffer, byte offset and byte size for each of the * currently bound shaders. * * This function is only for convenience, specifically for compatibility with * the effects API. * * This call requires a valid MOJOSHADER_vkContext to have been made current, * or it will crash your program. See MOJOSHADER_vkMakeContextCurrent(). */ DECLSPEC void MOJOSHADER_vkGetUniformBuffers(VkBuffer *vbuf, unsigned long long *voff, unsigned long long *vsize, VkBuffer *pbuf, unsigned long long *poff, unsigned long long *psize); /* * Prepares uniform buffers for reuse. * * Always call this after submitting the final command buffer for a frame! */ DECLSPEC void MOJOSHADER_vkEndFrame(); /* * Return the location of a vertex attribute for the given 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 to create * a VkVertexInputAttributeDescription, or -1 if the stream is not used. * * This call requires a valid MOJOSHADER_vkContext to have been made current, * or it will crash your program. See MOJOSHADER_vkMakeContextCurrent(). */ DECLSPEC int MOJOSHADER_vkGetVertexAttribLocation(MOJOSHADER_vkShader *vert, MOJOSHADER_usage usage, int index); /* * Get the VkShaderModules from the currently bound shader program. */ DECLSPEC void MOJOSHADER_vkGetShaderModules(VkShaderModule *vmodule, VkShaderModule *pmodule); /* 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-strict Shader Model 4 rule set. This must be * 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" #ifdef __cplusplus } #endif #endif /* include-once blocker. */ /* end of mojoshader.h ... */