Harbor

branch main
showing the latest snapshot on main
dxbc_spec.odin 11.1 KB · Plain text
shader/dxbc_spec.odin 0644 Raw
package shader

// DXBC (SM5.0) binary format constants.
// Subset needed for Luma shader compilation.

// Container magic
DXBC_MAGIC :: 0x43425844 // "DXBC" little-endian

// Chunk type identifiers
DXBC_CHUNK_RDEF :: 0x46454452 // "RDEF"
DXBC_CHUNK_ISGN :: 0x4E475349 // "ISGN"
DXBC_CHUNK_OSGN :: 0x4E47534F // "OSGN"
DXBC_CHUNK_SHEX :: 0x58454853 // "SHEX"
DXBC_CHUNK_STAT :: 0x54415453 // "STAT"

// Shader types for version token
DXBC_PROG_PIXEL    :: 0
DXBC_PROG_VERTEX   :: 1
DXBC_PROG_GEOMETRY :: 2
DXBC_PROG_HULL     :: 3
DXBC_PROG_DOMAIN   :: 4
DXBC_PROG_COMPUTE  :: 5

// Build version token: (type << 16) | (major << 4) | minor
dxbc_version_token :: proc(prog_type: u32, major: u32 = 5, minor: u32 = 0) -> u32 {
	return (prog_type << 16) | (major << 4) | minor
}

// ---- Opcodes ----

DXBC_OP_ADD          :: 0
DXBC_OP_AND          :: 1
DXBC_OP_BREAK        :: 2
DXBC_OP_BREAKC       :: 3
DXBC_OP_CALL         :: 4
DXBC_OP_CALLC        :: 5
DXBC_OP_CASE         :: 6
DXBC_OP_CONTINUE     :: 7
DXBC_OP_CONTINUEC    :: 8
DXBC_OP_CUT          :: 9
DXBC_OP_DEFAULT      :: 10
DXBC_OP_DERIV_RTX    :: 11
DXBC_OP_DERIV_RTY    :: 12
DXBC_OP_DISCARD      :: 13
DXBC_OP_DIV          :: 14
DXBC_OP_DP2          :: 15
DXBC_OP_DP3          :: 16
DXBC_OP_DP4          :: 17
DXBC_OP_ELSE         :: 18
DXBC_OP_EMIT         :: 19
DXBC_OP_EMITTHENCUT  :: 20
DXBC_OP_ENDIF        :: 21
DXBC_OP_ENDLOOP      :: 22
DXBC_OP_ENDSWITCH    :: 23
DXBC_OP_EQ           :: 24
DXBC_OP_EXP          :: 25
DXBC_OP_FRC          :: 26
DXBC_OP_FTOI         :: 27
DXBC_OP_FTOU         :: 28
DXBC_OP_GE           :: 29
DXBC_OP_IADD         :: 30
DXBC_OP_IF           :: 31
DXBC_OP_IEQ          :: 32
DXBC_OP_IGE          :: 33
DXBC_OP_ILT          :: 34
DXBC_OP_IMAD         :: 35
DXBC_OP_IMAX         :: 36
DXBC_OP_IMIN         :: 37
DXBC_OP_IMUL         :: 38
DXBC_OP_INE          :: 39
DXBC_OP_INEG         :: 40
DXBC_OP_ISHL         :: 41
DXBC_OP_ISHR         :: 42
DXBC_OP_ITOF         :: 43
DXBC_OP_LABEL        :: 44
DXBC_OP_LD           :: 45
DXBC_OP_LD_MS        :: 46
DXBC_OP_LOG          :: 47
DXBC_OP_LOOP         :: 48
DXBC_OP_LT           :: 49
DXBC_OP_MAD          :: 50
DXBC_OP_MIN          :: 51
DXBC_OP_MAX          :: 52
DXBC_OP_CUSTOMDATA   :: 53
DXBC_OP_MOV          :: 54
DXBC_OP_MOVC         :: 55
DXBC_OP_MUL          :: 56
DXBC_OP_NE           :: 57
DXBC_OP_NOP          :: 58
DXBC_OP_NOT          :: 59
DXBC_OP_OR           :: 60
DXBC_OP_RESINFO      :: 61
DXBC_OP_RET          :: 62
DXBC_OP_RETC         :: 63
DXBC_OP_ROUND_NE     :: 64
DXBC_OP_ROUND_NI     :: 65
DXBC_OP_ROUND_PI     :: 66
DXBC_OP_ROUND_Z      :: 67
DXBC_OP_RSQ          :: 68
DXBC_OP_SAMPLE       :: 69
DXBC_OP_SAMPLE_C     :: 70
DXBC_OP_SAMPLE_C_LZ  :: 71
DXBC_OP_SAMPLE_L     :: 72
DXBC_OP_SAMPLE_D     :: 73
DXBC_OP_SAMPLE_B     :: 74
DXBC_OP_SQRT         :: 75
DXBC_OP_SWITCH       :: 76
DXBC_OP_SINCOS       :: 77
DXBC_OP_UDIV         :: 78
DXBC_OP_ULT          :: 79
DXBC_OP_UGE          :: 80
DXBC_OP_UMUL         :: 81
DXBC_OP_UMAD         :: 82
DXBC_OP_UMAX         :: 83
DXBC_OP_UMIN         :: 84
DXBC_OP_USHR         :: 85
DXBC_OP_UTOF         :: 86
DXBC_OP_XOR          :: 87
DXBC_OP_DCL_RESOURCE :: 88
DXBC_OP_DCL_CONSTANT_BUFFER :: 89
DXBC_OP_DCL_SAMPLER  :: 90
DXBC_OP_DCL_INDEX_RANGE :: 91
DXBC_OP_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY :: 92
DXBC_OP_DCL_GS_INPUT_PRIMITIVE           :: 93
DXBC_OP_DCL_MAX_OUTPUT_VERTEX_COUNT      :: 94
DXBC_OP_DCL_INPUT          :: 95
DXBC_OP_DCL_INPUT_SGV      :: 96
DXBC_OP_DCL_INPUT_SIV      :: 97
DXBC_OP_DCL_INPUT_PS       :: 98
DXBC_OP_DCL_INPUT_PS_SGV   :: 99
DXBC_OP_DCL_INPUT_PS_SIV   :: 100
DXBC_OP_DCL_OUTPUT         :: 101
DXBC_OP_DCL_OUTPUT_SGV     :: 102
DXBC_OP_DCL_OUTPUT_SIV     :: 103
DXBC_OP_DCL_TEMPS          :: 104
DXBC_OP_DCL_INDEXABLE_TEMP :: 105
DXBC_OP_DCL_GLOBAL_FLAGS   :: 106

// SM5.0 additions
DXBC_OP_DCL_THREAD_GROUP            :: 155
DXBC_OP_DCL_UNORDERED_ACCESS_VIEW_TYPED :: 138
DXBC_OP_DCL_TGSM_RAW               :: 159
DXBC_OP_DCL_TGSM_STRUCTURED        :: 160
DXBC_OP_LD_STRUCTURED              :: 161
DXBC_OP_STORE_STRUCTURED           :: 173
DXBC_OP_SYNC                        :: 168

// ---- Operand types (bits 12-19 of operand token) ----

DXBC_OPERAND_TEMP             :: 0
DXBC_OPERAND_INPUT            :: 1
DXBC_OPERAND_OUTPUT           :: 2
DXBC_OPERAND_INDEXABLE_TEMP   :: 3
DXBC_OPERAND_IMMEDIATE32      :: 4
DXBC_OPERAND_IMMEDIATE64      :: 5
DXBC_OPERAND_SAMPLER          :: 6
DXBC_OPERAND_RESOURCE         :: 7
DXBC_OPERAND_CONSTANT_BUFFER  :: 8
DXBC_OPERAND_IMMEDIATE_CONSTANT_BUFFER :: 9
DXBC_OPERAND_LABEL            :: 10
DXBC_OPERAND_INPUT_PRIMITIVEID :: 11
DXBC_OPERAND_OUTPUT_DEPTH     :: 12
DXBC_OPERAND_NULL             :: 13
DXBC_OPERAND_OUTPUT_COVERAGE_MASK :: 14
DXBC_OPERAND_STREAM           :: 15
DXBC_OPERAND_FUNCTION_BODY    :: 16
DXBC_OPERAND_FUNCTION_TABLE   :: 17
DXBC_OPERAND_INTERFACE        :: 18
DXBC_OPERAND_FUNCTION_INPUT   :: 19
DXBC_OPERAND_FUNCTION_OUTPUT  :: 20
DXBC_OPERAND_OUTPUT_CONTROL_POINT_ID :: 21
DXBC_OPERAND_INPUT_FORK_INSTANCE_ID  :: 22
DXBC_OPERAND_INPUT_JOIN_INSTANCE_ID  :: 23
DXBC_OPERAND_INPUT_CONTROL_POINT     :: 24
DXBC_OPERAND_OUTPUT_CONTROL_POINT    :: 25
DXBC_OPERAND_INPUT_PATCH_CONSTANT    :: 26
DXBC_OPERAND_INPUT_DOMAIN_POINT      :: 27
DXBC_OPERAND_THIS_POINTER            :: 28
DXBC_OPERAND_UNORDERED_ACCESS_VIEW   :: 29
DXBC_OPERAND_THREAD_GROUP_SHARED_MEMORY :: 30
DXBC_OPERAND_INPUT_THREAD_ID         :: 31
DXBC_OPERAND_INPUT_THREAD_GROUP_ID   :: 32
DXBC_OPERAND_INPUT_THREAD_ID_IN_GROUP :: 33
DXBC_OPERAND_INPUT_COVERAGE_MASK     :: 34
DXBC_OPERAND_INPUT_THREAD_ID_IN_GROUP_FLATTENED :: 35

// ---- Component selection modes (bits 2-3 of operand token) ----

DXBC_COMP_MASK     :: 0 // destination: write mask in bits 4-7
DXBC_COMP_SWIZZLE  :: 1 // source: component swizzle in bits 4-11
DXBC_COMP_SELECT_1 :: 2 // source: single component select in bits 4-5

// Component count (bits 0-1 of operand token)
DXBC_COMP_0 :: 0 // 0 components (e.g. label)
DXBC_COMP_1 :: 1 // 1 component (scalar)
DXBC_COMP_4 :: 2 // 4 components (vec4)
DXBC_COMP_N :: 3 // N components (rare)

// Swizzle component indices
DXBC_SWIZZLE_X :: 0
DXBC_SWIZZLE_Y :: 1
DXBC_SWIZZLE_Z :: 2
DXBC_SWIZZLE_W :: 3

// Component mask bits (for DXBC_COMP_MASK mode, bits 4-7)
DXBC_WRITEMASK_X :: 0x1
DXBC_WRITEMASK_Y :: 0x2
DXBC_WRITEMASK_Z :: 0x4
DXBC_WRITEMASK_W :: 0x8
DXBC_WRITEMASK_ALL :: 0xF

// Index dimensions (bits 20-21 of operand token)
DXBC_INDEX_0D :: 0 // no index (immediate)
DXBC_INDEX_1D :: 1 // one index (e.g. rN)
DXBC_INDEX_2D :: 2 // two indices (e.g. cbN[M])
DXBC_INDEX_3D :: 3 // three indices

// Index representation (bits 22-24 for dim0, bits 25-27 for dim1)
DXBC_INDEX_IMM32       :: 0
DXBC_INDEX_IMM64       :: 1
DXBC_INDEX_RELATIVE    :: 2
DXBC_INDEX_IMM32_PLUS_RELATIVE :: 3

// ---- System values for ISGN/OSGN ----

DXBC_SV_UNDEFINED      :: 0
DXBC_SV_POSITION       :: 1
DXBC_SV_CLIP_DISTANCE  :: 2
DXBC_SV_CULL_DISTANCE  :: 3
DXBC_SV_RENDER_TARGET_ARRAY_INDEX :: 4
DXBC_SV_VIEWPORT_ARRAY_INDEX     :: 5
DXBC_SV_VERTEX_ID      :: 6
DXBC_SV_PRIMITIVE_ID   :: 7
DXBC_SV_INSTANCE_ID    :: 8
DXBC_SV_IS_FRONT_FACE  :: 9
DXBC_SV_SAMPLE_INDEX   :: 10
DXBC_SV_TARGET         :: 0 // SV_Target uses system value 0 (undefined)
DXBC_SV_DEPTH          :: 12
DXBC_SV_COVERAGE       :: 13

// ---- Interpolation modes (for DCL_INPUT_PS) ----

DXBC_INTERPOLATION_UNDEFINED              :: 0
DXBC_INTERPOLATION_CONSTANT               :: 1
DXBC_INTERPOLATION_LINEAR                 :: 2
DXBC_INTERPOLATION_LINEAR_CENTROID        :: 3
DXBC_INTERPOLATION_LINEAR_NOPERSPECTIVE   :: 4
DXBC_INTERPOLATION_LINEAR_NOPERSPECTIVE_CENTROID :: 5
DXBC_INTERPOLATION_LINEAR_SAMPLE          :: 6
DXBC_INTERPOLATION_LINEAR_NOPERSPECTIVE_SAMPLE   :: 7

// ---- Resource dimensions (for DCL_RESOURCE) ----

DXBC_RESOURCE_DIM_BUFFER         :: 1
DXBC_RESOURCE_DIM_TEXTURE1D      :: 2
DXBC_RESOURCE_DIM_TEXTURE2D      :: 3
DXBC_RESOURCE_DIM_TEXTURE2DMS    :: 4
DXBC_RESOURCE_DIM_TEXTURE3D      :: 5
DXBC_RESOURCE_DIM_TEXTURECUBE    :: 6
DXBC_RESOURCE_DIM_TEXTURE1DARRAY :: 7
DXBC_RESOURCE_DIM_TEXTURE2DARRAY :: 8

// Resource return type (for DCL_RESOURCE return type token)
DXBC_RETURN_TYPE_UNORM  :: 1
DXBC_RETURN_TYPE_SNORM  :: 2
DXBC_RETURN_TYPE_SINT   :: 3
DXBC_RETURN_TYPE_UINT   :: 4
DXBC_RETURN_TYPE_FLOAT  :: 5
DXBC_RETURN_TYPE_MIXED  :: 6

// ---- Sampler mode (for DCL_SAMPLER) ----

DXBC_SAMPLER_DEFAULT    :: 0
DXBC_SAMPLER_COMPARISON :: 1
DXBC_SAMPLER_MONO       :: 2

// ---- Constant buffer access pattern (for DCL_CONSTANT_BUFFER) ----

DXBC_CB_ACCESS_IMMEDIATE :: 0
DXBC_CB_ACCESS_DYNAMIC   :: 1

// ---- Sync flags (for SYNC instruction) ----

DXBC_SYNC_THREADS_IN_GROUP      :: 0x800
DXBC_SYNC_THREAD_GROUP_SHARED   :: 0x400
DXBC_SYNC_UNORDERED_ACCESS_VIEW :: 0x200

// ---- Shader type flags for RDEF ----

DXBC_RDEF_SHADER_VS :: 0xFFFE
DXBC_RDEF_SHADER_PS :: 0xFFFF
DXBC_RDEF_SHADER_CS :: 0x4353 // "CS"

// ---- RDEF variable types ----

DXBC_SVT_VOID    :: 0
DXBC_SVT_BOOL    :: 1
DXBC_SVT_INT     :: 2
DXBC_SVT_FLOAT   :: 3
DXBC_SVT_UINT    :: 19

DXBC_SVC_SCALAR         :: 0
DXBC_SVC_VECTOR         :: 1
DXBC_SVC_MATRIX_ROWS    :: 2
DXBC_SVC_MATRIX_COLUMNS :: 3

// ---- Helpers for building operand tokens ----

dxbc_operand_token :: proc(comp_count: u32, sel_mode: u32, op_type: u32, index_dim: u32) -> u32 {
	return comp_count | (sel_mode << 2) | (op_type << 12) | (index_dim << 20)
}

dxbc_mask_operand :: proc(op_type: u32, index_dim: u32, mask: u32) -> u32 {
	return DXBC_COMP_4 | (DXBC_COMP_MASK << 2) | (u32(mask) << 4) | (op_type << 12) | (index_dim << 20)
}

dxbc_swizzle_operand :: proc(op_type: u32, index_dim: u32, swizzle: u32) -> u32 {
	return DXBC_COMP_4 | (DXBC_COMP_SWIZZLE << 2) | (swizzle << 4) | (op_type << 12) | (index_dim << 20)
}

dxbc_select1_operand :: proc(op_type: u32, index_dim: u32, component: u32) -> u32 {
	return DXBC_COMP_4 | (DXBC_COMP_SELECT_1 << 2) | (component << 4) | (op_type << 12) | (index_dim << 20)
}

dxbc_scalar_operand :: proc(op_type: u32, index_dim: u32) -> u32 {
	return DXBC_COMP_1 | (op_type << 12) | (index_dim << 20)
}

// Build a swizzle value from 4 component indices (each 0-3)
dxbc_swizzle :: proc(x: u32 = 0, y: u32 = 1, z: u32 = 2, w: u32 = 3) -> u32 {
	return x | (y << 2) | (z << 4) | (w << 6)
}

// Identity swizzle (.xyzw)
DXBC_SWIZZLE_IDENTITY :: u32(0) | (1 << 2) | (2 << 4) | (3 << 6) // x,y,z,w

// Replicate swizzle (e.g. .xxxx)
dxbc_swizzle_replicate :: proc(c: u32) -> u32 {
	return c | (c << 2) | (c << 4) | (c << 6)
}

// Write mask from component count
dxbc_mask_from_count :: proc(count: int) -> u32 {
	switch count {
	case 1: return DXBC_WRITEMASK_X
	case 2: return DXBC_WRITEMASK_X | DXBC_WRITEMASK_Y
	case 3: return DXBC_WRITEMASK_X | DXBC_WRITEMASK_Y | DXBC_WRITEMASK_Z
	case:   return DXBC_WRITEMASK_ALL
	}
}

// Index representation encoding in operand token
// dim0 rep goes in bits 22-24, dim1 rep in bits 25-27
dxbc_index_rep :: proc(dim0: u32, dim1: u32 = 0) -> u32 {
	return (dim0 << 22) | (dim1 << 25)
}

// Opcode token: bits 0-10 = opcode, bits 24-30 = length
dxbc_opcode_token :: proc(opcode: u32, length: u32) -> u32 {
	return (opcode & 0x7FF) | ((length & 0x7F) << 24)
}

// Opcode token with additional control bits in 12-23
dxbc_opcode_token_ex :: proc(opcode: u32, length: u32, control: u32) -> u32 {
	return (opcode & 0x7FF) | ((control & 0xFFF) << 11) | ((length & 0x7F) << 24)
}