The BASE field is actually split across BASE_LO and BASE_HI, but '.baseN' should only appear in the bindless case.. the easiest way to accomplish that is by splitting it out into a bitset. We just arbitrarily map this to BASE_LO {BINDLESS} .base{BASE} ({BASE_HI} * 2) | {BASE_LO} src->cat5.tex_base & 0x1 {S2EN_BINDLESS} The s2en (indirect) or bindless case {SY}{JP}{NAME}{3D}{A}{O}{P}{S}{S2EN}{UNIFORM}{NONUNIFORM}{BASE} {TYPE}({WRMASK}){DST_HALF}{DST}{SRC1}{SRC2}{SRC3}{A1} The "normal" case, ie. not s2en (indirect) and/or bindless {SY}{JP}{NAME}{3D}{A}{O}{P}{S} {TYPE}({WRMASK}){DST_HALF}{DST}{SRC1}{SRC2}{SAMP}{TEX} ({TYPE} == 0) /* f16 */ || ({TYPE} == 2) /* u16 */ || ({TYPE} == 4) /* s16 */ || ({TYPE} == 6) /* u8 */ || ({TYPE} == 7) /* s8 */ 0x 00 0 101 extract_cat5_FULL(src) src src src->dsts[0]->wrmask src src src->cat5.tex_base >> 1 !!(src->flags & IR3_INSTR_3D) !!(src->flags & IR3_INSTR_A) !!(src->flags & IR3_INSTR_S) !!(src->flags & (IR3_INSTR_S2EN | IR3_INSTR_B)) !!(src->flags & IR3_INSTR_O) !!(src->flags & IR3_INSTR_P) extract_cat5_DESC_MODE(src) extract_cat5_SRC(src, 0) extract_cat5_SRC(src, 1) (src->srcs_count > 0) ? src->srcs[0] : NULL 00000 00001 00010 00011 00100 00101 00110 00111 01000 01001 01010 01011 01100 01101 01110 01111 10000 10001 10010 10011 10100 10101 10110 10111 11000 11001 11010 11011 {NUM_SRC} > 0 , {HALF}{SRC} 00000000 src {O} || ({NUM_SRC} > 1) , {HALF}{SRC} 00000000 src {HAS_SAMP} , s#{SAMP} 0000 src->cat5.samp s2en (indirect) / bindless case with a1.x has 8b samp {HAS_SAMP} , s#{SAMP} 00000000 src->cat5.samp {HAS_TEX} , t#{TEX} 0000000 src->cat5.tex s2en (indirect) / bindless case only has 4b tex {HAS_TEX} , t#{TEX} 0000 src->cat5.samp >> 4 {HAS_TYPE} ({TYPE}) src->cat5.type We don't actually display this enum, but it is useful to document the various cases TODO we should probably have an option for uniforms w/out display strings, but which have 'C' names that can be used to generate header that the compiler can use Use traditional GL binding model, get texture and sampler index from src3 which is not presumed to be uniform. This is backwards-compatible with earlier generations, where this field was always 0 and nonuniform-indexed sampling always worked. The sampler base comes from the low 3 bits of a1.x, and the sampler and texture index come from src3 which is presumed to be uniform. The texture and sampler share the same base, and the sampler and texture index come from src3 which is *not* presumed to be uniform. The sampler base comes from the low 3 bits of a1.x, and the sampler and texture index come from src3 which is *not* presumed to be uniform. Use traditional GL binding model, get texture and sampler index from src3 which is presumed to be uniform. The texture and sampler share the same base, and the sampler and texture index come from src3 which is presumed to be uniform. The texture and sampler share the same base, get sampler index from low 4 bits of src3 and texture index from high 4 bits. The sampler base comes from the low 3 bits of a1.x, and the texture index comes from the next 8 bits of a1.x. The sampler index is an immediate in src3. {DESC_MODE} < 6 /* CAT5_BINDLESS_IMM */ ({DESC_MODE} == 1) /* CAT5_BINDLESS_A1_UNIFORM */ || ({DESC_MODE} == 2) /* CAT5_BINDLESS_NONUNIFORM */ || ({DESC_MODE} == 3) /* CAT5_BINDLESS_A1_NONUNIFORM */ || ({DESC_MODE} == 5) /* CAT5_BINDLESS_UNIFORM */ || ({DESC_MODE} == 6) /* CAT5_BINDLESS_IMM */ || ({DESC_MODE} == 7) /* CAT5_BINDLESS_A1_IMM */ ({DESC_MODE} == 1) /* CAT5_BINDLESS_A1_UNIFORM */ || ({DESC_MODE} == 3) /* CAT5_BINDLESS_A1_NONUNIFORM */ || ({DESC_MODE} == 7) /* CAT5_BINDLESS_A1_IMM */ ({DESC_MODE} == 1) /* CAT5_BINDLESS_A1_UNIFORM */ || ({DESC_MODE} == 4) /* CAT5_UNIFORM */ || ({DESC_MODE} == 5) /* CAT5_BINDLESS_UNIFORM */ ({DESC_MODE} == 2) /* CAT5_BINDLESS_NONUNIFORM */ || ({DESC_MODE} == 3) /* CAT5_BINDLESS_A1_NONUNIFORM */ bindless/indirect src3, which can either be GPR or samp/tex , {SRC_HALF}{SRC} !{BINDLESS} In the case that a1.x is used, all 8 bits encode sampler {SAMP} {SAMP}{TEX} s->instr s->instr src