[Mesa-dev] [PATCH 11/11] glsl_to_tgsi: skip UARL for 1D registers if the driver doesn't need it
Marek Olšák
maraeo at gmail.com
Fri Sep 29 12:25:34 UTC 2017
From: Marek Olšák <marek.olsak at amd.com>
---
src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 45 +++++++++++++++++++-----
src/mesa/state_tracker/st_glsl_to_tgsi_private.h | 8 +++++
2 files changed, 44 insertions(+), 9 deletions(-)
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index e9d98ed..879ae65 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -186,20 +186,21 @@ public:
bool indirect_addr_consts;
int wpos_transform_const;
int glsl_version;
bool native_integers;
bool have_sqrt;
bool have_fma;
bool use_shared_memory;
bool has_tex_txf_lz;
bool precise;
+ bool need_uarl;
variable_storage *find_variable_storage(ir_variable *var);
int add_constant(gl_register_file file, gl_constant_value values[8],
int size, int datatype, uint16_t *swizzle_out);
st_src_reg get_temp(const glsl_type *type);
void reladdr_to_temp(ir_instruction *ir, st_src_reg *reg, int *num_reladdr);
st_src_reg st_src_reg_for_double(double val);
@@ -796,22 +797,26 @@ glsl_to_tgsi_visitor::emit_scalar(ir_instruction *ir, unsigned op,
emit_scalar(ir, op, dst, src0, undef);
}
void
glsl_to_tgsi_visitor::emit_arl(ir_instruction *ir,
st_dst_reg dst, st_src_reg src0)
{
int op = TGSI_OPCODE_ARL;
- if (src0.type == GLSL_TYPE_INT || src0.type == GLSL_TYPE_UINT)
- op = TGSI_OPCODE_UARL;
+ if (src0.type == GLSL_TYPE_INT || src0.type == GLSL_TYPE_UINT) {
+ if (this->need_uarl || !src0.is_legal_tgsi_address_operand())
+ op = TGSI_OPCODE_UARL;
+ else
+ return;
+ }
assert(dst.file == PROGRAM_ADDRESS);
if (dst.index >= this->num_address_regs)
this->num_address_regs = dst.index + 1;
emit_asm(NULL, op, dst, src0);
}
int
glsl_to_tgsi_visitor::add_constant(gl_register_file file,
@@ -5319,20 +5324,21 @@ struct st_translate {
unsigned *array_sizes;
struct inout_decl *input_decls;
unsigned num_input_decls;
struct inout_decl *output_decls;
unsigned num_output_decls;
const ubyte *inputMapping;
const ubyte *outputMapping;
unsigned procType; /**< PIPE_SHADER_VERTEX/FRAGMENT */
+ bool need_uarl;
};
/** Map Mesa's SYSTEM_VALUE_x to TGSI_SEMANTIC_x */
unsigned
_mesa_sysval_to_semantic(unsigned sysval)
{
switch (sysval) {
/* Vertex shader */
case SYSTEM_VALUE_VERTEX_ID:
return TGSI_SEMANTIC_VERTEXID;
@@ -5515,20 +5521,33 @@ dst_register(struct st_translate *t, gl_register_file file, unsigned index,
case PROGRAM_ADDRESS:
return t->address[index];
default:
assert(!"unknown dst register file");
return ureg_dst_undef();
}
}
+static struct ureg_src
+translate_src(struct st_translate *t, const st_src_reg *src_reg);
+
+static struct ureg_src
+translate_addr(struct st_translate *t, const st_src_reg *reladdr,
+ unsigned addr_index)
+{
+ if (t->need_uarl || !reladdr->is_legal_tgsi_address_operand())
+ return ureg_src(t->address[addr_index]);
+
+ return translate_src(t, reladdr);
+}
+
/**
* Create a TGSI ureg_dst register from an st_dst_reg.
*/
static struct ureg_dst
translate_dst(struct st_translate *t,
const st_dst_reg *dst_reg,
bool saturate)
{
struct ureg_dst dst = dst_register(t, dst_reg->file, dst_reg->index,
dst_reg->array_id);
@@ -5536,26 +5555,27 @@ translate_dst(struct st_translate *t,
if (dst.File == TGSI_FILE_NULL)
return dst;
dst = ureg_writemask(dst, dst_reg->writemask);
if (saturate)
dst = ureg_saturate(dst);
if (dst_reg->reladdr != NULL) {
assert(dst_reg->file != PROGRAM_TEMPORARY);
- dst = ureg_dst_indirect(dst, ureg_src(t->address[0]));
+ dst = ureg_dst_indirect(dst, translate_addr(t, dst_reg->reladdr, 0));
}
if (dst_reg->has_index2) {
if (dst_reg->reladdr2)
- dst = ureg_dst_dimension_indirect(dst, ureg_src(t->address[1]),
+ dst = ureg_dst_dimension_indirect(dst,
+ translate_addr(t, dst_reg->reladdr2, 1),
dst_reg->index2D);
else
dst = ureg_dst_dimension(dst, dst_reg->index2D);
}
return dst;
}
/**
* Create a TGSI ureg_src register from an st_src_reg.
@@ -5644,41 +5664,42 @@ translate_src(struct st_translate *t, const st_src_reg *src_reg)
default:
assert(!"unknown src register file");
return ureg_src_undef();
}
if (src_reg->has_index2) {
/* 2D indexes occur with geometry shader inputs (attrib, vertex)
* and UBO constant buffers (buffer, position).
*/
if (src_reg->reladdr2)
- src = ureg_src_dimension_indirect(src, ureg_src(t->address[1]),
+ src = ureg_src_dimension_indirect(src,
+ translate_addr(t, src_reg->reladdr2, 1),
src_reg->index2D);
else
src = ureg_src_dimension(src, src_reg->index2D);
}
src = ureg_swizzle(src,
GET_SWZ(src_reg->swizzle, 0) & 0x3,
GET_SWZ(src_reg->swizzle, 1) & 0x3,
GET_SWZ(src_reg->swizzle, 2) & 0x3,
GET_SWZ(src_reg->swizzle, 3) & 0x3);
if (src_reg->abs)
src = ureg_abs(src);
if ((src_reg->negate & 0xf) == NEGATE_XYZW)
src = ureg_negate(src);
if (src_reg->reladdr != NULL) {
assert(src_reg->file != PROGRAM_TEMPORARY);
- src = ureg_src_indirect(src, ureg_src(t->address[0]));
+ src = ureg_src_indirect(src, translate_addr(t, src_reg->reladdr, 0));
}
return src;
}
static struct tgsi_texture_offset
translate_tex_offset(struct st_translate *t,
const st_src_reg *in_offset)
{
struct tgsi_texture_offset offset;
@@ -5752,21 +5773,22 @@ compile_tgsi_instruction(struct st_translate *t,
case TGSI_OPCODE_LODQ:
if (inst->resource.file == PROGRAM_SAMPLER) {
src[num_src] = t->samplers[inst->resource.index];
} else {
/* Bindless samplers. */
src[num_src] = translate_src(t, &inst->resource);
}
assert(src[num_src].File != TGSI_FILE_NULL);
if (inst->resource.reladdr)
src[num_src] =
- ureg_src_indirect(src[num_src], ureg_src(t->address[2]));
+ ureg_src_indirect(src[num_src],
+ translate_addr(t, inst->resource.reladdr, 2));
num_src++;
for (i = 0; i < (int)inst->tex_offset_num_offset; i++) {
texoffsets[i] = translate_tex_offset(t, &inst->tex_offsets[i]);
}
tex_target = st_translate_texture_target(inst->tex_target, inst->tex_shadow);
ureg_tex_insn(ureg,
inst->op,
dst, num_dst,
tex_target,
@@ -5801,21 +5823,22 @@ compile_tgsi_instruction(struct st_translate *t,
assert(inst->resource.file != PROGRAM_UNDEFINED);
if (inst->resource.file == PROGRAM_IMAGE) {
src[0] = t->images[inst->resource.index];
} else {
/* Bindless images. */
src[0] = translate_src(t, &inst->resource);
}
tex_target = st_translate_texture_target(inst->tex_target, inst->tex_shadow);
}
if (inst->resource.reladdr)
- src[0] = ureg_src_indirect(src[0], ureg_src(t->address[2]));
+ src[0] = ureg_src_indirect(src[0],
+ translate_addr(t, inst->resource.reladdr, 2));
assert(src[0].File != TGSI_FILE_NULL);
ureg_memory_insn(ureg, inst->op, dst, num_dst, src, num_src,
inst->buffer_access,
tex_target, inst->image_format);
break;
case TGSI_OPCODE_STORE:
if (inst->resource.file == PROGRAM_MEMORY) {
dst[0] = ureg_dst(t->shared_memory);
} else if (inst->resource.file == PROGRAM_BUFFER) {
@@ -5824,21 +5847,22 @@ compile_tgsi_instruction(struct st_translate *t,
if (inst->resource.file == PROGRAM_IMAGE) {
dst[0] = ureg_dst(t->images[inst->resource.index]);
} else {
/* Bindless images. */
dst[0] = ureg_dst(translate_src(t, &inst->resource));
}
tex_target = st_translate_texture_target(inst->tex_target, inst->tex_shadow);
}
dst[0] = ureg_writemask(dst[0], inst->dst[0].writemask);
if (inst->resource.reladdr)
- dst[0] = ureg_dst_indirect(dst[0], ureg_src(t->address[2]));
+ dst[0] = ureg_dst_indirect(dst[0],
+ translate_addr(t, inst->resource.reladdr, 2));
assert(dst[0].File != TGSI_FILE_NULL);
ureg_memory_insn(ureg, inst->op, dst, num_dst, src, num_src,
inst->buffer_access,
tex_target, inst->image_format);
break;
default:
ureg_insn(ureg,
inst->op,
dst, num_dst,
@@ -6143,36 +6167,38 @@ st_translate_program(
const ubyte inputMapping[],
const ubyte inputSlotToAttr[],
const ubyte inputSemanticName[],
const ubyte inputSemanticIndex[],
const ubyte interpMode[],
GLuint numOutputs,
const ubyte outputMapping[],
const ubyte outputSemanticName[],
const ubyte outputSemanticIndex[])
{
+ struct pipe_screen *screen = st_context(ctx)->pipe->screen;
struct st_translate *t;
unsigned i;
struct gl_program_constants *frag_const =
&ctx->Const.Program[MESA_SHADER_FRAGMENT];
enum pipe_error ret = PIPE_OK;
assert(numInputs <= ARRAY_SIZE(t->inputs));
assert(numOutputs <= ARRAY_SIZE(t->outputs));
t = CALLOC_STRUCT(st_translate);
if (!t) {
ret = PIPE_ERROR_OUT_OF_MEMORY;
goto out;
}
t->procType = procType;
+ t->need_uarl = !screen->get_param(screen, PIPE_CAP_TGSI_ANY_REG_AS_ADDRESS);
t->inputMapping = inputMapping;
t->outputMapping = outputMapping;
t->ureg = ureg;
t->num_temp_arrays = program->next_array;
if (t->num_temp_arrays)
t->arrays = (struct ureg_dst*)
calloc(t->num_temp_arrays, sizeof(t->arrays[0]));
/*
* Declare input attributes.
@@ -6584,20 +6610,21 @@ get_mesa_program_tgsi(struct gl_context *ctx,
v->options = options;
v->glsl_version = ctx->Const.GLSLVersion;
v->native_integers = ctx->Const.NativeIntegers;
v->have_sqrt = pscreen->get_shader_param(pscreen, ptarget,
PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED);
v->have_fma = pscreen->get_shader_param(pscreen, ptarget,
PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED);
v->has_tex_txf_lz = pscreen->get_param(pscreen,
PIPE_CAP_TGSI_TEX_TXF_LZ);
+ v->need_uarl = !pscreen->get_param(pscreen, PIPE_CAP_TGSI_ANY_REG_AS_ADDRESS);
v->variables = _mesa_hash_table_create(v->mem_ctx, _mesa_hash_pointer,
_mesa_key_pointer_equal);
skip_merge_registers =
pscreen->get_shader_param(pscreen, ptarget,
PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS);
_mesa_generate_parameters_list_for_uniforms(ctx, shader_program, shader,
prog->Parameters);
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi_private.h b/src/mesa/state_tracker/st_glsl_to_tgsi_private.h
index b9112e5..d57525d 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi_private.h
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi_private.h
@@ -67,20 +67,28 @@ public:
* Is this the second half of a double register pair?
* currently used for input mapping only.
*/
unsigned double_reg2:1;
unsigned is_double_vertex_input:1;
unsigned array_id:10;
/** Register index should be offset by the integer in this reg. */
st_src_reg *reladdr;
st_src_reg *reladdr2;
+ bool is_legal_tgsi_address_operand() const
+ {
+ /* 2D registers can't be used as an address operand, or if the address
+ * operand itself is a result of indirect addressing.
+ */
+ return (type == GLSL_TYPE_INT || type == GLSL_TYPE_UINT) &&
+ !has_index2 && !reladdr && !reladdr2;
+ }
};
class st_dst_reg {
public:
st_dst_reg(gl_register_file file, int writemask, enum glsl_base_type type, int index);
st_dst_reg(gl_register_file file, int writemask, enum glsl_base_type type);
st_dst_reg();
st_dst_reg(const st_dst_reg ®);
--
2.7.4
More information about the mesa-dev
mailing list