Hi,
I finally managed to iron out the last issue with getting a fully
working fragment.position for the r300 driver.
This should really require the big discussion if it wasn't for the fact
that it depends on functional changes in r300_vertexprog.c
(r300_select_vertex_shader4).
The patches:
r300_select_vertex_shader4:
The patch makes the vertex program output from the fragment input. It
makes the driver capable of catching output-input mismatches. primarily
based on some of Aapo Tahkola's code.
mesa-support_internal_driver_state_vars:
Makes it possible for driver to define its own internal state parameters.
r300_fragment_wpos5:
Adds fragment.position support, depends on the above patches.
Any questions/ideas/comments/??, I am all ears.
Rune Petersen
P.S.
Brian, Roland, Keith, thank you for your patient replies.
Index: program.c
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/shader/program.c,v
retrieving revision 1.59
diff -u -r1.59 program.c
--- program.c 10 Oct 2006 22:45:50 -0000 1.59
+++ program.c 4 Nov 2006 19:03:48 -0000
@@ -927,7 +927,9 @@
break;
}
default:
- _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()");
+ /* unknown state indexes are silently ignored
+ * should be handled by the driver.
+ */
return;
}
}
@@ -1000,7 +1002,9 @@
case STATE_TEXRECT_SCALE:
return _NEW_TEXTURE;
default:
- _mesa_problem(NULL, "unexpected int. state in make_state_flags()");
+ /* unknown state indexes are silently ignored and
+ * no flag set, since it is handled by the driver.
+ */
return 0;
}
@@ -1272,7 +1276,7 @@
case STATE_INTERNAL:
break;
default:
- _mesa_problem(NULL, "Invalid state in maka_state_string");
+ _mesa_problem(NULL, "Invalid state in make_state_string");
break;
}
Index: program.h
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/shader/program.h,v
retrieving revision 1.22
diff -u -r1.22 program.h
--- program.h 20 Sep 2006 14:30:22 -0000 1.22
+++ program.h 4 Nov 2006 19:03:48 -0000
@@ -189,7 +189,8 @@
STATE_INTERNAL, /* Mesa additions */
STATE_NORMAL_SCALE,
STATE_TEXRECT_SCALE,
- STATE_POSITION_NORMALIZED /* normalized light position */
+ STATE_POSITION_NORMALIZED, /* normalized light position */
+ STATE_INTERNAL_DRIVER /* first available state index for drivers
(must be last) */
};
diff -x '*.o' -x '*.so' -x Entries -x 'depend*' -Naur r300_context.h
r300_context.h
--- r300_context.h 2006-09-19 18:52:45.000000000 +0200
+++ r300_context.h 2006-11-16 19:50:22.000000000 +0100
@@ -549,6 +549,7 @@
/* Can be tested with colormat currently. */
#define VSF_MAX_FRAGMENT_TEMPS (14)
+#define STATE_R300_WINDOW_DIMENSION (STATE_INTERNAL_DRIVER+0)
struct r300_vertex_shader_fragment {
int length;
@@ -623,6 +624,7 @@
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];
int native;
diff -x '*.o' -x '*.so' -x Entries -x 'depend*' -Naur r300_fragprog.c
r300_fragprog.c
--- r300_fragprog.c 2006-11-16 20:00:35.000000000 +0100
+++ r300_fragprog.c 2006-11-13 22:01:30.000000000 +0100
@@ -1555,6 +1555,13 @@
}
InputsRead &= ~FRAG_BITS_TEX_ANY;
+ /* fragment position treated as a texcoord */
+ if (InputsRead & FRAG_BIT_WPOS) {
+ cs->inputs[FRAG_ATTRIB_WPOS].refcount = 0;
+ cs->inputs[FRAG_ATTRIB_WPOS].reg = get_hw_temp(rp);
+ }
+ InputsRead &= ~FRAG_BIT_WPOS;
+
/* Then primary colour */
if (InputsRead & FRAG_BIT_COL0) {
cs->inputs[FRAG_ATTRIB_COL0].refcount = 0;
diff -x '*.o' -x '*.so' -x Entries -x 'depend*' -Naur r300_state.c r300_state.c
--- r300_state.c 2006-11-16 20:00:41.000000000 +0100
+++ r300_state.c 2006-11-16 20:17:58.000000000 +0100
@@ -1044,6 +1044,59 @@
#endif
}
+static void r300FetchStateParameter(GLcontext *ctx, const enum state_index
state[],
+ GLfloat *value)
+{
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
+
+ switch(state[0])
+ {
+ case STATE_INTERNAL:
+ switch(state[1])
+ {
+ case STATE_R300_WINDOW_DIMENSION:
+ value[0] = r300->radeon.dri.drawable->w; /* width */
+ value[1] = r300->radeon.dri.drawable->h; /* height */
+ value[2] = 0.5F; /* for moving range [-1
1] -> [0 1] */
+ value[3] = 1.0F; /* not used */
+ break;
+ default:;
+ }
+ default:;
+ }
+}
+
+/**
+ * Update R300's own internal state parameters.
+ * For now just STATE_R300_WINDOW_DIMENSION
+ */
+static void r300UpdateStateParameters(GLcontext * ctx, GLuint new_state)
+{
+ struct r300_vertex_program_cont *vpc;
+ struct gl_program_parameter_list *paramList;
+ GLuint i;
+
+ if(!(new_state & (_NEW_BUFFERS|_NEW_PROGRAM)))
+ return;
+
+ vpc = (struct r300_vertex_program_cont *)ctx->VertexProgram._Current;
+ if (!vpc)
+ return;
+
+ paramList = vpc->mesa_program.Base.Parameters;
+
+ if (!paramList)
+ return;
+
+ for (i = 0; i < paramList->NumParameters; i++) {
+ if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR){
+ r300FetchStateParameter(ctx,
+ paramList->Parameters[i].StateIndexes,
+ paramList->ParameterValues[i]);
+ }
+ }
+}
+
/* =============================================================
* Polygon state
*/
@@ -1304,6 +1357,20 @@
r300->hw.rr.cmd[R300_RR_ROUTE_1] = 0;
+ if (InputsRead & FRAG_BIT_WPOS){
+ for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
+ if (!(InputsRead & (FRAG_BIT_TEX0 << i)))
+ break;
+
+ if(i == ctx->Const.MaxTextureUnits){
+ fprintf(stderr, "\tno free texcoord found...\n");
+ exit(0);
+ }
+
+ InputsRead |= (FRAG_BIT_TEX0 << i);
+ InputsRead &= ~FRAG_BIT_WPOS;
+ }
+
for (i=0;i<ctx->Const.MaxTextureUnits;i++) {
r300->hw.ri.cmd[R300_RI_INTERP_0+i] = 0
| R300_RS_INTERP_USED
@@ -1680,6 +1747,7 @@
return ;
}
+ r300UpdateStateParameters(ctx, _NEW_PROGRAM);
}
}
@@ -1813,6 +1881,9 @@
if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) {
r300UpdateDrawBuffer(ctx);
}
+
+ r300UpdateStateParameters(ctx, new_state);
+
#ifndef CB_DPATH
/* Go inefficiency! */
r300ResetHwState(r300);
diff -x '*.o' -x '*.so' -x Entries -x 'depend*' -Naur r300_vertexprog.c
r300_vertexprog.c
--- r300_vertexprog.c 2006-10-07 14:48:55.000000000 +0200
+++ r300_vertexprog.c 2006-11-16 19:54:29.000000000 +0100
@@ -958,17 +958,155 @@
assert(vpi->Opcode == OPCODE_END);
}
+static void insert_wpos(struct r300_vertex_program *vp,
+ struct gl_program *prog,
+ GLint pos)
+{
+
+ GLint tokens[6] = { STATE_INTERNAL, STATE_R300_WINDOW_DIMENSION, 0, 0,
0, 0 };
+ struct prog_instruction *vpi;
+ struct prog_instruction *vpi_insert;
+ GLuint temp_index;
+ GLuint window_index;
+ int i = 0;
+
+ vpi = malloc((prog->NumInstructions + 5) * sizeof(struct
prog_instruction));
+ memcpy(vpi, prog->Instructions, (pos+1) * sizeof(struct
prog_instruction));
+
+ vpi_insert = &vpi[pos];
+
+ /* make a copy before outputting VERT_RESULT_HPOS */
+ vpi_insert->DstReg.File = vpi_insert->SrcReg[2].File;
+ vpi_insert->DstReg.Index = temp_index = vpi_insert->SrcReg[2].Index;
+
+ vpi_insert++;
+ memset(vpi_insert, 0, 5 * sizeof(struct prog_instruction));
+
+ vpi_insert[i].Opcode = OPCODE_MOV;
+
+ vpi_insert[i].DstReg.File = PROGRAM_OUTPUT;
+ vpi_insert[i].DstReg.Index = VERT_RESULT_HPOS;
+ vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZW;
+ vpi_insert[i].DstReg.CondMask = COND_TR;
+
+ vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY;
+ vpi_insert[i].SrcReg[0].Index = temp_index;
+ vpi_insert[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
SWIZZLE_Z, SWIZZLE_W);
+ i++;
+
+ /* perspective divide */
+ vpi_insert[i].Opcode = OPCODE_RCP;
+
+ vpi_insert[i].DstReg.File = PROGRAM_TEMPORARY;
+ vpi_insert[i].DstReg.Index = temp_index;
+ vpi_insert[i].DstReg.WriteMask = WRITEMASK_W;
+ vpi_insert[i].DstReg.CondMask = COND_TR;
+
+ vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY;
+ vpi_insert[i].SrcReg[0].Index = temp_index;
+ vpi_insert[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_W,
SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO);
+ i++;
+
+ vpi_insert[i].Opcode = OPCODE_MUL;
+
+ vpi_insert[i].DstReg.File = PROGRAM_TEMPORARY;
+ vpi_insert[i].DstReg.Index = temp_index;
+ vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZ;
+ vpi_insert[i].DstReg.CondMask = COND_TR;
+
+ vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY;
+ vpi_insert[i].SrcReg[0].Index = temp_index;
+ vpi_insert[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
SWIZZLE_Z, SWIZZLE_ZERO);
+
+ vpi_insert[i].SrcReg[1].File = PROGRAM_TEMPORARY;
+ vpi_insert[i].SrcReg[1].Index = temp_index;
+ vpi_insert[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_W, SWIZZLE_W,
SWIZZLE_W, SWIZZLE_ZERO);
+ i++;
+
+ /* viewport transformation */
+ window_index = _mesa_add_state_reference(prog->Parameters, tokens);
+
+ vpi_insert[i].Opcode = OPCODE_MAD;
+
+ vpi_insert[i].DstReg.File = PROGRAM_TEMPORARY;
+ vpi_insert[i].DstReg.Index = temp_index;
+ vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZ;
+ vpi_insert[i].DstReg.CondMask = COND_TR;
+
+ vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY;
+ vpi_insert[i].SrcReg[0].Index = temp_index;
+ vpi_insert[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
SWIZZLE_Z, SWIZZLE_ZERO);
+
+ vpi_insert[i].SrcReg[1].File = PROGRAM_STATE_VAR;
+ vpi_insert[i].SrcReg[1].Index = window_index;
+ vpi_insert[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_Z,
SWIZZLE_Z, SWIZZLE_ZERO);
+
+ vpi_insert[i].SrcReg[2].File = PROGRAM_STATE_VAR;
+ vpi_insert[i].SrcReg[2].Index = window_index;
+ vpi_insert[i].SrcReg[2].Swizzle = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_Z,
SWIZZLE_Z, SWIZZLE_ZERO);
+ i++;
+
+ vpi_insert[i].Opcode = OPCODE_MUL;
+
+ vpi_insert[i].DstReg.File = PROGRAM_OUTPUT;
+ vpi_insert[i].DstReg.Index = VERT_RESULT_TEX0+vp->wpos_idx;
+ vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZW;
+ vpi_insert[i].DstReg.CondMask = COND_TR;
+
+ vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY;
+ vpi_insert[i].SrcReg[0].Index = temp_index;
+ vpi_insert[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
SWIZZLE_Z, SWIZZLE_W);
+
+ vpi_insert[i].SrcReg[1].File = PROGRAM_STATE_VAR;
+ vpi_insert[i].SrcReg[1].Index = window_index;
+ vpi_insert[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
SWIZZLE_ONE, SWIZZLE_ONE);
+ i++;
+
+ memcpy(&vpi_insert[i], &prog->Instructions[pos+1],
(prog->NumInstructions-(pos+1)) * sizeof(struct prog_instruction));
+
+ free(prog->Instructions);
+
+ prog->Instructions = vpi;
+
+ prog->NumInstructions += i;
+ vpi = &prog->Instructions[prog->NumInstructions-1];
+
+ assert(vpi->Opcode == OPCODE_END);
+}
+
+static void pos_as_texcoord(struct r300_vertex_program *vp,
+ struct gl_program *prog)
+{
+ struct prog_instruction *vpi;
+ int pos = 0;
+
+ for(vpi = prog->Instructions; vpi->Opcode != OPCODE_END; vpi++, pos++){
+ if( vpi->DstReg.File == PROGRAM_OUTPUT &&
+ vpi->DstReg.Index == VERT_RESULT_HPOS ){
+ insert_wpos(vp, prog, pos);
+ break;
+ }
+ }
+
+}
+
static struct r300_vertex_program *build_program(struct
r300_vertex_program_key *wanted_key,
- struct gl_vertex_program
*mesa_vp)
+ struct gl_vertex_program
*mesa_vp,
+ GLint wpos_idx)
{
struct r300_vertex_program *vp;
vp = _mesa_calloc(sizeof(*vp));
_mesa_memcpy(&vp->key, wanted_key, sizeof(vp->key));
+ vp->wpos_idx = wpos_idx;
+
if(mesa_vp->IsPositionInvariant)
position_invariant(&mesa_vp->Base);
+ if(wpos_idx > -1)
+ pos_as_texcoord(vp, &mesa_vp->Base);
+
assert(mesa_vp->Base.NumInstructions);
vp->num_temporaries=mesa_vp->Base.NumTemporaries;
@@ -986,12 +1124,28 @@
GLint i;
struct r300_vertex_program_cont *vpc;
struct r300_vertex_program *vp;
+ GLint wpos_idx;
vpc = (struct r300_vertex_program_cont *)ctx->VertexProgram._Current;
InputsRead = ctx->FragmentProgram._Current->Base.InputsRead;
wanted_key.OutputsWritten |= 1 << VERT_RESULT_HPOS;
+ wpos_idx = -1;
+ if (InputsRead & FRAG_BIT_WPOS){
+ for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
+ if (!(InputsRead & (FRAG_BIT_TEX0 << i)))
+ break;
+
+ if(i == ctx->Const.MaxTextureUnits){
+ fprintf(stderr, "\tno free texcoord found\n");
+ exit(0);
+ }
+
+ InputsRead |= (FRAG_BIT_TEX0 << i);
+ wpos_idx = i;
+ }
+
if (InputsRead & FRAG_BIT_COL0)
wanted_key.OutputsWritten |= 1 << VERT_RESULT_COL0;
@@ -1013,7 +1167,7 @@
//_mesa_print_program(&vpc->mesa_program.Base);
- vp = build_program(&wanted_key, &vpc->mesa_program);
+ vp = build_program(&wanted_key, &vpc->mesa_program, wpos_idx);
vp->next = vpc->progs;
vpc->progs = vp;
? server
Index: r300_context.h
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r300/r300_context.h,v
retrieving revision 1.104
diff -u -r1.104 r300_context.h
--- r300_context.h 12 Sep 2006 18:34:43 -0000 1.104
+++ r300_context.h 16 Nov 2006 19:12:31 -0000
@@ -592,7 +592,8 @@
extern int hw_tcl_on;
-#define CURRENT_VERTEX_SHADER(ctx) (ctx->VertexProgram._Current)
+//#define CURRENT_VERTEX_SHADER(ctx) (ctx->VertexProgram._Current)
+#define CURRENT_VERTEX_SHADER(ctx) (R300_CONTEXT(ctx)->selected_vp)
/* Should but doesnt work */
//#define CURRENT_VERTEX_SHADER(ctx) (R300_CONTEXT(ctx)->curr_vp)
@@ -607,12 +608,18 @@
/* r300_vertex_shader_state and r300_vertex_program should probably be merged
together someday.
* Keeping them them seperate for now should ensure fixed pipeline keeps
functioning properly.
*/
+
+struct r300_vertex_program_key {
+ GLuint InputsRead;
+ GLuint OutputsWritten;
+};
+
struct r300_vertex_program {
- struct gl_vertex_program mesa_program; /* Must be first */
+ struct r300_vertex_program *next;
+ struct r300_vertex_program_key key;
int translated;
struct r300_vertex_shader_fragment program;
- struct r300_vertex_shader_fragment params;
int pos_end;
int num_temporaries; /* Number of temp vars used by program */
@@ -623,6 +630,12 @@
int use_ref_count;
};
+struct r300_vertex_program_cont {
+ struct gl_vertex_program mesa_program; /* Must be first */
+ struct r300_vertex_shader_fragment params;
+ struct r300_vertex_program *progs;
+};
+
#define PFS_MAX_ALU_INST 64
#define PFS_MAX_TEX_INST 64
#define PFS_MAX_TEX_INDIRECT 4
@@ -797,6 +810,7 @@
struct r300_cmdbuf cmdbuf;
struct r300_state state;
struct gl_vertex_program *curr_vp;
+ struct r300_vertex_program *selected_vp;
/* Vertex buffers
*/
@@ -854,9 +868,9 @@
extern int r300_get_num_verts(r300ContextPtr rmesa, int num_verts, int prim);
-void r300_translate_vertex_shader(struct r300_vertex_program *vp);
+extern void r300_select_vertex_shader(r300ContextPtr r300);
extern void r300InitShaderFuncs(struct dd_function_table *functions);
-extern int r300VertexProgUpdateParams(GLcontext *ctx, struct
r300_vertex_program *vp, float *dst);
+extern int r300VertexProgUpdateParams(GLcontext *ctx, struct
r300_vertex_program_cont *vp, float *dst);
extern int r300Fallback(GLcontext *ctx);
extern void radeon_vb_to_rvb(r300ContextPtr rmesa, struct radeon_vertex_buffer
*rvb, struct vertex_buffer *vb);
Index: r300_maos.c
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r300/r300_maos.c,v
retrieving revision 1.39
diff -u -r1.39 r300_maos.c
--- r300_maos.c 14 Sep 2006 16:17:06 -0000 1.39
+++ r300_maos.c 16 Nov 2006 19:12:32 -0000
@@ -407,8 +407,8 @@
if (hw_tcl_on) {
struct r300_vertex_program *prog=(struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx);
inputs = prog->inputs;
- InputsRead = CURRENT_VERTEX_SHADER(ctx)->Base.InputsRead;
- OutputsWritten =
CURRENT_VERTEX_SHADER(ctx)->Base.OutputsWritten;
+ InputsRead = CURRENT_VERTEX_SHADER(ctx)->key.InputsRead;
+ OutputsWritten = CURRENT_VERTEX_SHADER(ctx)->key.OutputsWritten;
} else {
DECLARE_RENDERINPUTS(inputs_bitset);
inputs = r300->state.sw_tcl_inputs;
Index: r300_shader.c
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r300/r300_shader.c,v
retrieving revision 1.18
diff -u -r1.18 r300_shader.c
--- r300_shader.c 20 Jul 2006 16:49:57 -0000 1.18
+++ r300_shader.c 16 Nov 2006 19:12:32 -0000
@@ -12,13 +12,13 @@
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
- struct r300_vertex_program *vp=(void *)prog;
+ struct r300_vertex_program_cont *vp=(void *)prog;
switch(target){
case GL_VERTEX_PROGRAM_ARB:
- rmesa->curr_vp = (struct gl_vertex_program *)vp;
- vp->ref_count++;
+ //rmesa->curr_vp = (struct gl_vertex_program *)vp;
+ //vp->ref_count++;
#if 0
if((vp->ref_count % 1500) == 0) {
fprintf(stderr, "id %p, ref_count %d\n", vp,
vp->ref_count);
@@ -37,13 +37,13 @@
static struct gl_program *
r300NewProgram(GLcontext *ctx, GLenum target, GLuint id)
{
- struct r300_vertex_program *vp;
+ struct r300_vertex_program_cont *vp;
struct r300_fragment_program *fp;
switch(target){
case GL_VERTEX_STATE_PROGRAM_NV:
case GL_VERTEX_PROGRAM_ARB:
- vp=CALLOC_STRUCT(r300_vertex_program);
+ vp=CALLOC_STRUCT(r300_vertex_program_cont);
return _mesa_init_vertex_program(ctx,
&vp->mesa_program, target, id);
case GL_FRAGMENT_PROGRAM_ARB:
fp=CALLOC_STRUCT(r300_fragment_program);
@@ -77,13 +77,14 @@
static void
r300ProgramStringNotify(GLcontext *ctx, GLenum target, struct gl_program *prog)
{
- struct r300_vertex_program *vp=(void *)prog;
+ struct r300_vertex_program_cont *vp=(void *)prog;
struct r300_fragment_program *fp = (struct r300_fragment_program *)
prog;
switch(target) {
case GL_VERTEX_PROGRAM_ARB:
- vp->translated = GL_FALSE;
- memset(&vp->translated, 0, sizeof(struct r300_vertex_program) -
sizeof(struct gl_vertex_program));
+ vp->progs = NULL;
+ /*vp->translated = GL_FALSE;
+ memset(&vp->translated, 0, sizeof(struct r300_vertex_program) -
sizeof(struct gl_vertex_program));*/
/*r300_translate_vertex_shader(vp);*/
break;
case GL_FRAGMENT_PROGRAM_ARB:
Index: r300_state.c
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r300/r300_state.c,v
retrieving revision 1.168
diff -u -r1.168 r300_state.c
--- r300_state.c 2 Nov 2006 17:51:05 -0000 1.168
+++ r300_state.c 16 Nov 2006 19:12:33 -0000
@@ -1285,7 +1285,7 @@
int i;
if(hw_tcl_on)
- OutputsWritten.vp_outputs =
CURRENT_VERTEX_SHADER(ctx)->Base.OutputsWritten;
+ OutputsWritten.vp_outputs =
CURRENT_VERTEX_SHADER(ctx)->key.OutputsWritten;
else
RENDERINPUTS_COPY( OutputsWritten.index_bitset,
r300->state.render_inputs_bitset );
@@ -1610,7 +1610,7 @@
((drm_r300_cmd_header_t*)rmesa->hw.vpp.cmd)->vpu.count = 0;
R300_STATECHANGE(rmesa, vpp);
- param_count = r300VertexProgUpdateParams(ctx, prog, (float
*)&rmesa->hw.vpp.cmd[R300_VPP_PARAM_0]);
+ param_count = r300VertexProgUpdateParams(ctx, (struct
r300_vertex_program_cont *)ctx->VertexProgram._Current/*prog*/, (float
*)&rmesa->hw.vpp.cmd[R300_VPP_PARAM_0]);
bump_vpu_count(rmesa->hw.vpp.cmd, param_count);
param_count /= 4;
@@ -1669,9 +1669,10 @@
TNL_CONTEXT(ctx)->vb.AttribPtr[i] =
rmesa->temp_attrib[i];
}
+ r300_select_vertex_shader(rmesa);
vp = (struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);
- if (vp->translated == GL_FALSE)
- r300_translate_vertex_shader(vp);
+ /*if (vp->translated == GL_FALSE)
+ r300_translate_vertex_shader(vp);*/
if (vp->translated == GL_FALSE) {
fprintf(stderr, "Failing back to sw-tcl\n");
hw_tcl_on = future_hw_tcl_on = 0;
Index: r300_vertexprog.c
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r300/r300_vertexprog.c,v
retrieving revision 1.62
diff -u -r1.62 r300_vertexprog.c
--- r300_vertexprog.c 28 Aug 2006 19:42:41 -0000 1.62
+++ r300_vertexprog.c 16 Nov 2006 19:12:34 -0000
@@ -95,7 +95,7 @@
};
#undef OPN
-int r300VertexProgUpdateParams(GLcontext *ctx, struct r300_vertex_program *vp,
float *dst)
+int r300VertexProgUpdateParams(GLcontext *ctx, struct r300_vertex_program_cont
*vp, float *dst)
{
int pi;
struct gl_vertex_program *mesa_vp = &vp->mesa_program;
@@ -177,17 +177,9 @@
static unsigned long t_dst_index(struct r300_vertex_program *vp, struct
prog_dst_register *dst)
{
- if(dst->File == PROGRAM_OUTPUT) {
- if (vp->outputs[dst->Index] != -1)
- return vp->outputs[dst->Index];
- else {
- WARN_ONCE("Unknown output %d\n", dst->Index);
- return 10;
- }
- }else if(dst->File == PROGRAM_ADDRESS) {
- assert(dst->Index == 0);
- }
-
+ if(dst->File == PROGRAM_OUTPUT)
+ return vp->outputs[dst->Index];
+
return dst->Index;
}
@@ -335,6 +327,18 @@
return 0;
}
+static GLboolean valid_dst(struct r300_vertex_program *vp, struct
prog_dst_register *dst)
+{
+ if(dst->File == PROGRAM_OUTPUT && vp->outputs[dst->Index] == -1){
+ WARN_ONCE("Output %d not used by fragment program\n",
dst->Index);
+ return GL_FALSE;
+ }else if(dst->File == PROGRAM_ADDRESS) {
+ assert(dst->Index == 0);
+ }
+
+ return GL_TRUE;
+}
+
/* 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) == VSF_IN_CLASS_PARAM && \
@@ -384,10 +388,8 @@
u_temp_i=VSF_MAX_FRAGMENT_TEMPS-1; \
} while (0)
-void r300_translate_vertex_shader(struct r300_vertex_program *vp)
+static void r300_translate_vertex_shader(struct r300_vertex_program *vp,
struct prog_instruction *vpi)
{
- struct gl_vertex_program *mesa_vp= &vp->mesa_program;
- struct prog_instruction *vpi;
int i, cur_reg=0;
VERTEX_SHADER_INSTRUCTION *o_inst;
unsigned long operands;
@@ -399,131 +401,9 @@
int u_temp_i=VSF_MAX_FRAGMENT_TEMPS-1;
struct prog_src_register src[3];
- if (mesa_vp->Base.NumInstructions == 0)
- return;
-
- if (getenv("R300_VP_SAFETY")) {
- WARN_ONCE("R300_VP_SAFETY enabled.\n");
-
- vpi = malloc((mesa_vp->Base.NumInstructions +
VSF_MAX_FRAGMENT_TEMPS) * sizeof(struct prog_instruction));
- memset(vpi, 0, VSF_MAX_FRAGMENT_TEMPS * sizeof(struct
prog_instruction));
-
- for (i=0; i < VSF_MAX_FRAGMENT_TEMPS; i++) {
- vpi[i].Opcode = OPCODE_MOV;
- vpi[i].StringPos = 0;
- vpi[i].Data = 0;
-
- vpi[i].DstReg.File = PROGRAM_TEMPORARY;
- vpi[i].DstReg.Index = i;
- vpi[i].DstReg.WriteMask = WRITEMASK_XYZW;
- vpi[i].DstReg.CondMask = COND_TR;
-
- vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR;
- vpi[i].SrcReg[0].Index = 0;
- vpi[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_ONE,
SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE);
- }
-
- memcpy(&vpi[i], mesa_vp->Base.Instructions,
mesa_vp->Base.NumInstructions * sizeof(struct prog_instruction));
-
- free(mesa_vp->Base.Instructions);
-
- mesa_vp->Base.Instructions = vpi;
-
- mesa_vp->Base.NumInstructions += VSF_MAX_FRAGMENT_TEMPS;
- vpi =
&mesa_vp->Base.Instructions[mesa_vp->Base.NumInstructions-1];
-
- assert(vpi->Opcode == OPCODE_END);
- }
-
- if (mesa_vp->IsPositionInvariant) {
- struct gl_program_parameter_list *paramList;
- GLint tokens[6] = { STATE_MATRIX, STATE_MVP, 0, 0, 0,
STATE_MATRIX };
-
-#ifdef PREFER_DP4
- tokens[5] = STATE_MATRIX;
-#else
- tokens[5] = STATE_MATRIX_TRANSPOSE;
-#endif
- paramList = mesa_vp->Base.Parameters;
-
- vpi = malloc((mesa_vp->Base.NumInstructions + 4) *
sizeof(struct prog_instruction));
- memset(vpi, 0, 4 * sizeof(struct prog_instruction));
-
- for (i=0; i < 4; i++) {
- GLint idx;
- tokens[3] = tokens[4] = i;
- idx = _mesa_add_state_reference(paramList, tokens);
-#ifdef PREFER_DP4
- vpi[i].Opcode = OPCODE_DP4;
- vpi[i].StringPos = 0;
- vpi[i].Data = 0;
-
- vpi[i].DstReg.File = PROGRAM_OUTPUT;
- vpi[i].DstReg.Index = VERT_RESULT_HPOS;
- vpi[i].DstReg.WriteMask = 1 << i;
- vpi[i].DstReg.CondMask = COND_TR;
-
- vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR;
- vpi[i].SrcReg[0].Index = idx;
- vpi[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X,
SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
-
- vpi[i].SrcReg[1].File = PROGRAM_INPUT;
- vpi[i].SrcReg[1].Index = VERT_ATTRIB_POS;
- vpi[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X,
SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
-#else
- if (i == 0)
- vpi[i].Opcode = OPCODE_MUL;
- else
- vpi[i].Opcode = OPCODE_MAD;
-
- vpi[i].StringPos = 0;
- vpi[i].Data = 0;
-
- if (i == 3)
- vpi[i].DstReg.File = PROGRAM_OUTPUT;
- else
- vpi[i].DstReg.File = PROGRAM_TEMPORARY;
- vpi[i].DstReg.Index = 0;
- vpi[i].DstReg.WriteMask = 0xf;
- vpi[i].DstReg.CondMask = COND_TR;
-
- vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR;
- vpi[i].SrcReg[0].Index = idx;
- vpi[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X,
SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
-
- vpi[i].SrcReg[1].File = PROGRAM_INPUT;
- vpi[i].SrcReg[1].Index = VERT_ATTRIB_POS;
- vpi[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(i, i, i, i);
-
- if (i > 0) {
- vpi[i].SrcReg[2].File = PROGRAM_TEMPORARY;
- vpi[i].SrcReg[2].Index = 0;
- vpi[i].SrcReg[2].Swizzle =
MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
- }
-#endif
- }
-
- memcpy(&vpi[i], mesa_vp->Base.Instructions,
mesa_vp->Base.NumInstructions * sizeof(struct prog_instruction));
-
- free(mesa_vp->Base.Instructions);
-
- mesa_vp->Base.Instructions = vpi;
-
- mesa_vp->Base.NumInstructions += 4;
- vpi =
&mesa_vp->Base.Instructions[mesa_vp->Base.NumInstructions-1];
-
- assert(vpi->Opcode == OPCODE_END);
-
- mesa_vp->Base.InputsRead |= (1 << VERT_ATTRIB_POS);
- mesa_vp->Base.OutputsWritten |= (1 << VERT_RESULT_HPOS);
-
- //fprintf(stderr, "IsPositionInvariant is set!\n");
- //_mesa_print_program(&mesa_vp->Base);
- }
-
vp->pos_end=0; /* Not supported yet */
vp->program.length=0;
- vp->num_temporaries=mesa_vp->Base.NumTemporaries;
+ /*vp->num_temporaries=mesa_vp->Base.NumTemporaries;*/
for(i=0; i < VERT_ATTRIB_MAX; i++)
vp->inputs[i] = -1;
@@ -531,42 +411,49 @@
for(i=0; i < VERT_RESULT_MAX; i++)
vp->outputs[i] = -1;
- assert(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS));
+ assert(vp->key.OutputsWritten & (1 << VERT_RESULT_HPOS));
/* Assign outputs */
- if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS))
+ if(vp->key.OutputsWritten & (1 << VERT_RESULT_HPOS))
vp->outputs[VERT_RESULT_HPOS] = cur_reg++;
- if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_PSIZ))
+ if(vp->key.OutputsWritten & (1 << VERT_RESULT_PSIZ))
vp->outputs[VERT_RESULT_PSIZ] = cur_reg++;
- if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_COL0))
+ if(vp->key.OutputsWritten & (1 << VERT_RESULT_COL0))
vp->outputs[VERT_RESULT_COL0] = cur_reg++;
- if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_COL1))
+ if(vp->key.OutputsWritten & (1 << VERT_RESULT_COL1))
vp->outputs[VERT_RESULT_COL1] = cur_reg++;
#if 0 /* Not supported yet */
- if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_BFC0))
+ if(vp->key.OutputsWritten & (1 << VERT_RESULT_BFC0))
vp->outputs[VERT_RESULT_BFC0] = cur_reg++;
- if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_BFC1))
+ if(vp->key.OutputsWritten & (1 << VERT_RESULT_BFC1))
vp->outputs[VERT_RESULT_BFC1] = cur_reg++;
- if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_FOGC))
+ if(vp->key.OutputsWritten & (1 << VERT_RESULT_FOGC))
vp->outputs[VERT_RESULT_FOGC] = cur_reg++;
#endif
for(i=VERT_RESULT_TEX0; i <= VERT_RESULT_TEX7; i++)
- if(mesa_vp->Base.OutputsWritten & (1 << i))
+ if(vp->key.OutputsWritten & (1 << i))
vp->outputs[i] = cur_reg++;
vp->translated = GL_TRUE;
vp->native = GL_TRUE;
o_inst=vp->program.body.i;
- for(vpi=mesa_vp->Base.Instructions; vpi->Opcode != OPCODE_END; vpi++,
o_inst++){
+ for(; vpi->Opcode != OPCODE_END; vpi++, o_inst++){
FREE_TEMPS();
+
+ if(!valid_dst(vp, &vpi->DstReg))
+ {
+ /* redirect result to unused temp */
+ vpi->DstReg.File = PROGRAM_TEMPORARY;
+ vpi->DstReg.Index = u_temp_i;
+ }
operands=op_operands(vpi->Opcode);
are_srcs_scalar=operands & SCALAR_FLAG;
@@ -987,3 +874,148 @@
#endif
}
+static void position_invariant(struct gl_program *prog)
+{
+ struct prog_instruction *vpi;
+ struct gl_program_parameter_list *paramList;
+ int i;
+
+ GLint tokens[6] = { STATE_MATRIX, STATE_MVP, 0, 0, 0, STATE_MATRIX };
+
+#ifdef PREFER_DP4
+ tokens[5] = STATE_MATRIX;
+#else
+ tokens[5] = STATE_MATRIX_TRANSPOSE;
+#endif
+ paramList = prog->Parameters;
+
+ vpi = malloc((prog->NumInstructions + 4) * sizeof(struct
prog_instruction));
+ memset(vpi, 0, 4 * sizeof(struct prog_instruction));
+
+ for (i=0; i < 4; i++) {
+ GLint idx;
+ tokens[3] = tokens[4] = i;
+ idx = _mesa_add_state_reference(paramList, tokens);
+#ifdef PREFER_DP4
+ vpi[i].Opcode = OPCODE_DP4;
+ vpi[i].StringPos = 0;
+ vpi[i].Data = 0;
+
+ vpi[i].DstReg.File = PROGRAM_OUTPUT;
+ vpi[i].DstReg.Index = VERT_RESULT_HPOS;
+ vpi[i].DstReg.WriteMask = 1 << i;
+ vpi[i].DstReg.CondMask = COND_TR;
+
+ vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR;
+ vpi[i].SrcReg[0].Index = idx;
+ vpi[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
SWIZZLE_Z, SWIZZLE_W);
+
+ vpi[i].SrcReg[1].File = PROGRAM_INPUT;
+ vpi[i].SrcReg[1].Index = VERT_ATTRIB_POS;
+ vpi[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
SWIZZLE_Z, SWIZZLE_W);
+#else
+ if (i == 0)
+ vpi[i].Opcode = OPCODE_MUL;
+ else
+ vpi[i].Opcode = OPCODE_MAD;
+
+ vpi[i].StringPos = 0;
+ vpi[i].Data = 0;
+
+ if (i == 3)
+ vpi[i].DstReg.File = PROGRAM_OUTPUT;
+ else
+ vpi[i].DstReg.File = PROGRAM_TEMPORARY;
+ vpi[i].DstReg.Index = 0;
+ vpi[i].DstReg.WriteMask = 0xf;
+ vpi[i].DstReg.CondMask = COND_TR;
+
+ vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR;
+ vpi[i].SrcReg[0].Index = idx;
+ vpi[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
SWIZZLE_Z, SWIZZLE_W);
+
+ vpi[i].SrcReg[1].File = PROGRAM_INPUT;
+ vpi[i].SrcReg[1].Index = VERT_ATTRIB_POS;
+ vpi[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(i, i, i, i);
+
+ if (i > 0) {
+ vpi[i].SrcReg[2].File = PROGRAM_TEMPORARY;
+ vpi[i].SrcReg[2].Index = 0;
+ vpi[i].SrcReg[2].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X,
SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
+ }
+#endif
+ }
+
+ memcpy(&vpi[i], prog->Instructions, prog->NumInstructions *
sizeof(struct prog_instruction));
+
+ free(prog->Instructions);
+
+ prog->Instructions = vpi;
+
+ prog->NumInstructions += 4;
+ vpi = &prog->Instructions[prog->NumInstructions-1];
+
+ assert(vpi->Opcode == OPCODE_END);
+}
+
+static struct r300_vertex_program *build_program(struct
r300_vertex_program_key *wanted_key,
+ struct gl_vertex_program
*mesa_vp)
+{
+ struct r300_vertex_program *vp;
+
+ vp = _mesa_calloc(sizeof(*vp));
+ _mesa_memcpy(&vp->key, wanted_key, sizeof(vp->key));
+
+ if(mesa_vp->IsPositionInvariant)
+ position_invariant(&mesa_vp->Base);
+
+ assert(mesa_vp->Base.NumInstructions);
+
+ vp->num_temporaries=mesa_vp->Base.NumTemporaries;
+
+ r300_translate_vertex_shader(vp, mesa_vp->Base.Instructions);
+
+ return vp;
+}
+
+void r300_select_vertex_shader(r300ContextPtr r300)
+{
+ GLcontext *ctx = ctx = r300->radeon.glCtx;
+ GLuint InputsRead;
+ struct r300_vertex_program_key wanted_key = { 0 };
+ GLint i;
+ struct r300_vertex_program_cont *vpc;
+ struct r300_vertex_program *vp;
+
+ vpc = (struct r300_vertex_program_cont *)ctx->VertexProgram._Current;
+ InputsRead = ctx->FragmentProgram._Current->Base.InputsRead;
+
+ wanted_key.OutputsWritten |= 1 << VERT_RESULT_HPOS;
+
+ if (InputsRead & FRAG_BIT_COL0)
+ wanted_key.OutputsWritten |= 1 << VERT_RESULT_COL0;
+
+ if ((InputsRead & FRAG_BIT_COL1) /*||
+ (InputsRead & FRAG_BIT_FOGC)*/)
+ wanted_key.OutputsWritten |= 1 << VERT_RESULT_COL1;
+
+ for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
+ if (InputsRead & (FRAG_BIT_TEX0 << i))
+ wanted_key.OutputsWritten |= 1 << (VERT_RESULT_TEX0 +
i);
+
+ wanted_key.InputsRead = vpc->mesa_program.Base.InputsRead;
+
+ for (vp = vpc->progs; vp; vp = vp->next)
+ if (_mesa_memcmp(&vp->key, &wanted_key, sizeof(wanted_key)) ==
0) {
+ r300->selected_vp = vp;
+ return ;
+ }
+
+ //_mesa_print_program(&vpc->mesa_program.Base);
+
+ vp = build_program(&wanted_key, &vpc->mesa_program);
+ vp->next = vpc->progs;
+ vpc->progs = vp;
+
+ r300->selected_vp = vp;
+}
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel