mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 00:58:05 +02:00
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:
parent
fd12b37dba
commit
b1f176039a
21 changed files with 77 additions and 6892 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
@ -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 );
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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 ));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue