count_func( "SecondaryColor3ubv", &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT );
count_func( "Normal3f", &rmesa->vb.dfn_cache.Normal3f );
count_func( "Normal3fv", &rmesa->vb.dfn_cache.Normal3fv );
+ count_func( "TexCoord3f", &rmesa->vb.dfn_cache.TexCoord3f );
+ count_func( "TexCoord3fv", &rmesa->vb.dfn_cache.TexCoord3fv );
count_func( "TexCoord2f", &rmesa->vb.dfn_cache.TexCoord2f );
count_func( "TexCoord2fv", &rmesa->vb.dfn_cache.TexCoord2fv );
count_func( "TexCoord1f", &rmesa->vb.dfn_cache.TexCoord1f );
count_func( "TexCoord1fv", &rmesa->vb.dfn_cache.TexCoord1fv );
+ count_func( "MultiTexCoord3fARB", &rmesa->vb.dfn_cache.MultiTexCoord3fARB );
+ count_func( "MultiTexCoord3fvARB", &rmesa->vb.dfn_cache.MultiTexCoord3fvARB );
count_func( "MultiTexCoord2fARB", &rmesa->vb.dfn_cache.MultiTexCoord2fARB );
count_func( "MultiTexCoord2fvARB", &rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
count_func( "MultiTexCoord1fARB", &rmesa->vb.dfn_cache.MultiTexCoord1fARB );
void r200_copy_to_current( GLcontext *ctx )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
+ unsigned i;
if (R200_DEBUG & DEBUG_VFMT)
fprintf(stderr, "%s\n", __FUNCTION__);
ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2] = UBYTE_TO_FLOAT( rmesa->vb.specptr->blue );
}
- if (rmesa->vb.vtxfmt_1 & (7 << R200_VTX_TEX0_COMP_CNT_SHIFT)) {
- ctx->Current.Attrib[VERT_ATTRIB_TEX0][0] = rmesa->vb.texcoordptr[0][0];
- ctx->Current.Attrib[VERT_ATTRIB_TEX0][1] = rmesa->vb.texcoordptr[0][1];
- ctx->Current.Attrib[VERT_ATTRIB_TEX0][2] = 0.0F;
- ctx->Current.Attrib[VERT_ATTRIB_TEX0][3] = 1.0F;
- }
+ for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) {
+ const unsigned count = VTX_TEXn_COUNT( rmesa->vb.vtxfmt_1, i );
+ GLfloat * const src = rmesa->vb.texcoordptr[i];
+
+ if ( count != 0 ) {
+ switch( count ) {
+ case 3:
+ ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][1] = src[1];
+ ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][2] = src[2];
+ break;
+ case 2:
+ ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][1] = src[1];
+ ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][2] = 0.0F;
+ break;
+ case 1:
+ ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][1] = 0.0F;
+ ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][2] = 0.0F;
+ break;
+ }
- if (rmesa->vb.vtxfmt_1 & (7 << R200_VTX_TEX1_COMP_CNT_SHIFT)) {
- ctx->Current.Attrib[VERT_ATTRIB_TEX1][0] = rmesa->vb.texcoordptr[1][0];
- ctx->Current.Attrib[VERT_ATTRIB_TEX1][1] = rmesa->vb.texcoordptr[1][1];
- ctx->Current.Attrib[VERT_ATTRIB_TEX1][2] = 0.0F;
- ctx->Current.Attrib[VERT_ATTRIB_TEX1][3] = 1.0F;
+ ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][0] = src[0];
+ ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][3] = 1.0F;
+ }
}
ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT;
* memory. Could also use the counter/notify mechanism to populate
* tmp on the fly as vertices are generated.
*/
-static GLuint copy_dma_verts( r200ContextPtr rmesa, GLfloat (*tmp)[15] )
+static GLuint copy_dma_verts( r200ContextPtr rmesa, GLfloat (*tmp)[R200_MAX_VERTEX_SIZE] )
{
GLuint ovf, i;
GLuint nr = (rmesa->vb.initial_counter - rmesa->vb.counter) -
}
+/**
+ * \todo
+ * An interesting optimization of this function would be to have 3 element
+ * table with the dispatch offsets of the TexCoord?fv functions, use count
+ * to look-up the table, and a specialized version of GL_CALL that used the
+ * offset number instead of the name.
+ */
+static void dispatch_texcoord( GLuint count, GLfloat * f )
+{
+ switch( count ) {
+ case 3:
+ GL_CALL(TexCoord3fv)( f );
+ break;
+ case 2:
+ GL_CALL(TexCoord2fv)( f );
+ break;
+ case 1:
+ GL_CALL(TexCoord1fv)( f );
+ break;
+ default:
+ assert( count == 0 );
+ break;
+ }
+}
+
+static void dispatch_multitexcoord( GLuint count, GLuint unit, GLfloat * f )
+{
+ switch( count ) {
+ case 3:
+ GL_CALL(MultiTexCoord3fvARB)( GL_TEXTURE0+unit, f );
+ break;
+ case 2:
+ GL_CALL(MultiTexCoord2fvARB)( GL_TEXTURE0+unit, f );
+ break;
+ case 1:
+ GL_CALL(MultiTexCoord1fvARB)( GL_TEXTURE0+unit, f );
+ break;
+ default:
+ assert( count == 0 );
+ break;
+ }
+}
+
static void VFMT_FALLBACK( const char *caller )
{
GET_CURRENT_CONTEXT(ctx);
r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLfloat tmp[3][15];
+ GLfloat tmp[3][R200_MAX_VERTEX_SIZE];
GLuint i, prim;
GLuint ind0 = rmesa->vb.vtxfmt_0;
GLuint ind1 = rmesa->vb.vtxfmt_1;
GLuint nrverts;
GLfloat alpha = 1.0;
+ GLuint count;
+ GLuint unit;
if (R200_DEBUG & (DEBUG_FALLBACKS|DEBUG_VFMT))
fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
assert(rmesa->dma.flush == 0);
rmesa->vb.fell_back = GL_TRUE;
rmesa->vb.installed = GL_FALSE;
- glBegin( prim );
-
+ GL_CALL(Begin)( prim );
+
if (rmesa->vb.installed_color_3f_sz == 4)
alpha = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3];
*/
for (i = 0 ; i < nrverts; i++) {
GLuint offset = 3;
+
if (ind0 & R200_VTX_N0) {
- glNormal3fv( &tmp[i][offset] );
+ GL_CALL(Normal3fv)( &tmp[i][offset] );
offset += 3;
}
if (VTX_COLOR(ind0, 0) == R200_VTX_PK_RGBA) {
- glColor4ubv( (GLubyte *)&tmp[i][offset] );
+ GL_CALL(Color4ubv)( (GLubyte *)&tmp[i][offset] );
offset++;
}
else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGBA) {
- glColor4fv( &tmp[i][offset] );
+ GL_CALL(Color4fv)( &tmp[i][offset] );
offset+=4;
}
else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGB) {
- glColor3fv( &tmp[i][offset] );
+ GL_CALL(Color3fv)( &tmp[i][offset] );
offset+=3;
}
if (VTX_COLOR(ind0, 1) == R200_VTX_PK_RGBA) {
- _glapi_Dispatch->SecondaryColor3ubvEXT( (GLubyte *)&tmp[i][offset] );
+ GL_CALL(SecondaryColor3ubvEXT)( (GLubyte *)&tmp[i][offset] );
offset++;
}
- if (ind1 & (7 << R200_VTX_TEX0_COMP_CNT_SHIFT)) {
- glTexCoord2fv( &tmp[i][offset] );
- offset += 2;
+ for ( unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++ ) {
+ count = VTX_TEXn_COUNT( ind1, unit );
+ dispatch_multitexcoord( count, unit, &tmp[i][offset] );
+ offset += count;
}
- if (ind1 & (7 << R200_VTX_TEX1_COMP_CNT_SHIFT)) {
- glMultiTexCoord2fvARB( GL_TEXTURE1_ARB, &tmp[i][offset] );
- offset += 2;
- }
-
- glVertex3fv( &tmp[i][0] );
+ GL_CALL(Vertex3fv)( &tmp[i][0] );
}
/* Replay current vertex
*/
if (ind0 & R200_VTX_N0)
- glNormal3fv( rmesa->vb.normalptr );
-
- if (VTX_COLOR(ind0, 0) == R200_VTX_PK_RGBA)
- glColor4ub( rmesa->vb.colorptr->red,
- rmesa->vb.colorptr->green,
- rmesa->vb.colorptr->blue,
- rmesa->vb.colorptr->alpha );
- else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGBA)
- glColor4fv( rmesa->vb.floatcolorptr );
+ GL_CALL(Normal3fv)( rmesa->vb.normalptr );
+
+ if (VTX_COLOR(ind0, 0) == R200_VTX_PK_RGBA) {
+ GL_CALL(Color4ub)( rmesa->vb.colorptr->red,
+ rmesa->vb.colorptr->green,
+ rmesa->vb.colorptr->blue,
+ rmesa->vb.colorptr->alpha );
+ }
+ else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGBA) {
+ GL_CALL(Color4fv)( rmesa->vb.floatcolorptr );
+ }
else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGB) {
- if (rmesa->vb.installed_color_3f_sz == 4 && alpha != 1.0)
- glColor4f( rmesa->vb.floatcolorptr[0],
- rmesa->vb.floatcolorptr[1],
- rmesa->vb.floatcolorptr[2],
- alpha );
- else
- glColor3fv( rmesa->vb.floatcolorptr );
+ if (rmesa->vb.installed_color_3f_sz == 4 && alpha != 1.0) {
+ GL_CALL(Color4f)( rmesa->vb.floatcolorptr[0],
+ rmesa->vb.floatcolorptr[1],
+ rmesa->vb.floatcolorptr[2],
+ alpha );
+ }
+ else {
+ GL_CALL(Color3fv)( rmesa->vb.floatcolorptr );
+ }
}
if (VTX_COLOR(ind0, 1) == R200_VTX_PK_RGBA)
- _glapi_Dispatch->SecondaryColor3ubEXT( rmesa->vb.specptr->red,
- rmesa->vb.specptr->green,
- rmesa->vb.specptr->blue );
+ GL_CALL(SecondaryColor3ubEXT)( rmesa->vb.specptr->red,
+ rmesa->vb.specptr->green,
+ rmesa->vb.specptr->blue );
- if (ind1 & (7 << R200_VTX_TEX0_COMP_CNT_SHIFT))
- glTexCoord2fv( rmesa->vb.texcoordptr[0] );
-
- if (ind1 & (7 << R200_VTX_TEX1_COMP_CNT_SHIFT))
- glMultiTexCoord2fvARB( GL_TEXTURE1_ARB, rmesa->vb.texcoordptr[1] );
+ for ( unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++ ) {
+ count = VTX_TEXn_COUNT( ind1, unit );
+ dispatch_multitexcoord( count, unit, rmesa->vb.texcoordptr[unit] );
+ }
}
{
GET_CURRENT_CONTEXT(ctx);
r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLfloat tmp[3][15];
+ GLfloat tmp[3][R200_MAX_VERTEX_SIZE];
GLuint i, nrverts;
if (R200_DEBUG & (DEBUG_VFMT|DEBUG_PRIMS))
}
-
+/**
+ * Determines the hardware vertex format based on the current state vector.
+ *
+ * \returns
+ * If the hardware TCL unit is capable of handling the current state vector,
+ * \c GL_TRUE is returned. Otherwise, \c GL_FALSE is returned.
+ *
+ * \todo
+ * Make this color format selection data driven. If we receive only ubytes,
+ * send color as ubytes. Also check if converting (with free checking for
+ * overflow) is cheaper than sending floats directly.
+ *
+ * \todo
+ * When intializing texture coordinates, it might be faster to just copy the
+ * entire \c VERT_ATTRIB_TEX0 vector into the vertex buffer. It may mean that
+ * some of the data (i.e., the last texture coordinate components) get copied
+ * over, but that still may be faster than the conditional branching. If
+ * nothing else, the code will be smaller and easier to follow.
+ */
static GLboolean check_vtx_fmt( GLcontext *ctx )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
GLuint ind0 = R200_VTX_Z0;
GLuint ind1 = 0;
+ GLuint i;
+ GLuint count[R200_MAX_TEXTURE_UNITS];
+ GLuint re_cntl;
+
if (rmesa->TclFallback || rmesa->vb.fell_back || ctx->CompileFlag)
return GL_FALSE;
if (ctx->Light.Enabled) {
ind0 |= R200_VTX_N0;
- /* TODO: make this data driven: If we receive only ubytes, send
- * color as ubytes. Also check if converting (with free
- * checking for overflow) is cheaper than sending floats
- * directly.
- */
if (ctx->Light.ColorMaterialEnabled)
ind0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT;
else
}
}
- if (ctx->Texture.Unit[0]._ReallyEnabled) {
- if (ctx->Texture.Unit[0].TexGenEnabled) {
- if (rmesa->TexGenNeedNormals[0]) {
- ind0 |= R200_VTX_N0;
+ re_cntl = rmesa->hw.set.cmd[SET_RE_CNTL] & ~(R200_VTX_STQ0_D3D |
+ R200_VTX_STQ1_D3D |
+ R200_VTX_STQ2_D3D |
+ R200_VTX_STQ3_D3D |
+ R200_VTX_STQ4_D3D |
+ R200_VTX_STQ5_D3D );
+ for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) {
+ count[i] = 0;
+
+ if (ctx->Texture.Unit[i]._ReallyEnabled) {
+ if (ctx->Texture.Unit[i].TexGenEnabled) {
+ if (rmesa->TexGenNeedNormals[i]) {
+ ind0 |= R200_VTX_N0;
+ }
}
- } else {
- if (ctx->Current.Attrib[VERT_ATTRIB_TEX0][2] != 0.0F ||
- ctx->Current.Attrib[VERT_ATTRIB_TEX0][3] != 1.0) {
- if (R200_DEBUG & (DEBUG_VFMT|DEBUG_FALLBACKS))
- fprintf(stderr, "%s: rq0\n", __FUNCTION__);
- return GL_FALSE;
+ else {
+ switch( ctx->Texture.Unit[i]._ReallyEnabled ) {
+ case TEXTURE_CUBE_BIT:
+ re_cntl |= R200_VTX_STQ0_D3D << (2 * i);
+ /* FALLTHROUGH */
+ case TEXTURE_3D_BIT:
+ count[i] = 3;
+ break;
+ case TEXTURE_2D_BIT:
+ case TEXTURE_RECT_BIT:
+ count[i] = 2;
+ break;
+ case TEXTURE_1D_BIT:
+ count[i] = 1;
+ break;
+ }
+
+ ind1 |= count[i] << (3 * i);
}
- ind1 |= 2 << R200_VTX_TEX0_COMP_CNT_SHIFT;
}
}
- if (ctx->Texture.Unit[1]._ReallyEnabled) {
- if (ctx->Texture.Unit[1].TexGenEnabled) {
- if (rmesa->TexGenNeedNormals[1]) {
- ind0 |= R200_VTX_N0;
- }
- } else {
- if (ctx->Current.Attrib[VERT_ATTRIB_TEX1][2] != 0.0F ||
- ctx->Current.Attrib[VERT_ATTRIB_TEX1][3] != 1.0) {
- if (R200_DEBUG & (DEBUG_VFMT|DEBUG_FALLBACKS))
- fprintf(stderr, "%s: rq1\n", __FUNCTION__);
- return GL_FALSE;
- }
- ind1 |= 2 << R200_VTX_TEX1_COMP_CNT_SHIFT;
- }
+ if ( re_cntl != rmesa->hw.set.cmd[SET_RE_CNTL] ) {
+ R200_STATECHANGE( rmesa, set );
+ rmesa->hw.set.cmd[SET_RE_CNTL] = re_cntl;
}
if (R200_DEBUG & (DEBUG_VFMT|DEBUG_STATE))
rmesa->vb.floatspecptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR1];
rmesa->vb.texcoordptr[0] = ctx->Current.Attrib[VERT_ATTRIB_TEX0];
rmesa->vb.texcoordptr[1] = ctx->Current.Attrib[VERT_ATTRIB_TEX1];
+ rmesa->vb.texcoordptr[2] = ctx->Current.Attrib[VERT_ATTRIB_TEX2];
+ rmesa->vb.texcoordptr[3] = ctx->Current.Attrib[VERT_ATTRIB_TEX3];
+ rmesa->vb.texcoordptr[4] = ctx->Current.Attrib[VERT_ATTRIB_TEX4];
+ rmesa->vb.texcoordptr[5] = ctx->Current.Attrib[VERT_ATTRIB_TEX5];
+ rmesa->vb.texcoordptr[6] = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; /* dummy */
+ rmesa->vb.texcoordptr[7] = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; /* dummy */
/* Run through and initialize the vertex components in the order
* the hardware understands:
}
- if (ind1 & (7 << R200_VTX_TEX0_COMP_CNT_SHIFT)) {
- rmesa->vb.texcoordptr[0] = &rmesa->vb.vertex[rmesa->vb.vertex_size].f;
- rmesa->vb.vertex_size += 2;
- rmesa->vb.texcoordptr[0][0] = ctx->Current.Attrib[VERT_ATTRIB_TEX0][0];
- rmesa->vb.texcoordptr[0][1] = ctx->Current.Attrib[VERT_ATTRIB_TEX0][1];
- }
+ for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) {
+ if ( count[i] != 0 ) {
+ float * const attr = ctx->Current.Attrib[VERT_ATTRIB_TEX0+i];
+ unsigned j;
- if (ind1 & (7 << R200_VTX_TEX1_COMP_CNT_SHIFT)) {
- rmesa->vb.texcoordptr[1] = &rmesa->vb.vertex[rmesa->vb.vertex_size].f;
- rmesa->vb.vertex_size += 2;
- rmesa->vb.texcoordptr[1][0] = ctx->Current.Attrib[VERT_ATTRIB_TEX1][0];
- rmesa->vb.texcoordptr[1][1] = ctx->Current.Attrib[VERT_ATTRIB_TEX1][1];
- }
+ rmesa->vb.texcoordptr[i] = &rmesa->vb.vertex[rmesa->vb.vertex_size].f;
+
+ for ( j = 0 ; j < count[i] ; j++ ) {
+ rmesa->vb.texcoordptr[i][j] = attr[j];
+ }
+
+ rmesa->vb.vertex_size += count[i];
+ }
+ }
if (rmesa->vb.installed_vertex_format != rmesa->vb.vtxfmt_0) {
if (R200_DEBUG & DEBUG_VFMT)
if (R200_DEBUG & DEBUG_VFMT)
fprintf(stderr, "%s -- success\n", __FUNCTION__);
-
+
return GL_TRUE;
}
if (rmesa->vb.prim[0] != GL_POLYGON+1) {
VFMT_FALLBACK( __FUNCTION__ );
- glMaterialfv( face, pname, params );
+ GL_CALL(Materialfv)( face, pname, params );
return;
}
_mesa_noop_Materialfv( face, pname, params );
r200VtxfmtValidate( ctx );
if (!rmesa->vb.installed) {
- glBegin( mode );
+ GL_CALL(Begin)( mode );
return;
}
_mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" );
return;
}
-
+
note_last_prim( rmesa, PRIM_END );
rmesa->vb.prim[0] = GL_POLYGON+1;
}
vfmt->EvalMesh2 = r200_fallback_EvalMesh2;
vfmt->EvalPoint1 = r200_fallback_EvalPoint1;
vfmt->EvalPoint2 = r200_fallback_EvalPoint2;
- vfmt->TexCoord3f = r200_fallback_TexCoord3f;
- vfmt->TexCoord3fv = r200_fallback_TexCoord3fv;
vfmt->TexCoord4f = r200_fallback_TexCoord4f;
vfmt->TexCoord4fv = r200_fallback_TexCoord4fv;
- vfmt->MultiTexCoord3fARB = r200_fallback_MultiTexCoord3fARB;
- vfmt->MultiTexCoord3fvARB = r200_fallback_MultiTexCoord3fvARB;
vfmt->MultiTexCoord4fARB = r200_fallback_MultiTexCoord4fARB;
vfmt->MultiTexCoord4fvARB = r200_fallback_MultiTexCoord4fvARB;
vfmt->Vertex4f = r200_fallback_Vertex4f;
make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT );
make_empty_list( &rmesa->vb.dfn_cache.Normal3f );
make_empty_list( &rmesa->vb.dfn_cache.Normal3fv );
+ make_empty_list( &rmesa->vb.dfn_cache.TexCoord3f );
+ make_empty_list( &rmesa->vb.dfn_cache.TexCoord3fv );
make_empty_list( &rmesa->vb.dfn_cache.TexCoord2f );
make_empty_list( &rmesa->vb.dfn_cache.TexCoord2fv );
make_empty_list( &rmesa->vb.dfn_cache.TexCoord1f );
make_empty_list( &rmesa->vb.dfn_cache.TexCoord1fv );
+ make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord3fARB );
+ make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord3fvARB );
make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord2fARB );
make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord1fARB );
free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3fvEXT );
free_funcs( &rmesa->vb.dfn_cache.Normal3f );
free_funcs( &rmesa->vb.dfn_cache.Normal3fv );
+ free_funcs( &rmesa->vb.dfn_cache.TexCoord3f );
+ free_funcs( &rmesa->vb.dfn_cache.TexCoord3fv );
free_funcs( &rmesa->vb.dfn_cache.TexCoord2f );
free_funcs( &rmesa->vb.dfn_cache.TexCoord2fv );
free_funcs( &rmesa->vb.dfn_cache.TexCoord1f );
free_funcs( &rmesa->vb.dfn_cache.TexCoord1fv );
+ free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord3fARB );
+ free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord3fvARB );
free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord2fARB );
free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord1fARB );