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.cpp121
1 files changed, 93 insertions, 28 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 610fc68a8..a9e75d8a6 100644
--- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -87,7 +87,7 @@ extern "C" {
*/
#define MAX_ARRAYS 256
-/* will be 4 for GLSL 4.00 */
+/* if we support a native gallium TG4 with the ability to take 4 texoffsets then bump this */
#define MAX_GLSL_TEXTURE_OFFSET 1
class st_src_reg;
@@ -249,7 +249,8 @@ public:
int sampler; /**< sampler index */
int tex_target; /**< One of TEXTURE_*_INDEX */
GLboolean tex_shadow;
- struct tgsi_texture_offset tex_offsets[MAX_GLSL_TEXTURE_OFFSET];
+
+ st_src_reg tex_offsets[MAX_GLSL_TEXTURE_OFFSET];
unsigned tex_offset_num_offset;
int dead_mask; /**< Used in dead code elimination */
@@ -983,6 +984,7 @@ type_size(const struct glsl_type *type)
}
return size;
case GLSL_TYPE_SAMPLER:
+ case GLSL_TYPE_IMAGE:
/* Samplers take up one slot in UNIFORMS[], but they're baked in
* at link time.
*/
@@ -2685,7 +2687,7 @@ glsl_to_tgsi_visitor::visit(ir_call *ir)
void
glsl_to_tgsi_visitor::visit(ir_texture *ir)
{
- st_src_reg result_src, coord, cube_sc, lod_info, projector, dx, dy, offset, sample_index;
+ st_src_reg result_src, coord, cube_sc, lod_info, projector, dx, dy, offset, sample_index, component;
st_dst_reg result_dst, coord_dst, cube_sc_dst;
glsl_to_tgsi_instruction *inst = NULL;
unsigned opcode = TGSI_OPCODE_NOP;
@@ -2779,12 +2781,20 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
ir->lod_info.sample_index->accept(this);
sample_index = this->result;
break;
+ case ir_tg4:
+ opcode = TGSI_OPCODE_TG4;
+ ir->lod_info.component->accept(this);
+ component = this->result;
+ if (ir->offset) {
+ ir->offset->accept(this);
+ /* this should have been lowered */
+ assert(ir->offset->type->base_type != GLSL_TYPE_ARRAY);
+ offset = this->result;
+ }
+ break;
case ir_lod:
assert(!"Unexpected ir_lod opcode");
break;
- case ir_tg4:
- assert(!"Unexpected ir_tg4 opcode");
- break;
case ir_query_levels:
assert(!"Unexpected ir_query_levels opcode");
break;
@@ -2892,7 +2902,13 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
inst = emit(ir, opcode, result_dst, coord, lod_info);
} else if (opcode == TGSI_OPCODE_TEX2) {
inst = emit(ir, opcode, result_dst, coord, cube_sc);
- } else
+ } else if (opcode == TGSI_OPCODE_TG4) {
+ if (is_cube_array && ir->shadow_comparitor) {
+ inst = emit(ir, opcode, result_dst, coord, cube_sc);
+ } else {
+ inst = emit(ir, opcode, result_dst, coord, component);
+ }
+ } else
inst = emit(ir, opcode, result_dst, coord);
if (ir->shadow_comparitor)
@@ -2903,12 +2919,8 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
this->prog);
if (ir->offset) {
- inst->tex_offset_num_offset = 1;
- inst->tex_offsets[0].Index = offset.index;
- inst->tex_offsets[0].File = offset.file;
- inst->tex_offsets[0].SwizzleX = GET_SWZ(offset.swizzle, 0);
- inst->tex_offsets[0].SwizzleY = GET_SWZ(offset.swizzle, 1);
- inst->tex_offsets[0].SwizzleZ = GET_SWZ(offset.swizzle, 2);
+ inst->tex_offset_num_offset = 1;
+ inst->tex_offsets[0] = offset;
}
switch (sampler_type->sampler_dimensionality) {
@@ -3266,6 +3278,13 @@ glsl_to_tgsi_visitor::rename_temp_register(int index, int new_index)
inst->src[j].index = new_index;
}
}
+
+ for (j=0; j < inst->tex_offset_num_offset; j++) {
+ if (inst->tex_offsets[j].file == PROGRAM_TEMPORARY &&
+ inst->tex_offsets[j].index == index) {
+ inst->tex_offsets[j].index = new_index;
+ }
+ }
if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == index) {
inst->dst.index = new_index;
@@ -3289,6 +3308,12 @@ glsl_to_tgsi_visitor::get_first_temp_read(int index)
return (depth == 0) ? i : loop_start;
}
}
+ for (j=0; j < inst->tex_offset_num_offset; j++) {
+ if (inst->tex_offsets[j].file == PROGRAM_TEMPORARY &&
+ inst->tex_offsets[j].index == index) {
+ return (depth == 0) ? i : loop_start;
+ }
+ }
if (inst->op == TGSI_OPCODE_BGNLOOP) {
if(depth++ == 0)
@@ -3350,6 +3375,11 @@ glsl_to_tgsi_visitor::get_last_temp_read(int index)
last = (depth == 0) ? i : -2;
}
}
+ for (j=0; j < inst->tex_offset_num_offset; j++) {
+ if (inst->tex_offsets[j].file == PROGRAM_TEMPORARY &&
+ inst->tex_offsets[j].index == index)
+ last = (depth == 0) ? i : -2;
+ }
if (inst->op == TGSI_OPCODE_BGNLOOP)
depth++;
@@ -3726,6 +3756,26 @@ glsl_to_tgsi_visitor::eliminate_dead_code_advanced(void)
}
}
}
+ for (unsigned i = 0; i < inst->tex_offset_num_offset; i++) {
+ if (inst->tex_offsets[i].file == PROGRAM_TEMPORARY && inst->tex_offsets[i].reladdr){
+ /* Any temporary might be read, so no dead code elimination
+ * across this instruction.
+ */
+ memset(writes, 0, sizeof(*writes) * this->next_temp * 4);
+ } else if (inst->tex_offsets[i].file == PROGRAM_TEMPORARY) {
+ /* Clear where it's used as src. */
+ int src_chans = 1 << GET_SWZ(inst->tex_offsets[i].swizzle, 0);
+ src_chans |= 1 << GET_SWZ(inst->tex_offsets[i].swizzle, 1);
+ src_chans |= 1 << GET_SWZ(inst->tex_offsets[i].swizzle, 2);
+ src_chans |= 1 << GET_SWZ(inst->tex_offsets[i].swizzle, 3);
+
+ for (int c = 0; c < 4; c++) {
+ if (src_chans & (1 << c)) {
+ writes[4 * inst->tex_offsets[i].index + c] = NULL;
+ }
+ }
+ }
+ }
break;
}
@@ -4079,7 +4129,7 @@ struct st_translate {
struct ureg_dst address[2];
struct ureg_src samplers[PIPE_MAX_SAMPLERS];
struct ureg_src systemValues[SYSTEM_VALUE_MAX];
-
+ struct tgsi_texture_offset tex_offsets[MAX_GLSL_TEXTURE_OFFSET];
unsigned array_sizes[MAX_ARRAYS];
const GLuint *inputMapping;
@@ -4379,22 +4429,34 @@ translate_src(struct st_translate *t, const st_src_reg *src_reg)
static struct tgsi_texture_offset
translate_tex_offset(struct st_translate *t,
- const struct tgsi_texture_offset *in_offset)
+ const st_src_reg *in_offset, int idx)
{
struct tgsi_texture_offset offset;
struct ureg_src imm_src;
- assert(in_offset->File == PROGRAM_IMMEDIATE);
- imm_src = t->immediates[in_offset->Index];
-
- offset.File = imm_src.File;
- offset.Index = imm_src.Index;
- offset.SwizzleX = imm_src.SwizzleX;
- offset.SwizzleY = imm_src.SwizzleY;
- offset.SwizzleZ = imm_src.SwizzleZ;
- offset.File = TGSI_FILE_IMMEDIATE;
- offset.Padding = 0;
-
+ switch (in_offset->file) {
+ case PROGRAM_IMMEDIATE:
+ imm_src = t->immediates[in_offset->index];
+
+ offset.File = imm_src.File;
+ offset.Index = imm_src.Index;
+ offset.SwizzleX = imm_src.SwizzleX;
+ offset.SwizzleY = imm_src.SwizzleY;
+ offset.SwizzleZ = imm_src.SwizzleZ;
+ offset.Padding = 0;
+ break;
+ case PROGRAM_TEMPORARY:
+ imm_src = ureg_src(t->temps[in_offset->index]);
+ offset.File = imm_src.File;
+ offset.Index = imm_src.Index;
+ offset.SwizzleX = GET_SWZ(in_offset->swizzle, 0);
+ offset.SwizzleY = GET_SWZ(in_offset->swizzle, 1);
+ offset.SwizzleZ = GET_SWZ(in_offset->swizzle, 2);
+ offset.Padding = 0;
+ break;
+ default:
+ break;
+ }
return offset;
}
@@ -4450,9 +4512,10 @@ compile_tgsi_instruction(struct st_translate *t,
case TGSI_OPCODE_TEX2:
case TGSI_OPCODE_TXB2:
case TGSI_OPCODE_TXL2:
+ case TGSI_OPCODE_TG4:
src[num_src++] = t->samplers[inst->sampler];
for (i = 0; i < inst->tex_offset_num_offset; i++) {
- texoffsets[i] = translate_tex_offset(t, &inst->tex_offsets[i]);
+ texoffsets[i] = translate_tex_offset(t, &inst->tex_offsets[i], i);
}
tex_target = st_translate_texture_target(inst->tex_target, inst->tex_shadow);
@@ -5140,7 +5203,7 @@ get_mesa_program(struct gl_context *ctx,
printf("GLSL IR for linked %s program %d:\n",
_mesa_shader_stage_to_string(shader->Stage),
shader_program->Name);
- _mesa_print_ir(shader->ir, NULL);
+ _mesa_print_ir(stdout, shader->ir, NULL);
printf("\n");
printf("\n");
fflush(stdout);
@@ -5182,6 +5245,7 @@ get_mesa_program(struct gl_context *ctx,
stgp->Base.InputType = shader_program->Geom.InputType;
stgp->Base.OutputType = shader_program->Geom.OutputType;
stgp->Base.VerticesOut = shader_program->Geom.VerticesOut;
+ stgp->Base.Invocations = shader_program->Geom.Invocations;
break;
default:
assert(!"should not be reached");
@@ -5268,6 +5332,7 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
lower_packing_builtins(ir, lower_inst);
}
+ lower_offset_arrays(ir);
do_mat_op_to_vec(ir);
lower_instructions(ir,
MOD_TO_FRACT |