[Mesa-dev] [PATCH 11/11] glsl_to_tgsi: skip UARL for 1D registers if the driver doesn't need it
Nicolai Hähnle
nhaehnle at gmail.com
Mon Oct 2 11:12:06 UTC 2017
On 29.09.2017 14:25, Marek Olšák wrote:
> 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;
I'd find this cleaner as
if (!this->need_uarl && src0.is_legal_tgsi_address_operand())
return;
op = TGSI_OPCODE_UARL;
I also sent some comments on patches 3, 7, and 9. Apart from those, the
series is
Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>
> + }
>
> 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 ®);
>
--
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.
More information about the mesa-dev
mailing list