From: Marek Olšák Date: Mon, 2 Oct 2017 20:30:55 +0000 (+0200) Subject: tgsi: implement tgsi_util_get_inst_usage_mask properly X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=be3ab867bd444594f9d9e0f8e59d305d15769afd;p=mesa.git tgsi: implement tgsi_util_get_inst_usage_mask properly All opcodes are handled. Reviewed-by: Nicolai Hähnle --- diff --git a/src/gallium/auxiliary/tgsi/tgsi_util.c b/src/gallium/auxiliary/tgsi/tgsi_util.c index 327e42f7402..be8bcdf1233 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_util.c +++ b/src/gallium/auxiliary/tgsi/tgsi_util.c @@ -27,9 +27,11 @@ #include "util/u_debug.h" #include "pipe/p_shader_tokens.h" +#include "tgsi_info.h" #include "tgsi_parse.h" #include "tgsi_util.h" #include "tgsi_exec.h" +#include "util/bitscan.h" union pointer_hack { @@ -180,148 +182,227 @@ tgsi_util_get_inst_usage_mask(const struct tgsi_full_instruction *inst, unsigned chan; switch (inst->Instruction.Opcode) { - case TGSI_OPCODE_MOV: - case TGSI_OPCODE_ARL: - case TGSI_OPCODE_ARR: + case TGSI_OPCODE_IF: + case TGSI_OPCODE_UIF: + case TGSI_OPCODE_EMIT: + case TGSI_OPCODE_ENDPRIM: case TGSI_OPCODE_RCP: - case TGSI_OPCODE_MUL: - case TGSI_OPCODE_DIV: - case TGSI_OPCODE_ADD: - case TGSI_OPCODE_MIN: - case TGSI_OPCODE_MAX: - case TGSI_OPCODE_SLT: - case TGSI_OPCODE_SGE: - case TGSI_OPCODE_MAD: - case TGSI_OPCODE_LRP: - case TGSI_OPCODE_FMA: - case TGSI_OPCODE_FRC: - case TGSI_OPCODE_CEIL: - case TGSI_OPCODE_FLR: - case TGSI_OPCODE_ROUND: - case TGSI_OPCODE_POW: - case TGSI_OPCODE_COS: - case TGSI_OPCODE_SIN: - case TGSI_OPCODE_DDX: - case TGSI_OPCODE_DDY: - case TGSI_OPCODE_SEQ: - case TGSI_OPCODE_SGT: - case TGSI_OPCODE_SLE: - case TGSI_OPCODE_SNE: - case TGSI_OPCODE_SSG: - case TGSI_OPCODE_CMP: - case TGSI_OPCODE_TRUNC: - case TGSI_OPCODE_NOT: - case TGSI_OPCODE_AND: - case TGSI_OPCODE_OR: - case TGSI_OPCODE_XOR: - case TGSI_OPCODE_FSEQ: - case TGSI_OPCODE_FSGE: - case TGSI_OPCODE_FSLT: - case TGSI_OPCODE_FSNE: - case TGSI_OPCODE_F2I: - case TGSI_OPCODE_IDIV: - case TGSI_OPCODE_IMAX: - case TGSI_OPCODE_IMIN: - case TGSI_OPCODE_INEG: - case TGSI_OPCODE_ISGE: - case TGSI_OPCODE_ISHR: - case TGSI_OPCODE_ISLT: - case TGSI_OPCODE_F2U: - case TGSI_OPCODE_U2F: - case TGSI_OPCODE_UADD: - case TGSI_OPCODE_UDIV: - case TGSI_OPCODE_UMAD: - case TGSI_OPCODE_UMAX: - case TGSI_OPCODE_UMIN: - case TGSI_OPCODE_UMOD: - case TGSI_OPCODE_UMUL: - case TGSI_OPCODE_USEQ: - case TGSI_OPCODE_USGE: - case TGSI_OPCODE_USHR: - case TGSI_OPCODE_USLT: - case TGSI_OPCODE_USNE: - case TGSI_OPCODE_IMUL_HI: - case TGSI_OPCODE_UMUL_HI: - case TGSI_OPCODE_DDX_FINE: - case TGSI_OPCODE_DDY_FINE: - /* Channel-wise operations */ - read_mask = write_mask; - break; - + case TGSI_OPCODE_RSQ: + case TGSI_OPCODE_SQRT: case TGSI_OPCODE_EX2: case TGSI_OPCODE_LG2: + case TGSI_OPCODE_SIN: + case TGSI_OPCODE_COS: + case TGSI_OPCODE_POW: /* reads src0.x and src1.x */ + case TGSI_OPCODE_UP2H: + case TGSI_OPCODE_UP2US: + case TGSI_OPCODE_UP4B: + case TGSI_OPCODE_UP4UB: + case TGSI_OPCODE_MEMBAR: + case TGSI_OPCODE_BALLOT: read_mask = TGSI_WRITEMASK_X; break; - case TGSI_OPCODE_EXP: - case TGSI_OPCODE_LOG: - read_mask = write_mask & TGSI_WRITEMASK_XYZ ? TGSI_WRITEMASK_X : 0; - break; - case TGSI_OPCODE_DP2: + case TGSI_OPCODE_PK2H: + case TGSI_OPCODE_PK2US: + case TGSI_OPCODE_DFRACEXP: + case TGSI_OPCODE_F2D: + case TGSI_OPCODE_I2D: + case TGSI_OPCODE_U2D: + case TGSI_OPCODE_F2U64: + case TGSI_OPCODE_F2I64: + case TGSI_OPCODE_U2I64: + case TGSI_OPCODE_I2I64: + case TGSI_OPCODE_TXQS: /* bindless handle possible */ + case TGSI_OPCODE_RESQ: /* bindless handle possible */ read_mask = TGSI_WRITEMASK_XY; break; + case TGSI_OPCODE_TXQ: + if (src_idx == 0) + read_mask = TGSI_WRITEMASK_X; + else + read_mask = TGSI_WRITEMASK_XY; /* bindless handle possible */ + break; + case TGSI_OPCODE_DP3: read_mask = TGSI_WRITEMASK_XYZ; break; case TGSI_OPCODE_DP4: + case TGSI_OPCODE_PK4B: + case TGSI_OPCODE_PK4UB: + case TGSI_OPCODE_D2F: + case TGSI_OPCODE_I2F: + case TGSI_OPCODE_U2F: + case TGSI_OPCODE_U642F: + case TGSI_OPCODE_I642F: read_mask = TGSI_WRITEMASK_XYZW; break; + case TGSI_OPCODE_LIT: + read_mask = write_mask & TGSI_WRITEMASK_YZ ? + TGSI_WRITEMASK_XY | TGSI_WRITEMASK_W : 0; + break; + + case TGSI_OPCODE_EXP: + case TGSI_OPCODE_LOG: + read_mask = write_mask & TGSI_WRITEMASK_XYZ ? TGSI_WRITEMASK_X : 0; + break; + + case TGSI_OPCODE_DST: + if (src_idx == 0) + read_mask = TGSI_WRITEMASK_YZ; + else + read_mask = TGSI_WRITEMASK_YW; + break; + + case TGSI_OPCODE_DLDEXP: + if (src_idx == 0) { + read_mask = write_mask; + } else { + read_mask = + (write_mask & TGSI_WRITEMASK_XY ? TGSI_WRITEMASK_X : 0) | + (write_mask & TGSI_WRITEMASK_ZW ? TGSI_WRITEMASK_Z : 0); + } + break; + + case TGSI_OPCODE_READ_INVOC: + if (src_idx == 0) + read_mask = write_mask; + else + read_mask = TGSI_WRITEMASK_X; + break; + + case TGSI_OPCODE_FBFETCH: + read_mask = 0; /* not a real register read */ + break; + case TGSI_OPCODE_TEX: - case TGSI_OPCODE_TXD: + case TGSI_OPCODE_TEX_LZ: + case TGSI_OPCODE_TXF_LZ: + case TGSI_OPCODE_TXF: case TGSI_OPCODE_TXB: case TGSI_OPCODE_TXL: case TGSI_OPCODE_TXP: - if (src_idx == 0) { - /* Note that the SHADOW variants use the Z component too */ - switch (inst->Texture.Texture) { - case TGSI_TEXTURE_1D: - read_mask = TGSI_WRITEMASK_X; - break; - case TGSI_TEXTURE_SHADOW1D: - read_mask = TGSI_WRITEMASK_XZ; - break; - case TGSI_TEXTURE_1D_ARRAY: - case TGSI_TEXTURE_2D: - case TGSI_TEXTURE_RECT: - read_mask = TGSI_WRITEMASK_XY; - break; - case TGSI_TEXTURE_SHADOW1D_ARRAY: - case TGSI_TEXTURE_SHADOW2D: - case TGSI_TEXTURE_SHADOWRECT: - case TGSI_TEXTURE_2D_ARRAY: - case TGSI_TEXTURE_3D: - case TGSI_TEXTURE_CUBE: - case TGSI_TEXTURE_2D_MSAA: - read_mask = TGSI_WRITEMASK_XYZ; - break; - case TGSI_TEXTURE_SHADOW2D_ARRAY: - case TGSI_TEXTURE_CUBE_ARRAY: - case TGSI_TEXTURE_SHADOWCUBE: - case TGSI_TEXTURE_2D_ARRAY_MSAA: - case TGSI_TEXTURE_SHADOWCUBE_ARRAY: - read_mask = TGSI_WRITEMASK_XYZW; - break; - default: - assert(0); - read_mask = 0; - } - - if (inst->Instruction.Opcode != TGSI_OPCODE_TEX) { + case TGSI_OPCODE_TXD: + case TGSI_OPCODE_TEX2: + case TGSI_OPCODE_TXB2: + case TGSI_OPCODE_TXL2: + case TGSI_OPCODE_LODQ: + case TGSI_OPCODE_TG4: { + unsigned dim_layer_shadow = + tgsi_util_get_texture_coord_dim(inst->Texture.Texture); + unsigned dim_layer, dim; + + /* Remove shadow. */ + if (tgsi_is_shadow_target(inst->Texture.Texture)) { + dim_layer = dim_layer_shadow - 1; + if (inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D) + dim_layer = 1; + } else { + dim_layer = dim_layer_shadow; + } + + /* Remove layer. */ + if (tgsi_is_array_sampler(inst->Texture.Texture)) + dim = dim_layer - 1; + else + dim = dim_layer; + + read_mask = TGSI_WRITEMASK_XY; /* bindless handle in the last operand */ + + switch (src_idx) { + case 0: + if (inst->Instruction.Opcode == TGSI_OPCODE_LODQ) + read_mask = u_bit_consecutive(0, dim); + else + read_mask = u_bit_consecutive(0, dim_layer_shadow) & 0xf; + + if (inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D) + read_mask &= ~TGSI_WRITEMASK_Y; + + if (inst->Instruction.Opcode == TGSI_OPCODE_TXF || + inst->Instruction.Opcode == TGSI_OPCODE_TXB || + inst->Instruction.Opcode == TGSI_OPCODE_TXL || + inst->Instruction.Opcode == TGSI_OPCODE_TXP) read_mask |= TGSI_WRITEMASK_W; - } + break; + + case 1: + if (inst->Instruction.Opcode == TGSI_OPCODE_TXD) + read_mask = u_bit_consecutive(0, dim); + else if (inst->Instruction.Opcode == TGSI_OPCODE_TEX2 || + inst->Instruction.Opcode == TGSI_OPCODE_TXB2 || + inst->Instruction.Opcode == TGSI_OPCODE_TXL2 || + inst->Instruction.Opcode == TGSI_OPCODE_TG4) + read_mask = TGSI_WRITEMASK_X; + break; + + case 2: + if (inst->Instruction.Opcode == TGSI_OPCODE_TXD) + read_mask = u_bit_consecutive(0, dim); + break; + } + break; + } + + case TGSI_OPCODE_LOAD: + if (src_idx == 0) { + read_mask = TGSI_WRITEMASK_XY; /* bindless handle possible */ + } else { + unsigned dim = tgsi_util_get_texture_coord_dim(inst->Memory.Texture); + read_mask = u_bit_consecutive(0, dim); + } + break; + + case TGSI_OPCODE_STORE: + if (src_idx == 0) { + unsigned dim = tgsi_util_get_texture_coord_dim(inst->Memory.Texture); + read_mask = u_bit_consecutive(0, dim); + } else { + read_mask = TGSI_WRITEMASK_XYZW; + } + break; + + case TGSI_OPCODE_ATOMUADD: + case TGSI_OPCODE_ATOMXCHG: + case TGSI_OPCODE_ATOMCAS: + case TGSI_OPCODE_ATOMAND: + case TGSI_OPCODE_ATOMOR: + case TGSI_OPCODE_ATOMXOR: + case TGSI_OPCODE_ATOMUMIN: + case TGSI_OPCODE_ATOMUMAX: + case TGSI_OPCODE_ATOMIMIN: + case TGSI_OPCODE_ATOMIMAX: + if (src_idx == 0) { + read_mask = TGSI_WRITEMASK_XY; /* bindless handle possible */ + } else if (src_idx == 1) { + unsigned dim = tgsi_util_get_texture_coord_dim(inst->Memory.Texture); + read_mask = u_bit_consecutive(0, dim); } else { - /* A safe approximation */ read_mask = TGSI_WRITEMASK_XYZW; } break; + case TGSI_OPCODE_INTERP_CENTROID: + case TGSI_OPCODE_INTERP_SAMPLE: + case TGSI_OPCODE_INTERP_OFFSET: + if (src_idx == 0) + read_mask = write_mask; + else if (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_OFFSET) + read_mask = TGSI_WRITEMASK_XY; /* offset */ + else + read_mask = TGSI_WRITEMASK_X; /* sample */ + break; + default: - /* Assume all channels are read */ - read_mask = TGSI_WRITEMASK_XYZW; + if (tgsi_get_opcode_info(inst->Instruction.Opcode)->output_mode == + TGSI_OUTPUT_COMPONENTWISE) + read_mask = write_mask; + else + read_mask = TGSI_WRITEMASK_XYZW; /* assume all channels are read */ break; } diff --git a/src/gallium/auxiliary/tgsi/tgsi_util.h b/src/gallium/auxiliary/tgsi/tgsi_util.h index aa4606d0b27..534b5f78eb1 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_util.h +++ b/src/gallium/auxiliary/tgsi/tgsi_util.h @@ -98,6 +98,18 @@ tgsi_is_msaa_target(unsigned target) target == TGSI_TEXTURE_2D_ARRAY_MSAA); } +static inline bool +tgsi_is_array_sampler(unsigned target) +{ + return target == TGSI_TEXTURE_1D_ARRAY || + target == TGSI_TEXTURE_SHADOW1D_ARRAY || + target == TGSI_TEXTURE_2D_ARRAY || + target == TGSI_TEXTURE_SHADOW2D_ARRAY || + target == TGSI_TEXTURE_CUBE_ARRAY || + target == TGSI_TEXTURE_SHADOWCUBE_ARRAY || + target == TGSI_TEXTURE_2D_ARRAY_MSAA; +} + #if defined __cplusplus } #endif diff --git a/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c b/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c index 0863876ed89..f115bf4dcc1 100644 --- a/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c +++ b/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c @@ -91,17 +91,6 @@ shader_buffer_fetch_rsrc(struct si_shader_context *ctx, return ctx->abi.load_ssbo(&ctx->abi, index, false); } -static bool tgsi_is_array_sampler(unsigned target) -{ - return target == TGSI_TEXTURE_1D_ARRAY || - target == TGSI_TEXTURE_SHADOW1D_ARRAY || - target == TGSI_TEXTURE_2D_ARRAY || - target == TGSI_TEXTURE_SHADOW2D_ARRAY || - target == TGSI_TEXTURE_CUBE_ARRAY || - target == TGSI_TEXTURE_SHADOWCUBE_ARRAY || - target == TGSI_TEXTURE_2D_ARRAY_MSAA; -} - static bool tgsi_is_array_image(unsigned target) { return target == TGSI_TEXTURE_3D ||