aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp')
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp142
1 files changed, 68 insertions, 74 deletions
diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 0cef092d3..e3718eeda 100644
--- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -85,6 +85,11 @@ extern "C" {
*/
#define MAX_TEMPS 4096
+/**
+ * Maximum number of arrays
+ */
+#define MAX_ARRAYS 256
+
/* will be 4 for GLSL 4.00 */
#define MAX_GLSL_TEXTURE_OFFSET 1
@@ -315,9 +320,11 @@ public:
int next_temp;
+ unsigned array_sizes[MAX_ARRAYS];
+ unsigned next_array;
+
int num_address_regs;
int samplers_used;
- bool indirect_addr_temps;
bool indirect_addr_consts;
int glsl_version;
@@ -549,9 +556,6 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op,
/* Update indirect addressing status used by TGSI */
if (dst.reladdr) {
switch(dst.file) {
- case PROGRAM_TEMPORARY:
- this->indirect_addr_temps = true;
- break;
case PROGRAM_LOCAL_PARAM:
case PROGRAM_ENV_PARAM:
case PROGRAM_STATE_VAR:
@@ -570,9 +574,6 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op,
for (i=0; i<3; i++) {
if(inst->src[i].reladdr) {
switch(inst->src[i].file) {
- case PROGRAM_TEMPORARY:
- this->indirect_addr_temps = true;
- break;
case PROGRAM_LOCAL_PARAM:
case PROGRAM_ENV_PARAM:
case PROGRAM_STATE_VAR:
@@ -1005,17 +1006,26 @@ glsl_to_tgsi_visitor::get_temp(const glsl_type *type)
st_src_reg src;
src.type = native_integers ? type->base_type : GLSL_TYPE_FLOAT;
- src.file = PROGRAM_TEMPORARY;
- src.index = next_temp;
src.reladdr = NULL;
- next_temp += type_size(type);
+ src.negate = 0;
+
+ if (type->is_array() || type->is_matrix()) {
+ src.file = PROGRAM_ARRAY;
+ src.index = next_array << 16 | 0x8000;
+ array_sizes[next_array] = type_size(type);
+ ++next_array;
+
+ } else {
+ src.file = PROGRAM_TEMPORARY;
+ src.index = next_temp;
+ next_temp += type_size(type);
+ }
if (type->is_array() || type->is_record()) {
src.swizzle = SWIZZLE_NOOP;
} else {
src.swizzle = swizzle_for_size(type->vector_elements);
}
- src.negate = 0;
return src;
}
@@ -1078,13 +1088,11 @@ glsl_to_tgsi_visitor::visit(ir_variable *ir)
*/
assert((int) ir->num_state_slots == type_size(ir->type));
- storage = new(mem_ctx) variable_storage(ir, PROGRAM_TEMPORARY,
- this->next_temp);
- this->variables.push_tail(storage);
- this->next_temp += type_size(ir->type);
+ dst = st_dst_reg(get_temp(ir->type));
+
+ storage = new(mem_ctx) variable_storage(ir, dst.file, dst.index);
- dst = st_dst_reg(st_src_reg(PROGRAM_TEMPORARY, storage->index,
- native_integers ? ir->type->base_type : GLSL_TYPE_FLOAT));
+ this->variables.push_tail(storage);
}
@@ -2052,11 +2060,11 @@ glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir)
break;
case ir_var_auto:
case ir_var_temporary:
- entry = new(mem_ctx) variable_storage(var, PROGRAM_TEMPORARY,
- this->next_temp);
+ st_src_reg src = get_temp(var->type);
+
+ entry = new(mem_ctx) variable_storage(var, src.file, src.index);
this->variables.push_tail(entry);
- next_temp += type_size(var->type);
break;
}
@@ -2574,11 +2582,10 @@ glsl_to_tgsi_visitor::get_function_signature(ir_function_signature *sig)
storage = find_variable_storage(param);
assert(!storage);
- storage = new(mem_ctx) variable_storage(param, PROGRAM_TEMPORARY,
- this->next_temp);
- this->variables.push_tail(storage);
+ st_src_reg src = get_temp(param->type);
- this->next_temp += type_size(param->type);
+ storage = new(mem_ctx) variable_storage(param, src.file, src.index);
+ this->variables.push_tail(storage);
}
if (!sig->return_type->is_void()) {
@@ -2978,12 +2985,12 @@ glsl_to_tgsi_visitor::glsl_to_tgsi_visitor()
{
result.file = PROGRAM_UNDEFINED;
next_temp = 1;
+ next_array = 0;
next_signature_id = 1;
num_immediates = 0;
current_function = NULL;
num_address_regs = 0;
samplers_used = 0;
- indirect_addr_temps = false;
indirect_addr_consts = false;
glsl_version = 0;
native_integers = false;
@@ -3183,7 +3190,8 @@ glsl_to_tgsi_visitor::simplify_cmp(void)
assert(inst->dst.index < MAX_TEMPS);
prevWriteMask = tempWrites[inst->dst.index];
tempWrites[inst->dst.index] |= inst->dst.writemask;
- }
+ } else
+ break;
/* For a CMP to be considered a conditional write, the destination
* register and source register two must be the same. */
@@ -3821,7 +3829,6 @@ get_pixel_transfer_visitor(struct st_fragment_program *fp,
v->next_temp = original->next_temp;
v->num_address_regs = original->num_address_regs;
v->samplers_used = prog->SamplersUsed = original->samplers_used;
- v->indirect_addr_temps = original->indirect_addr_temps;
v->indirect_addr_consts = original->indirect_addr_consts;
memcpy(&v->immediates, &original->immediates, sizeof(v->immediates));
v->num_immediates = original->num_immediates;
@@ -3952,7 +3959,6 @@ get_bitmap_visitor(struct st_fragment_program *fp,
v->next_temp = original->next_temp;
v->num_address_regs = original->num_address_regs;
v->samplers_used = prog->SamplersUsed = original->samplers_used;
- v->indirect_addr_temps = original->indirect_addr_temps;
v->indirect_addr_consts = original->indirect_addr_consts;
memcpy(&v->immediates, &original->immediates, sizeof(v->immediates));
v->num_immediates = original->num_immediates;
@@ -4014,6 +4020,7 @@ struct st_translate {
struct ureg_program *ureg;
struct ureg_dst temps[MAX_TEMPS];
+ struct ureg_dst arrays[MAX_ARRAYS];
struct ureg_src *constants;
struct ureg_src *immediates;
struct ureg_dst outputs[PIPE_MAX_SHADER_OUTPUTS];
@@ -4022,6 +4029,8 @@ struct st_translate {
struct ureg_src samplers[PIPE_MAX_SAMPLERS];
struct ureg_src systemValues[SYSTEM_VALUE_MAX];
+ unsigned array_sizes[MAX_ARRAYS];
+
const GLuint *inputMapping;
const GLuint *outputMapping;
@@ -4132,16 +4141,34 @@ dst_register(struct st_translate *t,
gl_register_file file,
GLuint index)
{
+ unsigned array;
+
switch(file) {
case PROGRAM_UNDEFINED:
return ureg_dst_undef();
case PROGRAM_TEMPORARY:
+ assert(index >= 0);
+ assert(index < (int) Elements(t->temps));
+
if (ureg_dst_is_undef(t->temps[index]))
t->temps[index] = ureg_DECL_local_temporary(t->ureg);
return t->temps[index];
+ case PROGRAM_ARRAY:
+ array = index >> 16;
+
+ assert(array >= 0);
+ assert(array < (int) Elements(t->arrays));
+
+ if (ureg_dst_is_undef(t->arrays[array]))
+ t->arrays[array] = ureg_DECL_array_temporary(
+ t->ureg, t->array_sizes[array], TRUE);
+
+ return ureg_dst_array_offset(t->arrays[array],
+ (int)(index & 0xFFFF) - 0x8000);
+
case PROGRAM_OUTPUT:
if (t->procType == TGSI_PROCESSOR_VERTEX)
assert(index < VARYING_SLOT_MAX);
@@ -4176,11 +4203,8 @@ src_register(struct st_translate *t,
return ureg_src_undef();
case PROGRAM_TEMPORARY:
- assert(index >= 0);
- assert(index < (int) Elements(t->temps));
- if (ureg_dst_is_undef(t->temps[index]))
- t->temps[index] = ureg_DECL_local_temporary(t->ureg);
- return ureg_src(t->temps[index]);
+ case PROGRAM_ARRAY:
+ return ureg_src(dst_register(t, file, index));
case PROGRAM_ENV_PARAM:
case PROGRAM_LOCAL_PARAM:
@@ -4262,8 +4286,10 @@ translate_dst(struct st_translate *t,
}
}
- if (dst_reg->reladdr != NULL)
+ if (dst_reg->reladdr != NULL) {
+ assert(dst_reg->file != PROGRAM_TEMPORARY);
dst = ureg_dst_indirect(dst, ureg_src(t->address[0]));
+ }
return dst;
}
@@ -4286,26 +4312,8 @@ translate_src(struct st_translate *t, const st_src_reg *src_reg)
src = ureg_negate(src);
if (src_reg->reladdr != NULL) {
- /* Normally ureg_src_indirect() would be used here, but a stupid compiler
- * bug in g++ makes ureg_src_indirect (an inline C function) erroneously
- * set the bit for src.Negate. So we have to do the operation manually
- * here to work around the compiler's problems. */
- /*src = ureg_src_indirect(src, ureg_src(t->address[0]));*/
- struct ureg_src addr = ureg_src(t->address[0]);
- src.Indirect = 1;
- src.IndirectFile = addr.File;
- src.IndirectIndex = addr.Index;
- src.IndirectSwizzle = addr.SwizzleX;
-
- if (src_reg->file != PROGRAM_INPUT &&
- src_reg->file != PROGRAM_OUTPUT) {
- /* If src_reg->index was negative, it was set to zero in
- * src_register(). Reassign it now. But don't do this
- * for input/output regs since they get remapped while
- * const buffers don't.
- */
- src.Index = src_reg->index;
- }
+ assert(src_reg->file != PROGRAM_TEMPORARY);
+ src = ureg_src_indirect(src, ureg_src(t->address[0]));
}
return src;
@@ -4820,16 +4828,9 @@ st_translate_program(
}
}
- if (program->indirect_addr_temps) {
- /* If temps are accessed with indirect addressing, declare temporaries
- * in sequential order. Else, we declare them on demand elsewhere.
- * (Note: the number of temporaries is equal to program->next_temp)
- */
- for (i = 0; i < (unsigned)program->next_temp; i++) {
- /* XXX use TGSI_FILE_TEMPORARY_ARRAY when it's supported by ureg */
- t->temps[i] = ureg_DECL_local_temporary(t->ureg);
- }
- }
+ /* Copy over array sizes
+ */
+ memcpy(t->array_sizes, program->array_sizes, sizeof(unsigned) * program->next_array);
/* Emit constants and uniforms. TGSI uses a single index space for these,
* so we put all the translated regs in t->constants.
@@ -5064,16 +5065,9 @@ get_mesa_program(struct gl_context *ctx,
v->copy_propagate();
while (v->eliminate_dead_code_advanced());
- /* FIXME: These passes to optimize temporary registers don't work when there
- * is indirect addressing of the temporary register space. We need proper
- * array support so that we don't have to give up these passes in every
- * shader that uses arrays.
- */
- if (!v->indirect_addr_temps) {
- v->eliminate_dead_code();
- v->merge_registers();
- v->renumber_registers();
- }
+ v->eliminate_dead_code();
+ v->merge_registers();
+ v->renumber_registers();
/* Write the END instruction. */
v->emit(NULL, TGSI_OPCODE_END);