|
|
/**
|
|
|
* 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 MOJOSHADER_PROFILE_SPIRV_H
|
|
|
#define MOJOSHADER_PROFILE_SPIRV_H
|
|
|
|
|
|
#if SUPPORT_PROFILE_SPIRV
|
|
|
|
|
|
// For baked-in constants in SPIR-V we want to store scalar values that we can
|
|
|
// use in composites, since OpConstantComposite uses result ids constituates
|
|
|
// rather than value literals.
|
|
|
// We'll store these lists grouped by type and have the lists themselves
|
|
|
// ordered by value in the ctx.spirv struct.
|
|
|
typedef struct ComponentList
|
|
|
{
|
|
|
// result id from OpConstant
|
|
|
uint32 id;
|
|
|
union {
|
|
|
float f;
|
|
|
int i;
|
|
|
uint32 u;
|
|
|
} v;
|
|
|
struct ComponentList *next;
|
|
|
} ComponentList;
|
|
|
|
|
|
typedef struct SpirvLoopInfo
|
|
|
{
|
|
|
uint32 tid_counter;
|
|
|
uint32 id_counter;
|
|
|
uint32 id_counter_next;
|
|
|
uint32 id_aL;
|
|
|
uint32 id_label_header;
|
|
|
uint32 id_label_continue;
|
|
|
uint32 id_label_merge;
|
|
|
} SpirvLoopInfo;
|
|
|
|
|
|
typedef enum SpirvType
|
|
|
{
|
|
|
ST_FLOAT = 0,
|
|
|
ST_SINT = 1,
|
|
|
ST_UINT = 2,
|
|
|
ST_BOOL = 3,
|
|
|
} SpirvType;
|
|
|
|
|
|
typedef enum SpirvStorageClass
|
|
|
{
|
|
|
SC_INPUT = 0,
|
|
|
SC_OUTPUT = 1,
|
|
|
SC_PRIVATE = 2,
|
|
|
SC_UNIFORM_CONSTANT = 3,
|
|
|
} SpirvStorageClass;
|
|
|
|
|
|
/* Not all type parameter combinations are actually used, but it's all rounded up to 64 so
|
|
|
* it's easier to work with.
|
|
|
*/
|
|
|
typedef enum SpirvTypeIdx
|
|
|
{
|
|
|
STI_VOID = 0,
|
|
|
STI_FUNC_VOID = 1,
|
|
|
STI_FUNC_LIT = 2,
|
|
|
STI_IMAGE2D = 3,
|
|
|
STI_IMAGE3D = 4,
|
|
|
STI_IMAGECUBE = 5,
|
|
|
STI_PTR_IMAGE2D = 6,
|
|
|
STI_PTR_IMAGE3D = 7,
|
|
|
STI_PTR_IMAGECUBE = 8,
|
|
|
|
|
|
// 7 unused entries
|
|
|
|
|
|
// 4 base types * 4 vector sizes = 16 entries
|
|
|
STI_FLOAT = (0 << 5) | (1 << 4) | (ST_FLOAT << 2) | 0,
|
|
|
STI_VEC2 = (0 << 5) | (1 << 4) | (ST_FLOAT << 2) | 1,
|
|
|
STI_VEC3 = (0 << 5) | (1 << 4) | (ST_FLOAT << 2) | 2,
|
|
|
STI_VEC4 = (0 << 5) | (1 << 4) | (ST_FLOAT << 2) | 3,
|
|
|
STI_INT = (0 << 5) | (1 << 4) | (ST_SINT << 2) | 0,
|
|
|
STI_IVEC2 = (0 << 5) | (1 << 4) | (ST_SINT << 2) | 1,
|
|
|
STI_IVEC3 = (0 << 5) | (1 << 4) | (ST_SINT << 2) | 2,
|
|
|
STI_IVEC4 = (0 << 5) | (1 << 4) | (ST_SINT << 2) | 3,
|
|
|
STI_UINT = (0 << 5) | (1 << 4) | (ST_UINT << 2) | 0,
|
|
|
STI_UVEC2 = (0 << 5) | (1 << 4) | (ST_UINT << 2) | 1,
|
|
|
STI_UVEC3 = (0 << 5) | (1 << 4) | (ST_UINT << 2) | 2,
|
|
|
STI_UVEC4 = (0 << 5) | (1 << 4) | (ST_UINT << 2) | 3,
|
|
|
STI_BOOL = (0 << 5) | (1 << 4) | (ST_BOOL << 2) | 0,
|
|
|
STI_BVEC2 = (0 << 5) | (1 << 4) | (ST_BOOL << 2) | 1,
|
|
|
STI_BVEC3 = (0 << 5) | (1 << 4) | (ST_BOOL << 2) | 2,
|
|
|
STI_BVEC4 = (0 << 5) | (1 << 4) | (ST_BOOL << 2) | 3,
|
|
|
|
|
|
// 2 dims (vec4 + scalar) * 4 base types * 4 storage classes
|
|
|
STI_PTR_FLOAT_I = (1 << 5) | (0 << 4) | (ST_FLOAT << 2) | SC_INPUT,
|
|
|
STI_PTR_FLOAT_O = (1 << 5) | (0 << 4) | (ST_FLOAT << 2) | SC_OUTPUT,
|
|
|
STI_PTR_FLOAT_P = (1 << 5) | (0 << 4) | (ST_FLOAT << 2) | SC_PRIVATE,
|
|
|
STI_PTR_FLOAT_U = (1 << 5) | (0 << 4) | (ST_FLOAT << 2) | SC_UNIFORM_CONSTANT,
|
|
|
STI_PTR_INT_I = (1 << 5) | (0 << 4) | (ST_SINT << 2) | SC_INPUT,
|
|
|
STI_PTR_INT_O = (1 << 5) | (0 << 4) | (ST_SINT << 2) | SC_OUTPUT,
|
|
|
STI_PTR_INT_P = (1 << 5) | (0 << 4) | (ST_SINT << 2) | SC_PRIVATE,
|
|
|
STI_PTR_INT_U = (1 << 5) | (0 << 4) | (ST_SINT << 2) | SC_UNIFORM_CONSTANT,
|
|
|
STI_PTR_UINT_I = (1 << 5) | (0 << 4) | (ST_UINT << 2) | SC_INPUT,
|
|
|
STI_PTR_UINT_O = (1 << 5) | (0 << 4) | (ST_UINT << 2) | SC_OUTPUT,
|
|
|
STI_PTR_UINT_P = (1 << 5) | (0 << 4) | (ST_UINT << 2) | SC_PRIVATE,
|
|
|
STI_PTR_UINT_U = (1 << 5) | (0 << 4) | (ST_UINT << 2) | SC_UNIFORM_CONSTANT,
|
|
|
STI_PTR_BOOL_I = (1 << 5) | (0 << 4) | (ST_BOOL << 2) | SC_INPUT,
|
|
|
STI_PTR_BOOL_O = (1 << 5) | (0 << 4) | (ST_BOOL << 2) | SC_OUTPUT,
|
|
|
STI_PTR_BOOL_P = (1 << 5) | (0 << 4) | (ST_BOOL << 2) | SC_PRIVATE,
|
|
|
STI_PTR_BOOL_U = (1 << 5) | (0 << 4) | (ST_BOOL << 2) | SC_UNIFORM_CONSTANT,
|
|
|
STI_PTR_VEC4_I = (1 << 5) | (1 << 4) | (ST_FLOAT << 2) | SC_INPUT,
|
|
|
STI_PTR_VEC4_O = (1 << 5) | (1 << 4) | (ST_FLOAT << 2) | SC_OUTPUT,
|
|
|
STI_PTR_VEC4_P = (1 << 5) | (1 << 4) | (ST_FLOAT << 2) | SC_PRIVATE,
|
|
|
STI_PTR_VEC4_U = (1 << 5) | (1 << 4) | (ST_FLOAT << 2) | SC_UNIFORM_CONSTANT,
|
|
|
STI_PTR_IVEC4_I = (1 << 5) | (1 << 4) | (ST_SINT << 2) | SC_INPUT,
|
|
|
STI_PTR_IVEC4_O = (1 << 5) | (1 << 4) | (ST_SINT << 2) | SC_OUTPUT,
|
|
|
STI_PTR_IVEC4_P = (1 << 5) | (1 << 4) | (ST_SINT << 2) | SC_PRIVATE,
|
|
|
STI_PTR_IVEC4_U = (1 << 5) | (1 << 4) | (ST_SINT << 2) | SC_UNIFORM_CONSTANT,
|
|
|
STI_PTR_UVEC4_I = (1 << 5) | (1 << 4) | (ST_UINT << 2) | SC_INPUT,
|
|
|
STI_PTR_UVEC4_O = (1 << 5) | (1 << 4) | (ST_UINT << 2) | SC_OUTPUT,
|
|
|
STI_PTR_UVEC4_P = (1 << 5) | (1 << 4) | (ST_UINT << 2) | SC_PRIVATE,
|
|
|
STI_PTR_UVEC4_U = (1 << 5) | (1 << 4) | (ST_UINT << 2) | SC_UNIFORM_CONSTANT,
|
|
|
STI_PTR_BVEC4_I = (1 << 5) | (1 << 4) | (ST_BOOL << 2) | SC_INPUT,
|
|
|
STI_PTR_BVEC4_O = (1 << 5) | (1 << 4) | (ST_BOOL << 2) | SC_OUTPUT,
|
|
|
STI_PTR_BVEC4_P = (1 << 5) | (1 << 4) | (ST_BOOL << 2) | SC_PRIVATE,
|
|
|
STI_PTR_BVEC4_U = (1 << 5) | (1 << 4) | (ST_BOOL << 2) | SC_UNIFORM_CONSTANT,
|
|
|
|
|
|
// 2 + 6 + 16 + 32 = 56 entries (+ 8 unused)
|
|
|
|
|
|
// Helpers
|
|
|
STI_LENGTH_,
|
|
|
|
|
|
STI_MISC_START_ = 0,
|
|
|
STI_MISC_END_ = 8,
|
|
|
STI_CORE_START_ = (0 << 5) | (1 << 4),
|
|
|
STI_PTR_START_ = (1 << 5) | (0 << 4),
|
|
|
STI_CORE_END_ = STI_PTR_START_,
|
|
|
STI_PTR_END_ = STI_LENGTH_,
|
|
|
} SpirvTypeIdx;
|
|
|
|
|
|
// In addition to result ID we also need type ID (can't assume everything is vec4).
|
|
|
typedef struct SpirvResult
|
|
|
{
|
|
|
uint32 tid;
|
|
|
uint32 id;
|
|
|
} SpirvResult;
|
|
|
|
|
|
typedef struct SpirvContext
|
|
|
{
|
|
|
#if SUPPORT_PROFILE_GLSPIRV
|
|
|
uint32 id_vs_main_end;
|
|
|
#endif // SUPPORT_PROFILE_GLSPIRV
|
|
|
// ext. glsl instructions have been imported
|
|
|
uint32 idext;
|
|
|
uint32 idmax;
|
|
|
uint32 idmain;
|
|
|
uint32 id_func_lit;
|
|
|
uint32 inoutcount;
|
|
|
uint32 id_var_fragcoord;
|
|
|
uint32 id_var_vpos;
|
|
|
uint32 id_var_frontfacing;
|
|
|
uint32 id_var_vface;
|
|
|
// ids for types so we can reuse them after they're declared
|
|
|
uint32 tid[STI_LENGTH_];
|
|
|
uint32 idtrue;
|
|
|
uint32 idfalse;
|
|
|
uint32 id_0_0[4];
|
|
|
uint32 id_0_125[4];
|
|
|
uint32 id_0_25[4];
|
|
|
uint32 id_0_5[4];
|
|
|
uint32 id_1_0[4];
|
|
|
uint32 id_2_0[4];
|
|
|
uint32 id_4_0[4];
|
|
|
uint32 id_8_0[4];
|
|
|
uint32 id_flt_max[4];
|
|
|
struct {
|
|
|
uint32 idvec4;
|
|
|
uint32 idivec4;
|
|
|
uint32 idbool;
|
|
|
} uniform_arrays;
|
|
|
struct {
|
|
|
uint32 idvec4;
|
|
|
} constant_arrays;
|
|
|
struct {
|
|
|
ComponentList f;
|
|
|
ComponentList i;
|
|
|
ComponentList u;
|
|
|
} cl;
|
|
|
|
|
|
SpirvPatchTable patch_table;
|
|
|
|
|
|
// Required only on ps_1_3 and below, which only has 4 registers for this purpose.
|
|
|
struct {
|
|
|
uint32 idtexbem;
|
|
|
uint32 idtexbeml;
|
|
|
} sampler_extras[4];
|
|
|
|
|
|
int loop_stack_idx;
|
|
|
SpirvLoopInfo loop_stack[32];
|
|
|
} SpirvContext;
|
|
|
|
|
|
#endif // if SUPPORT_PROFILE_SPIRV
|
|
|
|
|
|
#endif
|
|
|
|