summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorBryan Cain <[email protected]>2011-07-21 15:49:26 -0500
committerBryan Cain <[email protected]>2011-08-01 17:59:09 -0500
commit7732822c833ee22e259af3f8bd2bfb57c986612e (patch)
tree16781cee1e751e00f0cec6a52e176a7a79f114fb /src/mesa
parent87f8d8547db9b947ae847c509a464e06d0ac6c64 (diff)
glsl_to_tgsi: separate immediates from array constants during IR translation
Before, if any uniform or constant array was accessed with indirect addressing, st_translate_program() would emit uniform constants in the place of immediates. This behavior was unavoidable with ir_to_mesa/mesa_to_tgsi, but glsl_to_tgsi can work around it since the GLSL IR backend and the TGSI emission are both inside the state tracker.
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/state_tracker/st_glsl_to_tgsi.cpp143
1 files changed, 95 insertions, 48 deletions
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 3df22eae918..389e5d8e2ef 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -70,6 +70,7 @@ extern "C" {
#include "st_mesa_to_tgsi.h"
}
+#define PROGRAM_IMMEDIATE PROGRAM_FILE_MAX
#define PROGRAM_ANY_CONST ((1 << PROGRAM_LOCAL_PARAM) | \
(1 << PROGRAM_ENV_PARAM) | \
(1 << PROGRAM_STATE_VAR) | \
@@ -272,6 +273,7 @@ public:
struct gl_program *prog;
struct gl_shader_program *shader_program;
struct gl_shader_compiler_options *options;
+ struct gl_program_parameter_list *immediates;
int next_temp;
@@ -505,6 +507,9 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op,
case PROGRAM_UNIFORM:
this->indirect_addr_consts = true;
break;
+ case PROGRAM_IMMEDIATE:
+ assert(!"immediates should not have indirect addressing");
+ break;
default:
break;
}
@@ -524,6 +529,9 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op,
case PROGRAM_UNIFORM:
this->indirect_addr_consts = true;
break;
+ case PROGRAM_IMMEDIATE:
+ assert(!"immediates should not have indirect addressing");
+ break;
default:
break;
}
@@ -804,12 +812,12 @@ glsl_to_tgsi_visitor::emit_scs(ir_instruction *ir, unsigned op,
struct st_src_reg
glsl_to_tgsi_visitor::st_src_reg_for_float(float val)
{
- st_src_reg src(PROGRAM_CONSTANT, -1, GLSL_TYPE_FLOAT);
+ st_src_reg src(PROGRAM_IMMEDIATE, -1, GLSL_TYPE_FLOAT);
union gl_constant_value uval;
uval.f = val;
- src.index = _mesa_add_typed_unnamed_constant(this->prog->Parameters,
- &uval, 1, GL_FLOAT, &src.swizzle);
+ src.index = _mesa_add_typed_unnamed_constant(this->immediates, &uval, 1,
+ GL_FLOAT, &src.swizzle);
return src;
}
@@ -817,14 +825,14 @@ glsl_to_tgsi_visitor::st_src_reg_for_float(float val)
struct st_src_reg
glsl_to_tgsi_visitor::st_src_reg_for_int(int val)
{
- st_src_reg src(PROGRAM_CONSTANT, -1, GLSL_TYPE_INT);
+ st_src_reg src(PROGRAM_IMMEDIATE, -1, GLSL_TYPE_INT);
union gl_constant_value uval;
assert(glsl_version >= 130);
uval.i = val;
- src.index = _mesa_add_typed_unnamed_constant(this->prog->Parameters,
- &uval, 1, GL_INT, &src.swizzle);
+ src.index = _mesa_add_typed_unnamed_constant(this->immediates, &uval, 1,
+ GL_INT, &src.swizzle);
return src;
}
@@ -1933,9 +1941,15 @@ glsl_to_tgsi_visitor::visit(ir_constant *ir)
gl_constant_value *values = (gl_constant_value *) stack_vals;
GLenum gl_type = GL_NONE;
unsigned int i;
+ gl_register_file file;
+ gl_program_parameter_list *param_list;
+ static int in_array = 0;
+
+ file = in_array ? PROGRAM_CONSTANT : PROGRAM_IMMEDIATE;
+ param_list = in_array ? this->prog->Parameters : this->immediates;
/* Unfortunately, 4 floats is all we can get into
- * _mesa_add_unnamed_constant. So, make a temp to store an
+ * _mesa_add_typed_unnamed_constant. So, make a temp to store an
* aggregate constant and move each constant value into it. If we
* get lucky, copy propagation will eliminate the extra moves.
*/
@@ -1969,6 +1983,7 @@ glsl_to_tgsi_visitor::visit(ir_constant *ir)
int size = type_size(ir->type->fields.array);
assert(size > 0);
+ in_array++;
for (i = 0; i < ir->type->length; i++) {
ir->array_elements[i]->accept(this);
@@ -1981,6 +1996,7 @@ glsl_to_tgsi_visitor::visit(ir_constant *ir)
}
}
this->result = temp_base;
+ in_array--;
return;
}
@@ -1992,8 +2008,8 @@ glsl_to_tgsi_visitor::visit(ir_constant *ir)
assert(ir->type->base_type == GLSL_TYPE_FLOAT);
values = (gl_constant_value *) &ir->value.f[i * ir->type->vector_elements];
- src = st_src_reg(PROGRAM_CONSTANT, -1, ir->type->base_type);
- src.index = _mesa_add_typed_unnamed_constant(this->prog->Parameters,
+ src = st_src_reg(file, -1, ir->type->base_type);
+ src.index = _mesa_add_typed_unnamed_constant(param_list,
values,
ir->type->vector_elements,
GL_FLOAT,
@@ -2007,7 +2023,6 @@ glsl_to_tgsi_visitor::visit(ir_constant *ir)
return;
}
- src.file = PROGRAM_CONSTANT;
switch (ir->type->base_type) {
case GLSL_TYPE_FLOAT:
gl_type = GL_FLOAT;
@@ -2046,8 +2061,8 @@ glsl_to_tgsi_visitor::visit(ir_constant *ir)
assert(!"Non-float/uint/int/bool constant");
}
- this->result = st_src_reg(PROGRAM_CONSTANT, -1, ir->type);
- this->result.index = _mesa_add_typed_unnamed_constant(this->prog->Parameters,
+ this->result = st_src_reg(file, -1, ir->type);
+ this->result.index = _mesa_add_typed_unnamed_constant(param_list,
values, ir->type->vector_elements, gl_type,
&this->result.swizzle);
}
@@ -2430,11 +2445,13 @@ glsl_to_tgsi_visitor::glsl_to_tgsi_visitor()
num_address_regs = 0;
indirect_addr_temps = false;
indirect_addr_consts = false;
+ immediates = _mesa_new_parameter_list();
mem_ctx = ralloc_context(NULL);
}
glsl_to_tgsi_visitor::~glsl_to_tgsi_visitor()
{
+ _mesa_free_parameter_list(immediates);
ralloc_free(mem_ctx);
}
@@ -3521,6 +3538,8 @@ get_pixel_transfer_visitor(struct st_fragment_program *fp,
v->samplers_used = prog->SamplersUsed = original->samplers_used;
v->indirect_addr_temps = original->indirect_addr_temps;
v->indirect_addr_consts = original->indirect_addr_consts;
+ _mesa_free_parameter_list(v->immediates);
+ v->immediates = _mesa_clone_parameter_list(original->immediates);
/*
* Get initial pixel color from the texture.
@@ -3648,6 +3667,8 @@ get_bitmap_visitor(struct st_fragment_program *fp,
v->samplers_used = prog->SamplersUsed = original->samplers_used;
v->indirect_addr_temps = original->indirect_addr_temps;
v->indirect_addr_consts = original->indirect_addr_consts;
+ _mesa_free_parameter_list(v->immediates);
+ v->immediates = _mesa_clone_parameter_list(original->immediates);
/* TEX tmp0, fragment.texcoord[0], texture[0], 2D; */
coord = st_src_reg(PROGRAM_INPUT, FRAG_ATTRIB_TEX0, glsl_type::vec2_type);
@@ -3707,6 +3728,7 @@ struct st_translate {
struct ureg_dst temps[MAX_TEMPS];
struct ureg_src *constants;
+ struct ureg_src *immediates;
struct ureg_dst outputs[PIPE_MAX_SHADER_OUTPUTS];
struct ureg_src inputs[PIPE_MAX_SHADER_INPUTS];
struct ureg_dst address[1];
@@ -3798,6 +3820,43 @@ static void set_insn_start( struct st_translate *t,
}
/**
+ * Map a glsl_to_tgsi constant/immediate to a TGSI immediate.
+ */
+static struct ureg_src
+emit_immediate( struct st_translate *t,
+ struct gl_program_parameter_list *params,
+ int index)
+{
+ struct ureg_program *ureg = t->ureg;
+
+ switch(params->Parameters[index].DataType)
+ {
+ case GL_FLOAT:
+ case GL_FLOAT_VEC2:
+ case GL_FLOAT_VEC3:
+ case GL_FLOAT_VEC4:
+ return ureg_DECL_immediate(ureg, (float *)params->ParameterValues[index], 4);
+ case GL_INT:
+ case GL_INT_VEC2:
+ case GL_INT_VEC3:
+ case GL_INT_VEC4:
+ return ureg_DECL_immediate_int(ureg, (int *)params->ParameterValues[index], 4);
+ case GL_UNSIGNED_INT:
+ case GL_UNSIGNED_INT_VEC2:
+ case GL_UNSIGNED_INT_VEC3:
+ case GL_UNSIGNED_INT_VEC4:
+ case GL_BOOL:
+ case GL_BOOL_VEC2:
+ case GL_BOOL_VEC3:
+ case GL_BOOL_VEC4:
+ return ureg_DECL_immediate_uint(ureg, (unsigned *)params->ParameterValues[index], 4);
+ default:
+ assert(!"should not get here - type must be float, int, uint, or bool");
+ return ureg_src_undef();
+ }
+}
+
+/**
* Map a Mesa dst register to a TGSI ureg_dst register.
*/
static struct ureg_dst
@@ -3871,6 +3930,9 @@ src_register( struct st_translate *t,
else
return t->constants[index];
+ case PROGRAM_IMMEDIATE:
+ return t->immediates[index];
+
case PROGRAM_INPUT:
assert(t->inputMapping[index] < Elements(t->inputs));
return t->inputs[t->inputMapping[index]];
@@ -4402,9 +4464,8 @@ st_translate_program(
}
}
- /* Emit constants and immediates. Mesa uses a single index space
- * for these, so we put all the translated regs in t->constants.
- * XXX: this entire if block depends on proginfo->Parameters from Mesa IR
+ /* Emit constants and uniforms. TGSI uses a single index space for these,
+ * so we put all the translated regs in t->constants.
*/
if (proginfo->Parameters) {
t->constants = (struct ureg_src *)CALLOC( proginfo->Parameters->NumParameters * sizeof t->constants[0] );
@@ -4423,49 +4484,34 @@ st_translate_program(
t->constants[i] = ureg_DECL_constant( ureg, i );
break;
- /* Emit immediates only when there's no indirect addressing of
- * the const buffer.
- * FIXME: Be smarter and recognize param arrays:
- * indirect addressing is only valid within the referenced
- * array.
- */
+ /* Emit immediates for PROGRAM_CONSTANT only when there's no indirect
+ * addressing of the const buffer.
+ * FIXME: Be smarter and recognize param arrays:
+ * indirect addressing is only valid within the referenced
+ * array.
+ */
case PROGRAM_CONSTANT:
if (program->indirect_addr_consts)
t->constants[i] = ureg_DECL_constant( ureg, i );
else
- switch(proginfo->Parameters->Parameters[i].DataType)
- {
- case GL_FLOAT:
- case GL_FLOAT_VEC2:
- case GL_FLOAT_VEC3:
- case GL_FLOAT_VEC4:
- t->constants[i] = ureg_DECL_immediate(ureg, (float *)proginfo->Parameters->ParameterValues[i], 4);
- break;
- case GL_INT:
- case GL_INT_VEC2:
- case GL_INT_VEC3:
- case GL_INT_VEC4:
- t->constants[i] = ureg_DECL_immediate_int(ureg, (int *)proginfo->Parameters->ParameterValues[i], 4);
- break;
- case GL_UNSIGNED_INT:
- case GL_UNSIGNED_INT_VEC2:
- case GL_UNSIGNED_INT_VEC3:
- case GL_UNSIGNED_INT_VEC4:
- case GL_BOOL:
- case GL_BOOL_VEC2:
- case GL_BOOL_VEC3:
- case GL_BOOL_VEC4:
- t->constants[i] = ureg_DECL_immediate_uint(ureg, (unsigned *)proginfo->Parameters->ParameterValues[i], 4);
- break;
- default:
- assert(!"should not get here");
- }
+ t->constants[i] = emit_immediate( t, proginfo->Parameters, i );
break;
default:
break;
}
}
}
+
+ /* Emit immediate values.
+ */
+ t->immediates = (struct ureg_src *)CALLOC( program->immediates->NumParameters * sizeof(struct ureg_src) );
+ if (t->immediates == NULL) {
+ ret = PIPE_ERROR_OUT_OF_MEMORY;
+ goto out;
+ }
+ for (i = 0; i < program->immediates->NumParameters; i++) {
+ t->immediates[i] = emit_immediate( t, program->immediates, i );
+ }
/* texture samplers */
for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
@@ -4512,6 +4558,7 @@ out:
FREE(t->insn);
FREE(t->labels);
FREE(t->constants);
+ FREE(t->immediates);
if (t->error) {
debug_printf("%s: translate error flag set\n", __FUNCTION__);