ir3: Fix handling cat6 immediates
We were treating them the same as regular cat2/cat3/cat4 immediates, but that's not right because cat6 sources are only 8 bits. Our bindless code was handling this before for bindless resources, and it was disabled for most other things, so this was mostly harmless, but fixing it will be necessary for handling ldc offsets. In addition enable tests for this that were just commented out, and add a custom test making sure that the immediate source is treated as unsigned. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13142>
This commit is contained in:
@@ -4638,12 +4638,12 @@ shader-blocks:
|
||||
size: 2048
|
||||
:0:0000:0000[00000000x_00003002x] nop
|
||||
:0:0001:0001[00000000x_00000000x] nop
|
||||
:6:0002:0002[deadbeefx_deadbeefx] (sy)(jp)atomic.xor.typed.4d.u8.4.l r59.w, l[r45.z], -34 ; dontcare bits in atomic.xor: 00000000000000ee, WARNING: unexpected bits[41:48] in #instruction-cat6-a3xx-atomic: 00000000000000df vs 0000000000000000, WARNING: unexpected bits[53:53] in #instruction-cat6-a3xx-atomic: 0000000000000001 vs 0000000000000000
|
||||
:6:0003:0003[deadbeefx_deadbeefx] (sy)(jp)atomic.xor.typed.4d.u8.4.l r59.w, l[r45.z], -34 ; dontcare bits in atomic.xor: 00000000000000ee, WARNING: unexpected bits[41:48] in #instruction-cat6-a3xx-atomic: 00000000000000df vs 0000000000000000, WARNING: unexpected bits[53:53] in #instruction-cat6-a3xx-atomic: 0000000000000001 vs 0000000000000000
|
||||
:6:0004:0004[deadbeefx_deadbeefx] (sy)(jp)atomic.xor.typed.4d.u8.4.l r59.w, l[r45.z], -34 ; dontcare bits in atomic.xor: 00000000000000ee, WARNING: unexpected bits[41:48] in #instruction-cat6-a3xx-atomic: 00000000000000df vs 0000000000000000, WARNING: unexpected bits[53:53] in #instruction-cat6-a3xx-atomic: 0000000000000001 vs 0000000000000000
|
||||
:6:0005:0005[deadbeefx_deadbeefx] (sy)(jp)atomic.xor.typed.4d.u8.4.l r59.w, l[r45.z], -34 ; dontcare bits in atomic.xor: 00000000000000ee, WARNING: unexpected bits[41:48] in #instruction-cat6-a3xx-atomic: 00000000000000df vs 0000000000000000, WARNING: unexpected bits[53:53] in #instruction-cat6-a3xx-atomic: 0000000000000001 vs 0000000000000000
|
||||
:6:0006:0006[deadbeefx_deadbeefx] (sy)(jp)atomic.xor.typed.4d.u8.4.l r59.w, l[r45.z], -34 ; dontcare bits in atomic.xor: 00000000000000ee, WARNING: unexpected bits[41:48] in #instruction-cat6-a3xx-atomic: 00000000000000df vs 0000000000000000, WARNING: unexpected bits[53:53] in #instruction-cat6-a3xx-atomic: 0000000000000001 vs 0000000000000000
|
||||
:6:0007:0007[deadbeefx_deadbeefx] (sy)(jp)atomic.xor.typed.4d.u8.4.l r59.w, l[r45.z], -34 ; dontcare bits in atomic.xor: 00000000000000ee, WARNING: unexpected bits[41:48] in #instruction-cat6-a3xx-atomic: 00000000000000df vs 0000000000000000, WARNING: unexpected bits[53:53] in #instruction-cat6-a3xx-atomic: 0000000000000001 vs 0000000000000000
|
||||
:6:0002:0002[deadbeefx_deadbeefx] (sy)(jp)atomic.xor.typed.4d.u8.4.l r59.w, l[r45.z], 222 ; dontcare bits in atomic.xor: 00000000000000ee, WARNING: unexpected bits[41:48] in #instruction-cat6-a3xx-atomic: 00000000000000df vs 0000000000000000, WARNING: unexpected bits[53:53] in #instruction-cat6-a3xx-atomic: 0000000000000001 vs 0000000000000000
|
||||
:6:0003:0003[deadbeefx_deadbeefx] (sy)(jp)atomic.xor.typed.4d.u8.4.l r59.w, l[r45.z], 222 ; dontcare bits in atomic.xor: 00000000000000ee, WARNING: unexpected bits[41:48] in #instruction-cat6-a3xx-atomic: 00000000000000df vs 0000000000000000, WARNING: unexpected bits[53:53] in #instruction-cat6-a3xx-atomic: 0000000000000001 vs 0000000000000000
|
||||
:6:0004:0004[deadbeefx_deadbeefx] (sy)(jp)atomic.xor.typed.4d.u8.4.l r59.w, l[r45.z], 222 ; dontcare bits in atomic.xor: 00000000000000ee, WARNING: unexpected bits[41:48] in #instruction-cat6-a3xx-atomic: 00000000000000df vs 0000000000000000, WARNING: unexpected bits[53:53] in #instruction-cat6-a3xx-atomic: 0000000000000001 vs 0000000000000000
|
||||
:6:0005:0005[deadbeefx_deadbeefx] (sy)(jp)atomic.xor.typed.4d.u8.4.l r59.w, l[r45.z], 222 ; dontcare bits in atomic.xor: 00000000000000ee, WARNING: unexpected bits[41:48] in #instruction-cat6-a3xx-atomic: 00000000000000df vs 0000000000000000, WARNING: unexpected bits[53:53] in #instruction-cat6-a3xx-atomic: 0000000000000001 vs 0000000000000000
|
||||
:6:0006:0006[deadbeefx_deadbeefx] (sy)(jp)atomic.xor.typed.4d.u8.4.l r59.w, l[r45.z], 222 ; dontcare bits in atomic.xor: 00000000000000ee, WARNING: unexpected bits[41:48] in #instruction-cat6-a3xx-atomic: 00000000000000df vs 0000000000000000, WARNING: unexpected bits[53:53] in #instruction-cat6-a3xx-atomic: 0000000000000001 vs 0000000000000000
|
||||
:6:0007:0007[deadbeefx_deadbeefx] (sy)(jp)atomic.xor.typed.4d.u8.4.l r59.w, l[r45.z], 222 ; dontcare bits in atomic.xor: 00000000000000ee, WARNING: unexpected bits[41:48] in #instruction-cat6-a3xx-atomic: 00000000000000df vs 0000000000000000, WARNING: unexpected bits[53:53] in #instruction-cat6-a3xx-atomic: 0000000000000001 vs 0000000000000000
|
||||
-----------------------------------------------
|
||||
8192 (0x2000) bytes
|
||||
000000: 00003002 00000000 00000000 00000000 |.0..............|
|
||||
|
@@ -974,3 +974,39 @@ ir3_valid_flags(struct ir3_instruction *instr, unsigned n, unsigned flags)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ir3_valid_immediate(struct ir3_instruction *instr, int32_t immed)
|
||||
{
|
||||
if (instr->opc == OPC_MOV || is_meta(instr))
|
||||
return true;
|
||||
|
||||
if (is_mem(instr)) {
|
||||
switch (instr->opc) {
|
||||
/* Some load/store instructions have a 13-bit offset and size which must
|
||||
* always be an immediate and the rest of the sources cannot be
|
||||
* immediates, so the frontend is responsible for checking the size:
|
||||
*/
|
||||
case OPC_LDL:
|
||||
case OPC_STL:
|
||||
case OPC_LDP:
|
||||
case OPC_STP:
|
||||
case OPC_LDG:
|
||||
case OPC_STG:
|
||||
case OPC_SPILL_MACRO:
|
||||
case OPC_RELOAD_MACRO:
|
||||
case OPC_LDG_A:
|
||||
case OPC_STG_A:
|
||||
case OPC_LDLW:
|
||||
case OPC_STLW:
|
||||
case OPC_LDLV:
|
||||
return true;
|
||||
default:
|
||||
/* most cat6 src immediates can only encode 8 bits: */
|
||||
return !(immed & ~0xff);
|
||||
}
|
||||
}
|
||||
|
||||
/* Other than cat1 (mov) we can only encode up to 10 bits, sign-extended: */
|
||||
return !(immed & ~0x1ff) || !(-immed & ~0x1ff);
|
||||
}
|
||||
|
@@ -736,6 +736,8 @@ int ir3_flut(struct ir3_register *src_reg);
|
||||
|
||||
bool ir3_valid_flags(struct ir3_instruction *instr, unsigned n, unsigned flags);
|
||||
|
||||
bool ir3_valid_immediate(struct ir3_instruction *instr, int32_t immed);
|
||||
|
||||
#include "util/set.h"
|
||||
#define foreach_ssa_use(__use, __instr) \
|
||||
for (struct ir3_instruction *__use = (void *)~0; __use && (__instr)->uses; \
|
||||
|
@@ -467,10 +467,8 @@ reg_cp(struct ir3_cp_ctx *ctx, struct ir3_instruction *instr,
|
||||
if (new_flags & IR3_REG_BNOT)
|
||||
iim_val = ~iim_val;
|
||||
|
||||
/* other than category 1 (mov) we can only encode up to 10 bits: */
|
||||
if (ir3_valid_flags(instr, n, new_flags) &&
|
||||
((instr->opc == OPC_MOV) || is_meta(instr) ||
|
||||
!((iim_val & ~0x1ff) && (-iim_val & ~0x1ff)))) {
|
||||
ir3_valid_immediate(instr, iim_val)) {
|
||||
new_flags &= ~(IR3_REG_SABS | IR3_REG_SNEG | IR3_REG_BNOT);
|
||||
src_reg = ir3_reg_clone(instr->block->shader, src_reg);
|
||||
src_reg->flags = new_flags;
|
||||
|
@@ -72,6 +72,9 @@ static void
|
||||
validate_src(struct ir3_validate_ctx *ctx, struct ir3_instruction *instr,
|
||||
struct ir3_register *reg)
|
||||
{
|
||||
if (reg->flags & IR3_REG_IMMED)
|
||||
validate_assert(ctx, ir3_valid_immediate(instr, reg->iim_val));
|
||||
|
||||
if (!(reg->flags & IR3_REG_SSA) || !reg->def)
|
||||
return;
|
||||
|
||||
|
@@ -291,22 +291,16 @@ static const struct test {
|
||||
/* LDC. Our disasm differs greatly from qcom here, and we've got some
|
||||
* important info they lack(?!), but same goes the other way.
|
||||
*/
|
||||
#if 0
|
||||
/* TODO our encoding differs in b23 for these four.. unsure if that is dontcare bit */
|
||||
/* dEQP-GLES31.functional.shaders.opaque_type_indexing.ubo.uniform_fragment */
|
||||
INSTR_6XX(c0260000_00c78040, "ldc.offset0.1.uniform r0.x, r0.x, r0.x"), /* ldc.1.mode1.base0 r0.x, 0, r0.x */
|
||||
INSTR_6XX(c0260201_00c78040, "ldc.offset0.1.uniform r0.y, r0.x, r0.y"), /* ldc.1.mode1.base0 r0.y, 0, r0.y */
|
||||
INSTR_6XX(c0260000_00c78040, "ldc.offset0.1.uniform r0.x, 0, r0.x"), /* ldc.1.mode1.base0 r0.x, 0, r0.x */
|
||||
INSTR_6XX(c0260201_00c78040, "ldc.offset0.1.uniform r0.y, 0, r0.y"), /* ldc.1.mode1.base0 r0.y, 0, r0.y */
|
||||
/* dEQP-GLES31.functional.shaders.opaque_type_indexing.ubo.dynamically_uniform_fragment */
|
||||
INSTR_6XX(c0260000_00c78080, "ldc.offset0.1.nonuniform r0.x, r0.x, r0.x"), /* ldc.1.mode2.base0 r0.x, 0, r0.x */
|
||||
INSTR_6XX(c0260201_00c78080, "ldc.offset0.1.nonuniform r0.y, r0.x, r0.y"), /* ldc.1.mode2.base0 r0.y, 0, r0.y */
|
||||
#else
|
||||
/* dEQP-GLES31.functional.shaders.opaque_type_indexing.ubo.uniform_fragment */
|
||||
INSTR_6XX(c0260000_00478040, "ldc.offset0.1.uniform r0.x, r0.x, r0.x"), /* ldc.1.mode1.base0 r0.x, 0, r0.x */
|
||||
INSTR_6XX(c0260201_00478040, "ldc.offset0.1.uniform r0.y, r0.x, r0.y"), /* ldc.1.mode1.base0 r0.y, 0, r0.y */
|
||||
/* dEQP-GLES31.functional.shaders.opaque_type_indexing.ubo.dynamically_uniform_fragment */
|
||||
INSTR_6XX(c0260000_00478080, "ldc.offset0.1.nonuniform r0.x, r0.x, r0.x"), /* ldc.1.mode2.base0 r0.x, 0, r0.x */
|
||||
INSTR_6XX(c0260201_00478080, "ldc.offset0.1.nonuniform r0.y, r0.x, r0.y"), /* ldc.1.mode2.base0 r0.y, 0, r0.y */
|
||||
#endif
|
||||
INSTR_6XX(c0260000_00c78080, "ldc.offset0.1.nonuniform r0.x, 0, r0.x"), /* ldc.1.mode2.base0 r0.x, 0, r0.x */
|
||||
INSTR_6XX(c0260201_00c78080, "ldc.offset0.1.nonuniform r0.y, 0, r0.y"), /* ldc.1.mode2.base0 r0.y, 0, r0.y */
|
||||
|
||||
/* custom */
|
||||
INSTR_6XX(c0260201_ffc78080, "ldc.offset0.1.nonuniform r0.y, 255, r0.y"), /* ldc.1.mode2.base0 r0.y, 255, r0.y */
|
||||
|
||||
/* custom shaders, loading .x, .y, .z, .w from an array of vec4 in block 0 */
|
||||
INSTR_6XX(c0260000_00478000, "ldc.offset0.1.imm r0.x, r0.x, 0"), /* ldc.1.mode0.base0 r0.x, r0.x, 0 */
|
||||
INSTR_6XX(c0260000_00478200, "ldc.offset1.1.imm r0.x, r0.x, 0"), /* ldc.1.mode0.base0 r0.x, r0.x, 0 */
|
||||
|
@@ -892,7 +892,7 @@ SOFTWARE.
|
||||
<display>
|
||||
{IMMED}
|
||||
</display>
|
||||
<field name="IMMED" low="0" high="7" type="int"/>
|
||||
<field name="IMMED" low="0" high="7" type="uint"/>
|
||||
</override>
|
||||
<display>
|
||||
r{GPR}.{SWIZ}
|
||||
|
Reference in New Issue
Block a user