r300: rewrite FOGC and HPOS attribs handling

Rewrite vertex and fragment programs so that we don't have to do any hacks on lower level.
This commit is contained in:
Maciej Cencora
2009-07-05 02:32:51 +02:00
parent df5fe747fa
commit f79ef95df4
7 changed files with 130 additions and 122 deletions
+7 -1
View File
@@ -410,6 +410,8 @@ struct r300_vertex_program {
struct r300_vertex_program_key {
GLuint FpReads;
GLuint FogAttr;
GLuint WPosAttr;
} key;
struct r300_vertex_shader_hw_code {
@@ -425,7 +427,6 @@ struct r300_vertex_program {
int pos_end;
int num_temporaries; /* Number of temp vars used by program */
int wpos_idx;
int inputs[VERT_ATTRIB_MAX];
int outputs[VERT_RESULT_MAX];
};
@@ -560,6 +561,11 @@ struct r300_fragment_program {
GLuint optimization;
struct r300_fragment_program *next;
/* attribute that we are sending the WPOS in */
gl_frag_attrib wpos_attr;
/* attribute that we are sending the fog coordinate in */
gl_frag_attrib fog_attr;
};
struct r300_fragment_program_cont {
-9
View File
@@ -116,15 +116,6 @@ GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint vp_writes, GLuint fp_reads)
}
}
if (fp_reads & FRAG_BIT_WPOS) {
ret |= (4 << (3 * first_free_texcoord));
++first_free_texcoord;
}
if (vp_writes & (1 << VERT_RESULT_FOGC) && fp_reads & FRAG_BIT_FOGC) {
ret |= 4 << (3 * first_free_texcoord);
}
if (first_free_texcoord > 8) {
fprintf(stderr, "\tout of free texcoords\n");
_mesa_exit(-1);
@@ -69,8 +69,10 @@ static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler)
{
GLuint InputsRead = compiler->fp->Base->InputsRead;
if (!(InputsRead & FRAG_BIT_WPOS))
if (!(InputsRead & FRAG_BIT_WPOS)) {
compiler->fp->wpos_attr = FRAG_ATTRIB_MAX;
return;
}
static gl_state_index tokens[STATE_LENGTH] = {
STATE_INTERNAL, STATE_R300_WINDOW_DIMENSION, 0, 0, 0
@@ -78,10 +80,23 @@ static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler)
struct prog_instruction *fpi;
GLuint window_index;
int i = 0;
for (i = FRAG_ATTRIB_TEX0; i <= FRAG_ATTRIB_TEX7; ++i)
{
if (!(InputsRead & (1 << i))) {
InputsRead &= ~(1 << FRAG_ATTRIB_WPOS);
InputsRead |= 1 << i;
compiler->fp->Base->InputsRead = InputsRead;
compiler->fp->wpos_attr = i;
break;
}
}
GLuint tempregi = _mesa_find_free_register(compiler->program, PROGRAM_TEMPORARY);
_mesa_insert_instructions(compiler->program, 0, 3);
fpi = compiler->program->Instructions;
i = 0;
/* perspective divide */
fpi[i].Opcode = OPCODE_RCP;
@@ -92,7 +107,7 @@ static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler)
fpi[i].DstReg.CondMask = COND_TR;
fpi[i].SrcReg[0].File = PROGRAM_INPUT;
fpi[i].SrcReg[0].Index = FRAG_ATTRIB_WPOS;
fpi[i].SrcReg[0].Index = compiler->fp->wpos_attr;
fpi[i].SrcReg[0].Swizzle = SWIZZLE_WWWW;
i++;
@@ -104,7 +119,7 @@ static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler)
fpi[i].DstReg.CondMask = COND_TR;
fpi[i].SrcReg[0].File = PROGRAM_INPUT;
fpi[i].SrcReg[0].Index = FRAG_ATTRIB_WPOS;
fpi[i].SrcReg[0].Index = compiler->fp->wpos_attr;
fpi[i].SrcReg[0].Swizzle = SWIZZLE_XYZW;
fpi[i].SrcReg[1].File = PROGRAM_TEMPORARY;
@@ -147,6 +162,45 @@ static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler)
}
}
static void rewriteFog(struct r300_fragment_program_compiler *compiler)
{
struct r300_fragment_program *fp = compiler->fp;
GLuint InputsRead;
int i;
InputsRead = fp->Base->InputsRead;
if (!(InputsRead & FRAG_BIT_FOGC)) {
fp->fog_attr = FRAG_ATTRIB_MAX;
return;
}
for (i = FRAG_ATTRIB_TEX0; i <= FRAG_ATTRIB_TEX7; ++i)
{
if (!(InputsRead & (1 << i))) {
InputsRead &= ~(1 << FRAG_ATTRIB_FOGC);
InputsRead |= 1 << i;
fp->Base->InputsRead = InputsRead;
fp->fog_attr = i;
break;
}
}
{
struct prog_instruction *inst;
inst = compiler->program->Instructions;
while (inst->Opcode != OPCODE_END) {
const int src_regs = _mesa_num_inst_src_regs(inst->Opcode);
for (i = 0; i < src_regs; ++i) {
if (inst->SrcReg[i].File == PROGRAM_INPUT && inst->SrcReg[i].Index == FRAG_ATTRIB_FOGC)
inst->SrcReg[i].Index = fp->fog_attr;
}
++inst;
}
}
}
static GLuint build_dtm(GLuint depthmode)
{
switch(depthmode) {
@@ -204,6 +258,8 @@ void r300TranslateFragmentShader(GLcontext *ctx, struct r300_fragment_program *f
insert_WPOS_trailer(&compiler);
rewriteFog(&compiler);
if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
struct radeon_program_transformation transformations[] = {
{ &r500_transform_TEX, &compiler },
+1 -2
View File
@@ -66,8 +66,7 @@ static struct gl_program *r300NewProgram(GLcontext * ctx, GLenum target,
case GL_VERTEX_STATE_PROGRAM_NV:
case GL_VERTEX_PROGRAM_ARB:
vp = CALLOC_STRUCT(r300_vertex_program_cont);
return _mesa_init_vertex_program(ctx, &vp->mesa_program,
target, id);
return _mesa_init_vertex_program(ctx, &vp->mesa_program, target, id);
case GL_FRAGMENT_PROGRAM_NV:
case GL_FRAGMENT_PROGRAM_ARB:
-53
View File
@@ -1519,29 +1519,6 @@ static void r300SetupRSUnit(GLcontext * ctx)
++fp_reg;
}
if (InputsRead & FRAG_BIT_WPOS) {
r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3) | R300_RS_TEX_PTR(rs_tex_count);
r300->hw.rr.cmd[R300_RR_INST_0 + tex_ip] |= R300_RS_INST_TEX_ID(tex_ip) | R300_RS_INST_TEX_CN_WRITE | R300_RS_INST_TEX_ADDR(fp_reg);
InputsRead &= ~FRAG_BIT_WPOS;
rs_tex_count += 4;
++tex_ip;
++fp_reg;
}
if (InputsRead & FRAG_BIT_FOGC) {
if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_FOGC, _TNL_ATTRIB_FOG)) {
r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= R300_RS_SEL_S(0) | R300_RS_SEL_T(R300_RS_SEL_K0) | R300_RS_SEL_R(R300_RS_SEL_K0);
r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= R300_RS_SEL_Q(R300_RS_SEL_K1) | R300_RS_TEX_PTR(rs_tex_count);
r300->hw.rr.cmd[R300_RR_INST_0 + tex_ip] |= R300_RS_INST_TEX_ID(tex_ip) | R300_RS_INST_TEX_CN_WRITE | R300_RS_INST_TEX_ADDR(fp_reg);
InputsRead &= ~FRAG_BIT_FOGC;
rs_tex_count += 4;
++tex_ip;
++fp_reg;
} else {
WARN_ONCE("fragprog wants fogc, vp doesn't provide it\n");
}
}
/* Setup default color if no color or tex was set */
if (rs_tex_count == 0 && col_ip == 0) {
r300->hw.rr.cmd[R300_RR_INST_0] = R300_RS_INST_COL_ID(0) | R300_RS_INST_COL_ADDR(0);
@@ -1640,36 +1617,6 @@ static void r500SetupRSUnit(GLcontext * ctx)
++fp_reg;
}
if (InputsRead & FRAG_BIT_WPOS) {
r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= ((rs_tex_count + 0) << R500_RS_IP_TEX_PTR_S_SHIFT) |
((rs_tex_count + 1) << R500_RS_IP_TEX_PTR_T_SHIFT) |
((rs_tex_count + 2) << R500_RS_IP_TEX_PTR_R_SHIFT) |
((rs_tex_count + 3) << R500_RS_IP_TEX_PTR_Q_SHIFT);
r300->hw.rr.cmd[R300_RR_INST_0 + tex_ip] |= R500_RS_INST_TEX_ID(tex_ip) | R500_RS_INST_TEX_CN_WRITE | R500_RS_INST_TEX_ADDR(fp_reg);
InputsRead &= ~FRAG_BIT_WPOS;
rs_tex_count += 4;
++tex_ip;
++fp_reg;
}
if (InputsRead & FRAG_BIT_FOGC) {
if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_FOGC, _TNL_ATTRIB_FOG)) {
r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= (rs_tex_count << R500_RS_IP_TEX_PTR_S_SHIFT) |
(R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_T_SHIFT) |
(R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) |
(R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT);
r300->hw.rr.cmd[R300_RR_INST_0 + tex_ip] |= R500_RS_INST_TEX_ID(tex_ip) | R500_RS_INST_TEX_CN_WRITE | R500_RS_INST_TEX_ADDR(fp_reg);
InputsRead &= ~FRAG_BIT_FOGC;
rs_tex_count += 4;
++tex_ip;
++fp_reg;
} else {
WARN_ONCE("fragprog wants fogc, vp doesn't provide it\n");
}
}
/* Setup default color if no color or tex was set */
if (rs_tex_count == 0 && col_ip == 0) {
r300->hw.rr.cmd[R300_RR_INST_0] = R500_RS_INST_COL_ID(0) | R500_RS_INST_COL_ADDR(0);
+16 -22
View File
@@ -192,31 +192,23 @@ void r300ChooseSwtclVertexFormat(GLcontext *ctx, GLuint *_InputsRead, GLuint *_
}
}
/* RS can't put fragment position on the pixel stack, so stuff it in texcoord if needed */
if (fp_reads & FRAG_BIT_WPOS) {
if (first_free_tex >= ctx->Const.MaxTextureUnits) {
fprintf(stderr, "\tout of free texcoords to write w pos\n");
_mesa_exit(-1);
}
if (rmesa->selected_fp->wpos_attr != FRAG_ATTRIB_MAX) {
int tex_id = rmesa->selected_fp->wpos_attr - FRAG_ATTRIB_TEX0;
InputsRead |= 1 << (VERT_ATTRIB_TEX0 + first_free_tex);
OutputsWritten |= 1 << (VERT_RESULT_TEX0 + first_free_tex);
EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F );
ADD_ATTR(VERT_ATTRIB_POS, R300_DATA_TYPE_FLOAT_4, SWTCL_OVM_TEX(first_free_tex), SWIZZLE_XYZW, MASK_XYZW, 0);
++first_free_tex;
VB->AttribPtr[VERT_ATTRIB_TEX0 + tex_id] = VB->AttribPtr[VERT_ATTRIB_POS];
RENDERINPUTS_SET(tnl->render_inputs_bitset, _TNL_ATTRIB_TEX0 + tex_id);
}
if (fp_reads & FRAG_BIT_FOGC) {
if (first_free_tex >= ctx->Const.MaxTextureUnits) {
fprintf(stderr, "\tout of free texcoords to write fog coordinate\n");
_mesa_exit(-1);
}
if (rmesa->selected_fp->fog_attr != FRAG_ATTRIB_MAX) {
int tex_id = rmesa->selected_fp->fog_attr - FRAG_ATTRIB_TEX0;
InputsRead |= 1 << VERT_ATTRIB_FOG;
OutputsWritten |= 1 << VERT_RESULT_FOGC;
GLuint swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO);
EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1F );
ADD_ATTR(VERT_ATTRIB_FOG, R300_DATA_TYPE_FLOAT_1, SWTCL_OVM_TEX(first_free_tex), swiz, MASK_XYZW, 0);
VB->AttribPtr[VERT_ATTRIB_TEX0 + tex_id] = VB->AttribPtr[VERT_ATTRIB_FOG];
RENDERINPUTS_SET(tnl->render_inputs_bitset, _TNL_ATTRIB_TEX0 + tex_id);
}
if (first_free_tex >= ctx->Const.MaxTextureUnits) {
fprintf(stderr, "\tout of free texcoords to write fog coordinate\n");
_mesa_exit(-1);
}
R300_NEWPRIM(rmesa);
@@ -497,11 +489,13 @@ void r300RenderStart(GLcontext *ctx)
r300ContextPtr rmesa = R300_CONTEXT( ctx );
r300ChooseRenderState(ctx);
r300UpdateShaders(rmesa);
r300PrepareVertices(ctx);
r300ValidateBuffers(ctx);
r300UpdateShaders(rmesa);
r300UpdateShaderStates(rmesa);
r300EmitCacheFlush(rmesa);
+47 -32
View File
@@ -1223,8 +1223,7 @@ void r300TranslateVertexShader(struct r300_vertex_program *vp)
}
}
static void insert_wpos(struct r300_vertex_program *vp, struct gl_program *prog,
GLuint temp_index)
static void insert_wpos(struct gl_program *prog, GLuint temp_index, int tex_id)
{
struct prog_instruction *vpi;
@@ -1248,7 +1247,7 @@ static void insert_wpos(struct r300_vertex_program *vp, struct gl_program *prog,
vpi->Opcode = OPCODE_MOV;
vpi->DstReg.File = PROGRAM_OUTPUT;
vpi->DstReg.Index = VERT_RESULT_TEX0 + vp->wpos_idx;
vpi->DstReg.Index = VERT_RESULT_TEX0 + tex_id;
vpi->DstReg.WriteMask = WRITEMASK_XYZW;
vpi->DstReg.CondMask = COND_TR;
@@ -1259,12 +1258,9 @@ static void insert_wpos(struct r300_vertex_program *vp, struct gl_program *prog,
++vpi;
vpi->Opcode = OPCODE_END;
prog->OutputsWritten |= 1 << (VERT_RESULT_TEX0 + vp->wpos_idx);
}
static void pos_as_texcoord(struct r300_vertex_program *vp,
struct gl_program *prog)
static void pos_as_texcoord(struct gl_program *prog, int tex_id)
{
struct prog_instruction *vpi;
GLuint tempregi = prog->NumTemporaries;
@@ -1278,7 +1274,37 @@ static void pos_as_texcoord(struct r300_vertex_program *vp,
}
}
insert_wpos(vp, prog, tempregi);
insert_wpos(prog, tempregi, tex_id);
prog->OutputsWritten |= 1 << (VERT_RESULT_TEX0 + tex_id);
}
/**
@TODO
We can put X001 swizzle only if input components are directly mapped from output components.
For some insts we need to skip source swizzles and add: MOV OUTPUT[fog_attr].yzw, CONST[0].0001
*/
static void fog_as_texcoord(struct gl_program *prog, int tex_id)
{
struct prog_instruction *vpi;
int i;
vpi = prog->Instructions;
while (vpi->Opcode != OPCODE_END) {
if (vpi->DstReg.File == PROGRAM_OUTPUT && vpi->DstReg.Index == VERT_RESULT_FOGC) {
vpi->DstReg.Index = VERT_RESULT_TEX0 + tex_id;
vpi->DstReg.WriteMask = WRITEMASK_XYZW;
for (i = 0; i < _mesa_num_inst_src_regs(vpi->Opcode); ++i) {
vpi->SrcReg[i].Swizzle = combineSwizzles(vpi->SrcReg[i].Swizzle, SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ONE);
}
}
++vpi;
}
prog->OutputsWritten &= ~(1 << VERT_RESULT_FOGC);
prog->OutputsWritten |= 1 << (VERT_RESULT_TEX0 + tex_id);
}
static int translateABS(struct gl_program *prog, int pos)
@@ -1513,16 +1539,15 @@ static void addArtificialOutputs(GLcontext *ctx, struct gl_program *prog)
static struct r300_vertex_program *build_program(GLcontext *ctx,
struct r300_vertex_program_key *wanted_key,
const struct gl_vertex_program *mesa_vp,
GLint wpos_idx)
const struct gl_vertex_program *mesa_vp)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
struct r300_vertex_program *vp;
struct gl_program *prog;
vp = _mesa_calloc(sizeof(*vp));
vp->Base = (struct gl_vertex_program *) _mesa_clone_program(ctx, &mesa_vp->Base);
_mesa_memcpy(&vp->key, wanted_key, sizeof(vp->key));
vp->wpos_idx = wpos_idx;
prog = &vp->Base->Base;
@@ -1532,12 +1557,16 @@ static struct r300_vertex_program *build_program(GLcontext *ctx,
fflush(stdout);
}
if (mesa_vp->IsPositionInvariant) {
if (vp->Base->IsPositionInvariant) {
_mesa_insert_mvp_code(ctx, vp->Base);
}
if (wpos_idx > -1) {
pos_as_texcoord(vp, prog);
if (r300->selected_fp->wpos_attr != FRAG_ATTRIB_MAX) {
pos_as_texcoord(&vp->Base->Base, r300->selected_fp->wpos_attr - FRAG_ATTRIB_TEX0);
}
if (r300->selected_fp->fog_attr != FRAG_ATTRIB_MAX) {
fog_as_texcoord(&vp->Base->Base, r300->selected_fp->fog_attr - FRAG_ATTRIB_TEX0);
}
addArtificialOutputs(ctx, prog);
@@ -1562,34 +1591,20 @@ struct r300_vertex_program * r300SelectVertexShader(GLcontext *ctx)
struct r300_vertex_program_key wanted_key = { 0 };
struct r300_vertex_program_cont *vpc;
struct r300_vertex_program *vp;
GLint wpos_idx;
vpc = (struct r300_vertex_program_cont *)ctx->VertexProgram._Current;
wanted_key.FpReads = r300->selected_fp->Base->InputsRead;
wanted_key.FogAttr = r300->selected_fp->fog_attr;
wanted_key.WPosAttr = r300->selected_fp->wpos_attr;
for (vp = vpc->progs; vp; vp = vp->next)
for (vp = vpc->progs; vp; vp = vp->next) {
if (_mesa_memcmp(&vp->key, &wanted_key, sizeof(wanted_key))
== 0) {
return r300->selected_vp = vp;
}
wpos_idx = -1;
if (wanted_key.FpReads & FRAG_BIT_WPOS) {
GLint i;
for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
if (!(wanted_key.FpReads & (FRAG_BIT_TEX(i))))
break;
if (i == ctx->Const.MaxTextureUnits) {
fprintf(stderr, "\tno free texcoord found\n");
_mesa_exit(-1);
}
wpos_idx = i;
}
vp = build_program(ctx, &wanted_key, &vpc->mesa_program, wpos_idx);
vp = build_program(ctx, &wanted_key, &vpc->mesa_program);
vp->next = vpc->progs;
vpc->progs = vp;