#define HAVE_TRI_STRIPS 1
#define HAVE_TRI_STRIP_1 0
#define HAVE_TRI_FANS 1
-#define HAVE_QUADS 0 /* hw quad verts in wrong order??? */
+#define HAVE_QUADS 1
#define HAVE_QUAD_STRIPS 1
#define HAVE_POLYGONS 1
#define HAVE_ELTS 1
-#define HW_POINTS R200_VF_PRIM_POINTS
+#define HW_POINTS ((ctx->Point.PointSprite || \
+ ((ctx->_TriangleCaps & (DD_POINT_SIZE | DD_POINT_ATTEN)) && \
+ !(ctx->_TriangleCaps & (DD_POINT_SMOOTH)))) ? \
+ R200_VF_PRIM_POINT_SPRITES : R200_VF_PRIM_POINTS)
#define HW_LINES R200_VF_PRIM_LINES
#define HW_LINE_LOOP 0
#define HW_LINE_STRIP R200_VF_PRIM_LINE_STRIP
};
-#define LOCAL_VARS r200ContextPtr rmesa = R200_CONTEXT(ctx); (void)rmesa
+#define LOCAL_VARS r200ContextPtr rmesa = R200_CONTEXT(ctx)
#define ELT_TYPE GLushort
#define ELT_INIT(prim, hw_prim) \
* discrete and there are no intervening state changes. (Somewhat
* duplicates changes to DrawArrays code)
*/
-static void EMIT_PRIM( GLcontext *ctx,
- GLenum prim,
- GLuint hwprim,
- GLuint start,
- GLuint count)
+static void r200EmitPrim( GLcontext *ctx,
+ GLenum prim,
+ GLuint hwprim,
+ GLuint start,
+ GLuint count)
{
r200ContextPtr rmesa = R200_CONTEXT( ctx );
r200TclPrimitive( ctx, prim, hwprim );
count - start );
}
-
+#define EMIT_PRIM(ctx, prim, hwprim, start, count) do { \
+ r200EmitPrim( ctx, prim, hwprim, start, count ); \
+ (void) rmesa; } while (0)
/* Try & join small primitives
*/
#ifdef MESA_BIG_ENDIAN
/* We could do without (most of) this ugliness if dest was always 32 bit word aligned... */
-#define EMIT_ELT(dest, offset, x) do { \
+#define EMIT_ELT(dest, offset, x) do { \
int off = offset + ( ( (GLuint)dest & 0x2 ) >> 1 ); \
GLushort *des = (GLushort *)( (GLuint)dest & ~0x2 ); \
- (des)[ off + 1 - 2 * ( off & 1 ) ] = (GLushort)(x); } while (0)
+ (des)[ off + 1 - 2 * ( off & 1 ) ] = (GLushort)(x); \
+ (void)rmesa; } while (0)
#else
-#define EMIT_ELT(dest, offset, x) (dest)[offset] = (GLushort) (x)
+#define EMIT_ELT(dest, offset, x) do { \
+ (dest)[offset] = (GLushort) (x); \
+ (void)rmesa; } while (0)
#endif
#define EMIT_TWO_ELTS(dest, offset, x, y) *(GLuint *)((dest)+offset) = ((y)<<16)|(x);
if (newprim != rmesa->tcl.hw_primitive ||
!discrete_prim[hw_prim&0xf]) {
+ /* need to disable perspective-correct texturing for point sprites */
+ if ((prim & PRIM_MODE_MASK) == GL_POINTS && ctx->Point.PointSprite) {
+ if (rmesa->hw.set.cmd[SET_RE_CNTL] & R200_PERSPECTIVE_ENABLE) {
+ R200_STATECHANGE( rmesa, set );
+ rmesa->hw.set.cmd[SET_RE_CNTL] &= ~R200_PERSPECTIVE_ENABLE;
+ }
+ }
+ else if (!(rmesa->hw.set.cmd[SET_RE_CNTL] & R200_PERSPECTIVE_ENABLE)) {
+ R200_STATECHANGE( rmesa, set );
+ rmesa->hw.set.cmd[SET_RE_CNTL] |= R200_PERSPECTIVE_ENABLE;
+ }
R200_NEWPRIM( rmesa );
rmesa->tcl.hw_primitive = newprim;
}
r200ContextPtr rmesa = R200_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
+ GLuint inputs = VERT_BIT_POS | VERT_BIT_COLOR0;
GLuint i;
/* TODO: separate this from the swtnl pipeline
if (VB->Count == 0)
return GL_FALSE;
- r200ReleaseArrays( ctx, ~0 /* stage->changed_inputs */ );
- r200EmitArrays( ctx, stage->inputs );
-
- rmesa->tcl.Elts = VB->Elts;
-
- for (i = 0 ; i < VB->PrimitiveCount ; i++)
- {
- GLuint prim = VB->Primitive[i].mode;
- GLuint start = VB->Primitive[i].start;
- GLuint length = VB->Primitive[i].count;
-
- if (!length)
- continue;
-
- if (rmesa->tcl.Elts)
- r200EmitEltPrimitive( ctx, start, start+length, prim );
- else
- r200EmitPrimitive( ctx, start, start+length, prim );
- }
-
- return GL_FALSE; /* finished the pipe */
-}
-
-
-
-static void r200_check_tcl_render( GLcontext *ctx,
- struct tnl_pipeline_stage *stage )
-{
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLuint inputs = VERT_BIT_POS;
- GLuint unit;
-
/* Validate state:
*/
if (rmesa->NewGLState)
r200ValidateState( ctx );
- if (ctx->RenderMode == GL_RENDER) {
- /* Make all this event-driven:
- */
+ if (!ctx->VertexProgram._Enabled) {
+ /* NOTE: inputs != tnl->render_inputs - these are the untransformed
+ * inputs.
+ */
if (ctx->Light.Enabled) {
inputs |= VERT_BIT_NORMAL;
-
- if (1 || ctx->Light.ColorMaterialEnabled) {
- inputs |= VERT_BIT_COLOR0;
- }
}
- else {
- inputs |= VERT_BIT_COLOR0;
-
- if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
- inputs |= VERT_BIT_COLOR1;
- }
+
+ if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
+ inputs |= VERT_BIT_COLOR1;
}
- if ( ctx->Fog.FogCoordinateSource == GL_FOG_COORD ) {
+ if ( (ctx->Fog.FogCoordinateSource == GL_FOG_COORD) && ctx->Fog.Enabled ) {
inputs |= VERT_BIT_FOG;
}
- for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
- if (ctx->Texture.Unit[unit]._ReallyEnabled) {
- if (rmesa->TexGenNeedNormals[unit]) {
+ for (i = 0 ; i < ctx->Const.MaxTextureUnits; i++) {
+ if (ctx->Texture.Unit[i]._ReallyEnabled) {
+ if (rmesa->TexGenNeedNormals[i]) {
inputs |= VERT_BIT_NORMAL;
}
- inputs |= VERT_BIT_TEX(unit);
+ inputs |= VERT_BIT_TEX(i);
}
}
+ }
+ else {
+ /* vtx_tcl_output_vtxfmt_0/1 need to match configuration of "fragment
+ part", since using some vertex interpolator later which is not in
+ out_vtxfmt0/1 will lock up. It seems to be ok to write in vertex
+ prog to a not enabled output however, so just don't mess with it.
+ We only need to change compsel. */
+ GLuint out_compsel = 0;
+ GLuint vp_out = rmesa->curr_vp_hw->mesa_program.Base.OutputsWritten;
+#if 0
+ /* can't handle other inputs, generic attribs etc. currently - should never arrive here */
+ assert ((rmesa->curr_vp_hw->mesa_program.Base.InputsRead &
+ ~(VERT_BIT_POS | VERT_BIT_NORMAL | VERT_BIT_COLOR0 | VERT_BIT_COLOR1 |
+ VERT_BIT_FOG | VERT_BIT_TEX0 | VERT_BIT_TEX1 | VERT_BIT_TEX2 |
+ VERT_BIT_TEX3 | VERT_BIT_TEX4 | VERT_BIT_TEX5)) == 0);
+#endif
+ inputs |= rmesa->curr_vp_hw->mesa_program.Base.InputsRead;
+ assert(vp_out & (1 << VERT_RESULT_HPOS));
+ out_compsel = R200_OUTPUT_XYZW;
+ if (vp_out & (1 << VERT_RESULT_COL0)) {
+ out_compsel |= R200_OUTPUT_COLOR_0;
+ }
+ if (vp_out & (1 << VERT_RESULT_COL1)) {
+ out_compsel |= R200_OUTPUT_COLOR_1;
+ }
+ if (vp_out & (1 << VERT_RESULT_FOGC)) {
+ out_compsel |= R200_OUTPUT_DISCRETE_FOG;
+ }
+ if (vp_out & (1 << VERT_RESULT_PSIZ)) {
+ out_compsel |= R200_OUTPUT_PT_SIZE;
+ }
+ for (i = VERT_RESULT_TEX0; i < VERT_RESULT_TEX6; i++) {
+ if (vp_out & (1 << i)) {
+ out_compsel |= R200_OUTPUT_TEX_0 << (i - VERT_RESULT_TEX0);
+ }
+ }
+ if (rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] != out_compsel) {
+ R200_STATECHANGE( rmesa, vtx );
+ rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] = out_compsel;
+ }
+ }
- stage->inputs = inputs;
- stage->active = 1;
+ /* Do the actual work:
+ */
+ r200ReleaseArrays( ctx, ~0 /* stage->changed_inputs */ );
+ r200EmitArrays( ctx, inputs );
+
+ rmesa->tcl.Elts = VB->Elts;
+
+ for (i = 0 ; i < VB->PrimitiveCount ; i++)
+ {
+ GLuint prim = VB->Primitive[i].mode;
+ GLuint start = VB->Primitive[i].start;
+ GLuint length = VB->Primitive[i].count;
+
+ if (!length)
+ continue;
+
+ if (rmesa->tcl.Elts)
+ r200EmitEltPrimitive( ctx, start, start+length, prim );
+ else
+ r200EmitPrimitive( ctx, start, start+length, prim );
}
- else
- stage->active = 0;
-}
-static void r200_init_tcl_render( GLcontext *ctx,
- struct tnl_pipeline_stage *stage )
-{
- stage->check = r200_check_tcl_render;
- stage->check( ctx, stage );
+ return GL_FALSE; /* finished the pipe */
}
-static void dtr( struct tnl_pipeline_stage *stage )
-{
- (void)stage;
-}
/* Initial state for tcl stage.
const struct tnl_pipeline_stage _r200_tcl_stage =
{
"r200 render",
- (_DD_NEW_SEPARATE_SPECULAR |
- _NEW_LIGHT|
- _NEW_TEXTURE|
- _NEW_FOG|
- _NEW_RENDERMODE), /* re-check (new inputs) */
- 0, /* re-run (always runs) */
- GL_TRUE, /* active */
- 0, 0, /* inputs (set in check_render), outputs */
- 0, 0, /* changed_inputs, private */
- dtr, /* destructor */
- r200_init_tcl_render, /* check - initially set to alloc data */
+ NULL, /* private */
+ NULL,
+ NULL,
+ NULL,
r200_run_tcl_render /* run */
};
* need to put the card into D3D mode to make it work:
*/
R200_STATECHANGE( rmesa, vap );
- rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~R200_VAP_TCL_ENABLE;
+ rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~(R200_VAP_TCL_ENABLE|R200_VAP_PROG_VTX_SHADER_ENABLE);
}
static void transition_to_hwtnl( GLcontext *ctx )
if ( rmesa->dma.flush )
rmesa->dma.flush( rmesa );
- rmesa->dma.flush = 0;
+ rmesa->dma.flush = NULL;
if (rmesa->swtcl.indexed_verts.buf)
r200ReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts,
rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_TCL_ENABLE;
rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~R200_VAP_FORCE_W_TO_ONE;
+ if (ctx->VertexProgram._Enabled) {
+ rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_PROG_VTX_SHADER_ENABLE;
+ }
+
if ( ((rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] & R200_FOG_USE_MASK)
== R200_FOG_USE_SPEC_ALPHA) &&
(ctx->Fog.FogCoordinateSource == GL_FOG_COORD )) {
rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~R200_FOG_USE_MASK;
rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |= R200_FOG_USE_VTX_FOG;
}
-
+
R200_STATECHANGE( rmesa, vte );
rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] &= ~(R200_VTX_XY_FMT|R200_VTX_Z_FMT);
+ rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] |= R200_VTX_W0_FMT;
if (R200_DEBUG & DEBUG_FALLBACKS)
fprintf(stderr, "R200 end tcl fallback\n");
"Texgen unit 4",
"Texgen unit 5",
"User disable",
- "Bitmap as points"
+ "Bitmap as points",
+ "Vertex program"
};