another checkpoint of struct immediate replacement code
This commit is contained in:
@@ -44,31 +44,34 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
/* MultiTexcoord ends up with both of these branches, unfortunately
|
||||
* (it may its own version of the macro after size-tracking is working).
|
||||
* (it may get its own version of the macro after size-tracking is
|
||||
* working).
|
||||
*
|
||||
* Errors (VertexAttribNV when ATTR>15) are handled at a higher level.
|
||||
*/
|
||||
#define ATTRF( ATTR, N, A, B, C, D ) \
|
||||
{ \
|
||||
GET_CURRENT_CONTEXT( ctx ); \
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx); \
|
||||
\
|
||||
if (((ATTR) & 0xf) == 0) { \
|
||||
if ((ATTR) == 0) { \
|
||||
int i; \
|
||||
\
|
||||
if (N>0) tnl->dmaptr[0].f = A; \
|
||||
if (N>1) tnl->dmaptr[1].f = B; \
|
||||
if (N>2) tnl->dmaptr[2].f = C; \
|
||||
if (N>3) tnl->dmaptr[3].f = D; \
|
||||
if (N>0) tnl->vbptr[0].f = A; \
|
||||
if (N>1) tnl->vbptr[1].f = B; \
|
||||
if (N>2) tnl->vbptr[2].f = C; \
|
||||
if (N>3) tnl->vbptr[3].f = D; \
|
||||
\
|
||||
for (i = N; i < tnl->vertex_size; i++) \
|
||||
*tnl->dmaptr[i].i = tnl->vertex[i].i; \
|
||||
*tnl->vbptr[i].i = tnl->vertex[i].i; \
|
||||
\
|
||||
tnl->dmaptr += tnl->vertex_size; \
|
||||
tnl->vbptr += tnl->vertex_size; \
|
||||
\
|
||||
if (--tnl->counter == 0) \
|
||||
tnl->notify(); \
|
||||
} \
|
||||
else { \
|
||||
GLfloat *dest = tnl->attrptr[(ATTR) & 0xf]; \
|
||||
GLfloat *dest = tnl->attrptr[ATTR]; \
|
||||
if (N>0) dest[0] = A; \
|
||||
if (N>1) dest[1] = B; \
|
||||
if (N>2) dest[2] = C; \
|
||||
@@ -266,139 +269,36 @@ static void tnl_TexCoord4fv( const GLfloat *v )
|
||||
}
|
||||
|
||||
|
||||
/* MultiTexcoord
|
||||
*/
|
||||
static void tnl_MultiTexCoord1fARB( GLenum target, GLfloat s )
|
||||
{
|
||||
GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
|
||||
ATTR1F( attr, s );
|
||||
}
|
||||
|
||||
static void tnl_MultiTexCoord1fvARB( GLenum target, const GLfloat *v )
|
||||
{
|
||||
GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
|
||||
ATTR1F( attr, v[0] );
|
||||
}
|
||||
|
||||
static void tnl_MultiTexCoord2fARB( GLenum target, GLfloat s, GLfloat t )
|
||||
{
|
||||
GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
|
||||
ATTR2F( attr, s, t );
|
||||
}
|
||||
|
||||
static void tnl_MultiTexCoord2fvARB( GLenum target, const GLfloat *v )
|
||||
{
|
||||
GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
|
||||
ATTR2F( attr, v[0], v[1] );
|
||||
}
|
||||
|
||||
static void tnl_MultiTexCoord3fARB( GLenum target, GLfloat s, GLfloat t,
|
||||
GLfloat r)
|
||||
{
|
||||
GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
|
||||
ATTR3F( attr, s, t, r );
|
||||
}
|
||||
|
||||
static void tnl_MultiTexCoord3fvARB( GLenum target, const GLfloat *v )
|
||||
{
|
||||
GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
|
||||
ATTR3F( attr, v[0], v[1], v[2] );
|
||||
}
|
||||
|
||||
static void tnl_MultiTexCoord4fARB( GLenum target, GLfloat s, GLfloat t,
|
||||
GLfloat r, GLfloat q )
|
||||
{
|
||||
GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
|
||||
ATTR4F( attr, s, t, r, q );
|
||||
}
|
||||
|
||||
static void tnl_MultiTexCoord4fvARB( GLenum target, const GLfloat *v )
|
||||
{
|
||||
GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
|
||||
ATTR4F( attr, v[0], v[1], v[2], v[3] );
|
||||
}
|
||||
|
||||
|
||||
/* NV_vertex_program:
|
||||
/* Miscellaneous:
|
||||
*
|
||||
* *** Need second dispatch layer above this for size tracking. One
|
||||
* *** dispatch layer handles both VertexAttribute and MultiTexCoord
|
||||
*/
|
||||
static void tnl_VertexAttrib1fNV( GLuint index, GLfloat s )
|
||||
{
|
||||
ATTR1F( index, s );
|
||||
}
|
||||
|
||||
static void tnl_VertexAttrib1fvNV( GLuint index, const GLfloat *v )
|
||||
{
|
||||
ATTR1F( index, v[0] );
|
||||
}
|
||||
|
||||
static void tnl_VertexAttrib2fNV( GLuint index, GLfloat s, GLfloat t )
|
||||
{
|
||||
ATTR2F( index, s, t );
|
||||
}
|
||||
|
||||
static void tnl_VertexAttrib2fvNV( GLuint index, const GLfloat *v )
|
||||
{
|
||||
ATTR2F( index, v[0], v[1] );
|
||||
}
|
||||
|
||||
static void tnl_VertexAttrib3fNV( GLuint index, GLfloat s, GLfloat t,
|
||||
GLfloat r )
|
||||
{
|
||||
ATTR3F( index, s, t, r );
|
||||
}
|
||||
|
||||
static void tnl_VertexAttrib3fvNV( GLuint index, const GLfloat *v )
|
||||
{
|
||||
ATTR3F( index, v[0], v[1], v[2] );
|
||||
}
|
||||
|
||||
static void tnl_VertexAttrib4fNV( GLuint index, GLfloat s, GLfloat t,
|
||||
GLfloat r, GLfloat q )
|
||||
{
|
||||
ATTR4F( index, s, t, r, q );
|
||||
}
|
||||
|
||||
static void tnl_VertexAttrib4fvNV( GLuint index, const GLfloat *v )
|
||||
{
|
||||
ATTR4F( index, v[0], v[1], v[2], v[3] );
|
||||
}
|
||||
|
||||
|
||||
/* Miscellaneous: (These don't alias NV attributes, right?)
|
||||
* These don't alias NV attributes, but still need similar treatment.
|
||||
* Basically these are attributes with numbers greater than 16.
|
||||
*/
|
||||
static void tnl_EdgeFlag( GLboolean flag )
|
||||
{
|
||||
GET_TNL;
|
||||
tnl->edgeflagptr[0] = flag;
|
||||
GLfloat f = flag ? 1 : 0;
|
||||
ATTR1F( VERT_ATTRIB_EDGEFLAG, f);
|
||||
}
|
||||
|
||||
static void tnl_EdgeFlagv( const GLboolean *flag )
|
||||
{
|
||||
GET_TNL;
|
||||
tnl->edgeflagptr[0] = *flag;
|
||||
GLfloat f = flag[0] ? 1 : 0;
|
||||
ATTR1F( VERT_ATTRIB_EDGEFLAG, f);
|
||||
}
|
||||
|
||||
static void tnl_Indexi( GLint idx )
|
||||
{
|
||||
GET_TNL;
|
||||
tnl->indexptr[0] = idx;
|
||||
ATTR1F( VERT_ATTRIB_INDEX, idx );
|
||||
}
|
||||
|
||||
static void tnl_Indexiv( const GLint *idx )
|
||||
{
|
||||
GET_TNL;
|
||||
tnl->indexptr[0] = *idx;
|
||||
ATTR1F( VERT_ATTRIB_INDEX, idx );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Could use dispatch switching to build 'ranges' of eval vertices for
|
||||
* each type, avoiding need for flags. (Make
|
||||
/* Use dispatch switching to build 'ranges' of eval vertices for each
|
||||
* type, avoiding need for flags. (Make
|
||||
* evalcoords/evalpoints/vertices/attr0 mutually exclusive)
|
||||
* --> In which case, may as well use Vertex{12}f{v} here.
|
||||
*/
|
||||
static void _tnl_EvalCoord1f( GLfloat u )
|
||||
{
|
||||
@@ -421,21 +321,267 @@ static void _tnl_EvalCoord2fv( const GLfloat *v )
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Second level dispatch table for MultiTexCoord, Material and
|
||||
* VertexAttribNV.
|
||||
*
|
||||
* Need this because we want to track things like vertex attribute
|
||||
* sizes, presence/otherwise of attribs in recorded vertices, etc, by
|
||||
* manipulating the state of dispatch tables. Need therefore a
|
||||
* dispatch slot for each value of 'index' or 'unit' in VertexAttribNV
|
||||
* and MultiTexCoordARB. Also need a mechnism for keeping this data
|
||||
* consistent with what's coming in via the Vertex/Normal/etc api
|
||||
* above (where aliasing exists with the traditional entrypoints).
|
||||
* Note that MultiTexCoordARB aliases with TexCoord when unit==0.
|
||||
*
|
||||
* Need presence tracking for material components, too, but not size
|
||||
* tracking or help with aliasing. Could move material to seperate
|
||||
* dispatch without the "*4" below, or even do the checks every time.
|
||||
*/
|
||||
struct attr_dispatch_tab {
|
||||
void (*tab[32*4])( void );
|
||||
void (*swapped[32*4])( void );
|
||||
int swapcount;
|
||||
int installed_sizes[32];
|
||||
};
|
||||
|
||||
#define DISPATCH_ATTR1F( ATTR, N, )
|
||||
tnl->vb.attr_dispatch
|
||||
|
||||
/* Result at the back end after second dispatch -- could further
|
||||
* specialize for attr zero -- maybe just in the codegen version.
|
||||
*/
|
||||
static void tnl_Attr1f( GLint attr, GLfloat s )
|
||||
{
|
||||
ATTR1F( attr, s );
|
||||
}
|
||||
|
||||
static void tnl_Attr1fv( GLint attr, const GLfloat *v )
|
||||
{
|
||||
ATTR1F( attr, v[0] );
|
||||
}
|
||||
|
||||
static void tnl_Attr2f( GLint attr, GLfloat s, GLfloat t )
|
||||
{
|
||||
ATTR2F( attr, s, t );
|
||||
}
|
||||
|
||||
static void tnl_Attr2fv( GLint attr, const GLfloat *v )
|
||||
{
|
||||
ATTR2F( attr, v[0], v[1] );
|
||||
}
|
||||
|
||||
static void tnl_Attr3f( GLint attr, GLfloat s, GLfloat t, GLfloat r )
|
||||
{
|
||||
ATTR3F( attr, s, t, r );
|
||||
}
|
||||
|
||||
static void tnl_Attr3fv( GLint attr, const GLfloat *v )
|
||||
{
|
||||
ATTR3F( attr, v[0], v[1], v[2] );
|
||||
}
|
||||
|
||||
static void tnl_Attr4f( GLint attr, GLfloat s, GLfloat t, GLfloat r, GLfloat q )
|
||||
{
|
||||
ATTR4F( attr, s, t, r, q );
|
||||
}
|
||||
|
||||
static void tnl_Attr4fv( GLint attr, const GLfloat *v )
|
||||
{
|
||||
ATTR4F( attr, v[0], v[1], v[2], v[3] );
|
||||
}
|
||||
|
||||
|
||||
/* MultiTexcoord: Send through second level dispatch.
|
||||
*/
|
||||
static void tnl_MultiTexCoord1fARB( GLenum target, GLfloat s )
|
||||
{
|
||||
GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
|
||||
if (attr < MAX_VERT_ATTRS)
|
||||
DISPATCH_ATTR1F( attr, s );
|
||||
}
|
||||
|
||||
static void tnl_MultiTexCoord1fvARB( GLenum target, const GLfloat *v )
|
||||
{
|
||||
GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
|
||||
if (attr < MAX_VERT_ATTRS)
|
||||
DISPATCH_ATTR1F( attr, v[0] );
|
||||
}
|
||||
|
||||
static void tnl_MultiTexCoord2fARB( GLenum target, GLfloat s, GLfloat t )
|
||||
{
|
||||
GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
|
||||
if (attr < MAX_VERT_ATTRS)
|
||||
DISPATCH_ATTR2F( attr, s, t );
|
||||
}
|
||||
|
||||
static void tnl_MultiTexCoord2fvARB( GLenum target, const GLfloat *v )
|
||||
{
|
||||
GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
|
||||
if (attr < MAX_VERT_ATTRS)
|
||||
DISPATCH_ATTR2F( attr, v[0], v[1] );
|
||||
}
|
||||
|
||||
static void tnl_MultiTexCoord3fARB( GLenum target, GLfloat s, GLfloat t,
|
||||
GLfloat r)
|
||||
{
|
||||
GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
|
||||
if (attr < MAX_VERT_ATTRS)
|
||||
DISPATCH_ATTR3F( attr, s, t, r );
|
||||
}
|
||||
|
||||
static void tnl_MultiTexCoord3fvARB( GLenum target, const GLfloat *v )
|
||||
{
|
||||
GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
|
||||
if (attr < MAX_VERT_ATTRS)
|
||||
DISPATCH_ATTR3F( attr, v[0], v[1], v[2] );
|
||||
}
|
||||
|
||||
static void tnl_MultiTexCoord4fARB( GLenum target, GLfloat s, GLfloat t,
|
||||
GLfloat r, GLfloat q )
|
||||
{
|
||||
GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
|
||||
if (attr < MAX_VERT_ATTRS)
|
||||
DISPATCH_ATTR4F( attr, s, t, r, q );
|
||||
}
|
||||
|
||||
static void tnl_MultiTexCoord4fvARB( GLenum target, const GLfloat *v )
|
||||
{
|
||||
GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
|
||||
if (attr < MAX_VERT_ATTRS)
|
||||
DISPATCH_ATTR4F( attr, v[0], v[1], v[2], v[3] );
|
||||
}
|
||||
|
||||
|
||||
/* NV_vertex_program:
|
||||
*
|
||||
* Check for errors & reroute through second dispatch layer to get
|
||||
* size tracking per-attribute.
|
||||
*/
|
||||
static void tnl_VertexAttrib1fNV( GLuint index, GLfloat s )
|
||||
{
|
||||
if (index < MAX_VERT_ATTRS)
|
||||
DISPATCH_ATTR1F( index, s );
|
||||
else
|
||||
DISPATCH_ERROR;
|
||||
}
|
||||
|
||||
static void tnl_VertexAttrib1fvNV( GLuint index, const GLfloat *v )
|
||||
{
|
||||
if (index < MAX_VERT_ATTRS)
|
||||
DISPATCH_ATTR1F( index, v[0] );
|
||||
else
|
||||
DISPATCH_ERROR;
|
||||
}
|
||||
|
||||
static void tnl_VertexAttrib2fNV( GLuint index, GLfloat s, GLfloat t )
|
||||
{
|
||||
if (index < MAX_VERT_ATTRS)
|
||||
DISPATCH_ATTR2F( index, s, t );
|
||||
else
|
||||
DISPATCH_ERROR;
|
||||
}
|
||||
|
||||
static void tnl_VertexAttrib2fvNV( GLuint index, const GLfloat *v )
|
||||
{
|
||||
if (index < MAX_VERT_ATTRS)
|
||||
DISPATCH_ATTR2F( index, v[0], v[1] );
|
||||
else
|
||||
DISPATCH_ERROR;
|
||||
}
|
||||
|
||||
static void tnl_VertexAttrib3fNV( GLuint index, GLfloat s, GLfloat t,
|
||||
GLfloat r )
|
||||
{
|
||||
if (index < MAX_VERT_ATTRS)
|
||||
DISPATCH_ATTR3F( index, s, t, r );
|
||||
else
|
||||
DISPATCH_ERROR;
|
||||
}
|
||||
|
||||
static void tnl_VertexAttrib3fvNV( GLuint index, const GLfloat *v )
|
||||
{
|
||||
if (index < MAX_VERT_ATTRS)
|
||||
DISPATCH_ATTR3F( index, v[0], v[1], v[2] );
|
||||
else
|
||||
DISPATCH_ERROR;
|
||||
}
|
||||
|
||||
static void tnl_VertexAttrib4fNV( GLuint index, GLfloat s, GLfloat t,
|
||||
GLfloat r, GLfloat q )
|
||||
{
|
||||
if (index < MAX_VERT_ATTRS)
|
||||
DISPATCH_ATTR4F( index, s, t, r, q );
|
||||
else
|
||||
DISPATCH_ERROR;
|
||||
}
|
||||
|
||||
static void tnl_VertexAttrib4fvNV( GLuint index, const GLfloat *v )
|
||||
{
|
||||
if (index < MAX_VERT_ATTRS)
|
||||
DISPATCH_ATTR4F( index, v[0], v[1], v[2], v[3] );
|
||||
else
|
||||
DISPATCH_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Materials:
|
||||
* *** Treat as more vertex attributes
|
||||
*
|
||||
* These are treated as per-vertex attributes, at indices above where
|
||||
* the NV_vertex_program leaves off. There are a lot of good things
|
||||
* about treating materials this way.
|
||||
*
|
||||
* *** Need a dispatch step (like VertexAttribute GLint attr, and MultiTexCoord)
|
||||
* *** to expand vertex size, etc. Use the same second level dispatch
|
||||
* *** (keyed by attr number) as above.
|
||||
*/
|
||||
#define MAT( ATTR, face, params ) \
|
||||
do { \
|
||||
if (face != GL_BACK) \
|
||||
DISPATCH_ATTRF( ATTR, N, params ); \
|
||||
if (face != GL_FRONT) \
|
||||
DISPATCH_ATTRF( ATTR+7, N, params ); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* NOTE: Have to remove/dealwith colormaterial crossovers, probably
|
||||
* later on - in the meantime just store everything.
|
||||
*/
|
||||
static void _tnl_Materialfv( GLenum face, GLenum pname,
|
||||
const GLfloat *params )
|
||||
{
|
||||
if (MESA_VERBOSE & DEBUG_VFMT)
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
if (tnl->prim[0] != GL_POLYGON+1) {
|
||||
VFMT_FALLBACK( __FUNCTION__ );
|
||||
glMaterialfv( face, pname, params );
|
||||
switch (pname) {
|
||||
case GL_EMISSION:
|
||||
MAT( VERT_ATTRIB_FRONT_EMMISSION, 4, face, params );
|
||||
break;
|
||||
case GL_AMBIENT:
|
||||
MAT( VERT_ATTRIB_FRONT_AMBIENT, 4, face, params );
|
||||
break;
|
||||
case GL_DIFFUSE:
|
||||
MAT( VERT_ATTRIB_FRONT_DIFFUSE, 4, face, params );
|
||||
break;
|
||||
case GL_SPECULAR:
|
||||
MAT( VERT_ATTRIB_FRONT_SPECULAR, 4, face, params );
|
||||
break;
|
||||
case GL_SHININESS:
|
||||
MAT( VERT_ATTRIB_FRONT_SHININESS, 1, face, params );
|
||||
break;
|
||||
case GL_COLOR_INDEXES:
|
||||
MAT( VERT_ATTRIB_FRONT_EMMISSION, 3, face, params );
|
||||
break;
|
||||
case GL_AMBIENT_AND_DIFFUSE:
|
||||
MAT( VERT_ATTRIB_FRONT_AMBIENT, 4, face, params );
|
||||
MAT( VERT_ATTRIB_FRONT_DIFFUSE, 4, face, params );
|
||||
break;
|
||||
default:
|
||||
_mesa_error( ctx, GL_INVALID_ENUM, where );
|
||||
return;
|
||||
}
|
||||
_mesa_noop_Materialfv( face, pname, params );
|
||||
}
|
||||
|
||||
|
||||
@@ -455,6 +601,13 @@ static struct dynfn *lookup( struct dynfn *l, int key )
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Vertex descriptor
|
||||
*/
|
||||
struct _tnl_vertex_descriptor {
|
||||
GLuint attr_bits[4];
|
||||
};
|
||||
|
||||
|
||||
/* Can't use the loopback template for this:
|
||||
*/
|
||||
#define CHOOSE(FN, FNTYPE, MASK, ACTIVE, ARGS1, ARGS2 ) \
|
||||
@@ -560,28 +713,28 @@ void _tnl_InitVtxfmtChoosers( GLvertexformat *vfmt )
|
||||
vfmt->SecondaryColor3fvEXT = choose_SecondaryColor3fvEXT;
|
||||
vfmt->SecondaryColor3ubEXT = choose_SecondaryColor3ubEXT;
|
||||
vfmt->SecondaryColor3ubvEXT = choose_SecondaryColor3ubvEXT;
|
||||
vfmt->MultiTexCoord1fARB = choose_MultiTexCoord1fARB;
|
||||
vfmt->MultiTexCoord1fvARB = choose_MultiTexCoord1fvARB;
|
||||
vfmt->MultiTexCoord2fARB = choose_MultiTexCoord2fARB;
|
||||
vfmt->MultiTexCoord2fvARB = choose_MultiTexCoord2fvARB;
|
||||
vfmt->MultiTexCoord1fARB = dd_MultiTexCoord1fARB;
|
||||
vfmt->MultiTexCoord1fvARB = dd_MultiTexCoord1fvARB;
|
||||
vfmt->MultiTexCoord2fARB = dd_MultiTexCoord2fARB;
|
||||
vfmt->MultiTexCoord2fvARB = dd_MultiTexCoord2fvARB;
|
||||
vfmt->MultiTexCoord3fARB = dd_MultiTexCoord3fARB;
|
||||
vfmt->MultiTexCoord3fvARB = dd_MultiTexCoord3fvARB;
|
||||
vfmt->MultiTexCoord4fARB = dd_MultiTexCoord4fARB;
|
||||
vfmt->MultiTexCoord4fvARB = dd_MultiTexCoord4fvARB;
|
||||
vfmt->Normal3f = choose_Normal3f;
|
||||
vfmt->Normal3fv = choose_Normal3fv;
|
||||
vfmt->TexCoord1f = choose_TexCoord1f;
|
||||
vfmt->TexCoord1fv = choose_TexCoord1fv;
|
||||
vfmt->TexCoord2f = choose_TexCoord2f;
|
||||
vfmt->TexCoord2fv = choose_TexCoord2fv;
|
||||
vfmt->Vertex2f = choose_Vertex2f;
|
||||
vfmt->Vertex2fv = choose_Vertex2fv;
|
||||
vfmt->Vertex3f = choose_Vertex3f;
|
||||
vfmt->Vertex3fv = choose_Vertex3fv;
|
||||
vfmt->TexCoord3f = choose_TexCoord3f;
|
||||
vfmt->TexCoord3fv = choose_TexCoord3fv;
|
||||
vfmt->TexCoord4f = choose_TexCoord4f;
|
||||
vfmt->TexCoord4fv = choose_TexCoord4fv;
|
||||
vfmt->MultiTexCoord3fARB = choose_MultiTexCoord3fARB;
|
||||
vfmt->MultiTexCoord3fvARB = choose_MultiTexCoord3fvARB;
|
||||
vfmt->MultiTexCoord4fARB = choose_MultiTexCoord4fARB;
|
||||
vfmt->MultiTexCoord4fvARB = choose_MultiTexCoord4fvARB;
|
||||
vfmt->Vertex2f = choose_Vertex2f;
|
||||
vfmt->Vertex2fv = choose_Vertex2fv;
|
||||
vfmt->Vertex3f = choose_Vertex3f;
|
||||
vfmt->Vertex3fv = choose_Vertex3fv;
|
||||
vfmt->Vertex4f = choose_Vertex4f;
|
||||
vfmt->Vertex4fv = choose_Vertex4fv;
|
||||
vfmt->FogCoordfvEXT = choose_FogCoordfvEXT;
|
||||
@@ -594,12 +747,7 @@ void _tnl_InitVtxfmtChoosers( GLvertexformat *vfmt )
|
||||
vfmt->EvalCoord1fv = choose_EvalCoord1fv;
|
||||
vfmt->EvalCoord2f = choose_EvalCoord2f;
|
||||
vfmt->EvalCoord2fv = choose_EvalCoord2fv;
|
||||
vfmt->EvalMesh1 = choose_EvalMesh1;
|
||||
vfmt->EvalMesh2 = choose_EvalMesh2;
|
||||
vfmt->EvalPoint1 = choose_EvalPoint1;
|
||||
vfmt->EvalPoint2 = choose_EvalPoint2;
|
||||
|
||||
vfmt->Materialfv = _tnl_Materialfv;
|
||||
vfmt->Materialfv = dd_Materialfv;
|
||||
}
|
||||
|
||||
|
||||
@@ -611,13 +759,8 @@ static struct dynfn *codegen_noop( struct _vb *vb, int key )
|
||||
|
||||
void _tnl_InitCodegen( struct dfn_generators *gen )
|
||||
{
|
||||
gen->Vertex2f = codegen_noop;
|
||||
gen->Vertex2fv = codegen_noop;
|
||||
gen->Vertex3f = codegen_noop;
|
||||
gen->Vertex3fv = codegen_noop;
|
||||
gen->Vertex4f = codegen_noop;
|
||||
gen->Vertex4fv = codegen_noop;
|
||||
|
||||
/* Generate an attribute or vertex command.
|
||||
*/
|
||||
gen->Attr1f = codegen_noop;
|
||||
gen->Attr1fv = codegen_noop;
|
||||
gen->Attr2f = codegen_noop;
|
||||
@@ -626,18 +769,16 @@ void _tnl_InitCodegen( struct dfn_generators *gen )
|
||||
gen->Attr3fv = codegen_noop;
|
||||
gen->Attr4f = codegen_noop;
|
||||
gen->Attr4fv = codegen_noop;
|
||||
|
||||
/* Index is never zero for these...
|
||||
*/
|
||||
gen->Attr3ub = codegen_noop;
|
||||
gen->Attr3ubv = codegen_noop;
|
||||
gen->Attr4ub = codegen_noop;
|
||||
gen->Attr4ubv = codegen_noop;
|
||||
|
||||
/* Probably need two versions of this, one for the front end
|
||||
* (double dispatch), one for the back end (do the work) -- but
|
||||
* will also need a second level of CHOOSE functions?
|
||||
* -- Generate the dispatch layer using the existing templates somehow.
|
||||
* -- Generate the backend and 2nd level choosers here.
|
||||
* -- No need for a chooser on the top level.
|
||||
* -- Can aliasing help -- ie can NVAttr1f == Attr1f/Vertex2f at this level (index is known)
|
||||
/* As above, but deal with the extra (redundant by now) index
|
||||
* argument to the generated function.
|
||||
*/
|
||||
gen->NVAttr1f = codegen_noop;
|
||||
gen->NVAttr1fv = codegen_noop;
|
||||
@@ -648,14 +789,6 @@ void _tnl_InitCodegen( struct dfn_generators *gen )
|
||||
gen->NVAttr4f = codegen_noop;
|
||||
gen->NVAttr4fv = codegen_noop;
|
||||
|
||||
gen->MTAttr1f = codegen_noop;
|
||||
gen->MTAttr1fv = codegen_noop;
|
||||
gen->MTAttr2f = codegen_noop;
|
||||
gen->MTAttr2fv = codegen_noop;
|
||||
gen->MTAttr3f = codegen_noop;
|
||||
gen->MTAttr3fv = codegen_noop;
|
||||
gen->MTAttr4f = codegen_noop;
|
||||
gen->MTAttr4fv = codegen_noop;
|
||||
|
||||
if (!getenv("MESA_NO_CODEGEN")) {
|
||||
#if defined(USE_X86_ASM)
|
||||
|
@@ -184,10 +184,6 @@ static void copy_vertex( TNLcontext *tnl, GLuint n, GLfloat *dst )
|
||||
}
|
||||
}
|
||||
|
||||
/* NOTE: This actually reads the copied vertices back from uncached
|
||||
* memory. Could also use the counter/notify mechanism to populate
|
||||
* tmp on the fly as vertices are generated.
|
||||
*/
|
||||
static GLuint copy_wrapped_verts( TNLcontext *tnl, GLfloat (*tmp)[15] )
|
||||
{
|
||||
GLuint ovf, i;
|
||||
|
@@ -40,6 +40,61 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#if defined(USE_X86_ASM)
|
||||
|
||||
|
||||
struct dynfn *tnl_makeX86Vertex2f( TNLcontext *tnl, int key )
|
||||
{
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
|
||||
|
||||
switch (tnl->vertex_size) {
|
||||
default: {
|
||||
/* Repz convenient as it's possible to emit code for any size
|
||||
* vertex with little tweaking. Might as well read vertsize
|
||||
* though, and have only one of these.
|
||||
*/
|
||||
static char temp[] = {
|
||||
0x57, /* push %edi */
|
||||
0x56, /* push %esi */
|
||||
0xbe, 0, 0, 0, 0, /* mov $VERTEX+2,%esi */
|
||||
0x8b, 0x3d, 0, 0, 0, 0, /* mov DMAPTR,%edi */
|
||||
0x8b, 0x44, 0x24, 0x0c, /* mov 0x0c(%esp,1),%eax */
|
||||
0x8b, 0x54, 0x24, 0x10, /* mov 0x10(%esp,1),%edx */
|
||||
0x89, 0x07, /* mov %eax,(%edi) */
|
||||
0x89, 0x57, 0x04, /* mov %edx,0x4(%edi) */
|
||||
0x83, 0xc7, 0x08, /* add $0x8,%edi */
|
||||
0xb9, 0, 0, 0, 0, /* mov $VERTSIZE-2,%ecx */
|
||||
0xf3, 0xa5, /* repz movsl %ds:(%esi),%es:(%edi)*/
|
||||
0xa1, 0, 0, 0, 0, /* mov COUNTER,%eax */
|
||||
0x89, 0x3d, 0, 0, 0, 0, /* mov %edi,DMAPTR */
|
||||
0x48, /* dec %eax */
|
||||
0xa3, 0, 0, 0, 0, /* mov %eax,COUNTER */
|
||||
0x5e, /* pop %esi */
|
||||
0x5f, /* pop %edi */
|
||||
0x74, 0x01, /* je +1 */
|
||||
0xc3, /* ret */
|
||||
0xff, 0x25, 0, 0, 0, 0 /* jmp NOTIFY */
|
||||
};
|
||||
|
||||
dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
|
||||
memcpy (dfn->code, temp, sizeof(temp));
|
||||
FIXUP(dfn->code, 3, 0x0, (int)&tnl->vertex[2]);
|
||||
FIXUP(dfn->code, 9, 0x0, (int)&tnl->dmaptr);
|
||||
FIXUP(dfn->code, 37, 0x0, tnl->vertex_size-2);
|
||||
FIXUP(dfn->code, 44, 0x0, (int)&tnl->counter);
|
||||
FIXUP(dfn->code, 50, 0x0, (int)&tnl->dmaptr);
|
||||
FIXUP(dfn->code, 56, 0x0, (int)&tnl->counter);
|
||||
FIXUP(dfn->code, 67, 0x0, (int)&tnl->notify);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
insert_at_head( &tnl->dfn_cache.Vertex3f, dfn );
|
||||
dfn->key = key;
|
||||
return dfn;
|
||||
}
|
||||
|
||||
/* Build specialized versions of the immediate calls on the fly for
|
||||
* the current state. Generic x86 versions.
|
||||
*/
|
||||
@@ -317,7 +372,65 @@ struct dynfn *tnl_makeX86Vertex3fv( TNLcontext *tnl, int key )
|
||||
}
|
||||
|
||||
|
||||
struct dynfn *tnl_makeX86Normal3fv( TNLcontext *tnl, int key )
|
||||
struct dynfn *tnl_makeX86Attr4fv( TNLcontext *tnl, int key )
|
||||
{
|
||||
static char temp[] = {
|
||||
0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
|
||||
0xba, 0, 0, 0, 0, /* mov $DEST,%edx */
|
||||
0x8b, 0x08, /* mov (%eax),%ecx */
|
||||
0x89, 0x0a, /* mov %ecx,(%edx) */
|
||||
0x8b, 0x48, 0x04, /* mov 0x4(%eax),%ecx */
|
||||
0x89, 0x4a, 0x04, /* mov %ecx,0x4(%edx) */
|
||||
0x8b, 0x48, 0x08, /* mov 0x8(%eax),%ecx */
|
||||
0x89, 0x4a, 0x08, /* mov %ecx,0x8(%edx) */
|
||||
0x8b, 0x48, 0x0a, /* mov 0xa(%eax),%ecx */
|
||||
0x89, 0x4a, 0x0a, /* mov %ecx,0xa(%edx) */
|
||||
0xc3, /* ret */
|
||||
};
|
||||
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
|
||||
if (TNL_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
|
||||
|
||||
insert_at_head( &tnl->dfn_cache.Normal3fv, dfn );
|
||||
dfn->key = key;
|
||||
dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
|
||||
memcpy (dfn->code, temp, sizeof(temp));
|
||||
FIXUP(dfn->code, 5, 0x0, (int)tnl->normalptr);
|
||||
return dfn;
|
||||
}
|
||||
|
||||
struct dynfn *tnl_makeX86Attr4f( TNLcontext *tnl, int key )
|
||||
{
|
||||
static char temp[] = {
|
||||
0xba, 0x78, 0x56, 0x34, 0x12, /* mov $DEST,%edx */
|
||||
0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
|
||||
0x89, 0x02, /* mov %eax,(%edx) */
|
||||
0x8b, 0x44, 0x24, 0x08, /* mov 0x8(%esp,1),%eax */
|
||||
0x89, 0x42, 0x04, /* mov %eax,0x4(%edx) */
|
||||
0x8b, 0x44, 0x24, 0x0c, /* mov 0xc(%esp,1),%eax */
|
||||
0x89, 0x42, 0x08, /* mov %eax,0x8(%edx) */
|
||||
0x8b, 0x44, 0x24, 0x10, /* mov 0x10(%esp,1),%eax */
|
||||
0x89, 0x42, 0x0a, /* mov %eax,0xa(%edx) */
|
||||
0xc3, /* ret */
|
||||
};
|
||||
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
|
||||
if (TNL_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
|
||||
|
||||
insert_at_head( &tnl->dfn_cache.Normal3f, dfn );
|
||||
dfn->key = key;
|
||||
dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
|
||||
memcpy (dfn->code, temp, sizeof(temp));
|
||||
FIXUP(dfn->code, 1, 0x12345678, (int)tnl->normalptr);
|
||||
return dfn;
|
||||
}
|
||||
|
||||
|
||||
struct dynfn *tnl_makeX86Attr3fv( TNLcontext *tnl, int key )
|
||||
{
|
||||
static char temp[] = {
|
||||
0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
|
||||
@@ -344,7 +457,7 @@ struct dynfn *tnl_makeX86Normal3fv( TNLcontext *tnl, int key )
|
||||
return dfn;
|
||||
}
|
||||
|
||||
struct dynfn *tnl_makeX86Normal3f( TNLcontext *tnl, int key )
|
||||
struct dynfn *tnl_makeX86Attr3f( TNLcontext *tnl, int key )
|
||||
{
|
||||
static char temp[] = {
|
||||
0xba, 0x78, 0x56, 0x34, 0x12, /* mov $DEST,%edx */
|
||||
@@ -370,7 +483,7 @@ struct dynfn *tnl_makeX86Normal3f( TNLcontext *tnl, int key )
|
||||
return dfn;
|
||||
}
|
||||
|
||||
struct dynfn *tnl_makeX86Color4ubv( TNLcontext *tnl, int key )
|
||||
struct dynfn *tnl_makeX86Attr4ubv( TNLcontext *tnl, int key )
|
||||
{
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
insert_at_head( &tnl->dfn_cache.Color4ubv, dfn );
|
||||
@@ -431,7 +544,7 @@ struct dynfn *tnl_makeX86Color4ubv( TNLcontext *tnl, int key )
|
||||
}
|
||||
}
|
||||
|
||||
struct dynfn *tnl_makeX86Color4ub( TNLcontext *tnl, int key )
|
||||
struct dynfn *tnl_makeX86Attr4ub( TNLcontext *tnl, int key )
|
||||
{
|
||||
if (TNL_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
|
||||
@@ -469,72 +582,8 @@ struct dynfn *tnl_makeX86Color4ub( TNLcontext *tnl, int key )
|
||||
}
|
||||
|
||||
|
||||
struct dynfn *tnl_makeX86Color3fv( TNLcontext *tnl, int key )
|
||||
{
|
||||
if (key & (TNL_CP_VC_FRMT_PKCOLOR|TNL_CP_VC_FRMT_FPALPHA))
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
static char temp[] = {
|
||||
0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
|
||||
0xba, 0, 0, 0, 0, /* mov $DEST,%edx */
|
||||
0x8b, 0x08, /* mov (%eax),%ecx */
|
||||
0x89, 0x0a, /* mov %ecx,(%edx) */
|
||||
0x8b, 0x48, 0x04, /* mov 0x4(%eax),%ecx */
|
||||
0x89, 0x4a, 0x04, /* mov %ecx,0x4(%edx) */
|
||||
0x8b, 0x48, 0x08, /* mov 0x8(%eax),%ecx */
|
||||
0x89, 0x4a, 0x08, /* mov %ecx,0x8(%edx) */
|
||||
0xc3, /* ret */
|
||||
};
|
||||
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
|
||||
if (TNL_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
|
||||
|
||||
insert_at_head( &tnl->dfn_cache.Color3fv, dfn );
|
||||
dfn->key = key;
|
||||
dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
|
||||
memcpy (dfn->code, temp, sizeof(temp));
|
||||
FIXUP(dfn->code, 5, 0x0, (int)tnl->floatcolorptr);
|
||||
return dfn;
|
||||
}
|
||||
}
|
||||
|
||||
struct dynfn *tnl_makeX86Color3f( TNLcontext *tnl, int key )
|
||||
{
|
||||
if (key & (TNL_CP_VC_FRMT_PKCOLOR|TNL_CP_VC_FRMT_FPALPHA))
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
static char temp[] = {
|
||||
0xba, 0x78, 0x56, 0x34, 0x12, /* mov $DEST,%edx */
|
||||
0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
|
||||
0x89, 0x02, /* mov %eax,(%edx) */
|
||||
0x8b, 0x44, 0x24, 0x08, /* mov 0x8(%esp,1),%eax */
|
||||
0x89, 0x42, 0x04, /* mov %eax,0x4(%edx) */
|
||||
0x8b, 0x44, 0x24, 0x0c, /* mov 0xc(%esp,1),%eax */
|
||||
0x89, 0x42, 0x08, /* mov %eax,0x8(%edx) */
|
||||
0xc3, /* ret */
|
||||
};
|
||||
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
|
||||
if (TNL_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
|
||||
|
||||
insert_at_head( &tnl->dfn_cache.Color3f, dfn );
|
||||
dfn->key = key;
|
||||
dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
|
||||
memcpy (dfn->code, temp, sizeof(temp));
|
||||
FIXUP(dfn->code, 1, 0x12345678, (int)tnl->floatcolorptr);
|
||||
return dfn;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct dynfn *tnl_makeX86TexCoord2fv( TNLcontext *tnl, int key )
|
||||
struct dynfn *tnl_makeX86Attr2fv( TNLcontext *tnl, int key )
|
||||
{
|
||||
static char temp[] = {
|
||||
0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
|
||||
@@ -559,7 +608,7 @@ struct dynfn *tnl_makeX86TexCoord2fv( TNLcontext *tnl, int key )
|
||||
return dfn;
|
||||
}
|
||||
|
||||
struct dynfn *tnl_makeX86TexCoord2f( TNLcontext *tnl, int key )
|
||||
struct dynfn *tnl_makeX86Attr2f( TNLcontext *tnl, int key )
|
||||
{
|
||||
static char temp[] = {
|
||||
0xba, 0x78, 0x56, 0x34, 0x12, /* mov $DEST,%edx */
|
||||
@@ -583,31 +632,36 @@ struct dynfn *tnl_makeX86TexCoord2f( TNLcontext *tnl, int key )
|
||||
return dfn;
|
||||
}
|
||||
|
||||
struct dynfn *tnl_makeX86MultiTexCoord2fvARB( TNLcontext *tnl, int key )
|
||||
|
||||
struct dynfn *tnl_makeX86Attr1fv( TNLcontext *tnl, int key )
|
||||
{
|
||||
static char temp[] = {
|
||||
0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
|
||||
0x8b, 0x4c, 0x24, 0x08, /* mov 0x8(%esp,1),%ecx */
|
||||
0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */
|
||||
0x83, 0xe0, 0x01, /* and $0x1,%eax */
|
||||
0x8b, 0x11, /* mov (%ecx),%edx */
|
||||
0xc1, 0xe0, 0x03, /* shl $0x3,%eax */
|
||||
0x8b, 0x49, 0x04, /* mov 0x4(%ecx),%ecx */
|
||||
0x89, 0x90, 0, 0, 0, 0,/* mov %edx,DEST(%eax) */
|
||||
0x89, 0x88, 0, 0, 0, 0,/* mov %ecx,DEST+8(%eax) */
|
||||
0xba, 0x78, 0x56, 0x34, 0x12, /* mov $DEST,%edx */
|
||||
0x8b, 0x08, /* mov (%eax),%ecx */
|
||||
0x89, 0x0a, /* mov %ecx,(%edx) */
|
||||
0xc3, /* ret */
|
||||
};
|
||||
|
||||
static char temp2[] = {
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
|
||||
if (TNL_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
|
||||
|
||||
insert_at_head( &tnl->dfn_cache.TexCoord2fv, dfn );
|
||||
dfn->key = key;
|
||||
dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
|
||||
memcpy (dfn->code, temp, sizeof(temp));
|
||||
FIXUP(dfn->code, 5, 0x12345678, (int)tnl->texcoordptr[0]);
|
||||
return dfn;
|
||||
}
|
||||
|
||||
struct dynfn *tnl_makeX86Attr1f( TNLcontext *tnl, int key )
|
||||
{
|
||||
static char temp[] = {
|
||||
0xba, 0x78, 0x56, 0x34, 0x12, /* mov $DEST,%edx */
|
||||
0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
|
||||
0x8b, 0x4c, 0x24, 0x08, /* mov 0x8(%esp,1),%ecx */
|
||||
0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */
|
||||
0x83, 0xe0, 0x01, /* and $0x1,%eax */
|
||||
0x8b, 0x14, 0x85, 0, 0, 0, 0, /* mov DEST(,%eax,4),%edx */
|
||||
0x8b, 0x01, /* mov (%ecx),%eax */
|
||||
0x89, 0x02, /* mov %eax,(%edx) */
|
||||
0x8b, 0x41, 0x04, /* mov 0x4(%ecx),%eax */
|
||||
0x89, 0x42, 0x04, /* mov %eax,0x4(%edx) */
|
||||
0xc3, /* ret */
|
||||
};
|
||||
|
||||
@@ -616,104 +670,30 @@ struct dynfn *tnl_makeX86MultiTexCoord2fvARB( TNLcontext *tnl, int key )
|
||||
if (TNL_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
|
||||
|
||||
insert_at_head( &tnl->dfn_cache.MultiTexCoord2fvARB, dfn );
|
||||
insert_at_head( &tnl->dfn_cache.TexCoord2f, dfn );
|
||||
dfn->key = key;
|
||||
|
||||
if ((key & (TNL_CP_VC_FRMT_ST0|TNL_CP_VC_FRMT_ST1)) ==
|
||||
(TNL_CP_VC_FRMT_ST0|TNL_CP_VC_FRMT_ST1)) {
|
||||
dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
|
||||
memcpy (dfn->code, temp, sizeof(temp));
|
||||
FIXUP(dfn->code, 26, 0x0, (int)tnl->texcoordptr[0]);
|
||||
FIXUP(dfn->code, 32, 0x0, (int)tnl->texcoordptr[0]+4);
|
||||
} else {
|
||||
dfn->code = ALIGN_MALLOC( sizeof(temp2), 16 );
|
||||
memcpy (dfn->code, temp2, sizeof(temp2));
|
||||
FIXUP(dfn->code, 19, 0x0, (int)tnl->texcoordptr);
|
||||
}
|
||||
FIXUP(dfn->code, 1, 0x12345678, (int)tnl->texcoordptr[0]);
|
||||
return dfn;
|
||||
}
|
||||
|
||||
struct dynfn *tnl_makeX86MultiTexCoord2fARB( TNLcontext *tnl,
|
||||
int key )
|
||||
{
|
||||
static char temp[] = {
|
||||
0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
|
||||
0x8b, 0x54, 0x24, 0x08, /* mov 0x8(%esp,1),%edx */
|
||||
0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */
|
||||
0x8b, 0x4c, 0x24, 0x0c, /* mov 0xc(%esp,1),%ecx */
|
||||
0x83, 0xe0, 0x01, /* and $0x1,%eax */
|
||||
0xc1, 0xe0, 0x03, /* shl $0x3,%eax */
|
||||
0x89, 0x90, 0, 0, 0, 0, /* mov %edx,DEST(%eax) */
|
||||
0x89, 0x88, 0, 0, 0, 0, /* mov %ecx,DEST+8(%eax) */
|
||||
0xc3, /* ret */
|
||||
};
|
||||
|
||||
static char temp2[] = {
|
||||
0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
|
||||
0x8b, 0x54, 0x24, 0x08, /* mov 0x8(%esp,1),%edx */
|
||||
0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */
|
||||
0x8b, 0x4c, 0x24, 0x0c, /* mov 0xc(%esp,1),%ecx */
|
||||
0x83, 0xe0, 0x01, /* and $0x1,%eax */
|
||||
0x8b, 0x04, 0x85, 0, 0, 0, 0, /* mov DEST(,%eax,4),%eax */
|
||||
0x89, 0x10, /* mov %edx,(%eax) */
|
||||
0x89, 0x48, 0x04, /* mov %ecx,0x4(%eax) */
|
||||
0xc3, /* ret */
|
||||
};
|
||||
|
||||
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
|
||||
|
||||
if (TNL_DEBUG & DEBUG_CODEGEN)
|
||||
fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
|
||||
|
||||
insert_at_head( &tnl->dfn_cache.MultiTexCoord2fARB, dfn );
|
||||
dfn->key = key;
|
||||
|
||||
if ((key & (TNL_CP_VC_FRMT_ST0|TNL_CP_VC_FRMT_ST1)) ==
|
||||
(TNL_CP_VC_FRMT_ST0|TNL_CP_VC_FRMT_ST1)) {
|
||||
dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
|
||||
memcpy (dfn->code, temp, sizeof(temp));
|
||||
FIXUP(dfn->code, 25, 0x0, (int)tnl->texcoordptr[0]);
|
||||
FIXUP(dfn->code, 31, 0x0, (int)tnl->texcoordptr[0]+4);
|
||||
}
|
||||
else {
|
||||
/* Note: this might get generated multiple times, even though the
|
||||
* actual emitted code is the same.
|
||||
*/
|
||||
dfn->code = ALIGN_MALLOC( sizeof(temp2), 16 );
|
||||
memcpy (dfn->code, temp2, sizeof(temp2));
|
||||
FIXUP(dfn->code, 23, 0x0, (int)tnl->texcoordptr);
|
||||
}
|
||||
return dfn;
|
||||
}
|
||||
|
||||
|
||||
void _tnl_InitX86Codegen( struct dfn_generators *gen )
|
||||
{
|
||||
gen->Attr1f = tnl_makeX86Attr1f;
|
||||
gen->Attr1fv = tnl_makeX86Attr1fv;
|
||||
gen->Attr2f = tnl_makeX86Attr2f;
|
||||
gen->Attr2fv = tnl_makeX86Attr2fv;
|
||||
gen->Attr3f = tnl_makeX86Attr3f;
|
||||
gen->Attr3fv = tnl_makeX86Attr3fv;
|
||||
gen->Attr4f = tnl_makeX86Attr4f;
|
||||
gen->Attr4fv = tnl_makeX86Attr4fv;
|
||||
gen->Attr4ub = tnl_makeX86Attr4ub;
|
||||
gen->Attr4ubv = tnl_makeX86Attr4ubv;
|
||||
gen->Vertex3f = tnl_makeX86Vertex3f;
|
||||
gen->Vertex3fv = tnl_makeX86Vertex3fv;
|
||||
gen->Color4ub = tnl_makeX86Color4ub; /* PKCOLOR only */
|
||||
gen->Color4ubv = tnl_makeX86Color4ubv; /* PKCOLOR only */
|
||||
gen->Normal3f = tnl_makeX86Normal3f;
|
||||
gen->Normal3fv = tnl_makeX86Normal3fv;
|
||||
gen->TexCoord2f = tnl_makeX86TexCoord2f;
|
||||
gen->TexCoord2fv = tnl_makeX86TexCoord2fv;
|
||||
gen->MultiTexCoord2fARB = tnl_makeX86MultiTexCoord2fARB;
|
||||
gen->MultiTexCoord2fvARB = tnl_makeX86MultiTexCoord2fvARB;
|
||||
gen->Color3f = tnl_makeX86Color3f;
|
||||
gen->Color3fv = tnl_makeX86Color3fv;
|
||||
|
||||
/* Not done:
|
||||
*/
|
||||
/* gen->Vertex2f = tnl_makeX86Vertex2f; */
|
||||
/* gen->Vertex2fv = tnl_makeX86Vertex2fv; */
|
||||
/* gen->Color3ub = tnl_makeX86Color3ub; */
|
||||
/* gen->Color3ubv = tnl_makeX86Color3ubv; */
|
||||
/* gen->Color4f = tnl_makeX86Color4f; */
|
||||
/* gen->Color4fv = tnl_makeX86Color4fv; */
|
||||
/* gen->TexCoord1f = tnl_makeX86TexCoord1f; */
|
||||
/* gen->TexCoord1fv = tnl_makeX86TexCoord1fv; */
|
||||
/* gen->MultiTexCoord1fARB = tnl_makeX86MultiTexCoord1fARB; */
|
||||
/* gen->MultiTexCoord1fvARB = tnl_makeX86MultiTexCoord1fvARB; */
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user