Shader lookup tables and compiled programs
A section’s material key joins three kinds of data: a parameter block in a loaded depot, a program-index row in
dingolevel_root_win32_shaderstate_db, and a streamable-texture-set row. Changing only one lookup can leave the
section bound inconsistently. Observed
The exhaustive level-root database census reads all 3,619 program records at 168 bytes each, with zero selector refusals. Proven · all level-root program records
The measured program grouping has 27 families. Observed
| Resource type | Role | Confidence |
|---|---|---|
0xe2e6955b ExpressionShaderDatabase |
Program records and material-key to program-index arrays | Observed |
0x2d254a89 StreamableTextureSetLookupTable family |
u64 key, u64 texture-set rows |
Observed |
0xd489facb RasterPermutation |
Shared-data id, input-layout id and vertex/pixel bytecode GUIDs | Observed |
0x95ce62dd ComputePermutation |
Shared-data id and compute-bytecode GUID | Observed |
0x0e2b02f7 CompiledBytecode |
Relocatable wrapper containing compiled DXBC/DXIL | Observed |
0x7d98f632 InputLayout |
Vertex input declaration | Observed |
0xa19b025d BindingSet |
Shader resource bindings | Observed |
0x2fec6526 ShaderStateAssetId |
32-byte sublevel-associated identity | Observed |
0x250047b2 RasterPermutationSharedData |
Packed fixed-function state (render-state bytes) | Observed |
0x879ba711 PermutationSharedData |
Not decoded here | Observed |
0x7a630735 StreamableTextureSet |
Not decoded here | Observed |
0xa8957ed6 RootSlotInitData |
Not decoded here | Observed |
0x589bb36e PassBinding |
Pass-supplied binding groups | Observed |
0x6a5be5db BindingSignature |
Not decoded here | Observed |
These type ids are djb2-XOR hashes of the lowercased full type names (ExpressionShaderDatabase,
ExpressionShaderRasterPermutation and so on), whose strings lie in the executable’s read-only data at
Skate+0x64dcb80. Observed
The ShaderStateAssetId’s final 16 bytes equal its sublevel EBX file GUID in measured examples. Its first 16 bytes have no established meaning. Cell depots without this resource still resolve correctly in game. Observed
Material lookup rows
Section titled “Material lookup rows”The ExpressionShaderDatabase metadata gives program bytes, relocation bytes and lookup bytes. The lookup starts
after program and relocation data with a u32 row count; each row is u64 material_key, u32 index_count, then
that many u32 program indexes. Texture-set lookup rows are sixteen bytes each. Observed
A measured mapping from program row to texture set is single-valued for all 2,016 checked rows. Every one of 1,245 checked program tuples uses exactly one vertex declaration. These checks cover the measured stock tables, not arbitrary newly authored programs. Observed
Program selectors
Section titled “Program selectors”Program records contain twelve (u32 count, u64 pointer) items from offset 0x18, at twelve-byte intervals.
Five items form a decision tree. A strict census reads every record in the game configuration and dingolevel_root
databases: 5,137 records (1,518 and 3,619 respectively), with zero refusals. The array layout and tree invariants
below hold throughout these two databases. Proven · all 5,137 records in both databases
| Offset | Array | Confidence |
|---|---|---|
0x30 |
Options: 16-byte name/type/count/extra records | Proven · 5,137 records |
0x3c |
Nodes: u16 option_index, start, length |
Proven · 5,137 records |
0x48 |
One u64 option-value hash per entry |
Proven · 5,137 records |
0x54 |
u16 entries: child-node index or 0x8000 + permutation_index |
Proven · 5,137 records |
0x60 |
u64 permutation ids |
Proven · 5,137 records |
Node zero is the root. A node tests its indexed option and selects an entry by value hash; an entry either continues to a child or terminates at a permutation. Options increase along a path. Of the 5,137 records, 473 have no options and one permutation; the other 4,664 have trees of one to seven options. Those trees contain 42,297 nodes, including 2,444 mixing child and leaf entries, and 62,274 leaves. Every permutation index occurs once among its record’s leaves, and walking each leaf’s own path returns the expected permutation in all 62,274 cases. Proven · all records and leaves in both databases
The option names and values are still hashes. Only 43 of 1,345 option-name hashes also appear in material depot parameters; deriving all selector values from the material alone is not supported by this measurement. Most options share a value-hash set with others (15 of 18 sampled names). In 130 sampled records, a permutation’s input layout depends on one or two tree levels, always including the last. Observed
Permutations and bytecode
Section titled “Permutations and bytecode”Little-endian; GUID array follows at 0x20 in measured records.
| Offset | Size | Type | Field | Confidence | Notes |
|---|---|---|---|---|---|
| 0x0 | 8 | u64 | shared-data id | Observed | |
| 0x8 | 8 | u64 | GUID array pointer | Observed | |
| 0x10 | 8 | u64 | input-layout id | Observed | |
| 0x18 | 8 | u64 | unknown | Unknown | Zero in measured records. |
A raster permutation names vertex bytecode and optionally pixel bytecode. A compute permutation stores shared-data
id and GUID pointer at 0 and 8, followed by its compute GUID at 0x10. The GUID resolves a resource named
shaders/bytecode/<guid>. Observed
A stock-data census counts 20,429 CompiledBytecode resource entries across twelve TOCs. All embedded containers
have DXIL chunks; eight entries in globals contain two DXBC signatures and the remainder contain one. The
ordinary wrapper begins u16 6, u16 2 and contains an RC2S block at 0x20; observed DXBC starts range from 88 to 294
bytes. Trailing wrapper data is common. Every CompiledBytecode entry in this twelve-TOC census contains the
described DXIL container structure; no container is refused. Proven · all CompiledBytecode entries
The parts of these containers, their digest, the PSV0 record and the feature mask are described on
Direct3D shader containers.
The compiled programs are not in the six high-entropy chunks stored beside the shader-state database, and the bytecode is not encrypted: it is these plain CompiledBytecode resources. Observed
Two-container ray-tracing wrappers use RPTR at 0x20. The embedded DXBC length is stored at container +24;
container bytes and surrounding wrapper bytes are separate extents. Observed
Register mappings and vertex-input structures are described under bindings and input layouts.
ReSkate’s map merge keeps base programs and does not accept map-supplied shader bytecode. Studio’s private
vertex_blend program is therefore subject to loader behaviour beyond a valid container layout.
Sourced · ReSkate See Studio compilation.
The tree structure is validated across both databases, but the option names, value hashes and all caller-supplied values are not decoded. The other seven program-array items are also unresolved. Unknown