Changes for new vbo-building module.

- Removed all the old immediate, array and display list code.
	- Remove references to the old array_cache module.
	- Added a _tnl_draw_prims() entrypoint.
	- Added a simplified data import facility for converting
non-floating point data as required.

Checkpoint commit - trivial/tri works.
This commit is contained in:
Keith Whitwell 2006-10-29 09:48:15 +00:00
parent fd12b37dba
commit b1f176039a
21 changed files with 77 additions and 6892 deletions

View file

@ -1,12 +1,7 @@
# List of ource files in this directory used for X.org xserver build
MESA_TNL_SOURCES = \
t_array_api.c \
t_array_import.c \
t_context.c \
t_pipeline.c \
t_save_api.c \
t_save_loopback.c \
t_save_playback.c \
t_vb_arbprogram.c \
t_vb_arbprogram_sse.c \
t_vb_arbshader.c \
@ -23,9 +18,4 @@ t_vb_vertex.c \
t_vertex.c \
t_vertex_generic.c \
t_vertex_sse.c \
t_vp_build.c \
t_vtx_api.c \
t_vtx_eval.c \
t_vtx_exec.c \
t_vtx_generic.c \
t_vtx_x86.c
t_vp_build.c

View file

@ -1,432 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 6.5.2
*
* Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* \file t_array_api.c
* \brief Vertex array API functions (glDrawArrays, etc)
* \author Keith Whitwell
*/
#include "glheader.h"
#include "api_validate.h"
#include "context.h"
#include "imports.h"
#include "macros.h"
#include "mtypes.h"
#include "state.h"
#include "array_cache/acache.h"
#include "t_array_api.h"
#include "t_array_import.h"
#include "t_save_api.h"
#include "t_context.h"
#include "t_pipeline.h"
#include "dispatch.h"
static void fallback_drawarrays( GLcontext *ctx, GLenum mode, GLint start,
GLsizei count )
{
GLint i;
assert(!ctx->CompileFlag);
assert(ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END);
CALL_Begin(GET_DISPATCH(), (mode));
for (i = 0; i < count; i++)
CALL_ArrayElement(GET_DISPATCH(), ( start + i ));
CALL_End(GET_DISPATCH(), ());
}
static void fallback_drawelements( GLcontext *ctx, GLenum mode, GLsizei count,
const GLuint *indices)
{
GLint i;
assert(!ctx->CompileFlag);
assert(ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END);
/* Here, indices will already reflect the buffer object if active */
CALL_Begin(GET_DISPATCH(), (mode));
for (i = 0 ; i < count ; i++) {
CALL_ArrayElement(GET_DISPATCH(), ( indices[i] ));
}
CALL_End(GET_DISPATCH(), ());
}
/* Note this function no longer takes a 'start' value, the range is
* assumed to start at zero. The old trick of subtracting 'start'
* from each index won't work if the indices are not in writeable
* memory.
*/
static void _tnl_draw_range_elements( GLcontext *ctx, GLenum mode,
GLuint max_index,
GLsizei index_count, GLuint *indices )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct tnl_prim prim;
FLUSH_CURRENT( ctx, 0 );
_tnl_vb_bind_arrays( ctx, 0, max_index );
tnl->vb.Primitive = &prim;
tnl->vb.Primitive[0].mode = mode | PRIM_BEGIN | PRIM_END;
tnl->vb.Primitive[0].start = 0;
tnl->vb.Primitive[0].count = index_count;
tnl->vb.PrimitiveCount = 1;
tnl->vb.Elts = (GLuint *)indices;
tnl->Driver.RunPipeline( ctx );
}
/**
* Called via the GL API dispatcher.
*/
void GLAPIENTRY
_tnl_DrawArrays(GLenum mode, GLint start, GLsizei count)
{
GET_CURRENT_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
/* It's tempting to get rid of this threshold value because we take
* very different paths if 'count' is less than or greater than 'thresh'.
* I've found/fixed at least one bug which only occured for particular
* array sizes. Also, several conformance tests use very short arrays
* which means the long-array path doesn't get tested. -Brian
*/
GLuint thresh = (ctx->Driver.NeedFlush & FLUSH_STORED_VERTICES) ? 30 : 10;
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(NULL, "_tnl_DrawArrays %d %d\n", start, count);
/* Check arguments, etc.
*/
if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))
return;
assert(!ctx->CompileFlag);
if (!ctx->Array.LockCount && (GLuint) count < thresh) {
/* Small primitives: attempt to share a vb (at the expense of
* using the immediate interface).
*/
fallback_drawarrays( ctx, mode, start, count );
}
else if (start >= (GLint) ctx->Array.LockFirst &&
start + count <= (GLint)(ctx->Array.LockFirst + ctx->Array.LockCount)) {
struct tnl_prim prim;
/* Locked primitives which can fit in a single vertex buffer:
*/
FLUSH_CURRENT( ctx, 0 );
/* Locked drawarrays. Reuse any previously transformed data.
*/
_tnl_vb_bind_arrays( ctx, ctx->Array.LockFirst,
ctx->Array.LockFirst + ctx->Array.LockCount );
tnl->vb.Primitive = &prim;
tnl->vb.Primitive[0].mode = mode | PRIM_BEGIN | PRIM_END;
tnl->vb.Primitive[0].start = start;
tnl->vb.Primitive[0].count = count;
tnl->vb.PrimitiveCount = 1;
tnl->Driver.RunPipeline( ctx );
}
else {
int bufsz = 256; /* Use a small buffer for cache goodness */
int j, nr;
int minimum, modulo, skip;
/* Large primitives requiring decomposition to multiple vertex
* buffers:
*/
switch (mode) {
case GL_POINTS:
minimum = 0;
modulo = 1;
skip = 0;
break;
case GL_LINES:
minimum = 1;
modulo = 2;
skip = 1;
break;
case GL_LINE_STRIP:
minimum = 1;
modulo = 1;
skip = 0;
break;
case GL_TRIANGLES:
minimum = 2;
modulo = 3;
skip = 2;
break;
case GL_TRIANGLE_STRIP:
minimum = 2;
modulo = 1;
skip = 0;
break;
case GL_QUADS:
minimum = 3;
modulo = 4;
skip = 3;
break;
case GL_QUAD_STRIP:
minimum = 3;
modulo = 2;
skip = 0;
break;
case GL_LINE_LOOP:
case GL_TRIANGLE_FAN:
case GL_POLYGON:
default:
/* Primitives requiring a copied vertex (fan-like primitives)
* must use the slow path if they cannot fit in a single
* vertex buffer.
*/
if (count <= (GLint) ctx->Const.MaxArrayLockSize) {
bufsz = ctx->Const.MaxArrayLockSize;
minimum = 0;
modulo = 1;
skip = 0;
}
else {
fallback_drawarrays( ctx, mode, start, count );
return;
}
}
FLUSH_CURRENT( ctx, 0 );
bufsz -= bufsz % modulo;
bufsz -= minimum;
count += start;
for (j = start + minimum ; j < count ; j += nr + skip ) {
struct tnl_prim prim;
nr = MIN2( bufsz, count - j );
/* XXX is the last parameter a count or index into the array??? */
_tnl_vb_bind_arrays( ctx, j - minimum, j + nr );
tnl->vb.Primitive = &prim;
tnl->vb.Primitive[0].mode = mode;
if (j == start + minimum)
tnl->vb.Primitive[0].mode |= PRIM_BEGIN;
if (j + nr + skip >= count)
tnl->vb.Primitive[0].mode |= PRIM_END;
tnl->vb.Primitive[0].start = 0;
tnl->vb.Primitive[0].count = nr + minimum;
tnl->vb.PrimitiveCount = 1;
tnl->Driver.RunPipeline( ctx );
}
}
}
/**
* Called via the GL API dispatcher.
*/
void GLAPIENTRY
_tnl_DrawRangeElements(GLenum mode,
GLuint start, GLuint end,
GLsizei count, GLenum type, const GLvoid *indices)
{
GET_CURRENT_CONTEXT(ctx);
GLuint *ui_indices;
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(NULL, "_tnl_DrawRangeElements %d %d %d\n", start, end, count);
if (ctx->Array.ElementArrayBufferObj->Name) {
/* use indices in the buffer object */
if (!ctx->Array.ElementArrayBufferObj->Data) {
_mesa_warning(ctx,
"DrawRangeElements with empty vertex elements buffer!");
return;
}
/* actual address is the sum of pointers */
indices = (const GLvoid *)
ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Data,
(const GLubyte *) indices);
}
/* Check arguments, etc.
*/
if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count,
type, indices ))
return;
ui_indices = (GLuint *)_ac_import_elements( ctx, GL_UNSIGNED_INT,
count, type, indices );
#ifdef DEBUG
/* check that array indices really fall inside [start, end] range */
{
GLuint i;
for (i = 0; i < count; i++) {
if (ui_indices[i] < start || ui_indices[i] > end) {
_mesa_warning(ctx, "Invalid array index in "
"glDrawRangeElements(index=%u)", ui_indices[i]);
}
}
}
#endif
assert(!ctx->CompileFlag);
if (ctx->Array.LockCount) {
/* Are the arrays already locked? If so we currently have to look
* at the whole locked range.
*/
if (start == 0 && ctx->Array.LockFirst == 0 &&
end < (ctx->Array.LockFirst + ctx->Array.LockCount))
_tnl_draw_range_elements( ctx, mode,
ctx->Array.LockCount,
count, ui_indices );
else {
fallback_drawelements( ctx, mode, count, ui_indices );
}
}
else if (start == 0 && end < ctx->Const.MaxArrayLockSize) {
/* The arrays aren't locked but we can still fit them inside a
* single vertexbuffer.
*/
_tnl_draw_range_elements( ctx, mode, end + 1, count, ui_indices );
}
else {
/* Range is too big to optimize:
*/
fallback_drawelements( ctx, mode, count, ui_indices );
}
}
/**
* Called via the GL API dispatcher.
*/
void GLAPIENTRY
_tnl_DrawElements(GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices)
{
GET_CURRENT_CONTEXT(ctx);
GLuint *ui_indices;
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(NULL, "_tnl_DrawElements %d\n", count);
/* Check arguments, etc. */
if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))
return;
if (ctx->Array.ElementArrayBufferObj->Name) {
/* actual address is the sum of pointers */
indices = (const GLvoid *)
ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Data,
(const GLubyte *) indices);
}
ui_indices = (GLuint *)_ac_import_elements( ctx, GL_UNSIGNED_INT,
count, type, indices );
assert(!ctx->CompileFlag);
if (ctx->Array.LockCount) {
if (ctx->Array.LockFirst == 0)
_tnl_draw_range_elements( ctx, mode,
ctx->Array.LockCount,
count, ui_indices );
else
fallback_drawelements( ctx, mode, count, ui_indices );
}
else {
/* Scan the index list and see if we can use the locked path anyway.
*/
GLuint max_elt = 0;
GLint i;
for (i = 0 ; i < count ; i++)
if (ui_indices[i] > max_elt)
max_elt = ui_indices[i];
if (max_elt < ctx->Const.MaxArrayLockSize && /* can we use it? */
max_elt < (GLuint) count) /* do we want to use it? */
_tnl_draw_range_elements( ctx, mode, max_elt+1, count, ui_indices );
else
fallback_drawelements( ctx, mode, count, ui_indices );
}
}
/**
* Initialize context's vertex array fields. Called during T 'n L context
* creation.
*/
void _tnl_array_init( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct tnl_vertex_arrays *tmp = &tnl->array_inputs;
GLvertexformat *vfmt = &(TNL_CONTEXT(ctx)->exec_vtxfmt);
GLuint i;
vfmt->DrawArrays = _tnl_DrawArrays;
vfmt->DrawElements = _tnl_DrawElements;
vfmt->DrawRangeElements = _tnl_DrawRangeElements;
/* Setup vector pointers that will be used to bind arrays to VB's.
*/
_mesa_vector4f_init( &tmp->Obj, 0, NULL);
_mesa_vector4f_init( &tmp->Normal, 0, NULL);
_mesa_vector4f_init( &tmp->FogCoord, 0, NULL);
_mesa_vector4f_init( &tmp->Index, 0, NULL);
for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++)
_mesa_vector4f_init( &tmp->TexCoord[i], 0, NULL);
}
/**
* Destroy the context's vertex array stuff.
* Called during T 'n L context destruction.
*/
void _tnl_array_destroy( GLcontext *ctx )
{
(void) ctx;
}

View file

@ -1,46 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _T_VARRAY_H
#define _T_VARRAY_H
#include "mtypes.h"
#include "t_context.h"
extern void GLAPIENTRY _tnl_DrawArrays(GLenum mode, GLint first, GLsizei count);
extern void GLAPIENTRY _tnl_DrawElements(GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices);
extern void GLAPIENTRY _tnl_DrawRangeElements(GLenum mode, GLuint start,
GLuint end, GLsizei count, GLenum type,
const GLvoid *indices);
extern void _tnl_array_init( GLcontext *ctx );
extern void _tnl_array_destroy( GLcontext *ctx );
#endif

View file

@ -1,376 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 6.5.1
*
* Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*/
#include "glheader.h"
#include "context.h"
#include "macros.h"
#include "imports.h"
#include "state.h"
#include "mtypes.h"
#include "array_cache/acache.h"
#include "t_array_import.h"
#include "t_context.h"
/**
* XXX writable and stride are always false in these functions...
*/
static void _tnl_import_vertex( GLcontext *ctx,
GLboolean writable,
GLboolean stride )
{
struct gl_client_array *tmp;
GLboolean is_writable = 0;
struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
const GLubyte *data;
tmp = _ac_import_vertex(ctx,
GL_FLOAT,
stride ? 4*sizeof(GLfloat) : 0,
0,
writable,
&is_writable);
data = tmp->Ptr;
inputs->Obj.data = (GLfloat (*)[4]) data;
inputs->Obj.start = (GLfloat *) data;
inputs->Obj.stride = tmp->StrideB;
inputs->Obj.size = tmp->Size;
}
static void _tnl_import_normal( GLcontext *ctx,
GLboolean writable,
GLboolean stride )
{
struct gl_client_array *tmp;
GLboolean is_writable = 0;
struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
const GLubyte *data;
tmp = _ac_import_normal(ctx, GL_FLOAT,
stride ? 3*sizeof(GLfloat) : 0, writable,
&is_writable);
data = tmp->Ptr;
inputs->Normal.data = (GLfloat (*)[4]) data;
inputs->Normal.start = (GLfloat *) data;
inputs->Normal.stride = tmp->StrideB;
inputs->Normal.size = 3;
}
static void _tnl_import_color( GLcontext *ctx,
GLboolean writable,
GLboolean stride )
{
struct gl_client_array *tmp;
GLboolean is_writable = 0;
struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
const GLubyte *data;
tmp = _ac_import_color(ctx,
GL_FLOAT,
stride ? 4*sizeof(GLfloat) : 0,
4,
writable,
&is_writable);
data = tmp->Ptr;
inputs->Color.data = (GLfloat (*)[4]) data;
inputs->Color.start = (GLfloat *) data;
inputs->Color.stride = tmp->StrideB;
inputs->Color.size = tmp->Size;
}
static void _tnl_import_secondarycolor( GLcontext *ctx,
GLboolean writable,
GLboolean stride )
{
struct gl_client_array *tmp;
GLboolean is_writable = 0;
struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
const GLubyte *data;
tmp = _ac_import_secondarycolor(ctx,
GL_FLOAT,
stride ? 4*sizeof(GLfloat) : 0,
4,
writable,
&is_writable);
data = tmp->Ptr;
inputs->SecondaryColor.data = (GLfloat (*)[4]) data;
inputs->SecondaryColor.start = (GLfloat *) data;
inputs->SecondaryColor.stride = tmp->StrideB;
inputs->SecondaryColor.size = tmp->Size;
}
static void _tnl_import_fogcoord( GLcontext *ctx,
GLboolean writable,
GLboolean stride )
{
struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
struct gl_client_array *tmp;
GLboolean is_writable = 0;
const GLubyte *data;
tmp = _ac_import_fogcoord(ctx, GL_FLOAT,
stride ? sizeof(GLfloat) : 0, writable,
&is_writable);
data = tmp->Ptr;
inputs->FogCoord.data = (GLfloat (*)[4]) data;
inputs->FogCoord.start = (GLfloat *) data;
inputs->FogCoord.stride = tmp->StrideB;
}
static void _tnl_import_index( GLcontext *ctx,
GLboolean writable,
GLboolean stride )
{
struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
struct gl_client_array *tmp;
GLboolean is_writable = 0;
const GLubyte *data;
tmp = _ac_import_index(ctx, GL_FLOAT,
stride ? sizeof(GLfloat) : 0, writable,
&is_writable);
data = tmp->Ptr;
inputs->Index.data = (GLfloat (*)[4]) data;
inputs->Index.start = (GLfloat *) data;
inputs->Index.stride = tmp->StrideB;
}
static void _tnl_import_texcoord( GLcontext *ctx,
GLuint unit,
GLboolean writable,
GLboolean stride )
{
struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
struct gl_client_array *tmp;
GLboolean is_writable = 0;
const GLubyte *data;
tmp = _ac_import_texcoord(ctx, unit, GL_FLOAT,
stride ? 4 * sizeof(GLfloat) : 0,
0,
writable,
&is_writable);
data = tmp->Ptr;
inputs->TexCoord[unit].data = (GLfloat (*)[4]) data;
inputs->TexCoord[unit].start = (GLfloat *) data;
inputs->TexCoord[unit].stride = tmp->StrideB;
inputs->TexCoord[unit].size = tmp->Size;
}
static void _tnl_import_edgeflag( GLcontext *ctx,
GLboolean writable,
GLboolean stride )
{
struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
struct gl_client_array *tmp;
GLboolean is_writable = 0;
const GLubyte *data;
(void) writable; (void) stride;
tmp = _ac_import_edgeflag(ctx, GL_UNSIGNED_BYTE,
sizeof(GLubyte),
0,
&is_writable);
data = tmp->Ptr;
inputs->EdgeFlag = (GLubyte *) data;
}
static void _tnl_import_attrib( GLcontext *ctx,
GLuint index,
GLboolean writable,
GLboolean stride )
{
struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
struct gl_client_array *tmp;
GLboolean is_writable = 0;
const GLubyte *data;
ASSERT(index < MAX_VERTEX_PROGRAM_ATTRIBS);
tmp = _ac_import_attrib(ctx, index, GL_FLOAT,
stride ? 4 * sizeof(GLfloat) : 0,
4, /* want GLfloat[4] */
writable,
&is_writable);
data = tmp->Ptr;
inputs->Attribs[index].data = (GLfloat (*)[4]) data;
inputs->Attribs[index].start = (GLfloat *) data;
inputs->Attribs[index].stride = tmp->StrideB;
inputs->Attribs[index].size = tmp->Size;
}
static void _tnl_constant_attrib( TNLcontext *tnl,
struct tnl_vertex_arrays *tmp,
GLuint i )
{
tmp->Attribs[i].count = 1;
tmp->Attribs[i].data = (GLfloat (*)[4]) tnl->vtx.current[i];
tmp->Attribs[i].start = tnl->vtx.current[i];
tmp->Attribs[i].size = 4;
tmp->Attribs[i].stride = 0;
tnl->vb.AttribPtr[i] = &tmp->Attribs[i];
}
void _tnl_vb_bind_arrays( GLcontext *ctx, GLint start, GLint end)
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
struct tnl_vertex_arrays *tmp = &tnl->array_inputs;
const struct gl_vertex_program *program
= ctx->VertexProgram._Enabled ? ctx->VertexProgram.Current : NULL;
GLuint i, index;
VB->Count = end - start;
VB->Elts = NULL;
_ac_import_range( ctx, start, end );
/* Note that the generic attribute arrays are treated differently
* depending on whether an NV or ARB vertex program is enabled
* (corresponding to aliasing vs. non-aliasing behaviour).
* Generic array 0 always aliases vertex position.
*/
for (index = 0; index < VERT_ATTRIB_MAX; index++) {
if (ctx->VertexProgram._Enabled
&& (program->IsNVProgram || index == 0)
&& ctx->Array.ArrayObj->VertexAttrib[index].Enabled) {
/* Use generic attribute array. If an NV vertex program is active,
* the generic arrays override the conventional attributes.
* Otherwise, if an ARB vertex program is active, we'll import the
* generic attributes without aliasing over conventional attribs
* (see below).
*/
_tnl_import_attrib( ctx, index, GL_FALSE, GL_TRUE );
VB->AttribPtr[index] = &tmp->Attribs[index];
}
/* use conventional arrays... */
else if (index == VERT_ATTRIB_POS) {
_tnl_import_vertex( ctx, GL_FALSE, GL_FALSE );
tmp->Obj.count = VB->Count;
VB->AttribPtr[_TNL_ATTRIB_POS] = &tmp->Obj;
}
else if (index == VERT_ATTRIB_NORMAL) {
_tnl_import_normal( ctx, GL_FALSE, GL_FALSE );
tmp->Normal.count = VB->Count;
VB->AttribPtr[_TNL_ATTRIB_NORMAL] = &tmp->Normal;
}
else if (index == VERT_ATTRIB_COLOR0) {
_tnl_import_color( ctx, GL_FALSE, GL_FALSE );
tmp->Color.count = VB->Count;
VB->AttribPtr[_TNL_ATTRIB_COLOR0] = &tmp->Color;
}
else if (index == VERT_ATTRIB_COLOR1) {
_tnl_import_secondarycolor( ctx, GL_FALSE, GL_FALSE );
tmp->SecondaryColor.count = VB->Count;
VB->AttribPtr[_TNL_ATTRIB_COLOR1] = &tmp->SecondaryColor;
}
else if (index == VERT_ATTRIB_FOG) {
_tnl_import_fogcoord( ctx, GL_FALSE, GL_FALSE );
tmp->FogCoord.count = VB->Count;
VB->AttribPtr[_TNL_ATTRIB_FOG] = &tmp->FogCoord;
}
else if (index == VERT_ATTRIB_COLOR_INDEX) {
_tnl_import_index( ctx, GL_FALSE, GL_FALSE );
tmp->Index.count = VB->Count;
VB->AttribPtr[_TNL_ATTRIB_COLOR_INDEX] = &tmp->Index;
}
else if (index >= VERT_ATTRIB_TEX0 && index <= VERT_ATTRIB_TEX7) {
i = index - VERT_ATTRIB_TEX0;
_tnl_import_texcoord( ctx, i, GL_FALSE, GL_FALSE );
tmp->TexCoord[i].count = VB->Count;
VB->AttribPtr[index] = &tmp->TexCoord[i];
}
else if (index >= VERT_ATTRIB_GENERIC1 &&
index <= VERT_ATTRIB_GENERIC15) {
const GLuint arrayIndex = index - VERT_ATTRIB_GENERIC0;
if (program && !program->IsNVProgram &&
ctx->Array.ArrayObj->VertexAttrib[arrayIndex].Enabled) {
/* GL_ARB_vertex_program: bind a generic attribute array */
_tnl_import_attrib(ctx, arrayIndex, GL_FALSE, GL_TRUE);
VB->AttribPtr[index] = &tmp->Attribs[arrayIndex];
}
else {
_tnl_constant_attrib(tnl, tmp, index);
}
}
else {
_tnl_constant_attrib(tnl, tmp, index);
}
assert(VB->AttribPtr[index]);
assert(VB->AttribPtr[index]->size);
}
/* odd-ball vertex attributes */
{
_tnl_import_edgeflag( ctx, GL_TRUE, sizeof(GLboolean) );
VB->EdgeFlag = (GLboolean *) tmp->EdgeFlag;
}
/* These are constant & could be precalculated:
*/
for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
_tnl_constant_attrib(tnl, tmp, i);
}
/* Legacy pointers -- remove one day.
*/
VB->ObjPtr = VB->AttribPtr[_TNL_ATTRIB_POS];
VB->NormalPtr = VB->AttribPtr[_TNL_ATTRIB_NORMAL];
VB->ColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR0];
VB->ColorPtr[1] = NULL;
VB->IndexPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR_INDEX];
VB->IndexPtr[1] = NULL;
VB->SecondaryColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR1];
VB->SecondaryColorPtr[1] = NULL;
VB->FogCoordPtr = VB->AttribPtr[_TNL_ATTRIB_FOG];
for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
VB->TexCoordPtr[i] = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i];
}
}

View file

@ -1,36 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _T_ARRAY_IMPORT_H
#define _T_ARRAY_IMPORT_H
#include "mtypes.h"
#include "t_context.h"
extern void _tnl_vb_bind_arrays( GLcontext *ctx, GLint start, GLint end );
extern void _tnl_array_import_init( GLcontext *ctx );
#endif

View file

@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
* Version: 6.5.2
* Version: 6.5
*
* Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
*
@ -26,38 +26,19 @@
*/
#include "api_arrayelt.h"
#include "glheader.h"
#include "imports.h"
#include "context.h"
#include "macros.h"
#include "mtypes.h"
#include "dlist.h"
#include "light.h"
#include "vtxfmt.h"
#include "tnl.h"
#include "t_array_api.h"
#include "t_context.h"
#include "t_pipeline.h"
#include "t_save_api.h"
#include "t_vp_build.h"
#include "t_vtx_api.h"
static void
install_driver_callbacks( GLcontext *ctx )
{
ctx->Driver.NewList = _tnl_NewList;
ctx->Driver.EndList = _tnl_EndList;
ctx->Driver.FlushVertices = _tnl_FlushVertices;
ctx->Driver.SaveFlushVertices = _tnl_SaveFlushVertices;
ctx->Driver.BeginCallList = _tnl_BeginCallList;
ctx->Driver.EndCallList = _tnl_EndCallList;
}
#include "vbo/vbo_attrib.h"
GLboolean
_tnl_CreateContext( GLcontext *ctx )
@ -72,20 +53,13 @@ _tnl_CreateContext( GLcontext *ctx )
return GL_FALSE;
}
if (_mesa_getenv("MESA_CODEGEN"))
tnl->AllowCodegen = GL_TRUE;
/* Initialize the VB.
*/
tnl->vb.Size = ctx->Const.MaxArrayLockSize + MAX_CLIPPED_VERTICES;
/* Initialize tnl state and tnl->vtxfmt.
/* Initialize tnl state.
*/
_tnl_save_init( ctx );
_tnl_array_init( ctx );
_tnl_vtx_init( ctx );
if (ctx->_MaintainTnlProgram) {
_tnl_ProgramCacheInit( ctx );
_tnl_install_pipeline( ctx, _tnl_vp_pipeline );
@ -93,30 +67,12 @@ _tnl_CreateContext( GLcontext *ctx )
_tnl_install_pipeline( ctx, _tnl_default_pipeline );
}
/* Initialize the arrayelt helper
*/
if (!_ae_create_context( ctx ))
return GL_FALSE;
tnl->NeedNdcCoords = GL_TRUE;
tnl->LoopbackDListCassettes = GL_FALSE;
tnl->CalcDListNormalLengths = GL_TRUE;
tnl->AllowVertexFog = GL_TRUE;
tnl->AllowPixelFog = GL_TRUE;
/* Hook our functions into exec and compile dispatch tables.
*/
_mesa_install_exec_vtxfmt( ctx, &tnl->exec_vtxfmt );
/* Set a few default values in the driver struct.
*/
install_driver_callbacks(ctx);
ctx->Driver.NeedFlush = 0;
ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN;
tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
tnl->Driver.NotifyMaterialChange = _mesa_validate_all_lighting_tables;
@ -130,11 +86,7 @@ _tnl_DestroyContext( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
_tnl_array_destroy( ctx );
_tnl_vtx_destroy( ctx );
_tnl_save_destroy( ctx );
_tnl_destroy_pipeline( ctx );
_ae_destroy_context( ctx );
if (ctx->_MaintainTnlProgram)
_tnl_ProgramCacheDestroy( ctx );
@ -155,10 +107,7 @@ _tnl_InvalidateState( GLcontext *ctx, GLuint new_state )
|| !tnl->AllowPixelFog;
}
_ae_invalidate_state(ctx, new_state);
tnl->pipeline.new_state |= new_state;
tnl->vtx.eval.new_state |= new_state;
/* Calculate tnl->render_inputs:
*/
@ -184,8 +133,7 @@ _tnl_InvalidateState( GLcontext *ctx, GLuint new_state )
if (ctx->Fog.Enabled ||
(ctx->FragmentProgram._Active &&
(ctx->FragmentProgram._Current->FogOption != GL_NONE ||
ctx->FragmentProgram._Current->Base.InputsRead & FRAG_BIT_FOGC)))
ctx->FragmentProgram._Current->FogOption != GL_NONE))
RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_FOG );
if (ctx->Polygon.FrontMode != GL_FILL ||
@ -205,36 +153,21 @@ _tnl_InvalidateState( GLcontext *ctx, GLuint new_state )
void
_tnl_wakeup_exec( GLcontext *ctx )
_tnl_wakeup( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
install_driver_callbacks(ctx);
ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT;
/* Hook our functions into exec and compile dispatch tables.
*/
_mesa_install_exec_vtxfmt( ctx, &tnl->exec_vtxfmt );
/* Assume we haven't been getting state updates either:
*/
_tnl_InvalidateState( ctx, ~0 );
#if 0
if (ctx->Light.ColorMaterialEnabled) {
_mesa_update_color_material( ctx,
ctx->Current.Attrib[VERT_ATTRIB_COLOR0] );
}
#endif
}
void
_tnl_wakeup_save_exec( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
_tnl_wakeup_exec( ctx );
_mesa_install_save_vtxfmt( ctx, &tnl->save_vtxfmt );
}
/**
@ -252,27 +185,6 @@ _tnl_need_projected_coords( GLcontext *ctx, GLboolean mode )
}
}
void
_tnl_need_dlist_loopback( GLcontext *ctx, GLboolean mode )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
tnl->LoopbackDListCassettes = mode;
}
void
_tnl_need_dlist_norm_lengths( GLcontext *ctx, GLboolean mode )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
tnl->CalcDListNormalLengths = mode;
}
void
_tnl_isolate_materials( GLcontext *ctx, GLboolean mode )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
tnl->IsolateMaterials = mode;
}
void
_tnl_allow_vertex_fog( GLcontext *ctx, GLboolean value )
{

View file

@ -43,29 +43,6 @@
* stages to the vertex_buffer TNLcontext::vb, where the vertex data
* is stored. The last stage in the pipeline is the rasterizer.
*
* The initial vertex_buffer data may either come from an ::immediate
* structure or client vertex_arrays or display lists:
*
*
* - The ::immediate structure records all the GL commands issued between
* glBegin and glEnd. \n
* The structure accumulates data, until it is either full or it is
* flushed (usually by a state change). Before starting then the pipeline,
* the collected vertex data in ::immediate has to be pushed into
* TNLcontext::vb.
* This happens in ::_tnl_vb_bind_immediate. The pipeline is then run by
* calling tnl_device_driver::RunPipeline = ::_tnl_run_pipeline, which
* is stored in TNLcontext::Driver. \n
* An ::immediate does (for performance reasons) usually not finish with a
* glEnd, and hence it also does not need to start with a glBegin.
* This means that the last vertices of one ::immediate may need to be
* saved for the next one.
*
*
* - NOT SURE ABOUT THIS: The vertex_arrays structure is used to handle
* glDrawArrays etc. \n
* Here, the data of the vertex_arrays is copied by ::_tnl_vb_bind_arrays
* into TNLcontext::vb, so that the pipeline can be started.
*/
@ -79,6 +56,7 @@
#include "math/m_vector.h"
#include "math/m_xform.h"
#include "vbo/vbo_attrib.h"
#define MAX_PIPELINE_STAGES 30
@ -106,7 +84,7 @@ enum {
_TNL_ATTRIB_COLOR1 = 4,
_TNL_ATTRIB_FOG = 5,
_TNL_ATTRIB_COLOR_INDEX = 6,
_TNL_ATTRIB_SEVEN = 7,
_TNL_ATTRIB_EDGEFLAG = 7,
_TNL_ATTRIB_TEX0 = 8,
_TNL_ATTRIB_TEX1 = 9,
_TNL_ATTRIB_TEX2 = 10,
@ -115,7 +93,8 @@ enum {
_TNL_ATTRIB_TEX5 = 13,
_TNL_ATTRIB_TEX6 = 14,
_TNL_ATTRIB_TEX7 = 15,
_TNL_ATTRIB_GENERIC0 = 16,
_TNL_ATTRIB_GENERIC0 = 16, /* doesn't really exist! */
_TNL_ATTRIB_GENERIC1 = 17,
_TNL_ATTRIB_GENERIC2 = 18,
_TNL_ATTRIB_GENERIC3 = 19,
@ -131,21 +110,36 @@ enum {
_TNL_ATTRIB_GENERIC13 = 29,
_TNL_ATTRIB_GENERIC14 = 30,
_TNL_ATTRIB_GENERIC15 = 31,
_TNL_ATTRIB_MAT_FRONT_AMBIENT = 32,
_TNL_ATTRIB_MAT_BACK_AMBIENT = 33,
_TNL_ATTRIB_MAT_FRONT_DIFFUSE = 34,
_TNL_ATTRIB_MAT_BACK_DIFFUSE = 35,
_TNL_ATTRIB_MAT_FRONT_SPECULAR = 36,
_TNL_ATTRIB_MAT_BACK_SPECULAR = 37,
_TNL_ATTRIB_MAT_FRONT_EMISSION = 38,
_TNL_ATTRIB_MAT_BACK_EMISSION = 39,
_TNL_ATTRIB_MAT_FRONT_SHININESS = 40,
_TNL_ATTRIB_MAT_BACK_SHININESS = 41,
_TNL_ATTRIB_MAT_FRONT_INDEXES = 42,
_TNL_ATTRIB_MAT_BACK_INDEXES = 43,
_TNL_ATTRIB_EDGEFLAG = 44,
_TNL_ATTRIB_POINTSIZE = 45,
_TNL_ATTRIB_MAX = 46
/* These alias with the generics, but they are not active
* concurrently, so it's not a problem. The TNL module
* doesn't have to do anything about this as this is how they
* are passed into the _draw_prims callback.
*
* When we generate fixed-function replacement programs (in
* t_vp_build.c currently), they refer to the appropriate
* generic attribute in order to pick up per-vertex material
* data.
*/
_TNL_ATTRIB_MAT_FRONT_AMBIENT = 16,
_TNL_ATTRIB_MAT_BACK_AMBIENT = 17,
_TNL_ATTRIB_MAT_FRONT_DIFFUSE = 18,
_TNL_ATTRIB_MAT_BACK_DIFFUSE = 19,
_TNL_ATTRIB_MAT_FRONT_SPECULAR = 20,
_TNL_ATTRIB_MAT_BACK_SPECULAR = 21,
_TNL_ATTRIB_MAT_FRONT_EMISSION = 22,
_TNL_ATTRIB_MAT_BACK_EMISSION = 23,
_TNL_ATTRIB_MAT_FRONT_SHININESS = 24,
_TNL_ATTRIB_MAT_BACK_SHININESS = 25,
_TNL_ATTRIB_MAT_FRONT_INDEXES = 26,
_TNL_ATTRIB_MAT_BACK_INDEXES = 27,
/* This is really a VERT_RESULT, not an attrib. Need to fix
* tnl to understand the difference.
*/
_TNL_ATTRIB_POINTSIZE = 16,
_TNL_ATTRIB_MAX = 32
} ;
#define _TNL_ATTRIB_TEX(u) (_TNL_ATTRIB_TEX0 + (u))
@ -166,8 +160,8 @@ enum {
#define _TNL_FIRST_GENERIC _TNL_ATTRIB_GENERIC0
#define _TNL_LAST_GENERIC _TNL_ATTRIB_GENERIC15
#define _TNL_FIRST_MAT _TNL_ATTRIB_MAT_FRONT_AMBIENT
#define _TNL_LAST_MAT _TNL_ATTRIB_MAT_BACK_INDEXES
#define _TNL_FIRST_MAT _TNL_ATTRIB_MAT_FRONT_AMBIENT /* GENERIC0 */
#define _TNL_LAST_MAT _TNL_ATTRIB_MAT_BACK_INDEXES /* GENERIC11 */
/* Number of available generic attributes */
#define _TNL_NUM_GENERIC 16
@ -175,220 +169,21 @@ enum {
/* Number of attributes used for evaluators */
#define _TNL_NUM_EVAL 16
#define PRIM_BEGIN 0x10
#define PRIM_END 0x20
#define PRIM_WEAK 0x40
#define PRIM_MODE_MASK 0x0f
/*
*/
struct tnl_prim {
GLuint mode;
GLuint start;
GLuint count;
};
struct tnl_eval1_map {
struct gl_1d_map *map;
GLuint sz;
};
struct tnl_eval2_map {
struct gl_2d_map *map;
GLuint sz;
};
struct tnl_eval {
GLuint new_state;
struct tnl_eval1_map map1[_TNL_NUM_EVAL];
struct tnl_eval2_map map2[_TNL_NUM_EVAL];
};
#define TNL_MAX_PRIM 16
#define TNL_MAX_COPIED_VERTS 3
struct tnl_copied_vtx {
GLfloat buffer[_TNL_ATTRIB_MAX * 4 * TNL_MAX_COPIED_VERTS];
GLuint nr;
};
#define VERT_BUFFER_SIZE 2048 /* 8kbytes */
typedef void (*tnl_attrfv_func)( const GLfloat * );
struct _tnl_dynfn {
struct _tnl_dynfn *next, *prev;
GLuint key;
char *code;
};
struct _tnl_dynfn_lists {
struct _tnl_dynfn Vertex[4];
struct _tnl_dynfn Attribute[4];
};
struct _tnl_dynfn_generators {
struct _tnl_dynfn *(*Vertex[4])( GLcontext *ctx, int key );
struct _tnl_dynfn *(*Attribute[4])( GLcontext *ctx, int key );
};
#define _TNL_MAX_ATTR_CODEGEN 32
/**
* The assembly of vertices in immediate mode is separated from
* display list compilation. This allows a simpler immediate mode
* treatment and a display list compiler better suited to
* hardware-acceleration.
*/
struct tnl_vtx {
GLfloat buffer[VERT_BUFFER_SIZE];
GLubyte attrsz[_TNL_ATTRIB_MAX];
GLubyte active_sz[_TNL_ATTRIB_MAX];
GLuint vertex_size;
struct tnl_prim prim[TNL_MAX_PRIM];
GLuint prim_count;
GLfloat *vbptr; /* cursor, points into buffer */
GLfloat vertex[_TNL_ATTRIB_MAX*4]; /* current vertex */
GLfloat *attrptr[_TNL_ATTRIB_MAX]; /* points into vertex */
GLfloat *current[_TNL_ATTRIB_MAX]; /* points into ctx->Current, etc */
GLfloat CurrentFloatEdgeFlag;
GLuint counter, initial_counter;
struct tnl_copied_vtx copied;
/** Note extra space for error handler: */
tnl_attrfv_func tabfv[_TNL_ATTRIB_ERROR+1][4];
struct _tnl_dynfn_lists cache;
struct _tnl_dynfn_generators gen;
struct tnl_eval eval;
GLboolean *edgeflag_tmp;
GLboolean have_materials;
};
/* For display lists, this structure holds a run of vertices of the
* same format, and a strictly well-formed set of begin/end pairs,
* starting on the first vertex and ending at the last. Vertex
* copying on buffer breaks is precomputed according to these
* primitives, though there are situations where the copying will need
* correction at execute-time, perhaps by replaying the list as
* immediate mode commands.
*
* On executing this list, the 'current' values may be updated with
* the values of the final vertex, and often no fixup of the start of
* the vertex list is required.
*
* Eval and other commands that don't fit into these vertex lists are
* compiled using the fallback opcode mechanism provided by dlist.c.
*/
struct tnl_vertex_list {
GLubyte attrsz[_TNL_ATTRIB_MAX];
GLuint vertex_size;
GLfloat *buffer;
GLuint count;
GLuint wrap_count; /* number of copied vertices at start */
GLboolean have_materials; /* bit of a hack - quick check for materials */
GLboolean dangling_attr_ref; /* current attr implicitly referenced
outside the list */
GLfloat *normal_lengths;
struct tnl_prim *prim;
GLuint prim_count;
struct tnl_vertex_store *vertex_store;
struct tnl_primitive_store *prim_store;
};
/* These buffers should be a reasonable size to support upload to
* hardware? Maybe drivers should stitch them back together, or
* specify a desired size?
*/
#define SAVE_BUFFER_SIZE (16*1024)
#define SAVE_PRIM_SIZE 128
/* Storage to be shared among several vertex_lists.
*/
struct tnl_vertex_store {
GLfloat buffer[SAVE_BUFFER_SIZE];
GLuint used;
GLuint refcount;
};
struct tnl_primitive_store {
struct tnl_prim buffer[SAVE_PRIM_SIZE];
GLuint used;
GLuint refcount;
};
struct tnl_save {
GLubyte attrsz[_TNL_ATTRIB_MAX];
GLuint vertex_size;
GLfloat *buffer;
GLuint count;
GLuint wrap_count;
GLuint replay_flags;
struct tnl_prim *prim;
GLuint prim_count, prim_max;
struct tnl_vertex_store *vertex_store;
struct tnl_primitive_store *prim_store;
GLfloat *vbptr; /* cursor, points into buffer */
GLfloat vertex[_TNL_ATTRIB_MAX*4]; /* current values */
GLfloat *attrptr[_TNL_ATTRIB_MAX];
GLuint counter, initial_counter;
GLboolean dangling_attr_ref;
GLboolean have_materials;
GLuint opcode_vertex_list;
struct tnl_copied_vtx copied;
GLfloat CurrentFloatEdgeFlag;
GLfloat *current[_TNL_ATTRIB_MAX]; /* points into ctx->ListState */
GLubyte *currentsz[_TNL_ATTRIB_MAX];
void (*tabfv[_TNL_ATTRIB_MAX][4])( const GLfloat * );
};
/**
* A collection of vertex arrays.
*/
struct tnl_vertex_arrays
static INLINE GLuint _tnl_translate_prim( const struct _mesa_prim *prim )
{
/* Conventional vertex attribute arrays */
GLvector4f Obj;
GLvector4f Normal;
GLvector4f Color;
GLvector4f SecondaryColor;
GLvector4f FogCoord;
GLvector4f TexCoord[MAX_TEXTURE_COORD_UNITS];
GLvector4f Index;
GLuint flag;
flag = prim->mode;
if (prim->begin) flag |= PRIM_BEGIN;
if (prim->end) flag |= PRIM_END;
return flag;
}
GLubyte *EdgeFlag;
GLuint *Elt;
/* These attributes don't alias with the conventional attributes.
* The GL_NV_vertex_program extension defines 16 extra sets of vertex
* arrays which have precedent over the conventional arrays when enabled.
*/
/* XXX I think the array size is wronge (47 vs. 16) */
GLvector4f Attribs[_TNL_ATTRIB_MAX];
};
/**
@ -424,11 +219,10 @@ struct vertex_buffer
GLvector4f *FogCoordPtr; /* _TNL_BIT_FOG */
GLvector4f *VaryingPtr[MAX_VARYING_VECTORS];
struct tnl_prim *Primitive;
const struct _mesa_prim *Primitive;
GLuint PrimitiveCount;
/* Inputs to the vertex program stage */
/* XXX This array may be too large (47 vs. 16) */
GLvector4f *AttribPtr[_TNL_ATTRIB_MAX]; /* GL_NV_vertex_program */
};
@ -626,12 +420,6 @@ struct tnl_device_driver
* arrays.
*/
GLboolean (*NotifyBegin)(GLcontext *ctx, GLenum p);
/* Allow drivers to hook in optimized begin/end engines.
* Return value: GL_TRUE - driver handled the begin
* GL_FALSE - driver didn't handle the begin
*/
/***
*** Rendering -- These functions called only from t_vb_render.c
***/
@ -737,26 +525,11 @@ typedef struct
*/
struct tnl_device_driver Driver;
/* Execute:
*/
struct tnl_vtx vtx;
/* Compile:
*/
struct tnl_save save;
/* Pipeline
*/
struct tnl_pipeline pipeline;
struct vertex_buffer vb;
/* GLvectors for binding to vb:
*/
struct tnl_vertex_arrays vtx_inputs;
struct tnl_vertex_arrays save_inputs;
struct tnl_vertex_arrays current;
struct tnl_vertex_arrays array_inputs;
/* Clipspace/ndc/window vertex managment:
*/
struct tnl_clipspace clipspace;
@ -764,26 +537,21 @@ typedef struct
/* Probably need a better configuration mechanism:
*/
GLboolean NeedNdcCoords;
GLboolean LoopbackDListCassettes;
GLboolean CalcDListNormalLengths;
GLboolean IsolateMaterials;
GLboolean AllowVertexFog;
GLboolean AllowPixelFog;
GLboolean AllowCodegen;
GLboolean _DoVertexFog; /* eval fog function at each vertex? */
/* If True, it means we started a glBegin/End primtive with an invalid
* vertex/fragment program or incomplete framebuffer. In that case,
* discard any buffered vertex data.
*/
GLboolean DiscardPrimitive;
DECLARE_RENDERINPUTS(render_inputs_bitset);
GLvertexformat exec_vtxfmt;
GLvertexformat save_vtxfmt;
GLvector4f tmp_inputs[VERT_ATTRIB_MAX];
/* Temp storage for t_draw.c:
*/
GLubyte *block[VERT_ATTRIB_MAX];
GLuint nr_blocks;
/* Cache of fixed-function-replacing vertex programs:
*/
struct tnl_cache *vp_cache;
} TNLcontext;

File diff suppressed because it is too large Load diff

View file

@ -1,57 +0,0 @@
/**************************************************************************
Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
on the rights to use, copy, modify, merge, publish, distribute, sub
license, and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
/*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*
*/
#ifndef __T_SAVE_API_H__
#define __T_SAVE_API_H__
#include "t_context.h"
extern GLboolean _tnl_weak_begin( GLcontext *ctx, GLenum mode );
extern void _tnl_EndList( GLcontext *ctx );
extern void _tnl_NewList( GLcontext *ctx, GLuint list, GLenum mode );
extern void _tnl_EndCallList( GLcontext *ctx );
extern void _tnl_BeginCallList( GLcontext *ctx, struct mesa_display_list *list );
extern void _tnl_SaveFlushVertices( GLcontext *ctx );
extern void _tnl_save_init( GLcontext *ctx );
extern void _tnl_save_destroy( GLcontext *ctx );
extern void _tnl_loopback_vertex_list( GLcontext *ctx,
const struct tnl_vertex_list *list );
extern void _tnl_playback_vertex_list( GLcontext *ctx, void *data );
#endif

View file

@ -1,330 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/* Author:
* Keith Whitwell <keith@tungstengraphics.com>
*/
#include "glheader.h"
#include "context.h"
#include "enums.h"
#include "glapi.h"
#include "imports.h"
#include "macros.h"
#include "mtypes.h"
#include "t_context.h"
#include "t_save_api.h"
#include "dispatch.h"
/* If someone compiles a display list like:
* glBegin(Triangles)
* glVertex()
* ... lots of vertices ...
* glEnd()
*
* or:
* glDrawArrays(...)
*
* and then tries to execute it like this:
*
* glBegin(Lines)
* glCallList()
* glEnd()
*
* it will wind up in here, as the vertex copying used when wrapping
* buffers in list compilation (Triangles) won't be right for how the
* list is being executed (as Lines).
*
* This could be avoided by not compiling as vertex_lists until after
* the first glEnd() has been seen. However, that would miss an
* important category of display lists, for the sake of a degenerate
* usage.
*
* Further, replaying degenerately-called lists in this fashion is
* probably still faster than the replay using opcodes.
*/
typedef void (*attr_func)( GLcontext *ctx, GLint target, const GLfloat * );
/* Wrapper functions in case glVertexAttrib*fvNV doesn't exist */
static void VertexAttrib1fvNV(GLcontext *ctx, GLint target, const GLfloat *v)
{
CALL_VertexAttrib1fvNV(ctx->Exec, (target, v));
}
static void VertexAttrib2fvNV(GLcontext *ctx, GLint target, const GLfloat *v)
{
CALL_VertexAttrib2fvNV(ctx->Exec, (target, v));
}
static void VertexAttrib3fvNV(GLcontext *ctx, GLint target, const GLfloat *v)
{
CALL_VertexAttrib3fvNV(ctx->Exec, (target, v));
}
static void VertexAttrib4fvNV(GLcontext *ctx, GLint target, const GLfloat *v)
{
CALL_VertexAttrib4fvNV(ctx->Exec, (target, v));
}
static attr_func vert_attrfunc[4] = {
VertexAttrib1fvNV,
VertexAttrib2fvNV,
VertexAttrib3fvNV,
VertexAttrib4fvNV
};
static void VertexAttrib1fvARB(GLcontext *ctx, GLint target, const GLfloat *v)
{
CALL_VertexAttrib1fvARB(ctx->Exec, (target, v));
}
static void VertexAttrib2fvARB(GLcontext *ctx, GLint target, const GLfloat *v)
{
CALL_VertexAttrib2fvARB(ctx->Exec, (target, v));
}
static void VertexAttrib3fvARB(GLcontext *ctx, GLint target, const GLfloat *v)
{
CALL_VertexAttrib3fvARB(ctx->Exec, (target, v));
}
static void VertexAttrib4fvARB(GLcontext *ctx, GLint target, const GLfloat *v)
{
CALL_VertexAttrib4fvARB(ctx->Exec, (target, v));
}
static attr_func vert_attrfunc_arb[4] = {
VertexAttrib1fvARB,
VertexAttrib2fvARB,
VertexAttrib3fvARB,
VertexAttrib4fvARB
};
static void mat_attr1fv( GLcontext *ctx, GLint target, const GLfloat *v )
{
switch (target) {
case _TNL_ATTRIB_MAT_FRONT_SHININESS:
CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_SHININESS, v ));
break;
case _TNL_ATTRIB_MAT_BACK_SHININESS:
CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_SHININESS, v ));
break;
}
}
static void mat_attr3fv( GLcontext *ctx, GLint target, const GLfloat *v )
{
switch (target) {
case _TNL_ATTRIB_MAT_FRONT_INDEXES:
CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_COLOR_INDEXES, v ));
break;
case _TNL_ATTRIB_MAT_BACK_INDEXES:
CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_COLOR_INDEXES, v ));
break;
}
}
static void mat_attr4fv( GLcontext *ctx, GLint target, const GLfloat *v )
{
switch (target) {
case _TNL_ATTRIB_MAT_FRONT_EMISSION:
CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_EMISSION, v ));
break;
case _TNL_ATTRIB_MAT_BACK_EMISSION:
CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_EMISSION, v ));
break;
case _TNL_ATTRIB_MAT_FRONT_AMBIENT:
CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_AMBIENT, v ));
break;
case _TNL_ATTRIB_MAT_BACK_AMBIENT:
CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_AMBIENT, v ));
break;
case _TNL_ATTRIB_MAT_FRONT_DIFFUSE:
CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_DIFFUSE, v ));
break;
case _TNL_ATTRIB_MAT_BACK_DIFFUSE:
CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_DIFFUSE, v ));
break;
case _TNL_ATTRIB_MAT_FRONT_SPECULAR:
CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_SPECULAR, v ));
break;
case _TNL_ATTRIB_MAT_BACK_SPECULAR:
CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_SPECULAR, v ));
break;
}
}
static attr_func mat_attrfunc[4] = {
mat_attr1fv,
NULL,
mat_attr3fv,
mat_attr4fv
};
static void edgeflag_attr1fv(GLcontext *ctx, GLint target, const GLfloat *v)
{
(void) target;
CALL_EdgeFlag(ctx->Exec, ((GLboolean)(v[0] == 1.0)));
}
struct loopback_attr {
GLint target;
GLint sz;
attr_func func;
};
/* Don't emit ends and begins on wrapped primitives. Don't replay
* wrapped vertices. If we get here, it's probably because the the
* precalculated wrapping is wrong.
*/
static void loopback_prim( GLcontext *ctx,
const struct tnl_vertex_list *list, GLuint i,
const struct loopback_attr *la, GLuint nr )
{
struct tnl_prim *prim = &list->prim[i];
GLint begin = prim->start;
GLint end = begin + prim->count;
GLfloat *data;
GLint j;
GLuint k;
if (prim->mode & PRIM_BEGIN) {
CALL_Begin(GET_DISPATCH(), ( prim->mode & PRIM_MODE_MASK ));
}
else {
assert(i == 0);
assert(begin == 0);
begin += list->wrap_count;
}
data = list->buffer + begin * list->vertex_size;
for (j = begin ; j < end ; j++) {
GLfloat *tmp = data + la[0].sz;
for (k = 1 ; k < nr ; k++) {
la[k].func( ctx, la[k].target, tmp );
tmp += la[k].sz;
}
/* Fire the vertex
*/
la[0].func( ctx, VERT_ATTRIB_POS, data );
data = tmp;
}
if (prim->mode & PRIM_END) {
CALL_End(GET_DISPATCH(), ());
}
else {
assert (i == list->prim_count-1);
}
}
/* Primitives generated by DrawArrays/DrawElements/Rectf may be
* caught here. If there is no primitive in progress, execute them
* normally, otherwise need to track and discard the generated
* primitives.
*/
static void loopback_weak_prim( GLcontext *ctx,
const struct tnl_vertex_list *list, GLuint i,
const struct loopback_attr *la, GLuint nr )
{
if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END)
loopback_prim( ctx, list, i, la, nr );
else {
struct tnl_prim *prim = &list->prim[i];
/* Use the prim_weak flag to ensure that if this primitive
* wraps, we don't mistake future vertex_lists for part of the
* surrounding primitive.
*
* While this flag is set, we are simply disposing of data
* generated by an operation now known to be a noop.
*/
if (prim->mode & PRIM_BEGIN)
ctx->Driver.CurrentExecPrimitive |= PRIM_WEAK;
if (prim->mode & PRIM_END)
ctx->Driver.CurrentExecPrimitive &= ~PRIM_WEAK;
}
}
void _tnl_loopback_vertex_list( GLcontext *ctx,
const struct tnl_vertex_list *list )
{
struct loopback_attr la[_TNL_ATTRIB_MAX];
GLuint i, nr = 0;
/* conventional + generic attributes */
for (i = 0 ; i <= _TNL_ATTRIB_GENERIC15 ; i++) {
if (list->attrsz[i]) {
la[nr].target = i;
la[nr].sz = list->attrsz[i];
la[nr].func = vert_attrfunc[list->attrsz[i]-1];
nr++;
}
}
/* material attributes */
for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT ;
i <= _TNL_ATTRIB_MAT_BACK_INDEXES ;
i++) {
if (list->attrsz[i]) {
la[nr].target = i;
la[nr].sz = list->attrsz[i];
la[nr].func = mat_attrfunc[list->attrsz[i]-1];
nr++;
}
}
/* special-case: edgeflag */
if (list->attrsz[_TNL_ATTRIB_EDGEFLAG]) {
la[nr].target = _TNL_ATTRIB_EDGEFLAG;
la[nr].sz = list->attrsz[_TNL_ATTRIB_EDGEFLAG];
la[nr].func = edgeflag_attr1fv;
nr++;
}
for (i = 0 ; i < list->prim_count ; i++) {
if (list->prim[i].mode & PRIM_WEAK)
loopback_weak_prim( ctx, list, i, la, nr );
else
loopback_prim( ctx, list, i, la, nr );
}
}

View file

@ -1,215 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 6.1
*
* Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/* Author:
* Keith Whitwell <keith@tungstengraphics.com>
*/
#include "glheader.h"
#include "context.h"
#include "imports.h"
#include "mtypes.h"
#include "macros.h"
#include "light.h"
#include "state.h"
#include "t_pipeline.h"
#include "t_save_api.h"
#include "t_vtx_api.h"
static INLINE GLint get_size( const GLfloat *f )
{
if (f[3] != 1.0) return 4;
if (f[2] != 0.0) return 3;
return 2;
}
/* Some nasty stuff still hanging on here.
*
* TODO - remove VB->ColorPtr, etc and just use the AttrPtr's.
*/
static void _tnl_bind_vertex_list( GLcontext *ctx,
const struct tnl_vertex_list *node )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
struct tnl_vertex_arrays *tmp = &tnl->save_inputs;
GLfloat *data = node->buffer;
GLuint attr, i;
/* Setup constant data in the VB.
*/
VB->Count = node->count;
VB->Primitive = node->prim;
VB->PrimitiveCount = node->prim_count;
VB->Elts = NULL;
VB->NormalLengthPtr = node->normal_lengths;
for (attr = 0; attr <= _TNL_ATTRIB_EDGEFLAG; attr++) {
if (node->attrsz[attr]) {
tmp->Attribs[attr].count = node->count;
tmp->Attribs[attr].data = (GLfloat (*)[4]) data;
tmp->Attribs[attr].start = data;
tmp->Attribs[attr].size = node->attrsz[attr];
tmp->Attribs[attr].stride = node->vertex_size * sizeof(GLfloat);
VB->AttribPtr[attr] = &tmp->Attribs[attr];
data += node->attrsz[attr];
}
else {
tmp->Attribs[attr].count = 1;
tmp->Attribs[attr].data = (GLfloat (*)[4]) tnl->vtx.current[attr];
tmp->Attribs[attr].start = tnl->vtx.current[attr];
tmp->Attribs[attr].size = get_size( tnl->vtx.current[attr] );
tmp->Attribs[attr].stride = 0;
VB->AttribPtr[attr] = &tmp->Attribs[attr];
}
}
/* Copy edgeflag to a contiguous array
*/
if (ctx->Polygon.FrontMode != GL_FILL || ctx->Polygon.BackMode != GL_FILL) {
if (node->attrsz[_TNL_ATTRIB_EDGEFLAG]) {
VB->EdgeFlag = _tnl_translate_edgeflag( ctx, data,
node->count,
node->vertex_size );
data++;
}
else
VB->EdgeFlag = _tnl_import_current_edgeflag( ctx, node->count );
}
/* Legacy pointers -- remove one day.
*/
VB->ObjPtr = VB->AttribPtr[_TNL_ATTRIB_POS];
VB->NormalPtr = VB->AttribPtr[_TNL_ATTRIB_NORMAL];
VB->ColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR0];
VB->ColorPtr[1] = NULL;
VB->IndexPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR_INDEX];
VB->IndexPtr[1] = NULL;
VB->SecondaryColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR1];
VB->SecondaryColorPtr[1] = NULL;
VB->FogCoordPtr = VB->AttribPtr[_TNL_ATTRIB_FOG];
for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
VB->TexCoordPtr[i] = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i];
}
}
static void _playback_copy_to_current( GLcontext *ctx,
const struct tnl_vertex_list *node )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
const GLfloat *data;
GLuint i;
if (node->count)
data = node->buffer + (node->count-1) * node->vertex_size;
else
data = node->buffer;
for (i = _TNL_ATTRIB_POS+1 ; i <= _TNL_ATTRIB_EDGEFLAG ; i++) {
if (node->attrsz[i]) {
COPY_CLEAN_4V(tnl->vtx.current[i], node->attrsz[i], data);
data += node->attrsz[i];
}
}
/* Edgeflag requires special treatment:
*/
if (node->attrsz[_TNL_ATTRIB_EDGEFLAG]) {
ctx->Current.EdgeFlag = (data[0] == 1.0);
}
/* Colormaterial -- this kindof sucks.
*/
if (ctx->Light.ColorMaterialEnabled) {
_mesa_update_color_material(ctx, ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
}
if (node->have_materials) {
tnl->Driver.NotifyMaterialChange( ctx );
}
/* CurrentExecPrimitive
*/
if (node->prim_count) {
GLenum mode = node->prim[node->prim_count - 1].mode;
if (mode & PRIM_END)
ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
else
ctx->Driver.CurrentExecPrimitive = (mode & PRIM_MODE_MASK);
}
}
/**
* Execute the buffer and save copied verts.
*/
void _tnl_playback_vertex_list( GLcontext *ctx, void *data )
{
const struct tnl_vertex_list *node = (const struct tnl_vertex_list *) data;
TNLcontext *tnl = TNL_CONTEXT(ctx);
FLUSH_CURRENT(ctx, 0);
if (node->prim_count > 0 && node->count > 0) {
if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END &&
(node->prim[0].mode & PRIM_BEGIN)) {
/* Degenerate case: list is called inside begin/end pair and
* includes operations such as glBegin or glDrawArrays.
*/
_mesa_error( ctx, GL_INVALID_OPERATION, "displaylist recursive begin");
_tnl_loopback_vertex_list( ctx, node );
return;
}
else if (tnl->save.replay_flags) {
/* Various degnerate cases: translate into immediate mode
* calls rather than trying to execute in place.
*/
_tnl_loopback_vertex_list( ctx, node );
return;
}
if (ctx->NewState)
_mesa_update_state( ctx );
if ((ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) ||
(ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glBegin (invalid vertex/fragment program)");
return;
}
_tnl_bind_vertex_list( ctx, node );
tnl->Driver.RunPipeline( ctx );
}
/* Copy to current?
*/
_playback_copy_to_current( ctx, node );
}

View file

@ -305,7 +305,7 @@ static GLboolean run_render( GLcontext *ctx,
for (i = 0 ; i < VB->PrimitiveCount ; i++)
{
GLuint prim = VB->Primitive[i].mode;
GLuint prim = _tnl_translate_prim(&VB->Primitive[i]);
GLuint start = VB->Primitive[i].start;
GLuint length = VB->Primitive[i].count;

View file

@ -45,8 +45,8 @@
#endif
#ifndef TEST_PRIM_END
#define TEST_PRIM_END(flags) (flags & PRIM_END)
#define TEST_PRIM_BEGIN(flags) (flags & PRIM_BEGIN)
#define TEST_PRIM_END(prim) (flags & PRIM_END)
#define TEST_PRIM_BEGIN(prim) (flags & PRIM_BEGIN)
#endif
#ifndef ELT

File diff suppressed because it is too large Load diff

View file

@ -1,86 +0,0 @@
/**************************************************************************
Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
on the rights to use, copy, modify, merge, publish, distribute, sub
license, and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
/*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*
*/
#ifndef __T_VTX_API_H__
#define __T_VTX_API_H__
#include "t_context.h"
/* t_vtx_api.c:
*/
extern void _tnl_vtx_init( GLcontext *ctx );
extern void _tnl_vtx_destroy( GLcontext *ctx );
extern void _tnl_FlushVertices( GLcontext *ctx, GLuint flags );
extern void _tnl_flush_vtx( GLcontext *ctx );
extern void GLAPIENTRY _tnl_wrap_filled_vertex( GLcontext *ctx );
/* t_vtx_exec.c:
*/
extern void _tnl_do_EvalCoord2f( GLcontext* ctx, GLfloat u, GLfloat v );
extern void _tnl_do_EvalCoord1f(GLcontext* ctx, GLfloat u);
extern void _tnl_update_eval( GLcontext *ctx );
extern GLboolean *_tnl_translate_edgeflag( GLcontext *ctx,
const GLfloat *data,
GLuint count,
GLuint stride );
extern GLboolean *_tnl_import_current_edgeflag( GLcontext *ctx,
GLuint count );
/* t_vtx_generic.c:
*/
extern void _tnl_generic_exec_vtxfmt_init( GLcontext *ctx );
extern void _tnl_generic_attr_table_init( tnl_attrfv_func (*tab)[4] );
/* t_vtx_x86.c:
*/
extern void _tnl_InitX86Codegen( struct _tnl_dynfn_generators *gen );
extern void _tnl_x86_exec_vtxfmt_init( GLcontext *ctx );
extern void _tnl_x86choosers( tnl_attrfv_func (*choose)[4],
tnl_attrfv_func (*do_choose)( GLuint attr,
GLuint sz ));
#endif

View file

@ -1,265 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 6.5.1
*
* Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*/
#include "glheader.h"
#include "api_eval.h"
#include "context.h"
#include "macros.h"
#include "math/m_eval.h"
#include "t_vtx_api.h"
#include "dispatch.h"
static void clear_active_eval1( TNLcontext *tnl, GLuint attr )
{
ASSERT(attr < _TNL_NUM_EVAL);
tnl->vtx.eval.map1[attr].map = NULL;
}
static void clear_active_eval2( TNLcontext *tnl, GLuint attr )
{
ASSERT(attr < _TNL_NUM_EVAL);
tnl->vtx.eval.map2[attr].map = NULL;
}
static void set_active_eval1( TNLcontext *tnl, GLuint attr, GLuint dim,
struct gl_1d_map *map )
{
ASSERT(attr < _TNL_NUM_EVAL);
if (!tnl->vtx.eval.map1[attr].map) {
tnl->vtx.eval.map1[attr].map = map;
tnl->vtx.eval.map1[attr].sz = dim;
}
}
static void set_active_eval2( TNLcontext *tnl, GLuint attr, GLuint dim,
struct gl_2d_map *map )
{
ASSERT(attr < _TNL_NUM_EVAL);
if (!tnl->vtx.eval.map2[attr].map) {
tnl->vtx.eval.map2[attr].map = map;
tnl->vtx.eval.map2[attr].sz = dim;
}
}
void _tnl_update_eval( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLuint attr;
/* Vertex program maps have priority over conventional attribs */
for (attr = 0; attr < _TNL_NUM_EVAL; attr++) {
clear_active_eval1( tnl, attr );
clear_active_eval2( tnl, attr );
}
if (ctx->Eval.Map1Color4)
set_active_eval1( tnl, VERT_ATTRIB_COLOR0, 4, &ctx->EvalMap.Map1Color4 );
if (ctx->Eval.Map2Color4)
set_active_eval2( tnl, VERT_ATTRIB_COLOR0, 4, &ctx->EvalMap.Map2Color4 );
if (ctx->Eval.Map1TextureCoord4)
set_active_eval1( tnl, VERT_ATTRIB_TEX0, 4, &ctx->EvalMap.Map1Texture4 );
else if (ctx->Eval.Map1TextureCoord3)
set_active_eval1( tnl, VERT_ATTRIB_TEX0, 3, &ctx->EvalMap.Map1Texture3 );
else if (ctx->Eval.Map1TextureCoord2)
set_active_eval1( tnl, VERT_ATTRIB_TEX0, 2, &ctx->EvalMap.Map1Texture2 );
else if (ctx->Eval.Map1TextureCoord1)
set_active_eval1( tnl, VERT_ATTRIB_TEX0, 1, &ctx->EvalMap.Map1Texture1 );
if (ctx->Eval.Map2TextureCoord4)
set_active_eval2( tnl, VERT_ATTRIB_TEX0, 4, &ctx->EvalMap.Map2Texture4 );
else if (ctx->Eval.Map2TextureCoord3)
set_active_eval2( tnl, VERT_ATTRIB_TEX0, 3, &ctx->EvalMap.Map2Texture3 );
else if (ctx->Eval.Map2TextureCoord2)
set_active_eval2( tnl, VERT_ATTRIB_TEX0, 2, &ctx->EvalMap.Map2Texture2 );
else if (ctx->Eval.Map2TextureCoord1)
set_active_eval2( tnl, VERT_ATTRIB_TEX0, 1, &ctx->EvalMap.Map2Texture1 );
if (ctx->Eval.Map1Normal)
set_active_eval1( tnl, VERT_ATTRIB_NORMAL, 3, &ctx->EvalMap.Map1Normal );
if (ctx->Eval.Map2Normal)
set_active_eval2( tnl, VERT_ATTRIB_NORMAL, 3, &ctx->EvalMap.Map2Normal );
if (ctx->Eval.Map1Vertex4)
set_active_eval1( tnl, VERT_ATTRIB_POS, 4, &ctx->EvalMap.Map1Vertex4 );
else if (ctx->Eval.Map1Vertex3)
set_active_eval1( tnl, VERT_ATTRIB_POS, 3, &ctx->EvalMap.Map1Vertex3 );
if (ctx->Eval.Map2Vertex4)
set_active_eval2( tnl, VERT_ATTRIB_POS, 4, &ctx->EvalMap.Map2Vertex4 );
else if (ctx->Eval.Map2Vertex3)
set_active_eval2( tnl, VERT_ATTRIB_POS, 3, &ctx->EvalMap.Map2Vertex3 );
/* Evaluators with generic attributes is only supported for NV vertex
* programs, not ARB vertex programs. 16 evaluator maps are supported.
* We do this after the conventional attributes since the spec says that
* these generic maps have higher priority.
*/
if (ctx->VertexProgram._Enabled &&
ctx->VertexProgram._Current &&
ctx->VertexProgram._Current->IsNVProgram) {
for (attr = 0; attr < 16; attr++) {
if (ctx->Eval.Map1Attrib[attr])
set_active_eval1( tnl, attr, 4, &ctx->EvalMap.Map1Attrib[attr] );
if (ctx->Eval.Map2Attrib[attr])
set_active_eval2( tnl, attr, 4, &ctx->EvalMap.Map2Attrib[attr] );
}
}
tnl->vtx.eval.new_state = 0;
}
void _tnl_do_EvalCoord1f(GLcontext* ctx, GLfloat u)
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLuint attr;
for (attr = 1; attr < _TNL_NUM_EVAL; attr++) {
struct gl_1d_map *map = tnl->vtx.eval.map1[attr].map;
if (map) {
GLfloat uu = (u - map->u1) * map->du;
GLfloat data[4];
ASSIGN_4V(data, 0, 0, 0, 1);
_math_horner_bezier_curve(map->Points, data, uu,
tnl->vtx.eval.map1[attr].sz,
map->Order);
COPY_SZ_4V( tnl->vtx.attrptr[attr],
tnl->vtx.attrsz[attr],
data );
}
}
/** Vertex -- EvalCoord1f is a noop if this map not enabled:
**/
if (tnl->vtx.eval.map1[0].map) {
struct gl_1d_map *map = tnl->vtx.eval.map1[0].map;
GLfloat uu = (u - map->u1) * map->du;
GLfloat vertex[4];
ASSIGN_4V(vertex, 0, 0, 0, 1);
_math_horner_bezier_curve(map->Points, vertex, uu,
tnl->vtx.eval.map1[0].sz,
map->Order);
if (tnl->vtx.eval.map1[0].sz == 4)
CALL_Vertex4fv(GET_DISPATCH(), ( vertex ));
else
CALL_Vertex3fv(GET_DISPATCH(), ( vertex ));
}
}
void _tnl_do_EvalCoord2f( GLcontext* ctx, GLfloat u, GLfloat v )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLuint attr;
for (attr = 1; attr < _TNL_NUM_EVAL; attr++) {
struct gl_2d_map *map = tnl->vtx.eval.map2[attr].map;
if (map) {
GLfloat uu = (u - map->u1) * map->du;
GLfloat vv = (v - map->v1) * map->dv;
GLfloat data[4];
ASSIGN_4V(data, 0, 0, 0, 1);
_math_horner_bezier_surf(map->Points,
data,
uu, vv,
tnl->vtx.eval.map2[attr].sz,
map->Uorder, map->Vorder);
COPY_SZ_4V( tnl->vtx.attrptr[attr],
tnl->vtx.attrsz[attr],
data );
}
}
/** Vertex -- EvalCoord2f is a noop if this map not enabled:
**/
if (tnl->vtx.eval.map2[0].map) {
struct gl_2d_map *map = tnl->vtx.eval.map2[0].map;
GLfloat uu = (u - map->u1) * map->du;
GLfloat vv = (v - map->v1) * map->dv;
GLfloat vertex[4];
ASSIGN_4V(vertex, 0, 0, 0, 1);
if (ctx->Eval.AutoNormal) {
GLfloat normal[4];
GLfloat du[4], dv[4];
_math_de_casteljau_surf(map->Points, vertex, du, dv, uu, vv,
tnl->vtx.eval.map2[0].sz,
map->Uorder, map->Vorder);
if (tnl->vtx.eval.map2[0].sz == 4) {
du[0] = du[0]*vertex[3] - du[3]*vertex[0];
du[1] = du[1]*vertex[3] - du[3]*vertex[1];
du[2] = du[2]*vertex[3] - du[3]*vertex[2];
dv[0] = dv[0]*vertex[3] - dv[3]*vertex[0];
dv[1] = dv[1]*vertex[3] - dv[3]*vertex[1];
dv[2] = dv[2]*vertex[3] - dv[3]*vertex[2];
}
CROSS3(normal, du, dv);
NORMALIZE_3FV(normal);
normal[3] = 1.0;
COPY_SZ_4V( tnl->vtx.attrptr[_TNL_ATTRIB_NORMAL],
tnl->vtx.attrsz[_TNL_ATTRIB_NORMAL],
normal );
}
else {
_math_horner_bezier_surf(map->Points, vertex, uu, vv,
tnl->vtx.eval.map2[0].sz,
map->Uorder, map->Vorder);
}
if (tnl->vtx.attrsz[0] == 4)
CALL_Vertex4fv(GET_DISPATCH(), ( vertex ));
else
CALL_Vertex3fv(GET_DISPATCH(), ( vertex ));
}
}

View file

@ -1,288 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 5.1
*
* Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*/
#include "glheader.h"
#include "api_eval.h"
#include "context.h"
#include "enums.h"
#include "state.h"
#include "macros.h"
#include "math/m_eval.h"
#include "t_vtx_api.h"
#include "t_pipeline.h"
static void _tnl_print_vtx( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLuint count = tnl->vtx.initial_counter - tnl->vtx.counter;
GLuint i;
_mesa_debug(ctx, "_tnl_print_vtx: %u vertices %d primitives, %d vertsize\n",
count,
tnl->vtx.prim_count,
tnl->vtx.vertex_size);
for (i = 0 ; i < tnl->vtx.prim_count ; i++) {
struct tnl_prim *prim = &tnl->vtx.prim[i];
_mesa_debug(NULL, " prim %d: %s %d..%d %s %s\n",
i,
_mesa_lookup_enum_by_nr(prim->mode & PRIM_MODE_MASK),
prim->start,
prim->start + prim->count,
(prim->mode & PRIM_BEGIN) ? "BEGIN" : "(wrap)",
(prim->mode & PRIM_END) ? "END" : "(wrap)");
}
}
GLboolean *_tnl_translate_edgeflag( GLcontext *ctx, const GLfloat *data,
GLuint count, GLuint stride )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLboolean *ef = tnl->vtx.edgeflag_tmp;
GLuint i;
if (!ef)
ef = tnl->vtx.edgeflag_tmp = (GLboolean *) MALLOC( tnl->vb.Size );
for (i = 0 ; i < count ; i++, data += stride)
ef[i] = (data[0] == 1.0);
return ef;
}
GLboolean *_tnl_import_current_edgeflag( GLcontext *ctx,
GLuint count )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLboolean *ef = tnl->vtx.edgeflag_tmp;
GLboolean tmp = ctx->Current.EdgeFlag;
GLuint i;
if (!ef)
ef = tnl->vtx.edgeflag_tmp = (GLboolean *) MALLOC( tnl->vb.Size );
for (i = 0 ; i < count ; i++)
ef[i] = tmp;
return ef;
}
static INLINE GLint get_size( const GLfloat *f )
{
if (f[3] != 1.0) return 4;
if (f[2] != 0.0) return 3;
return 2;
}
/* Some nasty stuff still hanging on here.
*
* TODO - remove VB->NormalPtr, etc and just use the AttrPtr's.
*/
static void _tnl_vb_bind_vtx( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
struct tnl_vertex_arrays *tmp = &tnl->vtx_inputs;
GLfloat *data = tnl->vtx.buffer;
GLuint count = tnl->vtx.initial_counter - tnl->vtx.counter;
GLuint attr, i;
#undef DEBUG_VTX
#ifdef DEBUG_VTX
fprintf(stderr, "_tnl_vb_bind_vtx(): %d verts %d vertsize\n",
count, tnl->vtx.vertex_size);
#endif
/* Setup constant data in the VB.
*/
VB->Count = count;
VB->Primitive = tnl->vtx.prim;
VB->PrimitiveCount = tnl->vtx.prim_count;
VB->Elts = NULL;
VB->NormalLengthPtr = NULL;
for (attr = 0; attr <= _TNL_ATTRIB_EDGEFLAG ; attr++) {
if (tnl->vtx.attrsz[attr]) {
tmp->Attribs[attr].count = count;
tmp->Attribs[attr].data = (GLfloat (*)[4]) data;
tmp->Attribs[attr].start = data;
tmp->Attribs[attr].size = tnl->vtx.attrsz[attr];
tmp->Attribs[attr].stride = tnl->vtx.vertex_size * sizeof(GLfloat);
VB->AttribPtr[attr] = &tmp->Attribs[attr];
data += tnl->vtx.attrsz[attr];
}
else {
/* VB->AttribPtr[attr] = &tnl->current.Attribs[attr]; */
tmp->Attribs[attr].count = 1;
tmp->Attribs[attr].data = (GLfloat (*)[4]) tnl->vtx.current[attr];
tmp->Attribs[attr].start = tnl->vtx.current[attr];
tmp->Attribs[attr].size = get_size( tnl->vtx.current[attr] );
tmp->Attribs[attr].stride = 0;
VB->AttribPtr[attr] = &tmp->Attribs[attr];
}
}
/* Copy and translate EdgeFlag to a contiguous array of GLbooleans
*/
if (ctx->Polygon.FrontMode != GL_FILL || ctx->Polygon.BackMode != GL_FILL) {
if (tnl->vtx.attrsz[_TNL_ATTRIB_EDGEFLAG]) {
VB->EdgeFlag = _tnl_translate_edgeflag( ctx, data, count,
tnl->vtx.vertex_size );
data++;
}
else
VB->EdgeFlag = _tnl_import_current_edgeflag( ctx, count );
}
/* Legacy pointers -- remove one day.
*/
VB->ObjPtr = VB->AttribPtr[_TNL_ATTRIB_POS];
VB->NormalPtr = VB->AttribPtr[_TNL_ATTRIB_NORMAL];
VB->ColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR0];
VB->ColorPtr[1] = NULL;
VB->SecondaryColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR1];
VB->SecondaryColorPtr[1] = NULL;
VB->IndexPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR_INDEX];
VB->IndexPtr[1] = NULL;
VB->FogCoordPtr = VB->AttribPtr[_TNL_ATTRIB_FOG];
for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
VB->TexCoordPtr[i] = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i];
}
}
/*
* NOTE: Need to have calculated primitives by this point -- do it on the fly.
* NOTE: Old 'parity' issue is gone.
*/
static GLuint _tnl_copy_vertices( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT( ctx );
GLuint nr = tnl->vtx.prim[tnl->vtx.prim_count-1].count;
GLuint ovf, i;
GLuint sz = tnl->vtx.vertex_size;
GLfloat *dst = tnl->vtx.copied.buffer;
GLfloat *src = (tnl->vtx.buffer +
tnl->vtx.prim[tnl->vtx.prim_count-1].start *
tnl->vtx.vertex_size);
switch( ctx->Driver.CurrentExecPrimitive )
{
case GL_POINTS:
return 0;
case GL_LINES:
ovf = nr&1;
for (i = 0 ; i < ovf ; i++)
_mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) );
return i;
case GL_TRIANGLES:
ovf = nr%3;
for (i = 0 ; i < ovf ; i++)
_mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) );
return i;
case GL_QUADS:
ovf = nr&3;
for (i = 0 ; i < ovf ; i++)
_mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) );
return i;
case GL_LINE_STRIP:
if (nr == 0)
return 0;
else {
_mesa_memcpy( dst, src+(nr-1)*sz, sz * sizeof(GLfloat) );
return 1;
}
case GL_LINE_LOOP:
case GL_TRIANGLE_FAN:
case GL_POLYGON:
if (nr == 0)
return 0;
else if (nr == 1) {
_mesa_memcpy( dst, src+0, sz * sizeof(GLfloat) );
return 1;
} else {
_mesa_memcpy( dst, src+0, sz * sizeof(GLfloat) );
_mesa_memcpy( dst+sz, src+(nr-1)*sz, sz * sizeof(GLfloat) );
return 2;
}
case GL_TRIANGLE_STRIP:
case GL_QUAD_STRIP:
switch (nr) {
case 0: ovf = 0; break;
case 1: ovf = 1; break;
default: ovf = 2 + (nr&1); break;
}
for (i = 0 ; i < ovf ; i++)
_mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) );
return i;
case PRIM_OUTSIDE_BEGIN_END:
return 0;
default:
assert(0);
return 0;
}
}
/**
* Execute the buffer and save copied verts.
*/
void _tnl_flush_vtx( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLuint vertex_count = tnl->vtx.initial_counter - tnl->vtx.counter;
if (0)
_tnl_print_vtx( ctx );
if (tnl->vtx.prim_count && vertex_count) {
tnl->vtx.copied.nr = _tnl_copy_vertices( ctx );
if (tnl->vtx.copied.nr != vertex_count) {
if (ctx->NewState)
_mesa_update_state( ctx );
_tnl_vb_bind_vtx( ctx );
tnl->Driver.RunPipeline( ctx );
}
}
tnl->vtx.prim_count = 0;
tnl->vtx.counter = tnl->vtx.initial_counter;
tnl->vtx.vbptr = tnl->vtx.buffer;
}

View file

@ -1,615 +0,0 @@
/**************************************************************************
Copyright 2004 Tungsten Graphics Inc., Cedar Park, Texas.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
on the rights to use, copy, modify, merge, publish, distribute, sub
license, and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
/*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*/
#include "glheader.h"
#include "context.h"
#include "macros.h"
#include "vtxfmt.h"
#include "dlist.h"
#include "state.h"
#include "light.h"
#include "api_arrayelt.h"
#include "api_noop.h"
#include "t_vtx_api.h"
/* Versions of all the entrypoints for situations where codegen isn't
* available.
*
* Note: Only one size for each attribute may be active at once.
* Eg. if Color3f is installed/active, then Color4f may not be, even
* if the vertex actually contains 4 color coordinates. This is
* because the 3f version won't otherwise set color[3] to 1.0 -- this
* is the job of the chooser function when switching between Color4f
* and Color3f.
*/
#define ATTRFV( ATTR, N ) \
static void attrib_##ATTR##_##N( const GLfloat *v ) \
{ \
GET_CURRENT_CONTEXT( ctx ); \
TNLcontext *tnl = TNL_CONTEXT(ctx); \
\
if ((ATTR) == 0) { \
GLuint i; \
\
if (N>0) tnl->vtx.vbptr[0] = v[0]; \
if (N>1) tnl->vtx.vbptr[1] = v[1]; \
if (N>2) tnl->vtx.vbptr[2] = v[2]; \
if (N>3) tnl->vtx.vbptr[3] = v[3]; \
\
for (i = N; i < tnl->vtx.vertex_size; i++) \
tnl->vtx.vbptr[i] = tnl->vtx.vertex[i]; \
\
tnl->vtx.vbptr += tnl->vtx.vertex_size; \
\
if (--tnl->vtx.counter == 0) \
_tnl_wrap_filled_vertex( ctx ); \
} \
else { \
GLfloat *dest = tnl->vtx.attrptr[ATTR]; \
if (N>0) dest[0] = v[0]; \
if (N>1) dest[1] = v[1]; \
if (N>2) dest[2] = v[2]; \
if (N>3) dest[3] = v[3]; \
} \
}
#define INIT(TAB, ATTR) \
TAB[ATTR][0] = attrib_##ATTR##_1; \
TAB[ATTR][1] = attrib_##ATTR##_2; \
TAB[ATTR][2] = attrib_##ATTR##_3; \
TAB[ATTR][3] = attrib_##ATTR##_4;
#define ATTRS( ATTRIB ) \
ATTRFV( ATTRIB, 1 ) \
ATTRFV( ATTRIB, 2 ) \
ATTRFV( ATTRIB, 3 ) \
ATTRFV( ATTRIB, 4 )
/* conventional attribs */
ATTRS( 0 )
ATTRS( 1 )
ATTRS( 2 )
ATTRS( 3 )
ATTRS( 4 )
ATTRS( 5 )
ATTRS( 6 )
ATTRS( 7 )
ATTRS( 8 )
ATTRS( 9 )
ATTRS( 10 )
ATTRS( 11 )
ATTRS( 12 )
ATTRS( 13 )
ATTRS( 14 )
ATTRS( 15 )
/* generic attribs */
ATTRS( 16 )
ATTRS( 17 )
ATTRS( 18 )
ATTRS( 19 )
ATTRS( 20 )
ATTRS( 21 )
ATTRS( 22 )
ATTRS( 23 )
ATTRS( 24 )
ATTRS( 25 )
ATTRS( 26 )
ATTRS( 27 )
ATTRS( 28 )
ATTRS( 29 )
ATTRS( 30 )
ATTRS( 31 )
void _tnl_generic_attr_table_init( tnl_attrfv_func (*tab)[4] )
{
/* conventional attribs */
INIT( tab, 0 );
INIT( tab, 1 );
INIT( tab, 2 );
INIT( tab, 3 );
INIT( tab, 4 );
INIT( tab, 5 );
INIT( tab, 6 );
INIT( tab, 7 );
INIT( tab, 8 );
INIT( tab, 9 );
INIT( tab, 10 );
INIT( tab, 11 );
INIT( tab, 12 );
INIT( tab, 13 );
INIT( tab, 14 );
INIT( tab, 15 );
/* generic attribs */
INIT( tab, 16 );
INIT( tab, 17 );
INIT( tab, 18 );
INIT( tab, 19 );
INIT( tab, 20 );
INIT( tab, 21 );
INIT( tab, 22 );
INIT( tab, 23 );
INIT( tab, 24 );
INIT( tab, 25 );
INIT( tab, 26 );
INIT( tab, 27 );
INIT( tab, 28 );
INIT( tab, 29 );
INIT( tab, 30 );
INIT( tab, 31 );
}
/* These can be made efficient with codegen. Further, by adding more
* logic to do_choose(), the double-dispatch for legacy entrypoints
* like glVertex3f() can be removed.
*/
#define DISPATCH_ATTRFV( ATTR, COUNT, P ) \
do { \
GET_CURRENT_CONTEXT( ctx ); \
TNLcontext *tnl = TNL_CONTEXT(ctx); \
tnl->vtx.tabfv[ATTR][COUNT-1]( P ); \
} while (0)
#define DISPATCH_ATTR1FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 1, V )
#define DISPATCH_ATTR2FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 2, V )
#define DISPATCH_ATTR3FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 3, V )
#define DISPATCH_ATTR4FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 4, V )
#define DISPATCH_ATTR1F( ATTR, S ) DISPATCH_ATTRFV( ATTR, 1, &(S) )
#if defined(USE_X86_ASM) && 0 /* will break register calling convention */
/* Naughty cheat:
*/
#define DISPATCH_ATTR2F( ATTR, S,T ) DISPATCH_ATTRFV( ATTR, 2, &(S) )
#define DISPATCH_ATTR3F( ATTR, S,T,R ) DISPATCH_ATTRFV( ATTR, 3, &(S) )
#define DISPATCH_ATTR4F( ATTR, S,T,R,Q ) DISPATCH_ATTRFV( ATTR, 4, &(S) )
#else
/* Safe:
*/
#define DISPATCH_ATTR2F( ATTR, S,T ) \
do { \
GLfloat v[2]; \
v[0] = S; v[1] = T; \
DISPATCH_ATTR2FV( ATTR, v ); \
} while (0)
#define DISPATCH_ATTR3F( ATTR, S,T,R ) \
do { \
GLfloat v[3]; \
v[0] = S; v[1] = T; v[2] = R; \
DISPATCH_ATTR3FV( ATTR, v ); \
} while (0)
#define DISPATCH_ATTR4F( ATTR, S,T,R,Q ) \
do { \
GLfloat v[4]; \
v[0] = S; v[1] = T; v[2] = R; v[3] = Q; \
DISPATCH_ATTR4FV( ATTR, v ); \
} while (0)
#endif
static void GLAPIENTRY _tnl_Vertex2f( GLfloat x, GLfloat y )
{
DISPATCH_ATTR2F( _TNL_ATTRIB_POS, x, y );
}
static void GLAPIENTRY _tnl_Vertex2fv( const GLfloat *v )
{
DISPATCH_ATTR2FV( _TNL_ATTRIB_POS, v );
}
static void GLAPIENTRY _tnl_Vertex3f( GLfloat x, GLfloat y, GLfloat z )
{
DISPATCH_ATTR3F( _TNL_ATTRIB_POS, x, y, z );
}
static void GLAPIENTRY _tnl_Vertex3fv( const GLfloat *v )
{
DISPATCH_ATTR3FV( _TNL_ATTRIB_POS, v );
}
static void GLAPIENTRY _tnl_Vertex4f( GLfloat x, GLfloat y, GLfloat z,
GLfloat w )
{
DISPATCH_ATTR4F( _TNL_ATTRIB_POS, x, y, z, w );
}
static void GLAPIENTRY _tnl_Vertex4fv( const GLfloat *v )
{
DISPATCH_ATTR4FV( _TNL_ATTRIB_POS, v );
}
static void GLAPIENTRY _tnl_TexCoord1f( GLfloat x )
{
DISPATCH_ATTR1F( _TNL_ATTRIB_TEX0, x );
}
static void GLAPIENTRY _tnl_TexCoord1fv( const GLfloat *v )
{
DISPATCH_ATTR1FV( _TNL_ATTRIB_TEX0, v );
}
static void GLAPIENTRY _tnl_TexCoord2f( GLfloat x, GLfloat y )
{
DISPATCH_ATTR2F( _TNL_ATTRIB_TEX0, x, y );
}
static void GLAPIENTRY _tnl_TexCoord2fv( const GLfloat *v )
{
DISPATCH_ATTR2FV( _TNL_ATTRIB_TEX0, v );
}
static void GLAPIENTRY _tnl_TexCoord3f( GLfloat x, GLfloat y, GLfloat z )
{
DISPATCH_ATTR3F( _TNL_ATTRIB_TEX0, x, y, z );
}
static void GLAPIENTRY _tnl_TexCoord3fv( const GLfloat *v )
{
DISPATCH_ATTR3FV( _TNL_ATTRIB_TEX0, v );
}
static void GLAPIENTRY _tnl_TexCoord4f( GLfloat x, GLfloat y, GLfloat z,
GLfloat w )
{
DISPATCH_ATTR4F( _TNL_ATTRIB_TEX0, x, y, z, w );
}
static void GLAPIENTRY _tnl_TexCoord4fv( const GLfloat *v )
{
DISPATCH_ATTR4FV( _TNL_ATTRIB_TEX0, v );
}
static void GLAPIENTRY _tnl_Normal3f( GLfloat x, GLfloat y, GLfloat z )
{
DISPATCH_ATTR3F( _TNL_ATTRIB_NORMAL, x, y, z );
}
static void GLAPIENTRY _tnl_Normal3fv( const GLfloat *v )
{
DISPATCH_ATTR3FV( _TNL_ATTRIB_NORMAL, v );
}
static void GLAPIENTRY _tnl_FogCoordfEXT( GLfloat x )
{
DISPATCH_ATTR1F( _TNL_ATTRIB_FOG, x );
}
static void GLAPIENTRY _tnl_FogCoordfvEXT( const GLfloat *v )
{
DISPATCH_ATTR1FV( _TNL_ATTRIB_FOG, v );
}
static void GLAPIENTRY _tnl_Color3f( GLfloat x, GLfloat y, GLfloat z )
{
DISPATCH_ATTR3F( _TNL_ATTRIB_COLOR0, x, y, z );
}
static void GLAPIENTRY _tnl_Color3fv( const GLfloat *v )
{
DISPATCH_ATTR3FV( _TNL_ATTRIB_COLOR0, v );
}
static void GLAPIENTRY _tnl_Color4f( GLfloat x, GLfloat y, GLfloat z,
GLfloat w )
{
DISPATCH_ATTR4F( _TNL_ATTRIB_COLOR0, x, y, z, w );
}
static void GLAPIENTRY _tnl_Color4fv( const GLfloat *v )
{
DISPATCH_ATTR4FV( _TNL_ATTRIB_COLOR0, v );
}
static void GLAPIENTRY _tnl_Indexf( GLfloat v )
{
DISPATCH_ATTR1F( _TNL_ATTRIB_COLOR_INDEX, v );
}
static void GLAPIENTRY _tnl_Indexfv( const GLfloat *v )
{
DISPATCH_ATTR1FV( _TNL_ATTRIB_COLOR_INDEX, v );
}
static void GLAPIENTRY _tnl_SecondaryColor3fEXT( GLfloat x, GLfloat y,
GLfloat z )
{
DISPATCH_ATTR3F( _TNL_ATTRIB_COLOR1, x, y, z );
}
static void GLAPIENTRY _tnl_SecondaryColor3fvEXT( const GLfloat *v )
{
DISPATCH_ATTR3FV( _TNL_ATTRIB_COLOR1, v );
}
static void GLAPIENTRY _tnl_MultiTexCoord1f( GLenum target, GLfloat x )
{
GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
DISPATCH_ATTR1F( attr, x );
}
static void GLAPIENTRY _tnl_MultiTexCoord1fv( GLenum target, const GLfloat *v )
{
GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
DISPATCH_ATTR1FV( attr, v );
}
static void GLAPIENTRY _tnl_MultiTexCoord2f( GLenum target, GLfloat x, GLfloat y )
{
GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
DISPATCH_ATTR2F( attr, x, y );
}
static void GLAPIENTRY _tnl_MultiTexCoord2fv( GLenum target, const GLfloat *v )
{
GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
DISPATCH_ATTR2FV( attr, v );
}
static void GLAPIENTRY _tnl_MultiTexCoord3f( GLenum target, GLfloat x,
GLfloat y, GLfloat z)
{
GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
DISPATCH_ATTR3F( attr, x, y, z );
}
static void GLAPIENTRY _tnl_MultiTexCoord3fv( GLenum target, const GLfloat *v )
{
GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
DISPATCH_ATTR3FV( attr, v );
}
static void GLAPIENTRY _tnl_MultiTexCoord4f( GLenum target, GLfloat x,
GLfloat y, GLfloat z,
GLfloat w )
{
GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
DISPATCH_ATTR4F( attr, x, y, z, w );
}
static void GLAPIENTRY _tnl_MultiTexCoord4fv( GLenum target, const GLfloat *v )
{
GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
DISPATCH_ATTR4FV( attr, v );
}
/**
* GL_NV_vertex_program Vertex Attributes
* Note that these attributes DO alias the conventional attributes.
* Also, calling glVertexAttribNV(0, xxx) is equivalent to glVertex(xxx).
*/
static void GLAPIENTRY _tnl_VertexAttrib1fNV( GLuint index, GLfloat x )
{
if (index >= MAX_VERTEX_PROGRAM_ATTRIBS)
index = _TNL_ATTRIB_ERROR;
DISPATCH_ATTR1F( index, x );
}
static void GLAPIENTRY _tnl_VertexAttrib1fvNV( GLuint index, const GLfloat *v )
{
if (index >= MAX_VERTEX_PROGRAM_ATTRIBS)
index = _TNL_ATTRIB_ERROR;
DISPATCH_ATTR1FV( index, v );
}
static void GLAPIENTRY _tnl_VertexAttrib2fNV(GLuint index, GLfloat x, GLfloat y)
{
if (index >= MAX_VERTEX_PROGRAM_ATTRIBS)
index = _TNL_ATTRIB_ERROR;
DISPATCH_ATTR2F( index, x, y );
}
static void GLAPIENTRY _tnl_VertexAttrib2fvNV( GLuint index, const GLfloat *v )
{
if (index >= MAX_VERTEX_PROGRAM_ATTRIBS)
index = _TNL_ATTRIB_ERROR;
DISPATCH_ATTR2FV( index, v );
}
static void GLAPIENTRY _tnl_VertexAttrib3fNV( GLuint index, GLfloat x,
GLfloat y, GLfloat z )
{
if (index >= MAX_VERTEX_PROGRAM_ATTRIBS)
index = _TNL_ATTRIB_ERROR;
DISPATCH_ATTR3F( index, x, y, z );
}
static void GLAPIENTRY _tnl_VertexAttrib3fvNV( GLuint index, const GLfloat *v )
{
if (index >= MAX_VERTEX_PROGRAM_ATTRIBS)
index = _TNL_ATTRIB_ERROR;
DISPATCH_ATTR3FV( index, v );
}
static void GLAPIENTRY _tnl_VertexAttrib4fNV( GLuint index, GLfloat x,
GLfloat y, GLfloat z,
GLfloat w )
{
if (index >= MAX_VERTEX_PROGRAM_ATTRIBS)
index = _TNL_ATTRIB_ERROR;
DISPATCH_ATTR4F( index, x, y, z, w );
}
static void GLAPIENTRY _tnl_VertexAttrib4fvNV( GLuint index, const GLfloat *v )
{
if (index >= MAX_VERTEX_PROGRAM_ATTRIBS)
index = _TNL_ATTRIB_ERROR;
DISPATCH_ATTR4FV( index, v );
}
/**
* GL_ARB_vertex_program Vertex Attributes
* Note that these attributes do NOT alias the conventional attributes.
* Also, calling glVertexAttribARB(0, xxx) is equivalent to glVertex(xxx).
*/
static void GLAPIENTRY _tnl_VertexAttrib1fARB( GLuint index, GLfloat x )
{
if (index >= MAX_VERTEX_ATTRIBS)
index = _TNL_ATTRIB_ERROR;
else if (index > 0)
index += VERT_ATTRIB_GENERIC0;
DISPATCH_ATTR1F( index, x );
}
static void GLAPIENTRY _tnl_VertexAttrib1fvARB(GLuint index, const GLfloat *v)
{
if (index >= MAX_VERTEX_ATTRIBS)
index = _TNL_ATTRIB_ERROR;
else if (index > 0)
index += VERT_ATTRIB_GENERIC0;
DISPATCH_ATTR1FV( index, v );
}
static void GLAPIENTRY _tnl_VertexAttrib2fARB( GLuint index, GLfloat x,
GLfloat y )
{
if (index >= MAX_VERTEX_ATTRIBS)
index = _TNL_ATTRIB_ERROR;
else if (index > 0)
index += VERT_ATTRIB_GENERIC0;
DISPATCH_ATTR2F( index, x, y );
}
static void GLAPIENTRY _tnl_VertexAttrib2fvARB(GLuint index, const GLfloat *v)
{
if (index >= MAX_VERTEX_ATTRIBS)
index = _TNL_ATTRIB_ERROR;
else if (index > 0)
index += VERT_ATTRIB_GENERIC0;
DISPATCH_ATTR2FV( index, v );
}
static void GLAPIENTRY _tnl_VertexAttrib3fARB(GLuint index, GLfloat x,
GLfloat y, GLfloat z)
{
if (index >= MAX_VERTEX_ATTRIBS)
index = _TNL_ATTRIB_ERROR;
else if (index > 0)
index += VERT_ATTRIB_GENERIC0;
DISPATCH_ATTR3F( index, x, y, z );
}
static void GLAPIENTRY _tnl_VertexAttrib3fvARB(GLuint index, const GLfloat *v)
{
if (index >= MAX_VERTEX_ATTRIBS)
index = _TNL_ATTRIB_ERROR;
else if (index > 0)
index += VERT_ATTRIB_GENERIC0;
DISPATCH_ATTR3FV( index, v );
}
static void GLAPIENTRY _tnl_VertexAttrib4fARB(GLuint index, GLfloat x,
GLfloat y, GLfloat z, GLfloat w)
{
if (index >= MAX_VERTEX_ATTRIBS)
index = _TNL_ATTRIB_ERROR;
else if (index > 0)
index += VERT_ATTRIB_GENERIC0;
DISPATCH_ATTR4F( index, x, y, z, w );
}
static void GLAPIENTRY _tnl_VertexAttrib4fvARB(GLuint index, const GLfloat *v)
{
if (index >= MAX_VERTEX_ATTRIBS)
index = _TNL_ATTRIB_ERROR;
else if (index > 0)
index += VERT_ATTRIB_GENERIC0;
DISPATCH_ATTR4FV( index, v );
}
/* Install the generic versions of the 2nd level dispatch
* functions. Some of these have a codegen alternative.
*/
void _tnl_generic_exec_vtxfmt_init( GLcontext *ctx )
{
GLvertexformat *vfmt = &(TNL_CONTEXT(ctx)->exec_vtxfmt);
vfmt->Color3f = _tnl_Color3f;
vfmt->Color3fv = _tnl_Color3fv;
vfmt->Color4f = _tnl_Color4f;
vfmt->Color4fv = _tnl_Color4fv;
vfmt->Indexf = _tnl_Indexf;
vfmt->Indexfv = _tnl_Indexfv;
vfmt->FogCoordfEXT = _tnl_FogCoordfEXT;
vfmt->FogCoordfvEXT = _tnl_FogCoordfvEXT;
vfmt->MultiTexCoord1fARB = _tnl_MultiTexCoord1f;
vfmt->MultiTexCoord1fvARB = _tnl_MultiTexCoord1fv;
vfmt->MultiTexCoord2fARB = _tnl_MultiTexCoord2f;
vfmt->MultiTexCoord2fvARB = _tnl_MultiTexCoord2fv;
vfmt->MultiTexCoord3fARB = _tnl_MultiTexCoord3f;
vfmt->MultiTexCoord3fvARB = _tnl_MultiTexCoord3fv;
vfmt->MultiTexCoord4fARB = _tnl_MultiTexCoord4f;
vfmt->MultiTexCoord4fvARB = _tnl_MultiTexCoord4fv;
vfmt->Normal3f = _tnl_Normal3f;
vfmt->Normal3fv = _tnl_Normal3fv;
vfmt->SecondaryColor3fEXT = _tnl_SecondaryColor3fEXT;
vfmt->SecondaryColor3fvEXT = _tnl_SecondaryColor3fvEXT;
vfmt->TexCoord1f = _tnl_TexCoord1f;
vfmt->TexCoord1fv = _tnl_TexCoord1fv;
vfmt->TexCoord2f = _tnl_TexCoord2f;
vfmt->TexCoord2fv = _tnl_TexCoord2fv;
vfmt->TexCoord3f = _tnl_TexCoord3f;
vfmt->TexCoord3fv = _tnl_TexCoord3fv;
vfmt->TexCoord4f = _tnl_TexCoord4f;
vfmt->TexCoord4fv = _tnl_TexCoord4fv;
vfmt->Vertex2f = _tnl_Vertex2f;
vfmt->Vertex2fv = _tnl_Vertex2fv;
vfmt->Vertex3f = _tnl_Vertex3f;
vfmt->Vertex3fv = _tnl_Vertex3fv;
vfmt->Vertex4f = _tnl_Vertex4f;
vfmt->Vertex4fv = _tnl_Vertex4fv;
vfmt->VertexAttrib1fNV = _tnl_VertexAttrib1fNV;
vfmt->VertexAttrib1fvNV = _tnl_VertexAttrib1fvNV;
vfmt->VertexAttrib2fNV = _tnl_VertexAttrib2fNV;
vfmt->VertexAttrib2fvNV = _tnl_VertexAttrib2fvNV;
vfmt->VertexAttrib3fNV = _tnl_VertexAttrib3fNV;
vfmt->VertexAttrib3fvNV = _tnl_VertexAttrib3fvNV;
vfmt->VertexAttrib4fNV = _tnl_VertexAttrib4fNV;
vfmt->VertexAttrib4fvNV = _tnl_VertexAttrib4fvNV;
vfmt->VertexAttrib1fARB = _tnl_VertexAttrib1fARB;
vfmt->VertexAttrib1fvARB = _tnl_VertexAttrib1fvARB;
vfmt->VertexAttrib2fARB = _tnl_VertexAttrib2fARB;
vfmt->VertexAttrib2fvARB = _tnl_VertexAttrib2fvARB;
vfmt->VertexAttrib3fARB = _tnl_VertexAttrib3fARB;
vfmt->VertexAttrib3fvARB = _tnl_VertexAttrib3fvARB;
vfmt->VertexAttrib4fARB = _tnl_VertexAttrib4fARB;
vfmt->VertexAttrib4fvARB = _tnl_VertexAttrib4fvARB;
}

View file

@ -1,396 +0,0 @@
/**************************************************************************
Copyright 2004 Tungsten Graphics Inc., Cedar Park, Texas.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
on the rights to use, copy, modify, merge, publish, distribute, sub
license, and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
/*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
* Daniel Borca <dborca@yahoo.com>
*/
#include "glheader.h"
#include "context.h"
#include "macros.h"
#include "vtxfmt.h"
#include "dlist.h"
#include "state.h"
#include "light.h"
#include "api_arrayelt.h"
#include "api_noop.h"
#include "t_vtx_api.h"
#include "simple_list.h"
#if defined(USE_X86_ASM) && !defined(HAVE_NONSTANDARD_GLAPIENTRY)
#define EXTERN( FUNC ) \
extern const char FUNC[]; \
extern const char FUNC##_end[]
EXTERN( _tnl_x86_Attribute1fv );
EXTERN( _tnl_x86_Attribute2fv );
EXTERN( _tnl_x86_Attribute3fv );
EXTERN( _tnl_x86_Attribute4fv );
EXTERN( _tnl_x86_Vertex1fv );
EXTERN( _tnl_x86_Vertex2fv );
EXTERN( _tnl_x86_Vertex3fv );
EXTERN( _tnl_x86_Vertex4fv );
EXTERN( _tnl_x86_dispatch_attrf1 );
EXTERN( _tnl_x86_dispatch_attrf2 );
EXTERN( _tnl_x86_dispatch_attrf3 );
EXTERN( _tnl_x86_dispatch_attrf4 );
EXTERN( _tnl_x86_dispatch_attrfv );
EXTERN( _tnl_x86_dispatch_multitexcoordf1 );
EXTERN( _tnl_x86_dispatch_multitexcoordf2 );
EXTERN( _tnl_x86_dispatch_multitexcoordf3 );
EXTERN( _tnl_x86_dispatch_multitexcoordf4 );
EXTERN( _tnl_x86_dispatch_multitexcoordfv );
EXTERN( _tnl_x86_dispatch_vertexattribf1 );
EXTERN( _tnl_x86_dispatch_vertexattribf2 );
EXTERN( _tnl_x86_dispatch_vertexattribf3 );
EXTERN( _tnl_x86_dispatch_vertexattribf4 );
EXTERN( _tnl_x86_dispatch_vertexattribfv );
EXTERN( _tnl_x86_choose_fv );
#define DONT_KNOW_OFFSETS 1
#define DFN( FUNC, CACHE, KEY ) \
struct _tnl_dynfn *dfn = MALLOC_STRUCT( _tnl_dynfn );\
const char *start = FUNC; \
const char *end = FUNC##_end; \
int offset = 0; \
insert_at_head( &CACHE, dfn ); \
dfn->key = KEY; \
dfn->code = ALIGN_MALLOC( end - start, 16 ); \
_mesa_memcpy (dfn->code, start, end - start)
#undef DEBUG_VTX
#ifdef DEBUG_VTX
#define FIXUP_PRINTF( offset, NEWVAL ) \
fprintf(stderr, "%s/%d: offset %d, new value: 0x%x\n", __FILE__, __LINE__, offset, (int)(NEWVAL))
#define FIXUPREL_PRINTF( offset, NEWVAL, CODE ) \
fprintf(stderr, "%s/%d: offset %d, new value: 0x%x\n", __FILE__, __LINE__, offset, (int)(NEWVAL) - ((int)(CODE)+offset) - 4)
#else
#define FIXUP_PRINTF( offset, NEWVAL )
#define FIXUPREL_PRINTF( offset, NEWVAL, CODE )
#endif
#define FIXUP( CODE, KNOWN_OFFSET, CHECKVAL, NEWVAL ) \
do { \
GLint subst = 0x10101010 + CHECKVAL; \
\
if (DONT_KNOW_OFFSETS) { \
while (*(int *)(CODE+offset) != subst) offset++; \
*(int *)(CODE+offset) = (int)(NEWVAL); \
FIXUP_PRINTF(offset, NEWVAL); \
offset += 4; \
} \
else { \
int *icode = (int *)(CODE+KNOWN_OFFSET); \
assert (*icode == subst); \
*icode = (int)NEWVAL; \
} \
} while (0)
#define FIXUPREL( CODE, KNOWN_OFFSET, CHECKVAL, NEWVAL )\
do { \
GLint subst = 0x10101010 + CHECKVAL; \
\
if (DONT_KNOW_OFFSETS) { \
while (*(int *)(CODE+offset) != subst) offset++; \
*(int *)(CODE+offset) = (int)(NEWVAL) - ((int)(CODE)+offset) - 4; \
FIXUPREL_PRINTF(offset, NEWVAL, CODE); \
offset += 4; \
} \
else { \
int *icode = (int *)(CODE+KNOWN_OFFSET); \
assert (*icode == subst); \
*icode = (int)(NEWVAL) - (int)(icode) - 4; \
} \
} while (0)
/* Build specialized versions of the immediate calls on the fly for
* the current state. Generic x86 versions.
*/
static struct _tnl_dynfn *makeX86Vertex1fv( GLcontext *ctx, int vertex_size )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
DFN ( _tnl_x86_Vertex1fv, tnl->vtx.cache.Vertex[1-1], vertex_size );
FIXUP(dfn->code, 0, 0, (int)&tnl->vtx.vbptr);
FIXUP(dfn->code, 0, 1, vertex_size - 1);
FIXUP(dfn->code, 0, 2, (int)&tnl->vtx.vertex[1]);
FIXUP(dfn->code, 0, 0, (int)&tnl->vtx.vbptr);
FIXUP(dfn->code, 0, 3, (int)&tnl->vtx.counter);
FIXUP(dfn->code, 0, 3, (int)&tnl->vtx.counter);
FIXUP(dfn->code, 0, 4, (int)ctx);
FIXUPREL(dfn->code, 0, 5, (int)&_tnl_wrap_filled_vertex);
return dfn;
}
static struct _tnl_dynfn *makeX86Vertex2fv( GLcontext *ctx, int vertex_size )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
DFN ( _tnl_x86_Vertex2fv, tnl->vtx.cache.Vertex[2-1], vertex_size );
FIXUP(dfn->code, 0, 0, (int)&tnl->vtx.vbptr);
FIXUP(dfn->code, 0, 1, vertex_size - 2);
FIXUP(dfn->code, 0, 2, (int)&tnl->vtx.vertex[2]);
FIXUP(dfn->code, 0, 0, (int)&tnl->vtx.vbptr);
FIXUP(dfn->code, 0, 3, (int)&tnl->vtx.counter);
FIXUP(dfn->code, 0, 3, (int)&tnl->vtx.counter);
FIXUP(dfn->code, 0, 4, (int)ctx);
FIXUPREL(dfn->code, 0, 5, (int)&_tnl_wrap_filled_vertex);
return dfn;
}
static struct _tnl_dynfn *makeX86Vertex3fv( GLcontext *ctx, int vertex_size )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
switch (vertex_size) {
default: {
DFN ( _tnl_x86_Vertex3fv, tnl->vtx.cache.Vertex[3-1], vertex_size );
FIXUP(dfn->code, 0, 0, (int)&tnl->vtx.vbptr);
FIXUP(dfn->code, 0, 1, vertex_size - 3);
FIXUP(dfn->code, 0, 2, (int)&tnl->vtx.vertex[3]);
FIXUP(dfn->code, 0, 0, (int)&tnl->vtx.vbptr);
FIXUP(dfn->code, 0, 3, (int)&tnl->vtx.counter);
FIXUP(dfn->code, 0, 3, (int)&tnl->vtx.counter);
FIXUP(dfn->code, 0, 4, (int)ctx);
FIXUPREL(dfn->code, 0, 5, (int)&_tnl_wrap_filled_vertex);
return dfn;
}
}
}
static struct _tnl_dynfn *makeX86Vertex4fv( GLcontext *ctx, int vertex_size )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
DFN ( _tnl_x86_Vertex4fv, tnl->vtx.cache.Vertex[4-1], vertex_size );
FIXUP(dfn->code, 0, 0, (int)&tnl->vtx.vbptr);
FIXUP(dfn->code, 0, 1, vertex_size - 4);
FIXUP(dfn->code, 0, 2, (int)&tnl->vtx.vertex[4]);
FIXUP(dfn->code, 0, 0, (int)&tnl->vtx.vbptr);
FIXUP(dfn->code, 0, 3, (int)&tnl->vtx.counter);
FIXUP(dfn->code, 0, 3, (int)&tnl->vtx.counter);
FIXUP(dfn->code, 0, 4, (int)ctx);
FIXUPREL(dfn->code, 0, 5, (int)&_tnl_wrap_filled_vertex);
return dfn;
}
static struct _tnl_dynfn *makeX86Attribute1fv( GLcontext *ctx, int dest )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
DFN ( _tnl_x86_Attribute1fv, tnl->vtx.cache.Attribute[1-1], dest );
FIXUP(dfn->code, 0, 0, dest);
return dfn;
}
static struct _tnl_dynfn *makeX86Attribute2fv( GLcontext *ctx, int dest )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
DFN ( _tnl_x86_Attribute2fv, tnl->vtx.cache.Attribute[2-1], dest );
FIXUP(dfn->code, 0, 0, dest);
FIXUP(dfn->code, 0, 1, 4+dest);
return dfn;
}
static struct _tnl_dynfn *makeX86Attribute3fv( GLcontext *ctx, int dest )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
DFN ( _tnl_x86_Attribute3fv, tnl->vtx.cache.Attribute[3-1], dest );
FIXUP(dfn->code, 0, 0, dest);
FIXUP(dfn->code, 0, 1, 4+dest);
FIXUP(dfn->code, 0, 2, 8+dest);
return dfn;
}
static struct _tnl_dynfn *makeX86Attribute4fv( GLcontext *ctx, int dest )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
DFN ( _tnl_x86_Attribute4fv, tnl->vtx.cache.Attribute[4-1], dest );
FIXUP(dfn->code, 0, 0, dest);
FIXUP(dfn->code, 0, 1, 4+dest);
FIXUP(dfn->code, 0, 2, 8+dest);
FIXUP(dfn->code, 0, 3, 12+dest);
return dfn;
}
void _tnl_InitX86Codegen( struct _tnl_dynfn_generators *gen )
{
gen->Vertex[0] = makeX86Vertex1fv;
gen->Vertex[1] = makeX86Vertex2fv;
gen->Vertex[2] = makeX86Vertex3fv;
gen->Vertex[3] = makeX86Vertex4fv;
gen->Attribute[0] = makeX86Attribute1fv;
gen->Attribute[1] = makeX86Attribute2fv;
gen->Attribute[2] = makeX86Attribute3fv;
gen->Attribute[3] = makeX86Attribute4fv;
}
#define MKDISP(FUNC, SIZE, ATTR, WARP) \
do { \
char *code; \
const char *start = WARP; \
const char *end = WARP##_end; \
int offset = 0; \
code = ALIGN_MALLOC( end - start, 16 ); \
_mesa_memcpy (code, start, end - start); \
FIXUP(code, 0, 0, (int)&(TNL_CONTEXT(ctx)->vtx.tabfv[ATTR][SIZE-1]));\
*(void **)&vfmt->FUNC = code; \
} while (0)
/* Install the codegen'ed versions of the 2nd level dispatch
* functions. We should keep a list and free them in the end...
*/
void _tnl_x86_exec_vtxfmt_init( GLcontext *ctx )
{
GLvertexformat *vfmt = &(TNL_CONTEXT(ctx)->exec_vtxfmt);
MKDISP(Color3f, 3, _TNL_ATTRIB_COLOR0, _tnl_x86_dispatch_attrf3);
MKDISP(Color3fv, 3, _TNL_ATTRIB_COLOR0, _tnl_x86_dispatch_attrfv);
MKDISP(Color4f, 4, _TNL_ATTRIB_COLOR0, _tnl_x86_dispatch_attrf4);
MKDISP(Color4fv, 4, _TNL_ATTRIB_COLOR0, _tnl_x86_dispatch_attrfv);
MKDISP(FogCoordfEXT, 1, _TNL_ATTRIB_FOG, _tnl_x86_dispatch_attrf1);
MKDISP(FogCoordfvEXT, 1, _TNL_ATTRIB_FOG, _tnl_x86_dispatch_attrfv);
MKDISP(Normal3f, 3, _TNL_ATTRIB_NORMAL, _tnl_x86_dispatch_attrf3);
MKDISP(Normal3fv, 3, _TNL_ATTRIB_NORMAL, _tnl_x86_dispatch_attrfv);
MKDISP(SecondaryColor3fEXT, 3, _TNL_ATTRIB_COLOR1, _tnl_x86_dispatch_attrf3);
MKDISP(SecondaryColor3fvEXT,3, _TNL_ATTRIB_COLOR1, _tnl_x86_dispatch_attrfv);
MKDISP(TexCoord1f, 1, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_attrf1);
MKDISP(TexCoord1fv, 1, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_attrfv);
MKDISP(TexCoord2f, 2, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_attrf2);
MKDISP(TexCoord2fv, 2, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_attrfv);
MKDISP(TexCoord3f, 3, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_attrf3);
MKDISP(TexCoord3fv, 3, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_attrfv);
MKDISP(TexCoord4f, 4, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_attrf4);
MKDISP(TexCoord4fv, 4, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_attrfv);
MKDISP(Vertex2f, 2, _TNL_ATTRIB_POS, _tnl_x86_dispatch_attrf2);
MKDISP(Vertex2fv, 2, _TNL_ATTRIB_POS, _tnl_x86_dispatch_attrfv);
MKDISP(Vertex3f, 3, _TNL_ATTRIB_POS, _tnl_x86_dispatch_attrf3);
MKDISP(Vertex3fv, 3, _TNL_ATTRIB_POS, _tnl_x86_dispatch_attrfv);
MKDISP(Vertex4f, 4, _TNL_ATTRIB_POS, _tnl_x86_dispatch_attrf4);
MKDISP(Vertex4fv, 4, _TNL_ATTRIB_POS, _tnl_x86_dispatch_attrfv);
MKDISP(MultiTexCoord1fARB, 1, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_multitexcoordf1);
MKDISP(MultiTexCoord1fvARB, 1, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_multitexcoordfv);
MKDISP(MultiTexCoord2fARB, 2, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_multitexcoordf2);
MKDISP(MultiTexCoord2fvARB, 2, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_multitexcoordfv);
MKDISP(MultiTexCoord3fARB, 3, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_multitexcoordf3);
MKDISP(MultiTexCoord3fvARB, 3, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_multitexcoordfv);
MKDISP(MultiTexCoord4fARB, 4, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_multitexcoordf4);
MKDISP(MultiTexCoord4fvARB, 4, _TNL_ATTRIB_TEX0, _tnl_x86_dispatch_multitexcoordfv);
MKDISP(VertexAttrib1fNV, 1, 0, _tnl_x86_dispatch_vertexattribf1);
MKDISP(VertexAttrib1fvNV, 1, 0, _tnl_x86_dispatch_vertexattribfv);
MKDISP(VertexAttrib2fNV, 2, 0, _tnl_x86_dispatch_vertexattribf2);
MKDISP(VertexAttrib2fvNV, 2, 0, _tnl_x86_dispatch_vertexattribfv);
MKDISP(VertexAttrib3fNV, 3, 0, _tnl_x86_dispatch_vertexattribf3);
MKDISP(VertexAttrib3fvNV, 3, 0, _tnl_x86_dispatch_vertexattribfv);
MKDISP(VertexAttrib4fNV, 4, 0, _tnl_x86_dispatch_vertexattribf4);
MKDISP(VertexAttrib4fvNV, 4, 0, _tnl_x86_dispatch_vertexattribfv);
}
/* Install the codegen'ed choosers.
* We should keep a list and free them in the end...
*/
void _tnl_x86choosers( tnl_attrfv_func (*choose)[4],
tnl_attrfv_func (*do_choose)( GLuint attr,
GLuint sz ))
{
int attr, size;
for (attr = 0; attr < _TNL_MAX_ATTR_CODEGEN; attr++) {
for (size = 0; size < 4; size++) {
char *code;
const char *start = _tnl_x86_choose_fv;
const char *end = _tnl_x86_choose_fv_end;
int offset = 0;
code = ALIGN_MALLOC( end - start, 16 );
_mesa_memcpy (code, start, end - start);
FIXUP(code, 0, 0, attr);
FIXUP(code, 0, 1, size + 1);
FIXUPREL(code, 0, 2, do_choose);
choose[attr][size] = (tnl_attrfv_func)code;
}
}
}
#else
void _tnl_InitX86Codegen( struct _tnl_dynfn_generators *gen )
{
(void) gen;
}
void _tnl_x86_exec_vtxfmt_init( GLcontext *ctx )
{
(void) ctx;
}
void _tnl_x86choosers( tnl_attrfv_func (*choose)[4],
tnl_attrfv_func (*do_choose)( GLuint attr,
GLuint sz ))
{
(void) choose;
(void) do_choose;
}
#endif

View file

@ -1,561 +0,0 @@
/**************************************************************************
Copyright 2004 Tungsten Graphics Inc., Cedar Park, Texas.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
on the rights to use, copy, modify, merge, publish, distribute, sub
license, and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
/*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
* Daniel Borca <dborca@yahoo.com>
*/
#if defined (__DJGPP__) || defined (__MINGW32__) || defined (__CYGWIN__)
#define GLOBL( x ) \
.globl _##x; \
_##x:
#else /* !defined (__DJGPP__) && !defined (__MINGW32__) && !defined (__CYGWIN__) */
#define GLOBL( x ) \
.globl x; \
x:
#endif /* !defined (__DJGPP__) && !defined (__MINGW32__) && !defined (__CYGWIN__) */
#if !defined (STDCALL_API)
#define RETCLEAN( x ) ret
#else
#define RETCLEAN( x ) ret $x
#endif
#define _JMP(x) \
.byte 0xe9; \
.long x
#define _CALL(x) \
.byte 0xe8; \
.long x
/* Someone who knew a lot about this sort of thing would use this
* macro to note current offsets, etc in a special region of the
* object file & just make everything work out neat. I don't know
* enough to do that...
*/
#define SUBST( x ) (0x10101010 + x)
.data
/* [dBorca] TODO
* Unfold functions for each vertex size?
* Build super-specialized SSE versions?
*
* There is a trick in Vertex*fv: under certain conditions,
* we tail to _tnl_wrap_filled_vertex(ctx). This means that
* if Vertex*fv is STDCALL, then _tnl_wrap_filled_vertex must
* be STDCALL as well, because (GLcontext *) and (GLfloat *)
* have the same size.
*/
.align 4
GLOBL ( _tnl_x86_Vertex1fv )
movl 4(%esp), %ecx
push %edi
push %esi
movl SUBST(0), %edi /* 0x0 --> tnl->vtx.vbptr */
movl (%ecx), %edx /* load v[0] */
movl %edx, (%edi) /* tnl->vtx.vbptr[0] = v[0] */
addl $4, %edi /* tnl->vtx.vbptr += 1 */
movl $SUBST(1), %ecx /* 0x1 --> (tnl->vtx.vertex_size - 1) */
movl $SUBST(2), %esi /* 0x2 --> (tnl->vtx.vertex + 1) */
repz
movsl %ds:(%esi), %es:(%edi)
movl %edi, SUBST(0) /* 0x0 --> tnl->vtx.vbptr */
movl SUBST(3), %edx /* 0x3 --> counter */
pop %esi
pop %edi
dec %edx /* counter-- */
movl %edx, SUBST(3) /* 0x3 --> counter */
je .0 /* if (counter == 0) goto .0 */
RETCLEAN(4) /* return */
.balign 16
.0:
movl $SUBST(4), %eax /* load ctx */
movl %eax, 4(%esp) /* push ctx */
_JMP (SUBST(5)) /* jmp _tnl_wrap_filled_vertex */
GLOBL ( _tnl_x86_Vertex1fv_end )
.align 4
GLOBL ( _tnl_x86_Vertex2fv )
movl 4(%esp), %ecx
push %edi
push %esi
movl SUBST(0), %edi /* load tnl->vtx.vbptr */
movl (%ecx), %edx /* load v[0] */
movl 4(%ecx), %eax /* load v[1] */
movl %edx, (%edi) /* tnl->vtx.vbptr[0] = v[0] */
movl %eax, 4(%edi) /* tnl->vtx.vbptr[1] = v[1] */
addl $8, %edi /* tnl->vtx.vbptr += 2 */
movl $SUBST(1), %ecx /* vertex_size - 2 */
movl $SUBST(2), %esi /* tnl->vtx.vertex + 2 */
repz
movsl %ds:(%esi), %es:(%edi)
movl %edi, SUBST(0) /* save tnl->vtx.vbptr */
movl SUBST(3), %edx /* load counter */
pop %esi
pop %edi
dec %edx /* counter-- */
movl %edx, SUBST(3) /* save counter */
je .1 /* if (counter == 0) goto .1 */
RETCLEAN(4) /* return */
.balign 16
.1:
movl $SUBST(4), %eax /* load ctx */
movl %eax, 4(%esp) /* push ctx */
_JMP (SUBST(5)) /* jmp _tnl_wrap_filled_vertex */
GLOBL ( _tnl_x86_Vertex2fv_end )
.align 4
GLOBL ( _tnl_x86_Vertex3fv )
movl 4(%esp), %ecx
push %edi
push %esi
movl SUBST(0), %edi /* load tnl->vtx.vbptr */
movl (%ecx), %edx /* load v[0] */
movl 4(%ecx), %eax /* load v[1] */
movl 8(%ecx), %esi /* load v[2] */
movl %edx, (%edi) /* tnl->vtx.vbptr[0] = v[0] */
movl %eax, 4(%edi) /* tnl->vtx.vbptr[1] = v[1] */
movl %esi, 8(%edi) /* tnl->vtx.vbptr[2] = v[2] */
addl $12, %edi /* tnl->vtx.vbptr += 3 */
movl $SUBST(1), %ecx /* vertex_size - 3 */
movl $SUBST(2), %esi /* tnl->vtx.vertex + 3 */
repz
movsl %ds:(%esi), %es:(%edi)
movl %edi, SUBST(0) /* save tnl->vtx.vbptr */
movl SUBST(3), %edx /* load counter */
pop %esi
pop %edi
dec %edx /* counter-- */
movl %edx, SUBST(3) /* save counter */
je .2 /* if (counter == 0) goto .2 */
RETCLEAN(4) /* return */
.balign 16
.2:
movl $SUBST(4), %eax /* load ctx */
movl %eax, 4(%esp) /* push ctx */
_JMP (SUBST(5)) /* jmp _tnl_wrap_filled_vertex */
GLOBL ( _tnl_x86_Vertex3fv_end )
.align 4
GLOBL ( _tnl_x86_Vertex4fv )
movl 4(%esp), %ecx
push %edi
push %esi
movl SUBST(0), %edi /* load tnl->vtx.vbptr */
movl (%ecx), %edx /* load v[0] */
movl 4(%ecx), %eax /* load v[1] */
movl 8(%ecx), %esi /* load v[2] */
movl 12(%ecx), %ecx /* load v[3] */
movl %edx, (%edi) /* tnl->vtx.vbptr[0] = v[0] */
movl %eax, 4(%edi) /* tnl->vtx.vbptr[1] = v[1] */
movl %esi, 8(%edi) /* tnl->vtx.vbptr[2] = v[2] */
movl %ecx, 12(%edi) /* tnl->vtx.vbptr[3] = v[3] */
addl $16, %edi /* tnl->vtx.vbptr += 4 */
movl $SUBST(1), %ecx /* vertex_size - 4 */
movl $SUBST(2), %esi /* tnl->vtx.vertex + 4 */
repz
movsl %ds:(%esi), %es:(%edi)
movl %edi, SUBST(0) /* save tnl->vtx.vbptr */
movl SUBST(3), %edx /* load counter */
pop %esi
pop %edi
dec %edx /* counter-- */
movl %edx, SUBST(3) /* save counter */
je .3 /* if (counter == 0) goto .3 */
RETCLEAN(4) /* return */
.balign 16
.3:
movl $SUBST(4), %eax /* load ctx */
movl %eax, 4(%esp) /* push ctx */
_JMP (SUBST(5)) /* jmp _tnl_wrap_filled_vertex */
GLOBL ( _tnl_x86_Vertex4fv_end )
/**
* Generic handlers for vector format data.
*/
GLOBL( _tnl_x86_Attribute1fv )
movl 4(%esp), %ecx
movl (%ecx), %eax /* load v[0] */
movl %eax, SUBST(0) /* store v[0] to current vertex */
RETCLEAN(4)
GLOBL ( _tnl_x86_Attribute1fv_end )
GLOBL( _tnl_x86_Attribute2fv )
movl 4(%esp), %ecx
movl (%ecx), %eax /* load v[0] */
movl 4(%ecx), %edx /* load v[1] */
movl %eax, SUBST(0) /* store v[0] to current vertex */
movl %edx, SUBST(1) /* store v[1] to current vertex */
RETCLEAN(4)
GLOBL ( _tnl_x86_Attribute2fv_end )
GLOBL( _tnl_x86_Attribute3fv )
movl 4(%esp), %ecx
movl (%ecx), %eax /* load v[0] */
movl 4(%ecx), %edx /* load v[1] */
movl 8(%ecx), %ecx /* load v[2] */
movl %eax, SUBST(0) /* store v[0] to current vertex */
movl %edx, SUBST(1) /* store v[1] to current vertex */
movl %ecx, SUBST(2) /* store v[2] to current vertex */
RETCLEAN(4)
GLOBL ( _tnl_x86_Attribute3fv_end )
GLOBL( _tnl_x86_Attribute4fv )
movl 4(%esp), %ecx
movl (%ecx), %eax /* load v[0] */
movl 4(%ecx), %edx /* load v[1] */
movl %eax, SUBST(0) /* store v[0] to current vertex */
movl %edx, SUBST(1) /* store v[1] to current vertex */
movl 8(%ecx), %eax /* load v[2] */
movl 12(%ecx), %edx /* load v[3] */
movl %eax, SUBST(2) /* store v[2] to current vertex */
movl %edx, SUBST(3) /* store v[3] to current vertex */
RETCLEAN(4)
GLOBL ( _tnl_x86_Attribute4fv_end )
/* Choosers:
*
* Must generate all of these ahead of first usage. Generate at
* compile-time?
*/
GLOBL( _tnl_x86_choose_fv )
subl $12, %esp /* gcc does 16 byte alignment of stack frames? */
movl $SUBST(0), (%esp) /* arg 0 - attrib */
movl $SUBST(1), 4(%esp) /* arg 1 - N */
_CALL (SUBST(2)) /* call do_choose */
add $12, %esp /* tear down stack frame */
jmp *%eax /* jump to new func */
GLOBL ( _tnl_x86_choose_fv_end )
/* FIRST LEVEL FUNCTIONS -- these are plugged directly into GL dispatch.
*
* In the 1st level dispatch functions, switch to a different
* calling convention -- (const GLfloat *v) in %ecx.
*
* As with regular (x86) dispatch, don't create a new stack frame -
* just let the 'ret' in the dispatched function return straight
* back to the original caller.
*
* Vertex/Normal/Color, etc: the address of the function pointer
* is known at codegen time.
*/
/* Unfortunately, have to play with the stack in the non-fv case:
*/
#if !defined (STDCALL_API)
GLOBL( _tnl_x86_dispatch_attrf1 )
GLOBL( _tnl_x86_dispatch_attrf2 )
GLOBL( _tnl_x86_dispatch_attrf3 )
GLOBL( _tnl_x86_dispatch_attrf4 )
subl $12, %esp /* gcc does 16 byte alignment of stack frames? */
leal 16(%esp), %edx /* address of first float on stack */
movl %edx, (%esp) /* save as 'v' */
call *SUBST(0) /* 0x0 --> tabfv[attr][n] */
addl $12, %esp /* tear down frame */
ret /* return */
GLOBL( _tnl_x86_dispatch_attrf4_end )
GLOBL( _tnl_x86_dispatch_attrf3_end )
GLOBL( _tnl_x86_dispatch_attrf2_end )
GLOBL( _tnl_x86_dispatch_attrf1_end )
#else /* defined(STDCALL_API) */
GLOBL( _tnl_x86_dispatch_attrf1 )
subl $12, %esp /* gcc does 16 byte alignment of stack frames? */
leal 16(%esp), %edx /* address of first float on stack */
movl %edx, (%esp) /* save as 'v' */
call *SUBST(0) /* 0x0 --> tabfv[attr][n] */
addl $8, %esp /* tear down frame (4 shaved off by the callee) */
ret $4 /* return */
GLOBL( _tnl_x86_dispatch_attrf1_end )
GLOBL( _tnl_x86_dispatch_attrf2 )
subl $12, %esp /* gcc does 16 byte alignment of stack frames? */
leal 16(%esp), %edx /* address of first float on stack */
movl %edx, (%esp) /* save as 'v' */
call *SUBST(0) /* 0x0 --> tabfv[attr][n] */
addl $8, %esp /* tear down frame (4 shaved off by the callee) */
ret $8 /* return */
GLOBL( _tnl_x86_dispatch_attrf2_end )
GLOBL( _tnl_x86_dispatch_attrf3 )
subl $12, %esp /* gcc does 16 byte alignment of stack frames? */
leal 16(%esp), %edx /* address of first float on stack */
movl %edx, (%esp) /* save as 'v' */
call *SUBST(0) /* 0x0 --> tabfv[attr][n] */
addl $8, %esp /* tear down frame (4 shaved off by the callee) */
ret $12 /* return */
GLOBL( _tnl_x86_dispatch_attrf3_end )
GLOBL( _tnl_x86_dispatch_attrf4 )
subl $12, %esp /* gcc does 16 byte alignment of stack frames? */
leal 16(%esp), %edx /* address of first float on stack */
movl %edx, (%esp) /* save as 'v' */
call *SUBST(0) /* 0x0 --> tabfv[attr][n] */
addl $8, %esp /* tear down frame (4 shaved off by the callee) */
ret $16 /* return */
GLOBL( _tnl_x86_dispatch_attrf4_end )
#endif /* defined(STDCALL_API) */
/* The fv case is simpler:
*/
GLOBL( _tnl_x86_dispatch_attrfv )
jmp *SUBST(0) /* 0x0 --> tabfv[attr][n] */
GLOBL( _tnl_x86_dispatch_attrfv_end )
/* MultiTexcoord: the address of the function pointer must be
* calculated, but can use the index argument slot to hold 'v', and
* avoid setting up a new stack frame.
*
* [dBorca]
* right, this would be the preferred approach, but gcc does not
* clean up the stack after each function call when optimizing (-fdefer-pop);
* can it make assumptions about what's already on the stack? I dunno,
* but in this case, we can't mess with the caller's stack frame, and
* we must use a model like `_x86_dispatch_attrfv' above. Caveat emptor!
*/
/* Also, will only need a maximum of four of each of these per context:
*/
#if !defined (STDCALL_API)
GLOBL( _tnl_x86_dispatch_multitexcoordf1 )
GLOBL( _tnl_x86_dispatch_multitexcoordf2 )
GLOBL( _tnl_x86_dispatch_multitexcoordf3 )
GLOBL( _tnl_x86_dispatch_multitexcoordf4 )
movl 4(%esp), %ecx
leal 8(%esp), %edx
andl $7, %ecx
movl %edx, 4(%esp)
sall $4, %ecx
jmp *SUBST(0)(%ecx) /* 0x0 - tabfv[tex0][n] */
GLOBL( _tnl_x86_dispatch_multitexcoordf4_end )
GLOBL( _tnl_x86_dispatch_multitexcoordf3_end )
GLOBL( _tnl_x86_dispatch_multitexcoordf2_end )
GLOBL( _tnl_x86_dispatch_multitexcoordf1_end )
GLOBL( _tnl_x86_dispatch_multitexcoordfv )
movl 4(%esp), %ecx
movl 8(%esp), %edx
andl $7, %ecx
movl %edx, 4(%esp)
sall $4, %ecx
jmp *SUBST(0)(%ecx) /* 0x0 - tabfv[tex0][n] */
GLOBL( _tnl_x86_dispatch_multitexcoordfv_end )
#else /* defined (STDCALL_API) */
GLOBL( _tnl_x86_dispatch_multitexcoordf1 )
subl $12, %esp /* gcc does 16 byte alignment of stack frames? */
movl 16(%esp), %ecx
leal 20(%esp), %edx
andl $7, %ecx
movl %edx, (%esp)
sall $4, %ecx
call *SUBST(0)(%ecx) /* 0x0 - tabfv[tex0][n] */
addl $8, %esp /* tear down frame (4 shaved off by the callee) */
ret $8 /* return */
GLOBL( _tnl_x86_dispatch_multitexcoordf1_end )
GLOBL( _tnl_x86_dispatch_multitexcoordf2 )
subl $12, %esp /* gcc does 16 byte alignment of stack frames? */
movl 16(%esp), %ecx
leal 20(%esp), %edx
andl $7, %ecx
movl %edx, (%esp)
sall $4, %ecx
call *SUBST(0)(%ecx) /* 0x0 - tabfv[tex0][n] */
addl $8, %esp /* tear down frame (4 shaved off by the callee) */
ret $12 /* return */
GLOBL( _tnl_x86_dispatch_multitexcoordf2_end )
GLOBL( _tnl_x86_dispatch_multitexcoordf3 )
subl $12, %esp /* gcc does 16 byte alignment of stack frames? */
movl 16(%esp), %ecx
leal 20(%esp), %edx
andl $7, %ecx
movl %edx, (%esp)
sall $4, %ecx
call *SUBST(0)(%ecx) /* 0x0 - tabfv[tex0][n] */
addl $8, %esp /* tear down frame (4 shaved off by the callee) */
ret $16 /* return */
GLOBL( _tnl_x86_dispatch_multitexcoordf3_end )
GLOBL( _tnl_x86_dispatch_multitexcoordf4 )
subl $12, %esp /* gcc does 16 byte alignment of stack frames? */
movl 16(%esp), %ecx
leal 20(%esp), %edx
andl $7, %ecx
movl %edx, (%esp)
sall $4, %ecx
call *SUBST(0)(%ecx) /* 0x0 - tabfv[tex0][n] */
addl $8, %esp /* tear down frame (4 shaved off by the callee) */
ret $20 /* return */
GLOBL( _tnl_x86_dispatch_multitexcoordf4_end )
GLOBL( _tnl_x86_dispatch_multitexcoordfv )
subl $12, %esp /* gcc does 16 byte alignment of stack frames? */
movl 16(%esp), %ecx
movl 20(%esp), %edx
andl $7, %ecx
movl %edx, (%esp)
sall $4, %ecx
call *SUBST(0)(%ecx) /* 0x0 - tabfv[tex0][n] */
addl $8, %esp /* tear down frame (4 shaved off by the callee) */
ret $8 /* return */
GLOBL( _tnl_x86_dispatch_multitexcoordfv_end )
#endif /* defined (STDCALL_API) */
/* VertexAttrib: the address of the function pointer must be
* calculated.
*/
#if !defined (STDCALL_API)
GLOBL( _tnl_x86_dispatch_vertexattribf1 )
GLOBL( _tnl_x86_dispatch_vertexattribf2 )
GLOBL( _tnl_x86_dispatch_vertexattribf3 )
GLOBL( _tnl_x86_dispatch_vertexattribf4 )
movl 4(%esp), %eax
cmpl $16, %eax
jb .8 /* "cmovge" is not supported on all CPUs */
movl $16, %eax
.8:
leal 8(%esp), %ecx /* calculate 'v' */
movl %ecx, 4(%esp) /* save in 1st arg slot */
sall $4, %eax
jmp *SUBST(0)(%eax) /* 0x0 - tabfv[0][n] */
GLOBL( _tnl_x86_dispatch_vertexattribf4_end )
GLOBL( _tnl_x86_dispatch_vertexattribf3_end )
GLOBL( _tnl_x86_dispatch_vertexattribf2_end )
GLOBL( _tnl_x86_dispatch_vertexattribf1_end )
GLOBL( _tnl_x86_dispatch_vertexattribfv )
movl 4(%esp), %eax
cmpl $16, %eax
jb .9 /* "cmovge" is not supported on all CPUs */
movl $16, %eax
.9:
movl 8(%esp), %ecx /* load 'v' */
movl %ecx, 4(%esp) /* save in 1st arg slot */
sall $4, %eax
jmp *SUBST(0)(%eax) /* 0x0 - tabfv[0][n] */
GLOBL( _tnl_x86_dispatch_vertexattribfv_end )
#else /* defined (STDCALL_API) */
GLOBL( _tnl_x86_dispatch_vertexattribf1 )
subl $12, %esp /* gcc does 16 byte alignment of stack frames? */
movl 16(%esp), %eax
cmpl $16, %eax
jb .81 /* "cmovge" is not supported on all CPUs */
movl $16, %eax
.81:
leal 20(%esp), %ecx /* load 'v' */
movl %ecx, (%esp) /* save in 1st arg slot */
sall $4, %eax
call *SUBST(0)(%eax) /* 0x0 - tabfv[0][n] */
addl $8, %esp /* tear down frame (4 shaved off by the callee) */
ret $8 /* return */
GLOBL( _tnl_x86_dispatch_vertexattribf1_end )
GLOBL( _tnl_x86_dispatch_vertexattribf2 )
subl $12, %esp /* gcc does 16 byte alignment of stack frames? */
movl 16(%esp), %eax
cmpl $16, %eax
jb .82 /* "cmovge" is not supported on all CPUs */
movl $16, %eax
.82:
leal 20(%esp), %ecx /* load 'v' */
movl %ecx, (%esp) /* save in 1st arg slot */
sall $4, %eax
call *SUBST(0)(%eax) /* 0x0 - tabfv[0][n] */
addl $8, %esp /* tear down frame (4 shaved off by the callee) */
ret $12 /* return */
GLOBL( _tnl_x86_dispatch_vertexattribf2_end )
GLOBL( _tnl_x86_dispatch_vertexattribf3 )
subl $12, %esp /* gcc does 16 byte alignment of stack frames? */
movl 16(%esp), %eax
cmpl $16, %eax
jb .83 /* "cmovge" is not supported on all CPUs */
movl $16, %eax
.83:
leal 20(%esp), %ecx /* load 'v' */
movl %ecx, (%esp) /* save in 1st arg slot */
sall $4, %eax
call *SUBST(0)(%eax) /* 0x0 - tabfv[0][n] */
addl $8, %esp /* tear down frame (4 shaved off by the callee) */
ret $16 /* return */
GLOBL( _tnl_x86_dispatch_vertexattribf3_end )
GLOBL( _tnl_x86_dispatch_vertexattribf4 )
subl $12, %esp /* gcc does 16 byte alignment of stack frames? */
movl 16(%esp), %eax
cmpl $16, %eax
jb .84 /* "cmovge" is not supported on all CPUs */
movl $16, %eax
.84:
leal 20(%esp), %ecx /* load 'v' */
movl %ecx, (%esp) /* save in 1st arg slot */
sall $4, %eax
call *SUBST(0)(%eax) /* 0x0 - tabfv[0][n] */
addl $8, %esp /* tear down frame (4 shaved off by the callee) */
ret $20 /* return */
GLOBL( _tnl_x86_dispatch_vertexattribf4_end )
GLOBL( _tnl_x86_dispatch_vertexattribfv )
subl $12, %esp /* gcc does 16 byte alignment of stack frames? */
movl 16(%esp), %eax
cmpl $16, %eax
jb .9 /* "cmovge" is not supported on all CPUs */
movl $16, %eax
.9:
movl 20(%esp), %ecx /* load 'v' */
movl %ecx, (%esp) /* save in 1st arg slot */
sall $4, %eax
call *SUBST(0)(%eax) /* 0x0 - tabfv[0][n] */
addl $8, %esp /* tear down frame (4 shaved off by the callee) */
ret $8 /* return */
GLOBL( _tnl_x86_dispatch_vertexattribfv_end )
#endif /* defined (STDCALL_API) */
#if defined (__ELF__) && defined (__linux__)
.section .note.GNU-stack,"",%progbits
#endif

View file

@ -50,30 +50,14 @@ _tnl_InvalidateState( GLcontext *ctx, GLuint new_state );
* dispatch and/or driver callbacks.
*/
/* Restore just the ctx->Exec table:
*/
extern void
_tnl_wakeup_exec( GLcontext *ctx );
/* Restore both ctx->Exec and ctx->Save:
*/
extern void
_tnl_wakeup_save_exec( GLcontext *ctx );
_tnl_wakeup( GLcontext *ctx );
/* Driver configuration options:
*/
extern void
_tnl_need_projected_coords( GLcontext *ctx, GLboolean flag );
extern void
_tnl_need_dlist_loopback( GLcontext *ctx, GLboolean flag );
extern void
_tnl_need_dlist_norm_lengths( GLcontext *ctx, GLboolean flag );
extern void
_tnl_isolate_materials( GLcontext *ctx, GLboolean flag );
/* Control whether T&L does per-vertex fog
*/
@ -86,4 +70,16 @@ _tnl_allow_pixel_fog( GLcontext *ctx, GLboolean value );
extern void
_tnl_program_string(GLcontext *ctx, GLenum target, struct gl_program *program);
struct _mesa_prim;
struct _mesa_index_buffer;
void
_tnl_draw_prims( GLcontext *ctx,
const struct gl_client_array *arrays[],
const struct _mesa_prim *prim,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
GLuint min_index,
GLuint max_index);
#endif