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.cpp237
1 files changed, 53 insertions, 184 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 efee4b258..93671ba9c 100644
--- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -30,40 +30,25 @@
* Translate GLSL IR to TGSI.
*/
-#include <stdio.h>
-#include "main/compiler.h"
-#include "ir.h"
-#include "ir_visitor.h"
-#include "ir_expression_flattening.h"
-#include "glsl_types.h"
+#include "st_glsl_to_tgsi.h"
+
#include "glsl_parser_extras.h"
-#include "../glsl/program.h"
#include "ir_optimization.h"
-#include "ast.h"
-#include "main/mtypes.h"
+#include "main/errors.h"
#include "main/shaderobj.h"
#include "main/uniforms.h"
#include "main/shaderapi.h"
-#include "program/hash_table.h"
#include "program/prog_instruction.h"
-#include "program/prog_optimize.h"
-#include "program/prog_print.h"
-#include "program/program.h"
-#include "program/prog_parameter.h"
#include "program/sampler.h"
-#include "pipe/p_compiler.h"
#include "pipe/p_context.h"
#include "pipe/p_screen.h"
-#include "pipe/p_shader_tokens.h"
-#include "pipe/p_state.h"
-#include "util/u_math.h"
#include "tgsi/tgsi_ureg.h"
#include "tgsi/tgsi_info.h"
-#include "st_context.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
#include "st_program.h"
-#include "st_glsl_to_tgsi.h"
#include "st_mesa_to_tgsi.h"
@@ -328,6 +313,7 @@ public:
int num_address_regs;
int samplers_used;
bool indirect_addr_consts;
+ int wpos_transform_const;
int glsl_version;
bool native_integers;
@@ -441,9 +427,6 @@ public:
void emit_arl(ir_instruction *ir, st_dst_reg dst, st_src_reg src0);
- void emit_scs(ir_instruction *ir, unsigned op,
- st_dst_reg dst, const st_src_reg &src);
-
bool try_emit_mad(ir_expression *ir,
int mul_operand);
bool try_emit_mad_for_and_not(ir_expression *ir,
@@ -966,101 +949,6 @@ glsl_to_tgsi_visitor::emit_arl(ir_instruction *ir,
emit(NULL, op, dst, src0);
}
-/**
- * Emit an TGSI_OPCODE_SCS instruction
- *
- * The \c SCS opcode functions a bit differently than the other TGSI opcodes.
- * Instead of splatting its result across all four components of the
- * destination, it writes one value to the \c x component and another value to
- * the \c y component.
- *
- * \param ir IR instruction being processed
- * \param op Either \c TGSI_OPCODE_SIN or \c TGSI_OPCODE_COS depending
- * on which value is desired.
- * \param dst Destination register
- * \param src Source register
- */
-void
-glsl_to_tgsi_visitor::emit_scs(ir_instruction *ir, unsigned op,
- st_dst_reg dst,
- const st_src_reg &src)
-{
- /* Vertex programs cannot use the SCS opcode.
- */
- if (this->prog->Target == GL_VERTEX_PROGRAM_ARB) {
- emit_scalar(ir, op, dst, src);
- return;
- }
-
- const unsigned component = (op == TGSI_OPCODE_SIN) ? 0 : 1;
- const unsigned scs_mask = (1U << component);
- int done_mask = ~dst.writemask;
- st_src_reg tmp;
-
- assert(op == TGSI_OPCODE_SIN || op == TGSI_OPCODE_COS);
-
- /* If there are compnents in the destination that differ from the component
- * that will be written by the SCS instrution, we'll need a temporary.
- */
- if (scs_mask != unsigned(dst.writemask)) {
- tmp = get_temp(glsl_type::vec4_type);
- }
-
- for (unsigned i = 0; i < 4; i++) {
- unsigned this_mask = (1U << i);
- st_src_reg src0 = src;
-
- if ((done_mask & this_mask) != 0)
- continue;
-
- /* The source swizzle specified which component of the source generates
- * sine / cosine for the current component in the destination. The SCS
- * instruction requires that this value be swizzle to the X component.
- * Replace the current swizzle with a swizzle that puts the source in
- * the X component.
- */
- unsigned src0_swiz = GET_SWZ(src.swizzle, i);
-
- src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz,
- src0_swiz, src0_swiz);
- for (unsigned j = i + 1; j < 4; j++) {
- /* If there is another enabled component in the destination that is
- * derived from the same inputs, generate its value on this pass as
- * well.
- */
- if (!(done_mask & (1 << j)) &&
- GET_SWZ(src0.swizzle, j) == src0_swiz) {
- this_mask |= (1 << j);
- }
- }
-
- if (this_mask != scs_mask) {
- glsl_to_tgsi_instruction *inst;
- st_dst_reg tmp_dst = st_dst_reg(tmp);
-
- /* Emit the SCS instruction.
- */
- inst = emit(ir, TGSI_OPCODE_SCS, tmp_dst, src0);
- inst->dst[0].writemask = scs_mask;
-
- /* Move the result of the SCS instruction to the desired location in
- * the destination.
- */
- tmp.swizzle = MAKE_SWIZZLE4(component, component,
- component, component);
- inst = emit(ir, TGSI_OPCODE_SCS, dst, tmp);
- inst->dst[0].writemask = this_mask;
- } else {
- /* Emit the SCS instruction to write directly to the destination.
- */
- glsl_to_tgsi_instruction *inst = emit(ir, TGSI_OPCODE_SCS, dst, src0);
- inst->dst[0].writemask = scs_mask;
- }
-
- done_mask |= this_mask;
- }
-}
-
int
glsl_to_tgsi_visitor::add_constant(gl_register_file file,
gl_constant_value values[8], int size, int datatype,
@@ -1611,12 +1499,6 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
case ir_unop_cos:
emit_scalar(ir, TGSI_OPCODE_COS, result_dst, op[0]);
break;
- case ir_unop_sin_reduced:
- emit_scs(ir, TGSI_OPCODE_SIN, result_dst, op[0]);
- break;
- case ir_unop_cos_reduced:
- emit_scs(ir, TGSI_OPCODE_COS, result_dst, op[0]);
- break;
case ir_unop_saturate: {
glsl_to_tgsi_instruction *inst;
inst = emit(ir, TGSI_OPCODE_MOV, result_dst, op[0]);
@@ -3134,7 +3016,7 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
break;
case ir_query_levels:
opcode = TGSI_OPCODE_TXQ;
- lod_info = st_src_reg(PROGRAM_IMMEDIATE, 0, GLSL_TYPE_INT);
+ lod_info = undef_src;
levels_src = get_temp(ir->type);
break;
case ir_txf:
@@ -3456,6 +3338,7 @@ glsl_to_tgsi_visitor::glsl_to_tgsi_visitor()
num_address_regs = 0;
samplers_used = 0;
indirect_addr_consts = false;
+ wpos_transform_const = -1;
glsl_version = 0;
native_integers = false;
mem_ctx = ralloc_context(NULL);
@@ -3465,6 +3348,7 @@ glsl_to_tgsi_visitor::glsl_to_tgsi_visitor()
shader = NULL;
options = NULL;
have_sqrt = false;
+ have_fma = false;
}
glsl_to_tgsi_visitor::~glsl_to_tgsi_visitor()
@@ -3937,6 +3821,7 @@ glsl_to_tgsi_visitor::copy_propagate(void)
inst->dst[0].index == inst->src[0].index) &&
!inst->dst[0].reladdr &&
!inst->saturate &&
+ inst->src[0].file != PROGRAM_ARRAY &&
!inst->src[0].reladdr &&
!inst->src[0].reladdr2 &&
!inst->src[0].negate) {
@@ -4464,7 +4349,9 @@ struct st_translate {
struct ureg_dst arrays[MAX_ARRAYS];
struct ureg_src *constants;
+ int num_constants;
struct ureg_src *immediates;
+ int num_immediates;
struct ureg_dst outputs[PIPE_MAX_SHADER_OUTPUTS];
struct ureg_src inputs[PIPE_MAX_SHADER_INPUTS];
struct ureg_dst address[3];
@@ -4666,7 +4553,7 @@ src_register(struct st_translate *t, const st_src_reg *reg)
{
switch(reg->file) {
case PROGRAM_UNDEFINED:
- return ureg_src_undef();
+ return ureg_imm4f(t->ureg, 0, 0, 0, 0);
case PROGRAM_TEMPORARY:
case PROGRAM_ARRAY:
@@ -4674,17 +4561,18 @@ src_register(struct st_translate *t, const st_src_reg *reg)
case PROGRAM_UNIFORM:
assert(reg->index >= 0);
- return t->constants[reg->index];
+ return reg->index < t->num_constants ?
+ t->constants[reg->index] : ureg_imm4f(t->ureg, 0, 0, 0, 0);
case PROGRAM_STATE_VAR:
case PROGRAM_CONSTANT: /* ie, immediate */
if (reg->has_index2)
return ureg_src_register(TGSI_FILE_CONSTANT, reg->index);
- else if (reg->index < 0)
- return ureg_DECL_constant(t->ureg, 0);
else
- return t->constants[reg->index];
+ return reg->index >= 0 && reg->index < t->num_constants ?
+ t->constants[reg->index] : ureg_imm4f(t->ureg, 0, 0, 0, 0);
case PROGRAM_IMMEDIATE:
+ assert(reg->index >= 0 && reg->index < t->num_immediates);
return t->immediates[reg->index];
case PROGRAM_INPUT:
@@ -4805,6 +4693,7 @@ translate_tex_offset(struct st_translate *t,
switch (in_offset->file) {
case PROGRAM_IMMEDIATE:
+ assert(in_offset->index >= 0 && in_offset->index < t->num_immediates);
imm_src = t->immediates[in_offset->index];
offset.File = imm_src.File;
@@ -4867,10 +4756,8 @@ compile_tgsi_instruction(struct st_translate *t,
inst->saturate,
clamp_dst_color_output);
- for (i = 0; i < num_src; i++) {
- assert(inst->src[i].file != PROGRAM_UNDEFINED);
+ for (i = 0; i < num_src; i++)
src[i] = translate_src(t, &inst->src[i]);
- }
switch(inst->op) {
case TGSI_OPCODE_BGNLOOP:
@@ -4939,28 +4826,19 @@ compile_tgsi_instruction(struct st_translate *t,
*/
static void
emit_wpos_adjustment( struct st_translate *t,
- const struct gl_program *program,
+ int wpos_transform_const,
boolean invert,
GLfloat adjX, GLfloat adjY[2])
{
struct ureg_program *ureg = t->ureg;
+ assert(wpos_transform_const >= 0);
+
/* Fragment program uses fragment position input.
* Need to replace instances of INPUT[WPOS] with temp T
- * where T = INPUT[WPOS] by y is inverted.
+ * where T = INPUT[WPOS] is inverted by Y.
*/
- static const gl_state_index wposTransformState[STATE_LENGTH]
- = { STATE_INTERNAL, STATE_FB_WPOS_Y_TRANSFORM,
- (gl_state_index)0, (gl_state_index)0, (gl_state_index)0 };
-
- /* XXX: note we are modifying the incoming shader here! Need to
- * do this before emitting the constant decls below, or this
- * will be missed:
- */
- unsigned wposTransConst = _mesa_add_state_reference(program->Parameters,
- wposTransformState);
-
- struct ureg_src wpostrans = ureg_DECL_constant( ureg, wposTransConst );
+ struct ureg_src wpostrans = ureg_DECL_constant(ureg, wpos_transform_const);
struct ureg_dst wpos_temp = ureg_DECL_temporary( ureg );
struct ureg_src wpos_input = t->inputs[t->inputMapping[VARYING_SLOT_POS]];
@@ -5024,7 +4902,8 @@ static void
emit_wpos(struct st_context *st,
struct st_translate *t,
const struct gl_program *program,
- struct ureg_program *ureg)
+ struct ureg_program *ureg,
+ int wpos_transform_const)
{
const struct gl_fragment_program *fp =
(const struct gl_fragment_program *) program;
@@ -5121,7 +5000,7 @@ emit_wpos(struct st_context *st,
/* we invert after adjustment so that we avoid the MOV to temporary,
* and reuse the adjustment ADD instead */
- emit_wpos_adjustment(t, program, invert, adjX, adjY);
+ emit_wpos_adjustment(t, wpos_transform_const, invert, adjX, adjY);
}
/**
@@ -5238,15 +5117,6 @@ st_translate_program(
t->outputMapping = outputMapping;
t->ureg = ureg;
- if (program->shader_program) {
- for (i = 0; i < program->shader_program->NumUserUniformStorage; i++) {
- struct gl_uniform_storage *const storage =
- &program->shader_program->UniformStorage[i];
-
- _mesa_uniform_detach_all_driver_storage(storage);
- }
- }
-
/*
* Declare input attributes.
*/
@@ -5260,10 +5130,9 @@ st_translate_program(
}
if (proginfo->InputsRead & VARYING_BIT_POS) {
- /* Must do this after setting up t->inputs, and before
- * emitting constant references, below:
- */
- emit_wpos(st_context(ctx), t, proginfo, ureg);
+ /* Must do this after setting up t->inputs. */
+ emit_wpos(st_context(ctx), t, proginfo, ureg,
+ program->wpos_transform_const);
}
if (proginfo->InputsRead & VARYING_BIT_FACE)
@@ -5400,6 +5269,7 @@ st_translate_program(
ret = PIPE_ERROR_OUT_OF_MEMORY;
goto out;
}
+ t->num_constants = proginfo->Parameters->NumParameters;
for (i = 0; i < proginfo->Parameters->NumParameters; i++) {
switch (proginfo->Parameters->Parameters[i].Type) {
@@ -5451,6 +5321,8 @@ st_translate_program(
ret = PIPE_ERROR_OUT_OF_MEMORY;
goto out;
}
+ t->num_immediates = program->num_immediates;
+
i = 0;
foreach_in_list(immediate_storage, imm, &program->immediates) {
assert(i < program->num_immediates);
@@ -5479,33 +5351,21 @@ st_translate_program(
t->insn[t->labels[i].branch_target]);
}
- if (program->shader_program) {
- /* This has to be done last. Any operation the can cause
- * prog->ParameterValues to get reallocated (e.g., anything that adds a
- * program constant) has to happen before creating this linkage.
- */
- for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
- if (program->shader_program->_LinkedShaders[i] == NULL)
- continue;
-
- _mesa_associate_uniform_storage(ctx, program->shader_program,
- program->shader_program->_LinkedShaders[i]->Program->Parameters);
- }
- }
-
out:
if (t) {
free(t->temps);
free(t->insn);
free(t->labels);
free(t->constants);
+ t->num_constants = 0;
free(t->immediates);
+ t->num_immediates = 0;
if (t->error) {
- debug_printf("%s: translate error flag set\n", __FUNCTION__);
+ debug_printf("%s: translate error flag set\n", __func__);
}
- free(t);
+ FREE(t);
}
return ret;
@@ -5634,14 +5494,12 @@ get_mesa_program(struct gl_context *ctx,
v->emit(NULL, TGSI_OPCODE_END);
if (ctx->_Shader->Flags & GLSL_DUMP) {
- printf("\n");
- printf("GLSL IR for linked %s program %d:\n",
+ _mesa_log("\n");
+ _mesa_log("GLSL IR for linked %s program %d:\n",
_mesa_shader_stage_to_string(shader->Stage),
shader_program->Name);
- _mesa_print_ir(stdout, shader->ir, NULL);
- printf("\n");
- printf("\n");
- fflush(stdout);
+ _mesa_print_ir(_mesa_get_log_file(), shader->ir, NULL);
+ _mesa_log("\n\n");
}
prog->Instructions = NULL;
@@ -5650,6 +5508,17 @@ get_mesa_program(struct gl_context *ctx,
do_set_program_inouts(shader->ir, prog, shader->Stage);
count_resources(v, prog);
+ /* This must be done before the uniform storage is associated. */
+ if (shader->Type == GL_FRAGMENT_SHADER &&
+ prog->InputsRead & VARYING_BIT_POS){
+ static const gl_state_index wposTransformState[STATE_LENGTH] = {
+ STATE_INTERNAL, STATE_FB_WPOS_Y_TRANSFORM
+ };
+
+ v->wpos_transform_const = _mesa_add_state_reference(prog->Parameters,
+ wposTransformState);
+ }
+
_mesa_reference_program(ctx, &shader->Program, prog);
/* This has to be done last. Any operation the can cause