mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-23 20:30:30 +01:00
r300/vertprog: Cleanup source conflict handling
Signed-off-by: Nicolai Hähnle <nhaehnle@gmail.com>
This commit is contained in:
parent
86e3334333
commit
d65404225d
4 changed files with 155 additions and 188 deletions
|
|
@ -31,12 +31,6 @@
|
|||
|
||||
#include "../r300_reg.h"
|
||||
|
||||
static void reset_srcreg(struct prog_src_register* reg)
|
||||
{
|
||||
_mesa_bzero(reg, sizeof(*reg));
|
||||
reg->Swizzle = SWIZZLE_NOOP;
|
||||
}
|
||||
|
||||
static struct prog_src_register shadow_ambient(struct gl_program *program, int tmu)
|
||||
{
|
||||
gl_state_index fail_value_tokens[STATE_LENGTH] = {
|
||||
|
|
|
|||
|
|
@ -32,27 +32,18 @@
|
|||
#include "shader/prog_print.h"
|
||||
|
||||
|
||||
/* TODO: Get rid of t_src_class call */
|
||||
#define CMP_SRCS(a, b) ((a.RelAddr != b.RelAddr) || (a.Index != b.Index && \
|
||||
((t_src_class(a.File) == PVS_SRC_REG_CONSTANT && \
|
||||
t_src_class(b.File) == PVS_SRC_REG_CONSTANT) || \
|
||||
(t_src_class(a.File) == PVS_SRC_REG_INPUT && \
|
||||
t_src_class(b.File) == PVS_SRC_REG_INPUT)))) \
|
||||
|
||||
/*
|
||||
* Take an already-setup and valid source then swizzle it appropriately to
|
||||
* obtain a constant ZERO or ONE source.
|
||||
*/
|
||||
#define __CONST(x, y) \
|
||||
(PVS_SRC_OPERAND(t_src_index(vp, &src[x]), \
|
||||
(PVS_SRC_OPERAND(t_src_index(vp, &vpi->SrcReg[x]), \
|
||||
t_swizzle(y), \
|
||||
t_swizzle(y), \
|
||||
t_swizzle(y), \
|
||||
t_swizzle(y), \
|
||||
t_src_class(src[x].File), \
|
||||
NEGATE_NONE) | (src[x].RelAddr << 4))
|
||||
|
||||
|
||||
t_src_class(vpi->SrcReg[x].File), \
|
||||
NEGATE_NONE) | (vpi->SrcReg[x].RelAddr << 4))
|
||||
|
||||
|
||||
static unsigned long t_dst_mask(GLuint mask)
|
||||
|
|
@ -121,6 +112,24 @@ static unsigned long t_src_class(gl_register_file file)
|
|||
}
|
||||
}
|
||||
|
||||
static GLboolean t_src_conflict(struct prog_src_register a, struct prog_src_register b)
|
||||
{
|
||||
unsigned long aclass = t_src_class(a.File);
|
||||
unsigned long bclass = t_src_class(b.File);
|
||||
|
||||
if (aclass != bclass)
|
||||
return GL_FALSE;
|
||||
if (aclass == PVS_SRC_REG_TEMPORARY)
|
||||
return GL_FALSE;
|
||||
|
||||
if (a.RelAddr || b.RelAddr)
|
||||
return GL_TRUE;
|
||||
if (a.Index != b.Index)
|
||||
return GL_TRUE;
|
||||
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
static INLINE unsigned long t_swizzle(GLubyte swizzle)
|
||||
{
|
||||
/* this is in fact a NOP as the Mesa SWIZZLE_* are all identical to VSF_IN_COMPONENT_* */
|
||||
|
|
@ -188,11 +197,10 @@ static GLboolean valid_dst(struct r300_vertex_program_code *vp,
|
|||
return GL_TRUE;
|
||||
}
|
||||
|
||||
static GLuint * ei_vector1(struct r300_vertex_program_code *vp,
|
||||
static void ei_vector1(struct r300_vertex_program_code *vp,
|
||||
GLuint hw_opcode,
|
||||
struct prog_instruction *vpi,
|
||||
GLuint * inst,
|
||||
struct prog_src_register src[3])
|
||||
GLuint * inst)
|
||||
{
|
||||
inst[0] = PVS_OP_DST_OPERAND(hw_opcode,
|
||||
GL_FALSE,
|
||||
|
|
@ -200,18 +208,15 @@ static GLuint * ei_vector1(struct r300_vertex_program_code *vp,
|
|||
t_dst_index(vp, &vpi->DstReg),
|
||||
t_dst_mask(vpi->DstReg.WriteMask),
|
||||
t_dst_class(vpi->DstReg.File));
|
||||
inst[1] = t_src(vp, &src[0]);
|
||||
inst[1] = t_src(vp, &vpi->SrcReg[0]);
|
||||
inst[2] = __CONST(0, SWIZZLE_ZERO);
|
||||
inst[3] = __CONST(0, SWIZZLE_ZERO);
|
||||
|
||||
return inst;
|
||||
}
|
||||
|
||||
static GLuint * ei_vector2(struct r300_vertex_program_code *vp,
|
||||
static void ei_vector2(struct r300_vertex_program_code *vp,
|
||||
GLuint hw_opcode,
|
||||
struct prog_instruction *vpi,
|
||||
GLuint * inst,
|
||||
struct prog_src_register src[3])
|
||||
GLuint * inst)
|
||||
{
|
||||
inst[0] = PVS_OP_DST_OPERAND(hw_opcode,
|
||||
GL_FALSE,
|
||||
|
|
@ -219,18 +224,15 @@ static GLuint * ei_vector2(struct r300_vertex_program_code *vp,
|
|||
t_dst_index(vp, &vpi->DstReg),
|
||||
t_dst_mask(vpi->DstReg.WriteMask),
|
||||
t_dst_class(vpi->DstReg.File));
|
||||
inst[1] = t_src(vp, &src[0]);
|
||||
inst[2] = t_src(vp, &src[1]);
|
||||
inst[1] = t_src(vp, &vpi->SrcReg[0]);
|
||||
inst[2] = t_src(vp, &vpi->SrcReg[1]);
|
||||
inst[3] = __CONST(1, SWIZZLE_ZERO);
|
||||
|
||||
return inst;
|
||||
}
|
||||
|
||||
static GLuint *ei_math1(struct r300_vertex_program_code *vp,
|
||||
static void ei_math1(struct r300_vertex_program_code *vp,
|
||||
GLuint hw_opcode,
|
||||
struct prog_instruction *vpi,
|
||||
GLuint * inst,
|
||||
struct prog_src_register src[3])
|
||||
GLuint * inst)
|
||||
{
|
||||
inst[0] = PVS_OP_DST_OPERAND(hw_opcode,
|
||||
GL_TRUE,
|
||||
|
|
@ -238,17 +240,14 @@ static GLuint *ei_math1(struct r300_vertex_program_code *vp,
|
|||
t_dst_index(vp, &vpi->DstReg),
|
||||
t_dst_mask(vpi->DstReg.WriteMask),
|
||||
t_dst_class(vpi->DstReg.File));
|
||||
inst[1] = t_src_scalar(vp, &src[0]);
|
||||
inst[1] = t_src_scalar(vp, &vpi->SrcReg[0]);
|
||||
inst[2] = __CONST(0, SWIZZLE_ZERO);
|
||||
inst[3] = __CONST(0, SWIZZLE_ZERO);
|
||||
|
||||
return inst;
|
||||
}
|
||||
|
||||
static GLuint *ei_lit(struct r300_vertex_program_code *vp,
|
||||
static void ei_lit(struct r300_vertex_program_code *vp,
|
||||
struct prog_instruction *vpi,
|
||||
GLuint * inst,
|
||||
struct prog_src_register src[3])
|
||||
GLuint * inst)
|
||||
{
|
||||
//LIT TMP 1.Y Z TMP 1{} {X W Z Y} TMP 1{} {Y W Z X} TMP 1{} {Y X Z W}
|
||||
|
||||
|
|
@ -259,35 +258,32 @@ static GLuint *ei_lit(struct r300_vertex_program_code *vp,
|
|||
t_dst_mask(vpi->DstReg.WriteMask),
|
||||
t_dst_class(vpi->DstReg.File));
|
||||
/* NOTE: Users swizzling might not work. */
|
||||
inst[1] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // X
|
||||
t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // W
|
||||
inst[1] = PVS_SRC_OPERAND(t_src_index(vp, &vpi->SrcReg[0]), t_swizzle(GET_SWZ(vpi->SrcReg[0].Swizzle, 0)), // X
|
||||
t_swizzle(GET_SWZ(vpi->SrcReg[0].Swizzle, 3)), // W
|
||||
PVS_SRC_SELECT_FORCE_0, // Z
|
||||
t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // Y
|
||||
t_src_class(src[0].File),
|
||||
src[0].Negate ? NEGATE_XYZW : NEGATE_NONE) |
|
||||
(src[0].RelAddr << 4);
|
||||
inst[2] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // Y
|
||||
t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // W
|
||||
t_swizzle(GET_SWZ(vpi->SrcReg[0].Swizzle, 1)), // Y
|
||||
t_src_class(vpi->SrcReg[0].File),
|
||||
vpi->SrcReg[0].Negate ? NEGATE_XYZW : NEGATE_NONE) |
|
||||
(vpi->SrcReg[0].RelAddr << 4);
|
||||
inst[2] = PVS_SRC_OPERAND(t_src_index(vp, &vpi->SrcReg[0]), t_swizzle(GET_SWZ(vpi->SrcReg[0].Swizzle, 1)), // Y
|
||||
t_swizzle(GET_SWZ(vpi->SrcReg[0].Swizzle, 3)), // W
|
||||
PVS_SRC_SELECT_FORCE_0, // Z
|
||||
t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // X
|
||||
t_src_class(src[0].File),
|
||||
src[0].Negate ? NEGATE_XYZW : NEGATE_NONE) |
|
||||
(src[0].RelAddr << 4);
|
||||
inst[3] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // Y
|
||||
t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // X
|
||||
t_swizzle(GET_SWZ(vpi->SrcReg[0].Swizzle, 0)), // X
|
||||
t_src_class(vpi->SrcReg[0].File),
|
||||
vpi->SrcReg[0].Negate ? NEGATE_XYZW : NEGATE_NONE) |
|
||||
(vpi->SrcReg[0].RelAddr << 4);
|
||||
inst[3] = PVS_SRC_OPERAND(t_src_index(vp, &vpi->SrcReg[0]), t_swizzle(GET_SWZ(vpi->SrcReg[0].Swizzle, 1)), // Y
|
||||
t_swizzle(GET_SWZ(vpi->SrcReg[0].Swizzle, 0)), // X
|
||||
PVS_SRC_SELECT_FORCE_0, // Z
|
||||
t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // W
|
||||
t_src_class(src[0].File),
|
||||
src[0].Negate ? NEGATE_XYZW : NEGATE_NONE) |
|
||||
(src[0].RelAddr << 4);
|
||||
|
||||
return inst;
|
||||
t_swizzle(GET_SWZ(vpi->SrcReg[0].Swizzle, 3)), // W
|
||||
t_src_class(vpi->SrcReg[0].File),
|
||||
vpi->SrcReg[0].Negate ? NEGATE_XYZW : NEGATE_NONE) |
|
||||
(vpi->SrcReg[0].RelAddr << 4);
|
||||
}
|
||||
|
||||
static GLuint *ei_mad(struct r300_vertex_program_code *vp,
|
||||
static void ei_mad(struct r300_vertex_program_code *vp,
|
||||
struct prog_instruction *vpi,
|
||||
GLuint * inst,
|
||||
struct prog_src_register src[3])
|
||||
GLuint * inst)
|
||||
{
|
||||
inst[0] = PVS_OP_DST_OPERAND(PVS_MACRO_OP_2CLK_MADD,
|
||||
GL_FALSE,
|
||||
|
|
@ -295,17 +291,14 @@ static GLuint *ei_mad(struct r300_vertex_program_code *vp,
|
|||
t_dst_index(vp, &vpi->DstReg),
|
||||
t_dst_mask(vpi->DstReg.WriteMask),
|
||||
t_dst_class(vpi->DstReg.File));
|
||||
inst[1] = t_src(vp, &src[0]);
|
||||
inst[2] = t_src(vp, &src[1]);
|
||||
inst[3] = t_src(vp, &src[2]);
|
||||
|
||||
return inst;
|
||||
inst[1] = t_src(vp, &vpi->SrcReg[0]);
|
||||
inst[2] = t_src(vp, &vpi->SrcReg[1]);
|
||||
inst[3] = t_src(vp, &vpi->SrcReg[2]);
|
||||
}
|
||||
|
||||
static GLuint *ei_pow(struct r300_vertex_program_code *vp,
|
||||
static void ei_pow(struct r300_vertex_program_code *vp,
|
||||
struct prog_instruction *vpi,
|
||||
GLuint * inst,
|
||||
struct prog_src_register src[3])
|
||||
GLuint * inst)
|
||||
{
|
||||
inst[0] = PVS_OP_DST_OPERAND(ME_POWER_FUNC_FF,
|
||||
GL_TRUE,
|
||||
|
|
@ -313,11 +306,9 @@ static GLuint *ei_pow(struct r300_vertex_program_code *vp,
|
|||
t_dst_index(vp, &vpi->DstReg),
|
||||
t_dst_mask(vpi->DstReg.WriteMask),
|
||||
t_dst_class(vpi->DstReg.File));
|
||||
inst[1] = t_src_scalar(vp, &src[0]);
|
||||
inst[1] = t_src_scalar(vp, &vpi->SrcReg[0]);
|
||||
inst[2] = __CONST(0, SWIZZLE_ZERO);
|
||||
inst[3] = t_src_scalar(vp, &src[1]);
|
||||
|
||||
return inst;
|
||||
inst[3] = t_src_scalar(vp, &vpi->SrcReg[1]);
|
||||
}
|
||||
|
||||
static void t_inputs_outputs(struct r300_vertex_program_code *vp, struct gl_program * glvp)
|
||||
|
|
@ -397,15 +388,7 @@ static void t_inputs_outputs(struct r300_vertex_program_code *vp, struct gl_prog
|
|||
static GLboolean translate_vertex_program(struct r300_vertex_program_compiler * compiler)
|
||||
{
|
||||
struct prog_instruction *vpi = compiler->program->Instructions;
|
||||
int i;
|
||||
GLuint *inst;
|
||||
unsigned long num_operands;
|
||||
/* Initial value should be last tmp reg that hw supports.
|
||||
Strangely enough r300 doesnt mind even though these would be out of range.
|
||||
Smart enough to realize that it doesnt need it? */
|
||||
int u_temp_i = VSF_MAX_FRAGMENT_TEMPS - 1;
|
||||
struct prog_src_register src[3];
|
||||
struct r300_vertex_program_code * vp = compiler->code;
|
||||
|
||||
compiler->code->pos_end = 0; /* Not supported yet */
|
||||
compiler->code->length = 0;
|
||||
|
|
@ -414,109 +397,33 @@ static GLboolean translate_vertex_program(struct r300_vertex_program_compiler *
|
|||
|
||||
for (inst = compiler->code->body.d; vpi->Opcode != OPCODE_END;
|
||||
vpi++, inst += 4) {
|
||||
|
||||
{
|
||||
int u_temp_used = (VSF_MAX_FRAGMENT_TEMPS - 1) - u_temp_i;
|
||||
if((compiler->code->num_temporaries + u_temp_used) > VSF_MAX_FRAGMENT_TEMPS) {
|
||||
fprintf(stderr, "Ran out of temps, num temps %d, us %d\n", compiler->code->num_temporaries, u_temp_used);
|
||||
return GL_FALSE;
|
||||
}
|
||||
u_temp_i=VSF_MAX_FRAGMENT_TEMPS-1;
|
||||
}
|
||||
|
||||
/* Skip instructions writing to non-existing destination */
|
||||
if (!valid_dst(compiler->code, &vpi->DstReg)) {
|
||||
/* redirect result to unused temp */
|
||||
vpi->DstReg.File = PROGRAM_TEMPORARY;
|
||||
vpi->DstReg.Index = u_temp_i;
|
||||
}
|
||||
|
||||
num_operands = _mesa_num_inst_src_regs(vpi->Opcode);
|
||||
|
||||
/* copy the sources (src) from mesa into a local variable... is this needed? */
|
||||
for (i = 0; i < num_operands; i++) {
|
||||
src[i] = vpi->SrcReg[i];
|
||||
}
|
||||
|
||||
if (num_operands == 3) { /* TODO: scalars */
|
||||
if (CMP_SRCS(src[1], src[2])
|
||||
|| CMP_SRCS(src[0], src[2])) {
|
||||
inst[0] = PVS_OP_DST_OPERAND(VE_ADD,
|
||||
GL_FALSE,
|
||||
GL_FALSE,
|
||||
u_temp_i,
|
||||
WRITEMASK_XYZW,
|
||||
PVS_DST_REG_TEMPORARY);
|
||||
inst[1] =
|
||||
PVS_SRC_OPERAND(t_src_index(compiler->code, &src[2]),
|
||||
SWIZZLE_X,
|
||||
SWIZZLE_Y,
|
||||
SWIZZLE_Z,
|
||||
SWIZZLE_W,
|
||||
t_src_class(src[2].File),
|
||||
NEGATE_NONE) | (src[2].
|
||||
RelAddr <<
|
||||
4);
|
||||
inst[2] = __CONST(2, SWIZZLE_ZERO);
|
||||
inst[3] = __CONST(2, SWIZZLE_ZERO);
|
||||
inst += 4;
|
||||
|
||||
src[2].File = PROGRAM_TEMPORARY;
|
||||
src[2].Index = u_temp_i;
|
||||
src[2].RelAddr = 0;
|
||||
u_temp_i--;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_operands >= 2) {
|
||||
if (CMP_SRCS(src[1], src[0])) {
|
||||
inst[0] = PVS_OP_DST_OPERAND(VE_ADD,
|
||||
GL_FALSE,
|
||||
GL_FALSE,
|
||||
u_temp_i,
|
||||
WRITEMASK_XYZW,
|
||||
PVS_DST_REG_TEMPORARY);
|
||||
inst[1] =
|
||||
PVS_SRC_OPERAND(t_src_index(compiler->code, &src[0]),
|
||||
SWIZZLE_X,
|
||||
SWIZZLE_Y,
|
||||
SWIZZLE_Z,
|
||||
SWIZZLE_W,
|
||||
t_src_class(src[0].File),
|
||||
NEGATE_NONE) | (src[0].
|
||||
RelAddr <<
|
||||
4);
|
||||
inst[2] = __CONST(0, SWIZZLE_ZERO);
|
||||
inst[3] = __CONST(0, SWIZZLE_ZERO);
|
||||
inst += 4;
|
||||
|
||||
src[0].File = PROGRAM_TEMPORARY;
|
||||
src[0].Index = u_temp_i;
|
||||
src[0].RelAddr = 0;
|
||||
u_temp_i--;
|
||||
}
|
||||
inst -= 4;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (vpi->Opcode) {
|
||||
case OPCODE_ADD: inst = ei_vector2(compiler->code, VE_ADD, vpi, inst, src); break;
|
||||
case OPCODE_ARL: inst = ei_vector1(compiler->code, VE_FLT2FIX_DX, vpi, inst, src); break;
|
||||
case OPCODE_DP4: inst = ei_vector2(compiler->code, VE_DOT_PRODUCT, vpi, inst, src); break;
|
||||
case OPCODE_DST: inst = ei_vector2(compiler->code, VE_DISTANCE_VECTOR, vpi, inst, src); break;
|
||||
case OPCODE_EX2: inst = ei_math1(compiler->code, ME_EXP_BASE2_FULL_DX, vpi, inst, src); break;
|
||||
case OPCODE_EXP: inst = ei_math1(compiler->code, ME_EXP_BASE2_DX, vpi, inst, src); break;
|
||||
case OPCODE_FRC: inst = ei_vector1(compiler->code, VE_FRACTION, vpi, inst, src); break;
|
||||
case OPCODE_LG2: inst = ei_math1(compiler->code, ME_LOG_BASE2_FULL_DX, vpi, inst, src); break;
|
||||
case OPCODE_LIT: inst = ei_lit(compiler->code, vpi, inst, src); break;
|
||||
case OPCODE_LOG: inst = ei_math1(compiler->code, ME_LOG_BASE2_DX, vpi, inst, src); break;
|
||||
case OPCODE_MAD: inst = ei_mad(compiler->code, vpi, inst, src); break;
|
||||
case OPCODE_MAX: inst = ei_vector2(compiler->code, VE_MAXIMUM, vpi, inst, src); break;
|
||||
case OPCODE_MIN: inst = ei_vector2(compiler->code, VE_MINIMUM, vpi, inst, src); break;
|
||||
case OPCODE_MOV: inst = ei_vector1(compiler->code, VE_ADD, vpi, inst, src); break;
|
||||
case OPCODE_MUL: inst = ei_vector2(compiler->code, VE_MULTIPLY, vpi, inst, src); break;
|
||||
case OPCODE_POW: inst = ei_pow(compiler->code, vpi, inst, src); break;
|
||||
case OPCODE_RCP: inst = ei_math1(compiler->code, ME_RECIP_DX, vpi, inst, src); break;
|
||||
case OPCODE_RSQ: inst = ei_math1(compiler->code, ME_RECIP_SQRT_DX, vpi, inst, src); break;
|
||||
case OPCODE_SGE: inst = ei_vector2(compiler->code, VE_SET_GREATER_THAN_EQUAL, vpi, inst, src); break;
|
||||
case OPCODE_SLT: inst = ei_vector2(compiler->code, VE_SET_LESS_THAN, vpi, inst, src); break;
|
||||
case OPCODE_ADD: ei_vector2(compiler->code, VE_ADD, vpi, inst); break;
|
||||
case OPCODE_ARL: ei_vector1(compiler->code, VE_FLT2FIX_DX, vpi, inst); break;
|
||||
case OPCODE_DP4: ei_vector2(compiler->code, VE_DOT_PRODUCT, vpi, inst); break;
|
||||
case OPCODE_DST: ei_vector2(compiler->code, VE_DISTANCE_VECTOR, vpi, inst); break;
|
||||
case OPCODE_EX2: ei_math1(compiler->code, ME_EXP_BASE2_FULL_DX, vpi, inst); break;
|
||||
case OPCODE_EXP: ei_math1(compiler->code, ME_EXP_BASE2_DX, vpi, inst); break;
|
||||
case OPCODE_FRC: ei_vector1(compiler->code, VE_FRACTION, vpi, inst); break;
|
||||
case OPCODE_LG2: ei_math1(compiler->code, ME_LOG_BASE2_FULL_DX, vpi, inst); break;
|
||||
case OPCODE_LIT: ei_lit(compiler->code, vpi, inst); break;
|
||||
case OPCODE_LOG: ei_math1(compiler->code, ME_LOG_BASE2_DX, vpi, inst); break;
|
||||
case OPCODE_MAD: ei_mad(compiler->code, vpi, inst); break;
|
||||
case OPCODE_MAX: ei_vector2(compiler->code, VE_MAXIMUM, vpi, inst); break;
|
||||
case OPCODE_MIN: ei_vector2(compiler->code, VE_MINIMUM, vpi, inst); break;
|
||||
case OPCODE_MOV: ei_vector1(compiler->code, VE_ADD, vpi, inst); break;
|
||||
case OPCODE_MUL: ei_vector2(compiler->code, VE_MULTIPLY, vpi, inst); break;
|
||||
case OPCODE_POW: ei_pow(compiler->code, vpi, inst); break;
|
||||
case OPCODE_RCP: ei_math1(compiler->code, ME_RECIP_DX, vpi, inst); break;
|
||||
case OPCODE_RSQ: ei_math1(compiler->code, ME_RECIP_SQRT_DX, vpi, inst); break;
|
||||
case OPCODE_SGE: ei_vector2(compiler->code, VE_SET_GREATER_THAN_EQUAL, vpi, inst); break;
|
||||
case OPCODE_SLT: ei_vector2(compiler->code, VE_SET_LESS_THAN, vpi, inst); break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown opcode %i\n", vpi->Opcode);
|
||||
return GL_FALSE;
|
||||
|
|
@ -531,6 +438,55 @@ static GLboolean translate_vertex_program(struct r300_vertex_program_compiler *
|
|||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vertex engine cannot read two inputs or two constants at the same time.
|
||||
* Introduce intermediate MOVs to temporary registers to account for this.
|
||||
*/
|
||||
static GLboolean transform_source_conflicts(
|
||||
struct radeon_transform_context *t,
|
||||
struct prog_instruction* orig_inst,
|
||||
void* unused)
|
||||
{
|
||||
struct prog_instruction inst = *orig_inst;
|
||||
struct prog_instruction * dst;
|
||||
GLuint num_operands = _mesa_num_inst_src_regs(inst.Opcode);
|
||||
|
||||
if (num_operands == 3) {
|
||||
if (t_src_conflict(inst.SrcReg[1], inst.SrcReg[2])
|
||||
|| t_src_conflict(inst.SrcReg[0], inst.SrcReg[2])) {
|
||||
int tmpreg = radeonFindFreeTemporary(t);
|
||||
struct prog_instruction * inst_mov = radeonAppendInstructions(t->Program, 1);
|
||||
inst_mov->Opcode = OPCODE_MOV;
|
||||
inst_mov->DstReg.File = PROGRAM_TEMPORARY;
|
||||
inst_mov->DstReg.Index = tmpreg;
|
||||
inst_mov->SrcReg[0] = inst.SrcReg[2];
|
||||
|
||||
reset_srcreg(&inst.SrcReg[2]);
|
||||
inst.SrcReg[2].File = PROGRAM_TEMPORARY;
|
||||
inst.SrcReg[2].Index = tmpreg;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_operands >= 2) {
|
||||
if (t_src_conflict(inst.SrcReg[1], inst.SrcReg[0])) {
|
||||
int tmpreg = radeonFindFreeTemporary(t);
|
||||
struct prog_instruction * inst_mov = radeonAppendInstructions(t->Program, 1);
|
||||
inst_mov->Opcode = OPCODE_MOV;
|
||||
inst_mov->DstReg.File = PROGRAM_TEMPORARY;
|
||||
inst_mov->DstReg.Index = tmpreg;
|
||||
inst_mov->SrcReg[0] = inst.SrcReg[1];
|
||||
|
||||
reset_srcreg(&inst.SrcReg[1]);
|
||||
inst.SrcReg[1].File = PROGRAM_TEMPORARY;
|
||||
inst.SrcReg[1].Index = tmpreg;
|
||||
}
|
||||
}
|
||||
|
||||
dst = radeonAppendInstructions(t->Program, 1);
|
||||
*dst = inst;
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
static void insert_wpos(struct gl_program *prog, GLuint temp_index, int tex_id)
|
||||
{
|
||||
struct prog_instruction *vpi;
|
||||
|
|
@ -746,6 +702,23 @@ GLboolean r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compi
|
|||
fflush(stdout);
|
||||
}
|
||||
|
||||
{
|
||||
/* Note: This pass has to be done seperately from ALU rewrite,
|
||||
* otherwise non-native ALU instructions with source conflits
|
||||
* will not be treated properly.
|
||||
*/
|
||||
struct radeon_program_transformation transformations[] = {
|
||||
{ &transform_source_conflicts, 0 },
|
||||
};
|
||||
radeonLocalTransform(compiler->program, 1, transformations);
|
||||
}
|
||||
|
||||
if (compiler->Base.Debug) {
|
||||
fprintf(stderr, "Vertex program after source conflict resolve:\n");
|
||||
_mesa_print_program(compiler->program);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
{
|
||||
struct radeon_nqssadce_descr nqssadce = {
|
||||
.Init = &nqssadceInit,
|
||||
|
|
|
|||
|
|
@ -29,12 +29,6 @@
|
|||
|
||||
#include "../r300_reg.h"
|
||||
|
||||
static void reset_srcreg(struct prog_src_register* reg)
|
||||
{
|
||||
_mesa_bzero(reg, sizeof(*reg));
|
||||
reg->Swizzle = SWIZZLE_NOOP;
|
||||
}
|
||||
|
||||
static struct prog_src_register shadow_ambient(struct gl_program *program, int tmu)
|
||||
{
|
||||
gl_state_index fail_value_tokens[STATE_LENGTH] = {
|
||||
|
|
|
|||
|
|
@ -79,6 +79,12 @@ static inline GLuint combine_swizzles(GLuint src, GLuint swz)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static INLINE void reset_srcreg(struct prog_src_register* reg)
|
||||
{
|
||||
_mesa_bzero(reg, sizeof(*reg));
|
||||
reg->Swizzle = SWIZZLE_NOOP;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Transformation context that is passed to local transformations.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue