summaryrefslogtreecommitdiff
path: root/lib/mesa/src/gallium/auxiliary/tgsi
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2022-09-02 05:47:02 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2022-09-02 05:47:02 +0000
commit0dbbf1e0708df85a357d70e2708c0a11aeb5480e (patch)
tree6656ff8eb8b15a2fc1c02888973caf618388cfd0 /lib/mesa/src/gallium/auxiliary/tgsi
parent5f66494d31f735486b8222ecfa0a0c9046e92543 (diff)
Merge Mesa 22.1.7
Diffstat (limited to 'lib/mesa/src/gallium/auxiliary/tgsi')
-rw-r--r--lib/mesa/src/gallium/auxiliary/tgsi/tgsi_aa_point.c11
-rw-r--r--lib/mesa/src/gallium/auxiliary/tgsi/tgsi_exec.c129
-rw-r--r--lib/mesa/src/gallium/auxiliary/tgsi/tgsi_lowering.c4
-rw-r--r--lib/mesa/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h5
-rw-r--r--lib/mesa/src/gallium/auxiliary/tgsi/tgsi_point_sprite.c8
-rw-r--r--lib/mesa/src/gallium/auxiliary/tgsi/tgsi_scan.c4
-rw-r--r--lib/mesa/src/gallium/auxiliary/tgsi/tgsi_scan.h1
-rw-r--r--lib/mesa/src/gallium/auxiliary/tgsi/tgsi_transform.h10
-rw-r--r--lib/mesa/src/gallium/auxiliary/tgsi/tgsi_ureg.c18
-rw-r--r--lib/mesa/src/gallium/auxiliary/tgsi/tgsi_ureg.h1
-rw-r--r--lib/mesa/src/gallium/auxiliary/tgsi/tgsi_util.c85
-rw-r--r--lib/mesa/src/gallium/auxiliary/tgsi/tgsi_util.h15
12 files changed, 128 insertions, 163 deletions
diff --git a/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_aa_point.c b/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_aa_point.c
index cdd4fef25..58f610fc4 100644
--- a/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_aa_point.c
+++ b/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_aa_point.c
@@ -276,12 +276,6 @@ tgsi_add_aa_point(const struct tgsi_token *tokens_in,
struct aa_transform_context transform;
const uint num_new_tokens = 200; /* should be enough */
const uint new_len = tgsi_num_tokens(tokens_in) + num_new_tokens;
- struct tgsi_token *new_tokens;
-
- /* allocate new tokens buffer */
- new_tokens = tgsi_alloc_tokens(new_len);
- if (!new_tokens)
- return NULL;
/* setup transformation context */
memset(&transform, 0, sizeof(transform));
@@ -302,8 +296,5 @@ tgsi_add_aa_point(const struct tgsi_token *tokens_in,
transform.num_imm = 0;
transform.num_input = 0;
- /* transform the shader */
- tgsi_transform_shader(tokens_in, new_tokens, new_len, &transform.base);
-
- return new_tokens;
+ return tgsi_transform_shader(tokens_in, new_len, &transform.base);
}
diff --git a/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_exec.c b/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_exec.c
index a8446ff27..ae1daa6dc 100644
--- a/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -975,23 +975,6 @@ static const union tgsi_exec_channel M128Vec = {
{-128.0f, -128.0f, -128.0f, -128.0f}
};
-
-/**
- * Assert that none of the float values in 'chan' are infinite or NaN.
- * NaN and Inf may occur normally during program execution and should
- * not lead to crashes, etc. But when debugging, it's helpful to catch
- * them.
- */
-static inline void
-check_inf_or_nan(const union tgsi_exec_channel *chan)
-{
- assert(!util_is_inf_or_nan((chan)->f[0]));
- assert(!util_is_inf_or_nan((chan)->f[1]));
- assert(!util_is_inf_or_nan((chan)->f[2]));
- assert(!util_is_inf_or_nan((chan)->f[3]));
-}
-
-
#ifdef DEBUG
static void
print_chan(const char *msg, const union tgsi_exec_channel *chan)
@@ -1518,8 +1501,6 @@ get_index_registers(const struct tgsi_exec_machine *mach,
union tgsi_exec_channel *index,
union tgsi_exec_channel *index2D)
{
- uint swizzle;
-
/* We start with a direct index into a register file.
*
* file[1],
@@ -1543,35 +1524,17 @@ get_index_registers(const struct tgsi_exec_machine *mach,
* .x = Indirect.SwizzleX
*/
if (reg->Register.Indirect) {
- union tgsi_exec_channel index2;
- union tgsi_exec_channel indir_index;
const uint execmask = mach->ExecMask;
- uint i;
- /* which address register (always zero now) */
- index2.i[0] =
- index2.i[1] =
- index2.i[2] =
- index2.i[3] = reg->Indirect.Index;
- /* get current value of address register[swizzle] */
- swizzle = reg->Indirect.Swizzle;
- fetch_src_file_channel(mach,
- reg->Indirect.File,
- swizzle,
- &index2,
- &ZeroVec,
- &indir_index);
-
- /* add value of address register to the offset */
- index->i[0] += indir_index.i[0];
- index->i[1] += indir_index.i[1];
- index->i[2] += indir_index.i[2];
- index->i[3] += indir_index.i[3];
+ assert(reg->Indirect.File == TGSI_FILE_ADDRESS);
+ const union tgsi_exec_channel *addr = &mach->Addrs[reg->Indirect.Index].xyzw[reg->Indirect.Swizzle];
+ for (int i = 0; i < TGSI_QUAD_SIZE; i++)
+ index->i[i] += addr->u[i];
/* for disabled execution channels, zero-out the index to
* avoid using a potential garbage value.
*/
- for (i = 0; i < TGSI_QUAD_SIZE; i++) {
+ for (int i = 0; i < TGSI_QUAD_SIZE; i++) {
if ((execmask & (1 << i)) == 0)
index->i[i] = 0;
}
@@ -1603,33 +1566,17 @@ get_index_registers(const struct tgsi_exec_machine *mach,
* .y = DimIndirect.SwizzleX
*/
if (reg->Dimension.Indirect) {
- union tgsi_exec_channel index2;
- union tgsi_exec_channel indir_index;
const uint execmask = mach->ExecMask;
- uint i;
-
- index2.i[0] =
- index2.i[1] =
- index2.i[2] =
- index2.i[3] = reg->DimIndirect.Index;
-
- swizzle = reg->DimIndirect.Swizzle;
- fetch_src_file_channel(mach,
- reg->DimIndirect.File,
- swizzle,
- &index2,
- &ZeroVec,
- &indir_index);
- index2D->i[0] += indir_index.i[0];
- index2D->i[1] += indir_index.i[1];
- index2D->i[2] += indir_index.i[2];
- index2D->i[3] += indir_index.i[3];
+ assert(reg->DimIndirect.File == TGSI_FILE_ADDRESS);
+ const union tgsi_exec_channel *addr = &mach->Addrs[reg->DimIndirect.Index].xyzw[reg->DimIndirect.Swizzle];
+ for (int i = 0; i < TGSI_QUAD_SIZE; i++)
+ index2D->i[i] += addr->u[i];
/* for disabled execution channels, zero-out the index to
* avoid using a potential garbage value.
*/
- for (i = 0; i < TGSI_QUAD_SIZE; i++) {
+ for (int i = 0; i < TGSI_QUAD_SIZE; i++) {
if ((execmask & (1 << i)) == 0) {
index2D->i[i] = 0;
}
@@ -3899,16 +3846,31 @@ exec_store_img(struct tgsi_exec_machine *mach,
rgba);
}
+
static void
-exec_store_buf(struct tgsi_exec_machine *mach,
+exec_store_membuf(struct tgsi_exec_machine *mach,
const struct tgsi_full_instruction *inst)
{
uint32_t unit = fetch_store_img_unit(mach, &inst->Dst[0]);
uint32_t size;
- char *ptr = mach->Buffer->lookup(mach->Buffer, unit, &size);
int execmask = mach->ExecMask & mach->NonHelperMask & ~mach->KillMask;
+ const char *ptr;
+ switch (inst->Dst[0].Register.File) {
+ case TGSI_FILE_MEMORY:
+ ptr = mach->LocalMem;
+ size = mach->LocalMemSize;
+ break;
+
+ case TGSI_FILE_BUFFER:
+ ptr = mach->Buffer->lookup(mach->Buffer, unit, &size);
+ break;
+
+ default:
+ unreachable("unsupported TGSI_OPCODE_STORE file");
+ }
+
union tgsi_exec_channel offset;
IFETCH(&offset, 0, TGSI_CHAN_X);
@@ -3933,46 +3895,13 @@ exec_store_buf(struct tgsi_exec_machine *mach,
}
static void
-exec_store_mem(struct tgsi_exec_machine *mach,
- const struct tgsi_full_instruction *inst)
-{
- union tgsi_exec_channel r[3];
- union tgsi_exec_channel value[4];
- uint i, chan;
- char *ptr = mach->LocalMem;
- int execmask = mach->ExecMask & mach->NonHelperMask & ~mach->KillMask;
-
- IFETCH(&r[0], 0, TGSI_CHAN_X);
-
- for (i = 0; i < 4; i++) {
- FETCH(&value[i], 1, TGSI_CHAN_X + i);
- }
-
- if (r[0].u[0] >= mach->LocalMemSize)
- return;
- ptr += r[0].u[0];
-
- for (i = 0; i < TGSI_QUAD_SIZE; i++) {
- if (execmask & (1 << i)) {
- for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
- if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
- memcpy(ptr + (chan * 4), &value[chan].u[0], 4);
- }
- }
- }
- }
-}
-
-static void
exec_store(struct tgsi_exec_machine *mach,
const struct tgsi_full_instruction *inst)
{
if (inst->Dst[0].Register.File == TGSI_FILE_IMAGE)
exec_store_img(mach, inst);
- else if (inst->Dst[0].Register.File == TGSI_FILE_BUFFER)
- exec_store_buf(mach, inst);
- else if (inst->Dst[0].Register.File == TGSI_FILE_MEMORY)
- exec_store_mem(mach, inst);
+ else
+ exec_store_membuf(mach, inst);
}
static void
diff --git a/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_lowering.c b/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_lowering.c
index db2302669..42f888016 100644
--- a/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_lowering.c
+++ b/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_lowering.c
@@ -1573,12 +1573,10 @@ tgsi_transform_lowering(const struct tgsi_lowering_config *config,
newlen += 2 * numtmp;
newlen += 5; /* immediate */
- newtoks = tgsi_alloc_tokens(newlen);
+ newtoks = tgsi_transform_shader(tokens, newlen, &ctx.base);
if (!newtoks)
return NULL;
- tgsi_transform_shader(tokens, newtoks, newlen, &ctx.base);
-
tgsi_scan_shader(newtoks, info);
#if 0 /* debug */
diff --git a/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h b/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h
index 1aff51381..684c06144 100644
--- a/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h
+++ b/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h
@@ -204,12 +204,17 @@ OP11(INTERP_CENTROID)
OP12(INTERP_SAMPLE)
OP12(INTERP_OFFSET)
+OP11(FBFETCH)
+
+OP10(CLOCK)
+
#undef OP00
#undef OP01
#undef OP10
#undef OP11
#undef OP12
#undef OP13
+#undef OP14
#undef OP00_LBL
#undef OP01_LBL
diff --git a/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_point_sprite.c b/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_point_sprite.c
index 67b4b0ab4..432a137fc 100644
--- a/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_point_sprite.c
+++ b/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_point_sprite.c
@@ -568,13 +568,7 @@ tgsi_add_point_sprite(const struct tgsi_token *tokens_in,
}
- /* allocate new tokens buffer */
- new_tokens = tgsi_alloc_tokens(new_len);
- if (!new_tokens)
- return NULL;
-
- /* transform the shader */
- tgsi_transform_shader(tokens_in, new_tokens, new_len, &transform.base);
+ new_tokens = tgsi_transform_shader(tokens_in, new_len, &transform.base);
if (aa_point_coord_index)
*aa_point_coord_index = transform.point_coord_aa;
diff --git a/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_scan.c b/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_scan.c
index ecb3706ed..5fab72eb6 100644
--- a/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_scan.c
+++ b/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_scan.c
@@ -663,6 +663,10 @@ scan_declaration(struct tgsi_shader_info *info,
info->shader_buffers_declared |= 1u << reg;
break;
+ case TGSI_FILE_HW_ATOMIC:
+ info->hw_atomic_declared |= 1u << reg;
+ break;
+
case TGSI_FILE_INPUT:
info->input_semantic_name[reg] = (ubyte) semName;
info->input_semantic_index[reg] = (ubyte) semIndex;
diff --git a/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_scan.h b/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_scan.h
index ace5b0887..076c138e4 100644
--- a/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_scan.h
+++ b/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_scan.h
@@ -164,6 +164,7 @@ struct tgsi_shader_info
bool uses_bindless_image_store;
bool uses_bindless_image_atomic;
+ unsigned hw_atomic_declared; /**< bitmask of declared atomic_counter */
/**
* Bitmask indicating which register files are accessed with
* indirect addressing. The bits are (1 << TGSI_FILE_x), etc.
diff --git a/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_transform.h b/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_transform.h
index 727edeb05..fc7a5877e 100644
--- a/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_transform.h
+++ b/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_transform.h
@@ -29,6 +29,7 @@
#define TGSI_TRANSFORM_H
+#include "pipe/p_defines.h"
#include "pipe/p_shader_tokens.h"
#include "tgsi/tgsi_parse.h"
#include "tgsi/tgsi_build.h"
@@ -64,10 +65,11 @@ struct tgsi_transform_context
/**
* Called at end of input program to allow caller to append extra
- * instructions. Return number of tokens emitted.
+ * instructions.
*/
void (*epilog)(struct tgsi_transform_context *ctx);
+ enum pipe_shader_type processor;
/*** PRIVATE ***/
@@ -88,6 +90,7 @@ struct tgsi_transform_context
uint max_tokens_out;
struct tgsi_token *tokens_out;
uint ti;
+ bool fail;
};
@@ -570,10 +573,9 @@ tgsi_transform_tex_inst(struct tgsi_transform_context *ctx,
}
-extern int
+extern struct tgsi_token *
tgsi_transform_shader(const struct tgsi_token *tokens_in,
- struct tgsi_token *tokens_out,
- uint max_tokens_out,
+ uint initial_tokens_len,
struct tgsi_transform_context *ctx);
diff --git a/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_ureg.c
index eedba34cb..207fcc45b 100644
--- a/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_ureg.c
+++ b/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_ureg.c
@@ -39,6 +39,7 @@
#include "util/u_inlines.h"
#include "util/u_memory.h"
#include "util/u_math.h"
+#include "util/u_prim.h"
#include "util/u_bitmask.h"
#include "GL/gl.h"
#include "compiler/shader_info.h"
@@ -205,6 +206,8 @@ struct ureg_program
struct ureg_tokens domain[2];
bool use_memory[TGSI_MEMORY_TYPE_COUNT];
+
+ bool precise;
};
static union tgsi_any_token error_tokens[32];
@@ -1267,7 +1270,7 @@ ureg_emit_insn(struct ureg_program *ureg,
out[0].insn = tgsi_default_instruction();
out[0].insn.Opcode = opcode;
out[0].insn.Saturate = saturate;
- out[0].insn.Precise = precise;
+ out[0].insn.Precise = precise || ureg->precise;
out[0].insn.NumDstRegs = num_dst;
out[0].insn.NumSrcRegs = num_src;
@@ -2190,7 +2193,7 @@ const struct tgsi_token *ureg_get_tokens( struct ureg_program *ureg,
if (nr_tokens)
*nr_tokens = ureg->domain[DOMAIN_DECL].count;
- ureg->domain[DOMAIN_DECL].tokens = 0;
+ ureg->domain[DOMAIN_DECL].tokens = NULL;
ureg->domain[DOMAIN_DECL].size = 0;
ureg->domain[DOMAIN_DECL].order = 0;
ureg->domain[DOMAIN_DECL].count = 0;
@@ -2295,11 +2298,7 @@ static void
ureg_setup_tess_eval_shader(struct ureg_program *ureg,
const struct shader_info *info)
{
- if (info->tess.primitive_mode == GL_ISOLINES)
- ureg_property(ureg, TGSI_PROPERTY_TES_PRIM_MODE, GL_LINES);
- else
- ureg_property(ureg, TGSI_PROPERTY_TES_PRIM_MODE,
- info->tess.primitive_mode);
+ ureg_property(ureg, TGSI_PROPERTY_TES_PRIM_MODE, u_tess_prim_from_shader(info->tess._primitive_mode));
STATIC_ASSERT((TESS_SPACING_EQUAL + 1) % 3 == PIPE_TESS_SPACING_EQUAL);
STATIC_ASSERT((TESS_SPACING_FRACTIONAL_ODD + 1) % 3 ==
@@ -2437,3 +2436,8 @@ void ureg_destroy( struct ureg_program *ureg )
FREE(ureg);
}
+
+void ureg_set_precise( struct ureg_program *ureg, bool precise )
+{
+ ureg->precise = precise;
+}
diff --git a/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_ureg.h
index 343708b6c..59041e94d 100644
--- a/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_ureg.h
+++ b/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_ureg.h
@@ -137,6 +137,7 @@ void ureg_free_tokens( const struct tgsi_token *tokens );
void
ureg_destroy( struct ureg_program * );
+void ureg_set_precise( struct ureg_program *ureg, bool precise );
/***********************************************************************
* Convenience routine:
diff --git a/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_util.c b/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_util.c
index d6ef81d28..a101cce24 100644
--- a/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_util.c
+++ b/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_util.c
@@ -108,16 +108,20 @@ tgsi_util_set_src_register_swizzle(struct tgsi_src_register *reg,
* used by this instruction.
*/
unsigned
-tgsi_util_get_inst_usage_mask(const struct tgsi_full_instruction *inst,
- unsigned src_idx)
+tgsi_util_get_src_usage_mask(enum tgsi_opcode opcode,
+ unsigned src_idx,
+ uint8_t write_mask,
+ uint8_t swizzle_x,
+ uint8_t swizzle_y,
+ uint8_t swizzle_z,
+ uint8_t swizzle_w,
+ enum tgsi_texture_type tex_target,
+ enum tgsi_texture_type mem_target)
{
- const struct tgsi_full_src_register *src = &inst->Src[src_idx];
- unsigned write_mask = inst->Dst[0].Register.WriteMask;
unsigned read_mask;
unsigned usage_mask;
- unsigned chan;
- switch (inst->Instruction.Opcode) {
+ switch (opcode) {
case TGSI_OPCODE_IF:
case TGSI_OPCODE_UIF:
case TGSI_OPCODE_EMIT:
@@ -241,20 +245,20 @@ tgsi_util_get_inst_usage_mask(const struct tgsi_full_instruction *inst,
case TGSI_OPCODE_LODQ:
case TGSI_OPCODE_TG4: {
unsigned dim_layer =
- tgsi_util_get_texture_coord_dim(inst->Texture.Texture);
+ tgsi_util_get_texture_coord_dim(tex_target);
unsigned dim_layer_shadow, dim;
/* Add shadow. */
- if (tgsi_is_shadow_target(inst->Texture.Texture)) {
+ if (tgsi_is_shadow_target(tex_target)) {
dim_layer_shadow = dim_layer + 1;
- if (inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D)
+ if (tex_target == TGSI_TEXTURE_SHADOW1D)
dim_layer_shadow = 3;
} else {
dim_layer_shadow = dim_layer;
}
/* Remove layer. */
- if (tgsi_is_array_sampler(inst->Texture.Texture))
+ if (tgsi_is_array_sampler(tex_target))
dim = dim_layer - 1;
else
dim = dim_layer;
@@ -263,33 +267,33 @@ tgsi_util_get_inst_usage_mask(const struct tgsi_full_instruction *inst,
switch (src_idx) {
case 0:
- if (inst->Instruction.Opcode == TGSI_OPCODE_LODQ)
+ if (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)
+ if (tex_target == 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)
+ if (opcode == TGSI_OPCODE_TXF ||
+ opcode == TGSI_OPCODE_TXB ||
+ opcode == TGSI_OPCODE_TXL ||
+ opcode == TGSI_OPCODE_TXP)
read_mask |= TGSI_WRITEMASK_W;
break;
case 1:
- if (inst->Instruction.Opcode == TGSI_OPCODE_TXD)
+ if (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)
+ else if (opcode == TGSI_OPCODE_TEX2 ||
+ opcode == TGSI_OPCODE_TXB2 ||
+ opcode == TGSI_OPCODE_TXL2 ||
+ opcode == TGSI_OPCODE_TG4)
read_mask = TGSI_WRITEMASK_X;
break;
case 2:
- if (inst->Instruction.Opcode == TGSI_OPCODE_TXD)
+ if (opcode == TGSI_OPCODE_TXD)
read_mask = u_bit_consecutive(0, dim);
break;
}
@@ -300,14 +304,14 @@ tgsi_util_get_inst_usage_mask(const struct tgsi_full_instruction *inst,
if (src_idx == 0) {
read_mask = TGSI_WRITEMASK_XY; /* bindless handle possible */
} else {
- unsigned dim = tgsi_util_get_texture_coord_dim(inst->Memory.Texture);
+ unsigned dim = tgsi_util_get_texture_coord_dim(mem_target);
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);
+ unsigned dim = tgsi_util_get_texture_coord_dim(mem_target);
read_mask = u_bit_consecutive(0, dim);
} else {
read_mask = TGSI_WRITEMASK_XYZW;
@@ -328,7 +332,7 @@ tgsi_util_get_inst_usage_mask(const struct tgsi_full_instruction *inst,
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);
+ unsigned dim = tgsi_util_get_texture_coord_dim(mem_target);
read_mask = u_bit_consecutive(0, dim);
} else {
read_mask = TGSI_WRITEMASK_XYZW;
@@ -340,14 +344,14 @@ tgsi_util_get_inst_usage_mask(const struct tgsi_full_instruction *inst,
case TGSI_OPCODE_INTERP_OFFSET:
if (src_idx == 0)
read_mask = write_mask;
- else if (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_OFFSET)
+ else if (opcode == TGSI_OPCODE_INTERP_OFFSET)
read_mask = TGSI_WRITEMASK_XY; /* offset */
else
read_mask = TGSI_WRITEMASK_X; /* sample */
break;
default:
- if (tgsi_get_opcode_info(inst->Instruction.Opcode)->output_mode ==
+ if (tgsi_get_opcode_info(opcode)->output_mode ==
TGSI_OUTPUT_COMPONENTWISE)
read_mask = write_mask;
else
@@ -356,15 +360,32 @@ tgsi_util_get_inst_usage_mask(const struct tgsi_full_instruction *inst,
}
usage_mask = 0;
- for (chan = 0; chan < 4; ++chan) {
- if (read_mask & (1 << chan)) {
- usage_mask |= 1 << tgsi_util_get_full_src_register_swizzle(src, chan);
- }
- }
+ if (read_mask & TGSI_WRITEMASK_X)
+ usage_mask |= 1 << swizzle_x;
+ if (read_mask & TGSI_WRITEMASK_Y)
+ usage_mask |= 1 << swizzle_y;
+ if (read_mask & TGSI_WRITEMASK_Z)
+ usage_mask |= 1 << swizzle_z;
+ if (read_mask & TGSI_WRITEMASK_W)
+ usage_mask |= 1 << swizzle_w;
return usage_mask;
}
+unsigned
+tgsi_util_get_inst_usage_mask(const struct tgsi_full_instruction *inst,
+ unsigned src_idx)
+{
+ return tgsi_util_get_src_usage_mask(inst->Instruction.Opcode, src_idx,
+ inst->Dst[0].Register.WriteMask,
+ inst->Src[src_idx].Register.SwizzleX,
+ inst->Src[src_idx].Register.SwizzleY,
+ inst->Src[src_idx].Register.SwizzleZ,
+ inst->Src[src_idx].Register.SwizzleW,
+ inst->Texture.Texture,
+ inst->Memory.Texture);
+}
+
/**
* Convert a tgsi_ind_register into a tgsi_src_register
*/
diff --git a/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_util.h b/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_util.h
index e1f913d74..6dbb23929 100644
--- a/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_util.h
+++ b/lib/mesa/src/gallium/auxiliary/tgsi/tgsi_util.h
@@ -57,10 +57,25 @@ tgsi_util_set_src_register_swizzle(struct tgsi_src_register *reg,
unsigned swizzle,
unsigned component);
+/* returns the channels of the src_idx src register used by the full instruction. */
unsigned
tgsi_util_get_inst_usage_mask(const struct tgsi_full_instruction *inst,
unsigned src_idx);
+/* Returns the channels of the src_idx src register used by an instruction with
+ * these parameters.
+ */
+unsigned
+tgsi_util_get_src_usage_mask(enum tgsi_opcode opcode,
+ unsigned src_idx,
+ uint8_t write_mask,
+ uint8_t swizzle_x,
+ uint8_t swizzle_y,
+ uint8_t swizzle_z,
+ uint8_t swizzle_w,
+ enum tgsi_texture_type tex_target,
+ enum tgsi_texture_type mem_target);
+
struct tgsi_src_register
tgsi_util_get_src_from_ind(const struct tgsi_ind_register *reg);