summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/r200/r200_state_init.c
diff options
context:
space:
mode:
authorRoland Scheidegger <rscheidegger@gmx.ch>2006-06-02 22:47:31 +0000
committerRoland Scheidegger <rscheidegger@gmx.ch>2006-06-02 22:47:31 +0000
commit98c791b543c4ba86b8bb54488bd872b33b10b1aa (patch)
tree1ca4402bf5f877c35f78fcc79f3f628d918de487 /src/mesa/drivers/dri/r200/r200_state_init.c
parent65ced474536bad23ee204170918f56eb8f8c4bf9 (diff)
implement arb_vertex_program in hw for r200. Code contains still some hacks, generic attribs cause a fallback, but otherwise it seems to work quite well. Passes all glean vertProg1 tests with the exception of the degnerated LIT case (which is a hw limitation), as well as runs the r200 render path of doom3/quake4 (1.1 patch needed for quake4). The code is heavily borrowed from the r300 driver as vertex programs encoding is almost identical. arb_vertex_program is not yet announced by default and still needs to be enabled via driconf.
Diffstat (limited to 'src/mesa/drivers/dri/r200/r200_state_init.c')
-rw-r--r--src/mesa/drivers/dri/r200/r200_state_init.c64
1 files changed, 60 insertions, 4 deletions
diff --git a/src/mesa/drivers/dri/r200/r200_state_init.c b/src/mesa/drivers/dri/r200/r200_state_init.c
index 14616b09f4..266beb61b6 100644
--- a/src/mesa/drivers/dri/r200/r200_state_init.c
+++ b/src/mesa/drivers/dri/r200/r200_state_init.c
@@ -93,6 +93,19 @@ static int cmdvec( int offset, int stride, int count )
return h.i;
}
+/* warning: the count here is divided by 4 compared to other cmds
+ (so it doesn't exceed the char size)! */
+static int cmdveclinear( int offset, int count )
+{
+ drm_radeon_cmd_header_t h;
+ h.i = 0;
+ h.veclinear.cmd_type = RADEON_CMD_VECLINEAR;
+ h.veclinear.addr_lo = offset & 0xff;
+ h.veclinear.addr_hi = (offset & 0xff00) >> 8;
+ h.veclinear.count = count;
+ return h.i;
+}
+
static int cmdscl( int offset, int stride, int count )
{
drm_radeon_cmd_header_t h;
@@ -129,9 +142,24 @@ static GLboolean check_##NM( GLcontext *ctx, int idx ) \
{ \
r200ContextPtr rmesa = R200_CONTEXT(ctx); \
(void) idx; \
+ return !rmesa->TclFallback && !ctx->VertexProgram._Enabled && (FLAG); \
+}
+
+#define TCL_OR_VP_CHECK( NM, FLAG ) \
+static GLboolean check_##NM( GLcontext *ctx, int idx ) \
+{ \
+ r200ContextPtr rmesa = R200_CONTEXT(ctx); \
+ (void) idx; \
return !rmesa->TclFallback && (FLAG); \
}
+#define VP_CHECK( NM, FLAG ) \
+static GLboolean check_##NM( GLcontext *ctx, int idx ) \
+{ \
+ r200ContextPtr rmesa = R200_CONTEXT(ctx); \
+ (void) idx; \
+ return !rmesa->TclFallback && ctx->VertexProgram._Enabled && (FLAG); \
+}
CHECK( always, GL_TRUE )
@@ -150,7 +178,11 @@ TCL_CHECK( tcl, GL_TRUE )
TCL_CHECK( tcl_tex, rmesa->state.texture.unit[idx].unitneeded )
TCL_CHECK( tcl_lighting, ctx->Light.Enabled )
TCL_CHECK( tcl_light, ctx->Light.Enabled && ctx->Light.Light[idx].Enabled )
-TCL_CHECK( tcl_ucp, (ctx->Transform.ClipPlanesEnabled & (1 << idx)) )
+TCL_OR_VP_CHECK( tcl_ucp, (ctx->Transform.ClipPlanesEnabled & (1 << idx)) )
+TCL_OR_VP_CHECK( tcl_or_vp, GL_TRUE )
+VP_CHECK( tcl_vp, GL_TRUE )
+VP_CHECK( tcl_vp_size, ctx->VertexProgram.Current->Base.NumNativeInstructions > 64 )
+VP_CHECK( tcl_vpp_size, ctx->VertexProgram.Current->Base.NumNativeParameters > 96 )
/* Initialize the context's hardware state.
@@ -307,13 +339,27 @@ void r200InitState( r200ContextPtr rmesa )
ALLOC_STATE( cube[4], never, CUBE_STATE_SIZE, "CUBE/tex-4", 4 );
ALLOC_STATE( cube[5], never, CUBE_STATE_SIZE, "CUBE/tex-5", 5 );
}
-
- ALLOC_STATE( tcl, tcl, TCL_STATE_SIZE, "TCL/tcl", 0 );
+ if (rmesa->r200Screen->drmSupportsVertexProgram) {
+ ALLOC_STATE( pvs, tcl_vp, PVS_STATE_SIZE, "PVS/pvscntl", 0 );
+ ALLOC_STATE( vpi[0], tcl_vp, VPI_STATE_SIZE, "VP/vertexprog-0", 0 );
+ ALLOC_STATE( vpi[1], tcl_vp_size, VPI_STATE_SIZE, "VP/vertexprog-1", 1 );
+ ALLOC_STATE( vpp[0], tcl_vp, VPP_STATE_SIZE, "VPP/vertexparam-0", 0 );
+ ALLOC_STATE( vpp[1], tcl_vpp_size, VPP_STATE_SIZE, "VPP/vertexparam-1", 1 );
+ }
+ else {
+ ALLOC_STATE( pvs, never, PVS_STATE_SIZE, "PVS/pvscntl", 0 );
+ ALLOC_STATE( vpi[0], never, VPI_STATE_SIZE, "VP/vertexprog-0", 0 );
+ ALLOC_STATE( vpi[1], never, VPI_STATE_SIZE, "VP/vertexprog-1", 1 );
+ ALLOC_STATE( vpp[0], never, VPP_STATE_SIZE, "VPP/vertexparam-0", 0 );
+ ALLOC_STATE( vpp[1], never, VPP_STATE_SIZE, "VPP/vertexparam-1", 1 );
+ }
+ /* FIXME: this atom has two commands, we need only one (ucp_vert_blend) for vp */
+ ALLOC_STATE( tcl, tcl_or_vp, TCL_STATE_SIZE, "TCL/tcl", 0 );
ALLOC_STATE( msl, tcl, MSL_STATE_SIZE, "MSL/matrix-select", 0 );
ALLOC_STATE( tcg, tcl, TCG_STATE_SIZE, "TCG/texcoordgen", 0 );
ALLOC_STATE( mtl[0], tcl_lighting, MTL_STATE_SIZE, "MTL0/material0", 0 );
ALLOC_STATE( mtl[1], tcl_lighting, MTL_STATE_SIZE, "MTL1/material1", 1 );
- ALLOC_STATE( grd, tcl, GRD_STATE_SIZE, "GRD/guard-band", 0 );
+ ALLOC_STATE( grd, tcl_or_vp, GRD_STATE_SIZE, "GRD/guard-band", 0 );
ALLOC_STATE( fog, fog, FOG_STATE_SIZE, "FOG/fog", 0 );
ALLOC_STATE( glt, tcl_lighting, GLT_STATE_SIZE, "GLT/light-global", 0 );
ALLOC_STATE( eye, tcl_lighting, EYE_STATE_SIZE, "EYE/eye-vector", 0 );
@@ -411,6 +457,7 @@ void r200InitState( r200ContextPtr rmesa )
}
rmesa->hw.afs[0].cmd[AFS_CMD_0] = cmdpkt(R200_EMIT_PP_AFS_0);
rmesa->hw.afs[1].cmd[AFS_CMD_0] = cmdpkt(R200_EMIT_PP_AFS_1);
+ rmesa->hw.pvs.cmd[PVS_CMD_0] = cmdpkt(R200_EMIT_VAP_PVS_CNTL);
rmesa->hw.cube[0].cmd[CUBE_CMD_0] = cmdpkt(R200_EMIT_PP_CUBIC_FACES_0);
rmesa->hw.cube[0].cmd[CUBE_CMD_1] = cmdpkt(R200_EMIT_PP_CUBIC_OFFSETS_0);
rmesa->hw.cube[1].cmd[CUBE_CMD_0] = cmdpkt(R200_EMIT_PP_CUBIC_FACES_1);
@@ -450,6 +497,15 @@ void r200InitState( r200ContextPtr rmesa )
rmesa->hw.mtl[1].cmd[MTL_CMD_1] =
cmdscl2( R200_SS_MAT_1_SHININESS, 1, 1 );
+ rmesa->hw.vpi[0].cmd[VPI_CMD_0] =
+ cmdveclinear( R200_PVS_PROG0, 64 );
+ rmesa->hw.vpi[1].cmd[VPI_CMD_0] =
+ cmdveclinear( R200_PVS_PROG1, 64 );
+ rmesa->hw.vpp[0].cmd[VPP_CMD_0] =
+ cmdveclinear( R200_PVS_PARAM0, 96 );
+ rmesa->hw.vpp[1].cmd[VPP_CMD_0] =
+ cmdveclinear( R200_PVS_PARAM1, 96 );
+
rmesa->hw.grd.cmd[GRD_CMD_0] =
cmdscl( R200_SS_VERT_GUARD_CLIP_ADJ_ADDR, 1, 4 );
rmesa->hw.fog.cmd[FOG_CMD_0] =