From fd12b37dbada6f945a94b93ecf332d0b6a8eef06 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 29 Oct 2006 09:46:11 +0000 Subject: Checkpoint of new vbo-building code. Currently builds regular arrays rather than VBO's - VBOs are easy but need to look closer at the driver interface. The trivial/tri demo works. --- src/mesa/vbo/vbo_attrib.h | 131 +++++ src/mesa/vbo/vbo_attrib_tmp.h | 485 ++++++++++++++++ src/mesa/vbo/vbo_context.c | 86 +++ src/mesa/vbo/vbo_context.h | 101 ++++ src/mesa/vbo/vbo_exec.c | 227 ++++++++ src/mesa/vbo/vbo_exec.h | 175 ++++++ src/mesa/vbo/vbo_exec_api.c | 716 +++++++++++++++++++++++ src/mesa/vbo/vbo_exec_array.c | 367 ++++++++++++ src/mesa/vbo/vbo_exec_draw.c | 199 +++++++ src/mesa/vbo/vbo_exec_eval.c | 255 +++++++++ src/mesa/vbo/vbo_save.c | 94 +++ src/mesa/vbo/vbo_save.h | 180 ++++++ src/mesa/vbo/vbo_save_api.c | 1160 ++++++++++++++++++++++++++++++++++++++ src/mesa/vbo/vbo_save_draw.c | 202 +++++++ src/mesa/vbo/vbo_save_loopback.c | 327 +++++++++++ 15 files changed, 4705 insertions(+) create mode 100644 src/mesa/vbo/vbo_attrib.h create mode 100644 src/mesa/vbo/vbo_attrib_tmp.h create mode 100644 src/mesa/vbo/vbo_context.c create mode 100644 src/mesa/vbo/vbo_context.h create mode 100644 src/mesa/vbo/vbo_exec.c create mode 100644 src/mesa/vbo/vbo_exec.h create mode 100644 src/mesa/vbo/vbo_exec_api.c create mode 100644 src/mesa/vbo/vbo_exec_array.c create mode 100644 src/mesa/vbo/vbo_exec_draw.c create mode 100644 src/mesa/vbo/vbo_exec_eval.c create mode 100644 src/mesa/vbo/vbo_save.c create mode 100644 src/mesa/vbo/vbo_save.h create mode 100644 src/mesa/vbo/vbo_save_api.c create mode 100644 src/mesa/vbo/vbo_save_draw.c create mode 100644 src/mesa/vbo/vbo_save_loopback.c (limited to 'src') diff --git a/src/mesa/vbo/vbo_attrib.h b/src/mesa/vbo/vbo_attrib.h new file mode 100644 index 0000000000..caedbd5ea6 --- /dev/null +++ b/src/mesa/vbo/vbo_attrib.h @@ -0,0 +1,131 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + 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 (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 NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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 + */ + +#ifndef VBO_ATTRIB_H +#define VBO_ATTRIB_H + + +/* + * Note: The first attributes match the VERT_ATTRIB_* definitions + * in mtypes.h. However, the tnl module has additional attributes + * for materials, color indexes, edge flags, etc. + */ +/* Although it's nice to use these as bit indexes in a DWORD flag, we + * could manage without if necessary. Another limit currently is the + * number of bits allocated for these numbers in places like vertex + * program instruction formats and register layouts. + */ +enum { + VBO_ATTRIB_POS = 0, + VBO_ATTRIB_WEIGHT = 1, + VBO_ATTRIB_NORMAL = 2, + VBO_ATTRIB_COLOR0 = 3, + VBO_ATTRIB_COLOR1 = 4, + VBO_ATTRIB_FOG = 5, + VBO_ATTRIB_INDEX = 6, + VBO_ATTRIB_EDGEFLAG = 7, + VBO_ATTRIB_TEX0 = 8, + VBO_ATTRIB_TEX1 = 9, + VBO_ATTRIB_TEX2 = 10, + VBO_ATTRIB_TEX3 = 11, + VBO_ATTRIB_TEX4 = 12, + VBO_ATTRIB_TEX5 = 13, + VBO_ATTRIB_TEX6 = 14, + VBO_ATTRIB_TEX7 = 15, + + VBO_ATTRIB_GENERIC0 = 16, /* Not used? */ + VBO_ATTRIB_GENERIC1 = 17, + VBO_ATTRIB_GENERIC2 = 18, + VBO_ATTRIB_GENERIC3 = 19, + VBO_ATTRIB_GENERIC4 = 20, + VBO_ATTRIB_GENERIC5 = 21, + VBO_ATTRIB_GENERIC6 = 22, + VBO_ATTRIB_GENERIC7 = 23, + VBO_ATTRIB_GENERIC8 = 24, + VBO_ATTRIB_GENERIC9 = 25, + VBO_ATTRIB_GENERIC10 = 26, + VBO_ATTRIB_GENERIC11 = 27, + VBO_ATTRIB_GENERIC12 = 28, + VBO_ATTRIB_GENERIC13 = 29, + VBO_ATTRIB_GENERIC14 = 30, + VBO_ATTRIB_GENERIC15 = 31, + + /* XXX: in the vertex program InputsRead flag, we alias + * materials and generics and use knowledge about the program + * (whether it is a fixed-function emulation) to + * differentiate. Here we must keep them apart instead. + */ + VBO_ATTRIB_MAT_FRONT_AMBIENT = 32, + VBO_ATTRIB_MAT_BACK_AMBIENT = 33, + VBO_ATTRIB_MAT_FRONT_DIFFUSE = 34, + VBO_ATTRIB_MAT_BACK_DIFFUSE = 35, + VBO_ATTRIB_MAT_FRONT_SPECULAR = 36, + VBO_ATTRIB_MAT_BACK_SPECULAR = 37, + VBO_ATTRIB_MAT_FRONT_EMISSION = 38, + VBO_ATTRIB_MAT_BACK_EMISSION = 39, + VBO_ATTRIB_MAT_FRONT_SHININESS = 40, + VBO_ATTRIB_MAT_BACK_SHININESS = 41, + VBO_ATTRIB_MAT_FRONT_INDEXES = 42, + VBO_ATTRIB_MAT_BACK_INDEXES = 43, + + VBO_ATTRIB_MAX = 44 +}; + +#define VBO_ATTRIB_FIRST_MATERIAL VBO_ATTRIB_MAT_FRONT_AMBIENT + +#define VBO_MAX_COPIED_VERTS 3 + +struct _mesa_prim { + GLuint mode:8; + GLuint indexed:1; + GLuint begin:1; + GLuint end:1; + GLuint weak:1; + GLuint pad:20; + + GLuint start; + GLuint count; +}; + +/* Would like to call this a "vbo_index_buffer", but this would be + * confusing as the indices are not neccessarily yet in a non-null + * buffer object. + */ +struct _mesa_index_buffer { + GLuint count; + GLenum type; + struct gl_buffer_object *obj; + const void *ptr; + GLuint rebase; +}; + + +#endif diff --git a/src/mesa/vbo/vbo_attrib_tmp.h b/src/mesa/vbo/vbo_attrib_tmp.h new file mode 100644 index 0000000000..72a8b04aca --- /dev/null +++ b/src/mesa/vbo/vbo_attrib_tmp.h @@ -0,0 +1,485 @@ +/************************************************************************** + +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. + +**************************************************************************/ + +#define ATTR1FV( A, V ) ATTR( A, 1, (V)[0], 0, 0, 1 ) +#define ATTR2FV( A, V ) ATTR( A, 2, (V)[0], (V)[1], 0, 1 ) +#define ATTR3FV( A, V ) ATTR( A, 3, (V)[0], (V)[1], (V)[2], 1 ) +#define ATTR4FV( A, V ) ATTR( A, 4, (V)[0], (V)[1], (V)[2], (V)[3] ) + +#define ATTR1F( A, X ) ATTR( A, 1, X, 0, 0, 1 ) +#define ATTR2F( A, X, Y ) ATTR( A, 2, X, Y, 0, 1 ) +#define ATTR3F( A, X, Y, Z ) ATTR( A, 3, X, Y, Z, 1 ) +#define ATTR4F( A, X, Y, Z, W ) ATTR( A, 4, X, Y, Z, W ) + +#define MAT_ATTR( A, N, V ) ATTR( A, N, (V)[0], (V)[1], (V)[2], (V)[3] ) + +static void GLAPIENTRY TAG(Vertex2f)( GLfloat x, GLfloat y ) +{ + GET_CURRENT_CONTEXT( ctx ); + ATTR2F( VBO_ATTRIB_POS, x, y ); +} + +static void GLAPIENTRY TAG(Vertex2fv)( const GLfloat *v ) +{ + GET_CURRENT_CONTEXT( ctx ); + ATTR2FV( VBO_ATTRIB_POS, v ); +} + +static void GLAPIENTRY TAG(Vertex3f)( GLfloat x, GLfloat y, GLfloat z ) +{ + GET_CURRENT_CONTEXT( ctx ); + ATTR3F( VBO_ATTRIB_POS, x, y, z ); +} + +static void GLAPIENTRY TAG(Vertex3fv)( const GLfloat *v ) +{ + GET_CURRENT_CONTEXT( ctx ); + ATTR3FV( VBO_ATTRIB_POS, v ); +} + +static void GLAPIENTRY TAG(Vertex4f)( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) +{ + GET_CURRENT_CONTEXT( ctx ); + ATTR4F( VBO_ATTRIB_POS, x, y, z, w ); +} + +static void GLAPIENTRY TAG(Vertex4fv)( const GLfloat *v ) +{ + GET_CURRENT_CONTEXT( ctx ); + ATTR4FV( VBO_ATTRIB_POS, v ); +} + +static void GLAPIENTRY TAG(TexCoord1f)( GLfloat x ) +{ + GET_CURRENT_CONTEXT( ctx ); + ATTR1F( VBO_ATTRIB_TEX0, x ); +} + +static void GLAPIENTRY TAG(TexCoord1fv)( const GLfloat *v ) +{ + GET_CURRENT_CONTEXT( ctx ); + ATTR1FV( VBO_ATTRIB_TEX0, v ); +} + +static void GLAPIENTRY TAG(TexCoord2f)( GLfloat x, GLfloat y ) +{ + GET_CURRENT_CONTEXT( ctx ); + ATTR2F( VBO_ATTRIB_TEX0, x, y ); +} + +static void GLAPIENTRY TAG(TexCoord2fv)( const GLfloat *v ) +{ + GET_CURRENT_CONTEXT( ctx ); + ATTR2FV( VBO_ATTRIB_TEX0, v ); +} + +static void GLAPIENTRY TAG(TexCoord3f)( GLfloat x, GLfloat y, GLfloat z ) +{ + GET_CURRENT_CONTEXT( ctx ); + ATTR3F( VBO_ATTRIB_TEX0, x, y, z ); +} + +static void GLAPIENTRY TAG(TexCoord3fv)( const GLfloat *v ) +{ + GET_CURRENT_CONTEXT( ctx ); + ATTR3FV( VBO_ATTRIB_TEX0, v ); +} + +static void GLAPIENTRY TAG(TexCoord4f)( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) +{ + GET_CURRENT_CONTEXT( ctx ); + ATTR4F( VBO_ATTRIB_TEX0, x, y, z, w ); +} + +static void GLAPIENTRY TAG(TexCoord4fv)( const GLfloat *v ) +{ + GET_CURRENT_CONTEXT( ctx ); + ATTR4FV( VBO_ATTRIB_TEX0, v ); +} + +static void GLAPIENTRY TAG(Normal3f)( GLfloat x, GLfloat y, GLfloat z ) +{ + GET_CURRENT_CONTEXT( ctx ); + ATTR3F( VBO_ATTRIB_NORMAL, x, y, z ); +} + +static void GLAPIENTRY TAG(Normal3fv)( const GLfloat *v ) +{ + GET_CURRENT_CONTEXT( ctx ); + ATTR3FV( VBO_ATTRIB_NORMAL, v ); +} + +static void GLAPIENTRY TAG(FogCoordfEXT)( GLfloat x ) +{ + GET_CURRENT_CONTEXT( ctx ); + ATTR1F( VBO_ATTRIB_FOG, x ); +} + +static void GLAPIENTRY TAG(FogCoordfvEXT)( const GLfloat *v ) +{ + GET_CURRENT_CONTEXT( ctx ); + ATTR1FV( VBO_ATTRIB_FOG, v ); +} + +static void GLAPIENTRY TAG(Color3f)( GLfloat x, GLfloat y, GLfloat z ) +{ + GET_CURRENT_CONTEXT( ctx ); + ATTR3F( VBO_ATTRIB_COLOR0, x, y, z ); +} + +static void GLAPIENTRY TAG(Color3fv)( const GLfloat *v ) +{ + GET_CURRENT_CONTEXT( ctx ); + ATTR3FV( VBO_ATTRIB_COLOR0, v ); +} + +static void GLAPIENTRY TAG(Color4f)( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) +{ + GET_CURRENT_CONTEXT( ctx ); + ATTR4F( VBO_ATTRIB_COLOR0, x, y, z, w ); +} + +static void GLAPIENTRY TAG(Color4fv)( const GLfloat *v ) +{ + GET_CURRENT_CONTEXT( ctx ); + ATTR4FV( VBO_ATTRIB_COLOR0, v ); +} + +static void GLAPIENTRY TAG(SecondaryColor3fEXT)( GLfloat x, GLfloat y, GLfloat z ) +{ + GET_CURRENT_CONTEXT( ctx ); + ATTR3F( VBO_ATTRIB_COLOR1, x, y, z ); +} + +static void GLAPIENTRY TAG(SecondaryColor3fvEXT)( const GLfloat *v ) +{ + GET_CURRENT_CONTEXT( ctx ); + ATTR3FV( VBO_ATTRIB_COLOR1, v ); +} + + +static void GLAPIENTRY TAG(EdgeFlag)( GLboolean b ) +{ + GET_CURRENT_CONTEXT( ctx ); + ATTR1F( VBO_ATTRIB_EDGEFLAG, (GLfloat)b ); +} + +static void GLAPIENTRY TAG(Indexf)( GLfloat f ) +{ + GET_CURRENT_CONTEXT( ctx ); + ATTR1F( VBO_ATTRIB_INDEX, f ); +} + +static void GLAPIENTRY TAG(Indexfv)( const GLfloat *f ) +{ + GET_CURRENT_CONTEXT( ctx ); + ATTR1FV( VBO_ATTRIB_INDEX, f ); +} + + +static void GLAPIENTRY TAG(MultiTexCoord1f)( GLenum target, GLfloat x ) +{ + GET_CURRENT_CONTEXT( ctx ); + GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0; + ATTR1F( attr, x ); +} + +static void GLAPIENTRY TAG(MultiTexCoord1fv)( GLenum target, const GLfloat *v ) +{ + GET_CURRENT_CONTEXT( ctx ); + GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0; + ATTR1FV( attr, v ); +} + +static void GLAPIENTRY TAG(MultiTexCoord2f)( GLenum target, GLfloat x, GLfloat y ) +{ + GET_CURRENT_CONTEXT( ctx ); + GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0; + ATTR2F( attr, x, y ); +} + +static void GLAPIENTRY TAG(MultiTexCoord2fv)( GLenum target, const GLfloat *v ) +{ + GET_CURRENT_CONTEXT( ctx ); + GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0; + ATTR2FV( attr, v ); +} + +static void GLAPIENTRY TAG(MultiTexCoord3f)( GLenum target, GLfloat x, GLfloat y, + GLfloat z) +{ + GET_CURRENT_CONTEXT( ctx ); + GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0; + ATTR3F( attr, x, y, z ); +} + +static void GLAPIENTRY TAG(MultiTexCoord3fv)( GLenum target, const GLfloat *v ) +{ + GET_CURRENT_CONTEXT( ctx ); + GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0; + ATTR3FV( attr, v ); +} + +static void GLAPIENTRY TAG(MultiTexCoord4f)( GLenum target, GLfloat x, GLfloat y, + GLfloat z, GLfloat w ) +{ + GET_CURRENT_CONTEXT( ctx ); + GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0; + ATTR4F( attr, x, y, z, w ); +} + +static void GLAPIENTRY TAG(MultiTexCoord4fv)( GLenum target, const GLfloat *v ) +{ + GET_CURRENT_CONTEXT( ctx ); + GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0; + ATTR4FV( attr, v ); +} + + +static void GLAPIENTRY TAG(VertexAttrib1fARB)( GLuint index, GLfloat x ) +{ + GET_CURRENT_CONTEXT( ctx ); + if (index == 0) + ATTR1F(0, x); + else if (index < MAX_VERTEX_ATTRIBS) + ATTR1F(VBO_ATTRIB_GENERIC0 + index, x); + else + ERROR(); +} + +static void GLAPIENTRY TAG(VertexAttrib1fvARB)( GLuint index, + const GLfloat *v ) +{ + GET_CURRENT_CONTEXT( ctx ); + if (index == 0) + ATTR1FV(0, v); + else if (index < MAX_VERTEX_ATTRIBS) + ATTR1FV(VBO_ATTRIB_GENERIC0 + index, v); + else + ERROR(); +} + +static void GLAPIENTRY TAG(VertexAttrib2fARB)( GLuint index, GLfloat x, + GLfloat y ) +{ + GET_CURRENT_CONTEXT( ctx ); + if (index == 0) + ATTR2F(0, x, y); + else if (index < MAX_VERTEX_ATTRIBS) + ATTR2F(VBO_ATTRIB_GENERIC0 + index, x, y); + else + ERROR(); +} + +static void GLAPIENTRY TAG(VertexAttrib2fvARB)( GLuint index, + const GLfloat *v ) +{ + GET_CURRENT_CONTEXT( ctx ); + if (index == 0) + ATTR2FV(0, v); + else if (index < MAX_VERTEX_ATTRIBS) + ATTR2FV(VBO_ATTRIB_GENERIC0 + index, v); + else + ERROR(); +} + +static void GLAPIENTRY TAG(VertexAttrib3fARB)( GLuint index, GLfloat x, + GLfloat y, GLfloat z ) +{ + GET_CURRENT_CONTEXT( ctx ); + if (index == 0) + ATTR3F(0, x, y, z); + else if (index < MAX_VERTEX_ATTRIBS) + ATTR3F(VBO_ATTRIB_GENERIC0 + index, x, y, z); + else + ERROR(); +} + +static void GLAPIENTRY TAG(VertexAttrib3fvARB)( GLuint index, + const GLfloat *v ) +{ + GET_CURRENT_CONTEXT( ctx ); + if (index == 0) + ATTR3FV(0, v); + else if (index < MAX_VERTEX_ATTRIBS) + ATTR3FV(VBO_ATTRIB_GENERIC0 + index, v); + else + ERROR(); +} + +static void GLAPIENTRY TAG(VertexAttrib4fARB)( GLuint index, GLfloat x, + GLfloat y, GLfloat z, + GLfloat w ) +{ + GET_CURRENT_CONTEXT( ctx ); + if (index == 0) + ATTR4F(0, x, y, z, w); + else if (index < MAX_VERTEX_ATTRIBS) + ATTR4F(VBO_ATTRIB_GENERIC0 + index, x, y, z, w); + else + ERROR(); +} + +static void GLAPIENTRY TAG(VertexAttrib4fvARB)( GLuint index, + const GLfloat *v ) +{ + GET_CURRENT_CONTEXT( ctx ); + if (index == 0) + ATTR4FV(0, v); + else if (index < MAX_VERTEX_ATTRIBS) + ATTR4FV(VBO_ATTRIB_GENERIC0 + index, v); + else + ERROR(); +} + + +/* Although we don't export NV_vertex_program, these entrypoints are + * used by the display list and other code specifically because of + * their property of aliasing with other attributes. + */ +static void GLAPIENTRY TAG(VertexAttrib1fNV)( GLuint index, GLfloat x ) +{ + GET_CURRENT_CONTEXT( ctx ); + if (index < VBO_ATTRIB_MAX) + ATTR1F(index, x); +} + +static void GLAPIENTRY TAG(VertexAttrib1fvNV)( GLuint index, + const GLfloat *v ) +{ + GET_CURRENT_CONTEXT( ctx ); + if (index < VBO_ATTRIB_MAX) + ATTR1FV(index, v); +} + +static void GLAPIENTRY TAG(VertexAttrib2fNV)( GLuint index, GLfloat x, + GLfloat y ) +{ + GET_CURRENT_CONTEXT( ctx ); + if (index < VBO_ATTRIB_MAX) + ATTR2F(index, x, y); +} + +static void GLAPIENTRY TAG(VertexAttrib2fvNV)( GLuint index, + const GLfloat *v ) +{ + GET_CURRENT_CONTEXT( ctx ); + if (index < VBO_ATTRIB_MAX) + ATTR2FV(index, v); +} + +static void GLAPIENTRY TAG(VertexAttrib3fNV)( GLuint index, GLfloat x, + GLfloat y, GLfloat z ) +{ + GET_CURRENT_CONTEXT( ctx ); + if (index < VBO_ATTRIB_MAX) + ATTR3F(index, x, y, z); +} + +static void GLAPIENTRY TAG(VertexAttrib3fvNV)( GLuint index, + const GLfloat *v ) +{ + GET_CURRENT_CONTEXT( ctx ); + if (index < VBO_ATTRIB_MAX) + ATTR3FV(index, v); +} + +static void GLAPIENTRY TAG(VertexAttrib4fNV)( GLuint index, GLfloat x, + GLfloat y, GLfloat z, + GLfloat w ) +{ + GET_CURRENT_CONTEXT( ctx ); + if (index < VBO_ATTRIB_MAX) + ATTR4F(index, x, y, z, w); +} + +static void GLAPIENTRY TAG(VertexAttrib4fvNV)( GLuint index, + const GLfloat *v ) +{ + GET_CURRENT_CONTEXT( ctx ); + if (index < VBO_ATTRIB_MAX) + ATTR4FV(index, v); +} + + +#define MAT( ATTR, N, face, params ) \ +do { \ + if (face != GL_BACK) \ + MAT_ATTR( ATTR, N, params ); /* front */ \ + if (face != GL_FRONT) \ + MAT_ATTR( ATTR + 1, N, params ); /* back */ \ +} while (0) + + +/* Colormaterial conflicts are dealt with later. + */ +static void GLAPIENTRY TAG(Materialfv)( GLenum face, GLenum pname, + const GLfloat *params ) +{ + GET_CURRENT_CONTEXT( ctx ); + switch (pname) { + case GL_EMISSION: + MAT( VBO_ATTRIB_MAT_FRONT_EMISSION, 4, face, params ); + break; + case GL_AMBIENT: + MAT( VBO_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params ); + break; + case GL_DIFFUSE: + MAT( VBO_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params ); + break; + case GL_SPECULAR: + MAT( VBO_ATTRIB_MAT_FRONT_SPECULAR, 4, face, params ); + break; + case GL_SHININESS: + MAT( VBO_ATTRIB_MAT_FRONT_SHININESS, 1, face, params ); + break; + case GL_COLOR_INDEXES: + MAT( VBO_ATTRIB_MAT_FRONT_INDEXES, 3, face, params ); + break; + case GL_AMBIENT_AND_DIFFUSE: + MAT( VBO_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params ); + MAT( VBO_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params ); + break; + default: + ERROR(); + return; + } +} + + +#undef ATTR1FV +#undef ATTR2FV +#undef ATTR3FV +#undef ATTR4FV + +#undef ATTR1F +#undef ATTR2F +#undef ATTR3F +#undef ATTR4F + +#undef MAT +#undef MAT_ATTR diff --git a/src/mesa/vbo/vbo_context.c b/src/mesa/vbo/vbo_context.c new file mode 100644 index 0000000000..5f28e6b0e0 --- /dev/null +++ b/src/mesa/vbo/vbo_context.c @@ -0,0 +1,86 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 1999-2005 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 + */ + +#include "mtypes.h" +#include "vbo_context.h" +#include "imports.h" +#include "api_arrayelt.h" + +/* Reach out and grab this to use as the default: + */ +extern void _tnl_draw_prims( GLcontext *ctx, + const struct gl_client_array *arrays[], + const struct _mesa_prim *prims, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLuint min_index, + GLuint max_index ); + +GLboolean _vbo_CreateContext( GLcontext *ctx ) +{ + struct vbo_context *vbo = CALLOC_STRUCT(vbo_context); + + ctx->swtnl_im = (void *)vbo; + + /* Initialize the arrayelt helper + */ + if (!ctx->aelt_context && + !_ae_create_context( ctx )) { + return GL_FALSE; + } + + /* Hook our functions into exec and compile dispatch tables. These + * will pretty much be permanently installed, which means that the + * vtxfmt mechanism can be removed now. + */ + vbo_exec_init( ctx ); + vbo_save_init( ctx ); + + /* By default: + */ + vbo->draw_prims = _tnl_draw_prims; + + return GL_TRUE; +} + +void vbo_save_invalidate_state( GLcontext *ctx, GLuint new_state ) +{ + _ae_invalidate_state(ctx, new_state); +} + + +void _vbo_DestroyContext( GLcontext *ctx ) +{ + if (ctx->aelt_context) { + _ae_destroy_context( ctx ); + ctx->aelt_context = NULL; + } + + FREE(vbo_context(ctx)); + ctx->swtnl_im = NULL; + +} diff --git a/src/mesa/vbo/vbo_context.h b/src/mesa/vbo/vbo_context.h new file mode 100644 index 0000000000..6b0f14d70e --- /dev/null +++ b/src/mesa/vbo/vbo_context.h @@ -0,0 +1,101 @@ +/* + * mesa 3-D graphics library + * Version: 6.5 + * + * 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 vbo_context.h + * \brief VBO builder module datatypes and definitions. + * \author Keith Whitwell + */ + + +/** + * \mainpage The VBO builder module + * + * This module hooks into the GL dispatch table and catches all vertex + * building and drawing commands, such as glVertex3f, glBegin and + * glDrawArrays. The module stores all incoming vertex data as arrays + * in GL vertex buffer objects (VBOs), and translates all drawing + * commands into calls to a driver supplied DrawPrimitives() callback. + * + * The module captures both immediate mode and display list drawing, + * and manages the allocation, reference counting and deallocation of + * vertex buffer objects itself. + * + * The DrawPrimitives() callback can be either implemented by the + * driver itself or hooked to the tnl module's _tnl_draw_primitives() + * function for hardware without tnl capablilties or during fallbacks. + */ + + +#ifndef _VBO_CONTEXT_H +#define _VBO_CONTEXT_H + +#include "vbo_attrib.h" +#include "vbo_save.h" +#include "vbo_exec.h" + +GLboolean _vbo_CreateContext( GLcontext *ctx ); +void _vbo_DestroyContext( GLcontext *ctx ); + + +struct vbo_context { + struct vbo_exec_context exec; + struct vbo_save_context save; + + /* Callback into the driver. This must always succeed, the driver + * is responsible for initiating any fallback actions required: + */ + void (*draw_prims)( GLcontext *ctx, + const struct gl_client_array *arrays[], + const struct _mesa_prim *prims, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLuint min_index, + GLuint max_index ); +}; + + +static INLINE struct vbo_context *vbo_context(GLcontext *ctx) +{ + return (struct vbo_context *)(ctx->swtnl_im); +} + +enum { + VP_NONE = 1, + VP_NV, + VP_ARB +}; + +static INLINE GLuint get_program_mode( GLcontext *ctx ) +{ + if (!ctx->VertexProgram._Enabled) + return VP_NONE; + else if (ctx->VertexProgram.Current->IsNVProgram) + return VP_NV; + else + return VP_ARB; +} + + +#endif diff --git a/src/mesa/vbo/vbo_exec.c b/src/mesa/vbo/vbo_exec.c new file mode 100644 index 0000000000..4499803b8c --- /dev/null +++ b/src/mesa/vbo/vbo_exec.c @@ -0,0 +1,227 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 1999-2005 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 + */ + + +#include "api_arrayelt.h" +#include "glheader.h" +#include "imports.h" +#include "context.h" +#include "macros.h" +#include "mtypes.h" +#include "dlist.h" +#include "vtxfmt.h" + +#include "vbo_context.h" + + +#define NR_LEGACY_ATTRIBS 16 +#define NR_GENERIC_ATTRIBS 16 +#define NR_MAT_ATTRIBS 12 + +static void init_legacy_currval(GLcontext *ctx) +{ + struct vbo_exec_context *exec = &vbo_context(ctx)->exec; + struct gl_client_array *arrays = exec->legacy_currval; + GLuint i; + + memset(arrays, 0, sizeof(*arrays) * NR_LEGACY_ATTRIBS); + + /* Set up a constant (StrideB == 0) array for each current + * attribute: + */ + for (i = 0; i < NR_LEGACY_ATTRIBS; i++) { + struct gl_client_array *cl = &arrays[i]; + + switch (i) { + case VBO_ATTRIB_EDGEFLAG: + cl->Type = GL_UNSIGNED_BYTE; + cl->Ptr = (const void *)&ctx->Current.EdgeFlag; + break; + case VBO_ATTRIB_INDEX: + cl->Type = GL_FLOAT; + cl->Ptr = (const void *)&ctx->Current.Index; + break; + default: + cl->Type = GL_FLOAT; + cl->Ptr = (const void *)ctx->Current.Attrib[i]; + break; + } + + /* This will have to be determined at runtime: + */ + cl->Size = 1; + cl->Stride = 0; + cl->StrideB = 0; + cl->Enabled = 1; + cl->BufferObj = ctx->Array.NullBufferObj; + } +} + + +static void init_generic_currval(GLcontext *ctx) +{ + struct vbo_exec_context *exec = &vbo_context(ctx)->exec; + struct gl_client_array *arrays = exec->generic_currval; + GLuint i; + + memset(arrays, 0, sizeof(*arrays) * NR_GENERIC_ATTRIBS); + + for (i = 0; i < NR_GENERIC_ATTRIBS; i++) { + struct gl_client_array *cl = &arrays[i]; + + /* This will have to be determined at runtime: + */ + cl->Size = 1; + + cl->Type = GL_FLOAT; + cl->Ptr = (const void *)ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + i]; + cl->Stride = 0; + cl->StrideB = 0; + cl->Enabled = 1; + cl->BufferObj = ctx->Array.NullBufferObj; + } +} + + +static void init_mat_currval(GLcontext *ctx) +{ + struct vbo_exec_context *exec = &vbo_context(ctx)->exec; + struct gl_client_array *arrays = exec->mat_currval; + GLuint i; + + memset(arrays, 0, sizeof(*arrays) * NR_GENERIC_ATTRIBS); + + /* Set up a constant (StrideB == 0) array for each current + * attribute: + */ + for (i = 0; i < NR_GENERIC_ATTRIBS; i++) { + struct gl_client_array *cl = &arrays[i]; + + /* Size is fixed for the material attributes, for others will + * be determined at runtime: + */ + switch (i - VERT_ATTRIB_GENERIC0) { + case MAT_ATTRIB_FRONT_SHININESS: + case MAT_ATTRIB_BACK_SHININESS: + cl->Size = 1; + break; + case MAT_ATTRIB_FRONT_INDEXES: + case MAT_ATTRIB_BACK_INDEXES: + cl->Size = 3; + break; + default: + cl->Size = 4; + break; + } + + if (i < MAT_ATTRIB_MAX) + cl->Ptr = (const void *)ctx->Light.Material.Attrib[i]; + else + cl->Ptr = (const void *)ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + i]; + + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 0; + cl->Enabled = 1; + cl->BufferObj = ctx->Array.NullBufferObj; + } +} + + +void vbo_exec_init( GLcontext *ctx ) +{ + struct vbo_exec_context *exec = &vbo_context(ctx)->exec; + + exec->ctx = ctx; + + /* Initialize the arrayelt helper + */ + if (!ctx->aelt_context && + !_ae_create_context( ctx )) + return; + + vbo_exec_vtx_init( exec ); + vbo_exec_array_init( exec ); + + init_legacy_currval( ctx ); + init_generic_currval( ctx ); + init_mat_currval( ctx ); + + ctx->Driver.NeedFlush = 0; + ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; + ctx->Driver.FlushVertices = vbo_exec_FlushVertices; + + exec->eval.recalculate_maps = 1; +} + + +void vbo_exec_destroy( GLcontext *ctx ) +{ + struct vbo_exec_context *exec = &vbo_context(ctx)->exec; + + if (ctx->aelt_context) { + _ae_destroy_context( ctx ); + ctx->aelt_context = NULL; + } + + vbo_exec_vtx_destroy( exec ); + vbo_exec_array_destroy( exec ); +} + +/* Really want to install these callbacks to a central facility to be + * invoked according to the state flags. That will have to wait for a + * mesa rework: + */ +void vbo_exec_invalidate_state( GLcontext *ctx, GLuint new_state ) +{ + struct vbo_exec_context *exec = &vbo_context(ctx)->exec; + + if (new_state & (_NEW_PROGRAM|_NEW_EVAL)) + exec->eval.recalculate_maps = 1; + + _ae_invalidate_state(ctx, new_state); +} + + +void vbo_exec_wakeup( GLcontext *ctx ) +{ + struct vbo_exec_context *exec = &vbo_context(ctx)->exec; + + ctx->Driver.FlushVertices = vbo_exec_FlushVertices; + ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; + + /* Hook our functions into exec and compile dispatch tables. + */ + _mesa_install_exec_vtxfmt( ctx, &exec->vtxfmt ); + + /* Assume we haven't been getting state updates either: + */ + vbo_exec_invalidate_state( ctx, ~0 ); +} + + + diff --git a/src/mesa/vbo/vbo_exec.h b/src/mesa/vbo/vbo_exec.h new file mode 100644 index 0000000000..4542d2807c --- /dev/null +++ b/src/mesa/vbo/vbo_exec.h @@ -0,0 +1,175 @@ +/************************************************************************** + +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 + * + */ + +#ifndef __VBO_EXEC_H__ +#define __VBO_EXEC_H__ + +#include "mtypes.h" +#include "vbo_attrib.h" + + +#define VBO_MAX_PRIM 64 + +/* Wierd implementation stuff: + */ +#define VBO_VERT_BUFFER_SIZE (1024*16) /* dwords == 64k */ +#define VBO_MAX_ATTR_CODEGEN 16 +#define ERROR_ATTRIB 16 + + + + +struct vbo_exec_eval1_map { + struct gl_1d_map *map; + GLuint sz; +}; + +struct vbo_exec_eval2_map { + struct gl_2d_map *map; + GLuint sz; +}; + + + +struct vbo_exec_copied_vtx { + GLfloat buffer[VBO_ATTRIB_MAX * 4 * VBO_MAX_COPIED_VERTS]; + GLuint nr; +}; + + +typedef void (*vbo_attrfv_func)( const GLfloat * ); + + +struct vbo_exec_context +{ + GLcontext *ctx; + GLvertexformat vtxfmt; + + struct gl_client_array legacy_currval[16]; + struct gl_client_array generic_currval[16]; + struct gl_client_array mat_currval[16]; + + struct { + struct gl_buffer_object *bufferobj; + GLubyte *buffer_map; + + GLuint vertex_size; + + struct _mesa_prim prim[VBO_MAX_PRIM]; + GLuint prim_count; + + GLfloat *vbptr; /* cursor, points into buffer */ + GLfloat vertex[VBO_ATTRIB_MAX*4]; /* current vertex */ + + GLfloat *current[VBO_ATTRIB_MAX]; /* points into ctx->Current, ctx->Light.Material */ + GLfloat CurrentFloatEdgeFlag; + + GLuint vert_count; + GLuint max_vert; + struct vbo_exec_copied_vtx copied; + + GLubyte attrsz[VBO_ATTRIB_MAX]; + GLubyte active_sz[VBO_ATTRIB_MAX]; + + GLfloat *attrptr[VBO_ATTRIB_MAX]; + struct gl_client_array arrays[VBO_ATTRIB_MAX]; + + /* According to program mode, the values above plus current + * values are squashed down to the 32 attributes passed to the + * vertex program below: + */ + GLuint program_mode; + GLuint enabled_flags; + const struct gl_client_array *inputs[VERT_ATTRIB_MAX]; + } vtx; + + + struct { + GLboolean recalculate_maps; + struct vbo_exec_eval1_map map1[VERT_ATTRIB_MAX]; + struct vbo_exec_eval2_map map2[VERT_ATTRIB_MAX]; + } eval; + + struct { + GLuint program_mode; + GLuint enabled_flags; + GLuint array_obj; + + /* These just mirror the current arrayobj (todo: make arrayobj + * look like this and remove the mirror): + */ + const struct gl_client_array *legacy_array[16]; + const struct gl_client_array *generic_array[16]; + + /* Arrays and current values manipulated according to program + * mode, etc. These are the attributes as seen by vertex + * programs: + */ + const struct gl_client_array *inputs[VERT_ATTRIB_MAX]; + + + struct gl_buffer_object *index_obj; + } array; +}; + + + +/* External API: + */ +void vbo_exec_init( GLcontext *ctx ); +void vbo_exec_destroy( GLcontext *ctx ); +void vbo_exec_invalidate_state( GLcontext *ctx, GLuint new_state ); +void vbo_exec_FlushVertices( GLcontext *ctx, GLuint flags ); +void vbo_exec_wakeup( GLcontext *ctx ); + + +/* Internal functions: + */ +void vbo_exec_array_init( struct vbo_exec_context *exec ); +void vbo_exec_array_destroy( struct vbo_exec_context *exec ); + + +void vbo_exec_vtx_init( struct vbo_exec_context *exec ); +void vbo_exec_vtx_destroy( struct vbo_exec_context *exec ); +void vbo_exec_vtx_flush( struct vbo_exec_context *exec ); +void vbo_exec_vtx_wrap( struct vbo_exec_context *exec ); + +void vbo_exec_eval_update( struct vbo_exec_context *exec ); + +void vbo_exec_do_EvalCoord2f( struct vbo_exec_context *exec, + GLfloat u, GLfloat v ); + +void vbo_exec_do_EvalCoord1f( struct vbo_exec_context *exec, + GLfloat u); + +#endif diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c new file mode 100644 index 0000000000..c764c4d8b6 --- /dev/null +++ b/src/mesa/vbo/vbo_exec_api.c @@ -0,0 +1,716 @@ +/************************************************************************** + +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 + */ + +#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 "dispatch.h" + +#include "vbo_context.h" + +static void reset_attrfv( struct vbo_exec_context *exec ); + + +/* Close off the last primitive, execute the buffer, restart the + * primitive. + */ +static void vbo_exec_wrap_buffers( struct vbo_exec_context *exec ) +{ + if (exec->vtx.prim_count == 0) { + exec->vtx.copied.nr = 0; + exec->vtx.vert_count = 0; + exec->vtx.vbptr = (GLfloat *)exec->vtx.buffer_map; + } + else { + GLuint last_begin = exec->vtx.prim[exec->vtx.prim_count-1].begin; + GLuint last_count; + + if (exec->ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) { + GLint i = exec->vtx.prim_count - 1; + assert(i >= 0); + exec->vtx.prim[i].count = (exec->vtx.vert_count - + exec->vtx.prim[i].start); + } + + last_count = exec->vtx.prim[exec->vtx.prim_count-1].count; + + /* Execute the buffer and save copied vertices. + */ + if (exec->vtx.vert_count) + vbo_exec_vtx_flush( exec ); + else { + exec->vtx.prim_count = 0; + exec->vtx.copied.nr = 0; + } + + /* Emit a glBegin to start the new list. + */ + assert(exec->vtx.prim_count == 0); + + if (exec->ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) { + exec->vtx.prim[0].mode = exec->ctx->Driver.CurrentExecPrimitive; + exec->vtx.prim[0].start = 0; + exec->vtx.prim[0].count = 0; + exec->vtx.prim_count++; + + if (exec->vtx.copied.nr == last_count) + exec->vtx.prim[0].begin = last_begin; + } + } +} + + +/* Deal with buffer wrapping where provoked by the vertex buffer + * filling up, as opposed to upgrade_vertex(). + */ +void vbo_exec_vtx_wrap( struct vbo_exec_context *exec ) +{ + GLfloat *data = exec->vtx.copied.buffer; + GLuint i; + + /* Run pipeline on current vertices, copy wrapped vertices + * to exec->vtx.copied. + */ + vbo_exec_wrap_buffers( exec ); + + /* Copy stored stored vertices to start of new list. + */ + assert(exec->vtx.max_vert - exec->vtx.vert_count > exec->vtx.copied.nr); + + for (i = 0 ; i < exec->vtx.copied.nr ; i++) { + _mesa_memcpy( exec->vtx.vbptr, data, + exec->vtx.vertex_size * sizeof(GLfloat)); + exec->vtx.vbptr += exec->vtx.vertex_size; + data += exec->vtx.vertex_size; + exec->vtx.vert_count++; + } + + exec->vtx.copied.nr = 0; +} + + +/* + * Copy the active vertex's values to the ctx->Current fields. + */ +static void vbo_exec_copy_to_current( struct vbo_exec_context *exec ) +{ + GLcontext *ctx = exec->ctx; + GLuint i; + + for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) { + if (exec->vtx.attrsz[i]) { + /* Note: the exec->vtx.current[i] pointers point into the + * ctx->Current.Attrib and ctx->Light.Material.Attrib arrays. + */ + COPY_CLEAN_4V(exec->vtx.current[i], + exec->vtx.attrsz[i], + exec->vtx.attrptr[i]); + + /* This triggers rather too much recalculation of Mesa state + * that doesn't get used (eg light positions). + */ + if (i >= VBO_ATTRIB_MAT_FRONT_AMBIENT && + i <= VBO_ATTRIB_MAT_BACK_INDEXES) + ctx->NewState |= _NEW_LIGHT; + } + } + + /* color index is special (it's not a float[4] so COPY_CLEAN_4V above + * will trash adjacent memory!) + */ + if (exec->vtx.attrsz[VBO_ATTRIB_INDEX]) { + ctx->Current.Index = exec->vtx.attrptr[VBO_ATTRIB_INDEX][0]; + } + + /* Edgeflag requires additional treatment: + */ + if (exec->vtx.attrsz[VBO_ATTRIB_EDGEFLAG]) { + ctx->Current.EdgeFlag = (exec->vtx.CurrentFloatEdgeFlag == 1.0); + } + + /* Colormaterial -- this kindof sucks. + */ + if (ctx->Light.ColorMaterialEnabled && + exec->vtx.attrsz[VBO_ATTRIB_COLOR0]) { + _mesa_update_color_material(ctx, + ctx->Current.Attrib[VBO_ATTRIB_COLOR0]); + } + + ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT; +} + + +static void vbo_exec_copy_from_current( struct vbo_exec_context *exec ) +{ + GLcontext *ctx = exec->ctx; + GLint i; + + /* Edgeflag requires additional treatment: + */ + exec->vtx.CurrentFloatEdgeFlag = + (GLfloat)ctx->Current.EdgeFlag; + + for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) + switch (exec->vtx.attrsz[i]) { + case 4: exec->vtx.attrptr[i][3] = exec->vtx.current[i][3]; + case 3: exec->vtx.attrptr[i][2] = exec->vtx.current[i][2]; + case 2: exec->vtx.attrptr[i][1] = exec->vtx.current[i][1]; + case 1: exec->vtx.attrptr[i][0] = exec->vtx.current[i][0]; + break; + } + + ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; +} + + +/* Flush existing data, set new attrib size, replay copied vertices. + */ +static void vbo_exec_wrap_upgrade_vertex( struct vbo_exec_context *exec, + GLuint attr, + GLuint newsz ) +{ + GLcontext *ctx = exec->ctx; + GLint lastcount = exec->vtx.vert_count; + GLfloat *tmp; + GLuint oldsz; + GLuint i; + + /* Run pipeline on current vertices, copy wrapped vertices + * to exec->vtx.copied. + */ + vbo_exec_wrap_buffers( exec ); + + + /* Do a COPY_TO_CURRENT to ensure back-copying works for the case + * when the attribute already exists in the vertex and is having + * its size increased. + */ + vbo_exec_copy_to_current( exec ); + + + /* Heuristic: Attempt to isolate attributes received outside + * begin/end so that they don't bloat the vertices. + */ + if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END && + exec->vtx.attrsz[attr] == 0 && + lastcount > 8 && + exec->vtx.vertex_size) { + reset_attrfv( exec ); + } + + /* Fix up sizes: + */ + oldsz = exec->vtx.attrsz[attr]; + exec->vtx.attrsz[attr] = newsz; + + exec->vtx.vertex_size += newsz - oldsz; + exec->vtx.max_vert = VBO_VERT_BUFFER_SIZE / exec->vtx.vertex_size; + exec->vtx.vert_count = 0; + exec->vtx.vbptr = (GLfloat *)exec->vtx.buffer_map; + + + /* Recalculate all the attrptr[] values + */ + for (i = 0, tmp = exec->vtx.vertex ; i < VBO_ATTRIB_MAX ; i++) { + if (exec->vtx.attrsz[i]) { + exec->vtx.attrptr[i] = tmp; + tmp += exec->vtx.attrsz[i]; + } + else + exec->vtx.attrptr[i] = NULL; /* will not be dereferenced */ + } + + /* Copy from current to repopulate the vertex with correct values. + */ + vbo_exec_copy_from_current( exec ); + + /* Replay stored vertices to translate them + * to new format here. + * + * -- No need to replay - just copy piecewise + */ + if (exec->vtx.copied.nr) + { + GLfloat *data = exec->vtx.copied.buffer; + GLfloat *dest = exec->vtx.vbptr; + GLuint j; + + assert(exec->vtx.vbptr == (GLfloat *)exec->vtx.buffer_map); + + for (i = 0 ; i < exec->vtx.copied.nr ; i++) { + for (j = 0 ; j < VBO_ATTRIB_MAX ; j++) { + if (exec->vtx.attrsz[j]) { + if (j == attr) { + if (oldsz) { + COPY_CLEAN_4V( dest, oldsz, data ); + data += oldsz; + dest += newsz; + } else { + COPY_SZ_4V( dest, newsz, exec->vtx.current[j] ); + dest += newsz; + } + } + else { + GLuint sz = exec->vtx.attrsz[j]; + COPY_SZ_4V( dest, sz, data ); + dest += sz; + data += sz; + } + } + } + } + + exec->vtx.vbptr = dest; + exec->vtx.vert_count += exec->vtx.copied.nr; + exec->vtx.copied.nr = 0; + } +} + + +static void vbo_exec_fixup_vertex( GLcontext *ctx, + GLuint attr, GLuint sz ) +{ + struct vbo_exec_context *exec = &vbo_context(ctx)->exec; + int i; + + if (sz > exec->vtx.attrsz[attr]) { + /* New size is larger. Need to flush existing vertices and get + * an enlarged vertex format. + */ + vbo_exec_wrap_upgrade_vertex( exec, attr, sz ); + } + else if (sz < exec->vtx.active_sz[attr]) { + static const GLfloat id[4] = { 0, 0, 0, 1 }; + + /* New size is smaller - just need to fill in some + * zeros. Don't need to flush or wrap. + */ + for (i = sz ; i <= exec->vtx.attrsz[attr] ; i++) + exec->vtx.attrptr[attr][i-1] = id[i-1]; + } + + exec->vtx.active_sz[attr] = sz; + + /* Does setting NeedFlush belong here? Necessitates resetting + * vtxfmt on each flush (otherwise flags won't get reset + * afterwards). + */ + if (attr == 0) + exec->ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; + else + exec->ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; +} + + + + +/* + */ +#define ATTR( A, N, V0, V1, V2, V3 ) \ +do { \ + struct vbo_exec_context *exec = &vbo_context(ctx)->exec; \ + \ + if (exec->vtx.active_sz[A] != N) \ + vbo_exec_fixup_vertex(ctx, A, N); \ + \ + { \ + GLfloat *dest = exec->vtx.attrptr[A]; \ + if (N>0) dest[0] = V0; \ + if (N>1) dest[1] = V1; \ + if (N>2) dest[2] = V2; \ + if (N>3) dest[3] = V3; \ + } \ + \ + if ((A) == 0) { \ + GLuint i; \ + \ + for (i = 0; i < exec->vtx.vertex_size; i++) \ + exec->vtx.vbptr[i] = exec->vtx.vertex[i]; \ + \ + exec->vtx.vbptr += exec->vtx.vertex_size; \ + exec->ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; \ + \ + if (++exec->vtx.vert_count >= exec->vtx.max_vert) \ + vbo_exec_vtx_wrap( exec ); \ + } \ +} while (0) + + +#define ERROR() _mesa_error( ctx, GL_INVALID_ENUM, __FUNCTION__ ) +#define TAG(x) vbo_##x + +#include "vbo_attrib_tmp.h" + + + + + +/* Eval + */ +static void GLAPIENTRY vbo_exec_EvalCoord1f( GLfloat u ) +{ + GET_CURRENT_CONTEXT( ctx ); + struct vbo_exec_context *exec = &vbo_context(ctx)->exec; + + { + GLint i; + if (exec->eval.recalculate_maps) + vbo_exec_eval_update( exec ); + + for (i = 0 ; i <= VBO_ATTRIB_INDEX ; i++) { + if (exec->eval.map1[i].map) + if (exec->vtx.active_sz[i] != exec->eval.map1[i].sz) + vbo_exec_fixup_vertex( ctx, i, exec->eval.map1[i].sz ); + } + } + + + _mesa_memcpy( exec->vtx.copied.buffer, exec->vtx.vertex, + exec->vtx.vertex_size * sizeof(GLfloat)); + + vbo_exec_do_EvalCoord1f( exec, u ); + + _mesa_memcpy( exec->vtx.vertex, exec->vtx.copied.buffer, + exec->vtx.vertex_size * sizeof(GLfloat)); +} + +static void GLAPIENTRY vbo_exec_EvalCoord2f( GLfloat u, GLfloat v ) +{ + GET_CURRENT_CONTEXT( ctx ); + struct vbo_exec_context *exec = &vbo_context(ctx)->exec; + + { + GLint i; + if (exec->eval.recalculate_maps) + vbo_exec_eval_update( exec ); + + for (i = 0 ; i <= VBO_ATTRIB_INDEX ; i++) { + if (exec->eval.map2[i].map) + if (exec->vtx.active_sz[i] != exec->eval.map2[i].sz) + vbo_exec_fixup_vertex( ctx, i, exec->eval.map2[i].sz ); + } + + if (ctx->Eval.AutoNormal) + if (exec->vtx.active_sz[VBO_ATTRIB_NORMAL] != 3) + vbo_exec_fixup_vertex( ctx, VBO_ATTRIB_NORMAL, 3 ); + } + + _mesa_memcpy( exec->vtx.copied.buffer, exec->vtx.vertex, + exec->vtx.vertex_size * sizeof(GLfloat)); + + vbo_exec_do_EvalCoord2f( exec, u, v ); + + _mesa_memcpy( exec->vtx.vertex, exec->vtx.copied.buffer, + exec->vtx.vertex_size * sizeof(GLfloat)); +} + +static void GLAPIENTRY vbo_exec_EvalCoord1fv( const GLfloat *u ) +{ + vbo_exec_EvalCoord1f( u[0] ); +} + +static void GLAPIENTRY vbo_exec_EvalCoord2fv( const GLfloat *u ) +{ + vbo_exec_EvalCoord2f( u[0], u[1] ); +} + +static void GLAPIENTRY vbo_exec_EvalPoint1( GLint i ) +{ + GET_CURRENT_CONTEXT( ctx ); + GLfloat du = ((ctx->Eval.MapGrid1u2 - ctx->Eval.MapGrid1u1) / + (GLfloat) ctx->Eval.MapGrid1un); + GLfloat u = i * du + ctx->Eval.MapGrid1u1; + + vbo_exec_EvalCoord1f( u ); +} + + +static void GLAPIENTRY vbo_exec_EvalPoint2( GLint i, GLint j ) +{ + GET_CURRENT_CONTEXT( ctx ); + GLfloat du = ((ctx->Eval.MapGrid2u2 - ctx->Eval.MapGrid2u1) / + (GLfloat) ctx->Eval.MapGrid2un); + GLfloat dv = ((ctx->Eval.MapGrid2v2 - ctx->Eval.MapGrid2v1) / + (GLfloat) ctx->Eval.MapGrid2vn); + GLfloat u = i * du + ctx->Eval.MapGrid2u1; + GLfloat v = j * dv + ctx->Eval.MapGrid2v1; + + vbo_exec_EvalCoord2f( u, v ); +} + + +/* Build a list of primitives on the fly. Keep + * ctx->Driver.CurrentExecPrimitive uptodate as well. + */ +static void GLAPIENTRY vbo_exec_Begin( GLenum mode ) +{ + GET_CURRENT_CONTEXT( ctx ); + + if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) { + struct vbo_exec_context *exec = &vbo_context(ctx)->exec; + int i; + + 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; + } + + CALL_Begin(ctx->Exec, (mode)); + return; + } + + /* Heuristic: attempt to isolate attributes occuring outside + * begin/end pairs. + */ + if (exec->vtx.vertex_size && !exec->vtx.attrsz[0]) + vbo_exec_FlushVertices( ctx, ~0 ); + + i = exec->vtx.prim_count++; + exec->vtx.prim[i].mode = mode; + exec->vtx.prim[i].begin = 1; + exec->vtx.prim[i].end = 0; + exec->vtx.prim[i].indexed = 0; + exec->vtx.prim[i].weak = 0; + exec->vtx.prim[i].pad = 0; + exec->vtx.prim[i].start = exec->vtx.vert_count; + exec->vtx.prim[i].count = 0; + + ctx->Driver.CurrentExecPrimitive = mode; + } + else + _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" ); + +} + +static void GLAPIENTRY vbo_exec_End( void ) +{ + GET_CURRENT_CONTEXT( ctx ); + + if (ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) { + struct vbo_exec_context *exec = &vbo_context(ctx)->exec; + int idx = exec->vtx.vert_count; + int i = exec->vtx.prim_count - 1; + + exec->vtx.prim[i].end = 1; + exec->vtx.prim[i].count = idx - exec->vtx.prim[i].start; + + ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1; + + if (exec->vtx.prim_count == VBO_MAX_PRIM) + vbo_exec_vtx_flush( exec ); + } + else + _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" ); +} + + +static void vbo_exec_vtxfmt_init( struct vbo_exec_context *exec ) +{ + GLvertexformat *vfmt = &exec->vtxfmt; + + vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ + vfmt->Begin = vbo_exec_Begin; + vfmt->CallList = _mesa_CallList; + vfmt->CallLists = _mesa_CallLists; + vfmt->End = vbo_exec_End; + vfmt->EvalCoord1f = vbo_exec_EvalCoord1f; + vfmt->EvalCoord1fv = vbo_exec_EvalCoord1fv; + vfmt->EvalCoord2f = vbo_exec_EvalCoord2f; + vfmt->EvalCoord2fv = vbo_exec_EvalCoord2fv; + vfmt->EvalPoint1 = vbo_exec_EvalPoint1; + vfmt->EvalPoint2 = vbo_exec_EvalPoint2; + + vfmt->Rectf = _mesa_noop_Rectf; + vfmt->EvalMesh1 = _mesa_noop_EvalMesh1; + vfmt->EvalMesh2 = _mesa_noop_EvalMesh2; + + + /* from attrib_tmp.h: + */ + vfmt->Color3f = vbo_Color3f; + vfmt->Color3fv = vbo_Color3fv; + vfmt->Color4f = vbo_Color4f; + vfmt->Color4fv = vbo_Color4fv; + vfmt->FogCoordfEXT = vbo_FogCoordfEXT; + vfmt->FogCoordfvEXT = vbo_FogCoordfvEXT; + vfmt->MultiTexCoord1fARB = vbo_MultiTexCoord1f; + vfmt->MultiTexCoord1fvARB = vbo_MultiTexCoord1fv; + vfmt->MultiTexCoord2fARB = vbo_MultiTexCoord2f; + vfmt->MultiTexCoord2fvARB = vbo_MultiTexCoord2fv; + vfmt->MultiTexCoord3fARB = vbo_MultiTexCoord3f; + vfmt->MultiTexCoord3fvARB = vbo_MultiTexCoord3fv; + vfmt->MultiTexCoord4fARB = vbo_MultiTexCoord4f; + vfmt->MultiTexCoord4fvARB = vbo_MultiTexCoord4fv; + vfmt->Normal3f = vbo_Normal3f; + vfmt->Normal3fv = vbo_Normal3fv; + vfmt->SecondaryColor3fEXT = vbo_SecondaryColor3fEXT; + vfmt->SecondaryColor3fvEXT = vbo_SecondaryColor3fvEXT; + vfmt->TexCoord1f = vbo_TexCoord1f; + vfmt->TexCoord1fv = vbo_TexCoord1fv; + vfmt->TexCoord2f = vbo_TexCoord2f; + vfmt->TexCoord2fv = vbo_TexCoord2fv; + vfmt->TexCoord3f = vbo_TexCoord3f; + vfmt->TexCoord3fv = vbo_TexCoord3fv; + vfmt->TexCoord4f = vbo_TexCoord4f; + vfmt->TexCoord4fv = vbo_TexCoord4fv; + vfmt->Vertex2f = vbo_Vertex2f; + vfmt->Vertex2fv = vbo_Vertex2fv; + vfmt->Vertex3f = vbo_Vertex3f; + vfmt->Vertex3fv = vbo_Vertex3fv; + vfmt->Vertex4f = vbo_Vertex4f; + vfmt->Vertex4fv = vbo_Vertex4fv; + + vfmt->VertexAttrib1fARB = vbo_VertexAttrib1fARB; + vfmt->VertexAttrib1fvARB = vbo_VertexAttrib1fvARB; + vfmt->VertexAttrib2fARB = vbo_VertexAttrib2fARB; + vfmt->VertexAttrib2fvARB = vbo_VertexAttrib2fvARB; + vfmt->VertexAttrib3fARB = vbo_VertexAttrib3fARB; + vfmt->VertexAttrib3fvARB = vbo_VertexAttrib3fvARB; + vfmt->VertexAttrib4fARB = vbo_VertexAttrib4fARB; + vfmt->VertexAttrib4fvARB = vbo_VertexAttrib4fvARB; + + vfmt->VertexAttrib1fNV = vbo_VertexAttrib1fNV; + vfmt->VertexAttrib1fvNV = vbo_VertexAttrib1fvNV; + vfmt->VertexAttrib2fNV = vbo_VertexAttrib2fNV; + vfmt->VertexAttrib2fvNV = vbo_VertexAttrib2fvNV; + vfmt->VertexAttrib3fNV = vbo_VertexAttrib3fNV; + vfmt->VertexAttrib3fvNV = vbo_VertexAttrib3fvNV; + vfmt->VertexAttrib4fNV = vbo_VertexAttrib4fNV; + vfmt->VertexAttrib4fvNV = vbo_VertexAttrib4fvNV; + + vfmt->Materialfv = vbo_Materialfv; + + vfmt->EdgeFlag = vbo_EdgeFlag; + vfmt->Indexf = vbo_Indexf; + vfmt->Indexfv = vbo_Indexfv; + +} + + +static void vbo_exec_current_init( struct vbo_exec_context *exec ) +{ + GLcontext *ctx = exec->ctx; + GLint i; + + /* setup the pointers for the typical 16 vertex attributes */ + for (i = 0; i < VBO_ATTRIB_FIRST_MATERIAL; i++) + exec->vtx.current[i] = ctx->Current.Attrib[i]; + + /* setup pointers for the 12 material attributes */ + for (i = 0; i < MAT_ATTRIB_MAX; i++) + exec->vtx.current[VBO_ATTRIB_FIRST_MATERIAL + i] = + ctx->Light.Material.Attrib[i]; + + exec->vtx.current[VBO_ATTRIB_INDEX] = &ctx->Current.Index; + exec->vtx.current[VBO_ATTRIB_EDGEFLAG] = &exec->vtx.CurrentFloatEdgeFlag; +} + +void vbo_exec_vtx_init( struct vbo_exec_context *exec ) +{ + GLcontext *ctx = exec->ctx; + GLuint i; + + /* Allocate a buffer object. Will just reuse this object + * continuously. + */ + exec->vtx.bufferobj = ctx->Array.NullBufferObj; + exec->vtx.buffer_map = ALIGN_MALLOC(VBO_VERT_BUFFER_SIZE * sizeof(GLfloat), 64); + + vbo_exec_current_init( exec ); + vbo_exec_vtxfmt_init( exec ); + + /* Hook our functions into the dispatch table. + */ + _mesa_install_exec_vtxfmt( exec->ctx, &exec->vtxfmt ); + + for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) { + exec->vtx.attrsz[i] = 0; + exec->vtx.active_sz[i] = 0; + exec->vtx.inputs[i] = &exec->vtx.arrays[i]; + } + + exec->vtx.vertex_size = 0; +} + + +void vbo_exec_vtx_destroy( struct vbo_exec_context *exec ) +{ + if (exec->vtx.buffer_map) { + ALIGN_FREE(exec->vtx.buffer_map); + exec->vtx.buffer_map = NULL; + } +} + + +void vbo_exec_FlushVertices( GLcontext *ctx, GLuint flags ) +{ + struct vbo_exec_context *exec = &vbo_context(ctx)->exec; + + if (exec->ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) + return; + + if (exec->vtx.vert_count) { + vbo_exec_vtx_flush( exec ); + } + + if (exec->vtx.vertex_size) { + vbo_exec_copy_to_current( exec ); + reset_attrfv( exec ); + } + + exec->ctx->Driver.NeedFlush = 0; +} + + +static void reset_attrfv( struct vbo_exec_context *exec ) +{ + GLuint i; + + for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) { + exec->vtx.attrsz[i] = 0; + exec->vtx.active_sz[i] = 0; + } + + exec->vtx.vertex_size = 0; +} + diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c new file mode 100644 index 0000000000..5cfa7a01a9 --- /dev/null +++ b/src/mesa/vbo/vbo_exec_array.c @@ -0,0 +1,367 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#include "glheader.h" +#include "context.h" +#include "state.h" +#include "api_validate.h" +#include "api_noop.h" +#include "dispatch.h" + +#include "vbo_context.h" + +static GLuint get_max_index( GLuint count, GLuint type, + const GLvoid *indices ) +{ + GLint i; + + /* Compute max element. This is only needed for upload of non-VBO, + * non-constant data elements. + * + * XXX: Postpone this calculation until it is known that it is + * needed. Otherwise could scan this pointlessly in the all-vbo + * case. + */ + switch(type) { + case GL_UNSIGNED_INT: { + const GLuint *ui_indices = (const GLuint *)indices; + GLuint max_ui = 0; + for (i = 0; i < count; i++) + if (ui_indices[i] > max_ui) + max_ui = ui_indices[i]; + return max_ui; + } + case GL_UNSIGNED_SHORT: { + const GLushort *us_indices = (const GLushort *)indices; + GLuint max_us = 0; + for (i = 0; i < count; i++) + if (us_indices[i] > max_us) + max_us = us_indices[i]; + return max_us; + } + case GL_UNSIGNED_BYTE: { + const GLubyte *ub_indices = (const GLubyte *)indices; + GLuint max_ub = 0; + for (i = 0; i < count; i++) + if (ub_indices[i] > max_ub) + max_ub = ub_indices[i]; + return max_ub; + } + default: + return 0; + } +} + + +/* Just translate the arrayobj into a sane layout. + */ +static void bind_array_obj( GLcontext *ctx ) +{ + struct vbo_exec_context *exec = &vbo_context(ctx)->exec; + GLuint i; + + /* TODO: Fix the ArrayObj struct to keep legacy arrays in an array + * rather than as individual named arrays. Then this function can + * go away. + */ + exec->array.legacy_array[VERT_ATTRIB_POS] = &ctx->Array.ArrayObj->Vertex; + exec->array.legacy_array[VERT_ATTRIB_NORMAL] = &ctx->Array.ArrayObj->Normal; + exec->array.legacy_array[VERT_ATTRIB_COLOR0] = &ctx->Array.ArrayObj->Color; + exec->array.legacy_array[VERT_ATTRIB_COLOR1] = &ctx->Array.ArrayObj->SecondaryColor; + exec->array.legacy_array[VERT_ATTRIB_FOG] = &ctx->Array.ArrayObj->FogCoord; + exec->array.legacy_array[VERT_ATTRIB_COLOR_INDEX] = &ctx->Array.ArrayObj->Index; + exec->array.legacy_array[VBO_ATTRIB_EDGEFLAG] = &ctx->Array.ArrayObj->EdgeFlag; + + for (i = 0; i < 8; i++) + exec->array.legacy_array[VBO_ATTRIB_TEX0 + i] = &ctx->Array.ArrayObj->TexCoord[i]; + + for (i = 0; i < VERT_ATTRIB_MAX; i++) + exec->array.generic_array[i] = &ctx->Array.ArrayObj->VertexAttrib[i]; + + exec->array.array_obj = ctx->Array.ArrayObj->Name; +} + +static void recalculate_input_bindings( GLcontext *ctx ) +{ + struct vbo_exec_context *exec = &vbo_context(ctx)->exec; + const struct gl_client_array **inputs = &exec->array.inputs[0]; + GLuint i; + + exec->array.program_mode = get_program_mode(ctx); + exec->array.enabled_flags = ctx->Array.ArrayObj->_Enabled; + + /* TODO: Get rid of NV_program (please!). + */ + switch (exec->array.program_mode) { + case VP_NONE: + /* When no vertex program is active, we put the material values + * into the generic slots. This is the only situation where + * material values are available as per-vertex attributes. + */ + for (i = 0; i <= VERT_ATTRIB_TEX7; i++) { + if (exec->array.legacy_array[i]->Enabled) + inputs[i] = exec->array.legacy_array[i]; + else + inputs[i] = &exec->legacy_currval[i]; + } + + for (i = 0; i < MAT_ATTRIB_MAX; i++) { + inputs[VERT_ATTRIB_GENERIC0 + i] = &exec->mat_currval[i]; + } + break; + case VP_NV: + /* NV_vertex_program - attribute arrays alias and override + * conventional, legacy arrays. No materials, and the generic + * slots are vacant. + */ + for (i = 0; i <= VERT_ATTRIB_TEX7; i++) { + if (exec->array.generic_array[i]->Enabled) + inputs[i] = exec->array.generic_array[i]; + else if (exec->array.legacy_array[i]->Enabled) + inputs[i] = exec->array.legacy_array[i]; + else + inputs[i] = &exec->legacy_currval[i]; + } + break; + case VP_ARB: + /* ARB_vertex_program - Only the attribute zero (position) array + * aliases and overrides the legacy position array. + * + * Otherwise, legacy attributes available in the legacy slots, + * generic attributes in the generic slots and materials are not + * available as per-vertex attributes. + */ + if (exec->array.generic_array[0]->Enabled) + inputs[0] = exec->array.generic_array[0]; + else if (exec->array.legacy_array[0]->Enabled) + inputs[0] = exec->array.legacy_array[0]; + else + inputs[0] = &exec->legacy_currval[0]; + + + for (i = 1; i <= VERT_ATTRIB_TEX7; i++) { + if (exec->array.legacy_array[i]->Enabled) + inputs[i] = exec->array.legacy_array[i]; + else + inputs[i] = &exec->legacy_currval[i]; + } + + for (i = 0; i < 16; i++) { + if (exec->array.generic_array[0]->Enabled) + inputs[VERT_ATTRIB_GENERIC0 + i] = exec->array.generic_array[i]; + else + inputs[VERT_ATTRIB_GENERIC0 + i] = &exec->generic_currval[i]; + } + break; + } +} + +static void bind_arrays( GLcontext *ctx ) +{ +#if 0 + if (ctx->Array.ArrayObj.Name != exec->array.array_obj) { + bind_array_obj(ctx); + recalculate_input_bindings(ctx); + } + else if (exec->array.program_mode != get_program_mode(ctx) || + exec->array.enabled_flags != ctx->Array.ArrayObj->_Enabled) { + + recalculate_input_bindings(ctx); + } +#else + bind_array_obj(ctx); + recalculate_input_bindings(ctx); +#endif +} + + + +/*********************************************************************** + * API functions. + */ + +static void GLAPIENTRY +vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count) +{ + GET_CURRENT_CONTEXT(ctx); + struct vbo_context *vbo = vbo_context(ctx); + struct vbo_exec_context *exec = &vbo->exec; + struct _mesa_prim prim[1]; + + if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) + return; + + FLUSH_CURRENT( ctx, 0 ); + + if (ctx->NewState) + _mesa_update_state( ctx ); + + bind_arrays( ctx ); + + prim[0].begin = 1; + prim[0].end = 1; + prim[0].weak = 0; + prim[0].pad = 0; + + if (exec->array.inputs[0]->BufferObj->Name) { + /* Use vertex attribute as a hint to tell us if we expect all + * arrays to be in VBO's and if so, don't worry about avoiding + * the upload of elements < start. + */ + prim[0].mode = mode; + prim[0].start = start; + prim[0].count = count; + prim[0].indexed = 0; + + vbo->draw_prims( ctx, exec->array.inputs, prim, 1, NULL, 0, start + count ); + } + else { + /* If not using VBO's, we don't want to upload any more elements + * than necessary from the arrays as they will not be valid next + * time the application tries to draw with them. + */ + prim[0].mode = mode; + prim[0].start = 0; + prim[0].count = count; + prim[0].indexed = 0; + + vbo->draw_prims( ctx, exec->array.inputs, prim, 1, NULL, start, start + count ); + } +} + + + +static void GLAPIENTRY +vbo_exec_DrawRangeElements(GLenum mode, + GLuint start, GLuint end, + GLsizei count, GLenum type, const GLvoid *indices) +{ + GET_CURRENT_CONTEXT(ctx); + struct vbo_context *vbo = vbo_context(ctx); + struct vbo_exec_context *exec = &vbo->exec; + struct _mesa_index_buffer ib; + struct _mesa_prim prim[1]; + + if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count, type, indices )) + return; + + FLUSH_CURRENT( ctx, 0 ); + + if (ctx->NewState) + _mesa_update_state( ctx ); + + ib.count = count; + ib.type = type; + ib.obj = ctx->Array.ElementArrayBufferObj; + ib.ptr = indices; + + if (ctx->Array.ElementArrayBufferObj->Name) { + /* Use the fact that indices are in a VBO as a hint that the + * program has put all the arrays in VBO's and we don't have to + * worry about performance implications of start > 0. + * + * XXX: consider passing start as min_index to draw_prims instead. + */ + ib.rebase = 0; + } + else { + ib.rebase = start; + } + + prim[0].begin = 1; + prim[0].end = 1; + prim[0].weak = 0; + prim[0].pad = 0; + prim[0].mode = mode; + prim[0].start = 0; + prim[0].count = count; + prim[0].indexed = 1; + + vbo->draw_prims( ctx, exec->array.inputs, prim, 1, &ib, ib.rebase, end+1 ); +} + + +static void GLAPIENTRY +vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint max_index; + + if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) + return; + + if (ctx->Array.ElementArrayBufferObj->Name) { + const GLvoid *map = ctx->Driver.MapBuffer(ctx, + GL_ELEMENT_ARRAY_BUFFER_ARB, + GL_DYNAMIC_READ_ARB, + ctx->Array.ElementArrayBufferObj); + + max_index = get_max_index(count, type, ADD_POINTERS(map, indices)); + + ctx->Driver.UnmapBuffer(ctx, + GL_ELEMENT_ARRAY_BUFFER_ARB, + ctx->Array.ElementArrayBufferObj); + } + else { + max_index = get_max_index(count, type, indices); + } + + vbo_exec_DrawRangeElements(mode, 0, max_index, count, type, indices); +} + + +/*********************************************************************** + * Initialization + */ + + + + +void vbo_exec_array_init( struct vbo_exec_context *exec ) +{ + GLcontext *ctx = exec->ctx; + +#if 1 + exec->vtxfmt.DrawArrays = vbo_exec_DrawArrays; + exec->vtxfmt.DrawElements = vbo_exec_DrawElements; + exec->vtxfmt.DrawRangeElements = vbo_exec_DrawRangeElements; +#else + exec->vtxfmt.DrawArrays = _mesa_noop_DrawArrays; + exec->vtxfmt.DrawElements = _mesa_noop_DrawElements; + exec->vtxfmt.DrawRangeElements = _mesa_noop_DrawRangeElements; +#endif + + exec->array.index_obj = ctx->Driver.NewBufferObject(ctx, 1, GL_ARRAY_BUFFER_ARB); +} + + +void vbo_exec_array_destroy( struct vbo_exec_context *exec ) +{ + GLcontext *ctx = exec->ctx; + + ctx->Driver.DeleteBuffer(ctx, exec->array.index_obj); +} diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c new file mode 100644 index 0000000000..f665c64c7a --- /dev/null +++ b/src/mesa/vbo/vbo_exec_draw.c @@ -0,0 +1,199 @@ +/* + * 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 + */ + +#include "glheader.h" +#include "context.h" +#include "enums.h" +#include "state.h" +#include "macros.h" + +#include "vbo_context.h" + + +static void vbo_exec_debug_verts( struct vbo_exec_context *exec ) +{ + GLuint count = exec->vtx.vert_count; + GLuint i; + + _mesa_printf("%s: %u vertices %d primitives, %d vertsize\n", + __FUNCTION__, + count, + exec->vtx.prim_count, + exec->vtx.vertex_size); + + for (i = 0 ; i < exec->vtx.prim_count ; i++) { + struct _mesa_prim *prim = &exec->vtx.prim[i]; + _mesa_printf(" prim %d: %s%s %d..%d %s %s\n", + i, + _mesa_lookup_enum_by_nr(prim->mode), + prim->weak ? " (weak)" : "", + prim->start, + prim->start + prim->count, + prim->begin ? "BEGIN" : "(wrap)", + prim->end ? "END" : "(wrap)"); + } +} + + +/* + * NOTE: Need to have calculated primitives by this point -- do it on the fly. + * NOTE: Old 'parity' issue is gone. + */ +static GLuint vbo_copy_vertices( struct vbo_exec_context *exec ) +{ + GLuint nr = exec->vtx.prim[exec->vtx.prim_count-1].count; + GLuint ovf, i; + GLuint sz = exec->vtx.vertex_size; + GLfloat *dst = exec->vtx.copied.buffer; + GLfloat *src = ((GLfloat *)exec->vtx.buffer_map + + exec->vtx.prim[exec->vtx.prim_count-1].start * + exec->vtx.vertex_size); + + + switch( exec->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 GL_POLYGON+1: + return 0; + default: + assert(0); + return 0; + } +} + + +/* TODO: populate these as the vertex is defined: + */ +static void vbo_exec_bind_arrays( struct vbo_exec_context *exec ) +{ + struct gl_client_array *arrays = exec->vtx.arrays; + GLuint count = exec->vtx.vert_count; + GLubyte *data = exec->vtx.buffer_map; + GLuint attr; + + memcpy(arrays, exec->legacy_currval, 16 * sizeof(arrays[0])); + memcpy(arrays + 16, exec->mat_currval, 16 * sizeof(arrays[0])); + + /* Make all active attributes (including edgeflag) available as + * arrays of floats. + */ + for (attr = 0; attr < VBO_ATTRIB_MAX ; attr++) { + if (exec->vtx.attrsz[attr]) { + arrays[attr].Ptr = (void *)data; + arrays[attr].Size = exec->vtx.attrsz[attr]; + arrays[attr].StrideB = exec->vtx.vertex_size * sizeof(GLfloat); + arrays[attr].Stride = exec->vtx.vertex_size * sizeof(GLfloat); + arrays[attr].Type = GL_FLOAT; + arrays[attr].Enabled = 1; + arrays[attr].BufferObj = exec->vtx.bufferobj; /* NullBufferObj */ + arrays[attr]._MaxElement = count; /* ??? */ + + data += exec->vtx.attrsz[attr] * sizeof(GLfloat); + } + } +} + + +/** + * Execute the buffer and save copied verts. + */ +void vbo_exec_vtx_flush( struct vbo_exec_context *exec ) +{ + if (0) + vbo_exec_debug_verts( exec ); + + + if (exec->vtx.prim_count && + exec->vtx.vert_count) { + + exec->vtx.copied.nr = vbo_copy_vertices( exec ); + + if (exec->vtx.copied.nr != exec->vtx.vert_count) { + GLcontext *ctx = exec->ctx; + + vbo_exec_bind_arrays( exec ); + + vbo_context(ctx)->draw_prims( ctx, + exec->vtx.inputs, + exec->vtx.prim, + exec->vtx.prim_count, + NULL, + 0, + exec->vtx.vert_count ); + } + } + + exec->vtx.prim_count = 0; + exec->vtx.vert_count = 0; + exec->vtx.vbptr = (GLfloat *)exec->vtx.buffer_map; +} diff --git a/src/mesa/vbo/vbo_exec_eval.c b/src/mesa/vbo/vbo_exec_eval.c new file mode 100644 index 0000000000..99a8044576 --- /dev/null +++ b/src/mesa/vbo/vbo_exec_eval.c @@ -0,0 +1,255 @@ +/* + * 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. + * + * Authors: + * Keith Whitwell + */ + +#include "glheader.h" +#include "api_eval.h" +#include "context.h" +#include "macros.h" +#include "math/m_eval.h" +#include "vbo_exec.h" +#include "dispatch.h" + + +static void clear_active_eval1( struct vbo_exec_context *exec, GLuint attr ) +{ + exec->eval.map1[attr].map = NULL; +} + +static void clear_active_eval2( struct vbo_exec_context *exec, GLuint attr ) +{ + exec->eval.map2[attr].map = NULL; +} + +static void set_active_eval1( struct vbo_exec_context *exec, GLuint attr, GLuint dim, + struct gl_1d_map *map ) +{ + if (!exec->eval.map1[attr].map) { + exec->eval.map1[attr].map = map; + exec->eval.map1[attr].sz = dim; + } +} + +static void set_active_eval2( struct vbo_exec_context *exec, GLuint attr, GLuint dim, + struct gl_2d_map *map ) +{ + if (!exec->eval.map2[attr].map) { + exec->eval.map2[attr].map = map; + exec->eval.map2[attr].sz = dim; + } +} + +void vbo_exec_eval_update( struct vbo_exec_context *exec ) +{ + GLcontext *ctx = exec->ctx; + GLuint attr; + + /* Vertex program maps have priority over conventional attribs */ + + for (attr = 0; attr < VBO_ATTRIB_FIRST_MATERIAL; attr++) { + clear_active_eval1( exec, attr ); + clear_active_eval2( exec, attr ); + } + + /* _NEW_PROGRAM */ + if (ctx->VertexProgram._Enabled) { + for (attr = 0; attr < VBO_ATTRIB_FIRST_MATERIAL; attr++) { + /* _NEW_EVAL */ + if (ctx->Eval.Map1Attrib[attr]) + set_active_eval1( exec, attr, 4, &ctx->EvalMap.Map1Attrib[attr] ); + + if (ctx->Eval.Map2Attrib[attr]) + set_active_eval2( exec, attr, 4, &ctx->EvalMap.Map2Attrib[attr] ); + } + } + + if (ctx->Eval.Map1Color4) + set_active_eval1( exec, VBO_ATTRIB_COLOR0, 4, &ctx->EvalMap.Map1Color4 ); + + if (ctx->Eval.Map2Color4) + set_active_eval2( exec, VBO_ATTRIB_COLOR0, 4, &ctx->EvalMap.Map2Color4 ); + + if (ctx->Eval.Map1TextureCoord4) + set_active_eval1( exec, VBO_ATTRIB_TEX0, 4, &ctx->EvalMap.Map1Texture4 ); + else if (ctx->Eval.Map1TextureCoord3) + set_active_eval1( exec, VBO_ATTRIB_TEX0, 3, &ctx->EvalMap.Map1Texture3 ); + else if (ctx->Eval.Map1TextureCoord2) + set_active_eval1( exec, VBO_ATTRIB_TEX0, 2, &ctx->EvalMap.Map1Texture2 ); + else if (ctx->Eval.Map1TextureCoord1) + set_active_eval1( exec, VBO_ATTRIB_TEX0, 1, &ctx->EvalMap.Map1Texture1 ); + + if (ctx->Eval.Map2TextureCoord4) + set_active_eval2( exec, VBO_ATTRIB_TEX0, 4, &ctx->EvalMap.Map2Texture4 ); + else if (ctx->Eval.Map2TextureCoord3) + set_active_eval2( exec, VBO_ATTRIB_TEX0, 3, &ctx->EvalMap.Map2Texture3 ); + else if (ctx->Eval.Map2TextureCoord2) + set_active_eval2( exec, VBO_ATTRIB_TEX0, 2, &ctx->EvalMap.Map2Texture2 ); + else if (ctx->Eval.Map2TextureCoord1) + set_active_eval2( exec, VBO_ATTRIB_TEX0, 1, &ctx->EvalMap.Map2Texture1 ); + + if (ctx->Eval.Map1Normal) + set_active_eval1( exec, VBO_ATTRIB_NORMAL, 3, &ctx->EvalMap.Map1Normal ); + + if (ctx->Eval.Map2Normal) + set_active_eval2( exec, VBO_ATTRIB_NORMAL, 3, &ctx->EvalMap.Map2Normal ); + + if (ctx->Eval.Map1Vertex4) + set_active_eval1( exec, VBO_ATTRIB_POS, 4, &ctx->EvalMap.Map1Vertex4 ); + else if (ctx->Eval.Map1Vertex3) + set_active_eval1( exec, VBO_ATTRIB_POS, 3, &ctx->EvalMap.Map1Vertex3 ); + + if (ctx->Eval.Map2Vertex4) + set_active_eval2( exec, VBO_ATTRIB_POS, 4, &ctx->EvalMap.Map2Vertex4 ); + else if (ctx->Eval.Map2Vertex3) + set_active_eval2( exec, VBO_ATTRIB_POS, 3, &ctx->EvalMap.Map2Vertex3 ); + + exec->eval.recalculate_maps = 0; +} + + + +void vbo_exec_do_EvalCoord1f(struct vbo_exec_context *exec, GLfloat u) +{ + GLuint attr; + + for (attr = 1; attr <= VBO_ATTRIB_INDEX; attr++) { + struct gl_1d_map *map = exec->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, + exec->eval.map1[attr].sz, + map->Order); + + COPY_SZ_4V( exec->vtx.attrptr[attr], + exec->vtx.attrsz[attr], + data ); + } + } + + /** Vertex -- EvalCoord1f is a noop if this map not enabled: + **/ + if (exec->eval.map1[0].map) { + struct gl_1d_map *map = exec->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, + exec->eval.map1[0].sz, + map->Order); + + if (exec->eval.map1[0].sz == 4) + CALL_Vertex4fv(GET_DISPATCH(), ( vertex )); + else + CALL_Vertex3fv(GET_DISPATCH(), ( vertex )); + } +} + + + +void vbo_exec_do_EvalCoord2f( struct vbo_exec_context *exec, + GLfloat u, GLfloat v ) +{ + GLuint attr; + + for (attr = 1; attr <= VBO_ATTRIB_INDEX; attr++) { + struct gl_2d_map *map = exec->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, + exec->eval.map2[attr].sz, + map->Uorder, map->Vorder); + + COPY_SZ_4V( exec->vtx.attrptr[attr], + exec->vtx.attrsz[attr], + data ); + } + } + + /** Vertex -- EvalCoord2f is a noop if this map not enabled: + **/ + if (exec->eval.map2[0].map) { + struct gl_2d_map *map = exec->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 (exec->ctx->Eval.AutoNormal) { + GLfloat normal[4]; + GLfloat du[4], dv[4]; + + _math_de_casteljau_surf(map->Points, vertex, du, dv, uu, vv, + exec->eval.map2[0].sz, + map->Uorder, map->Vorder); + + if (exec->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( exec->vtx.attrptr[VBO_ATTRIB_NORMAL], + exec->vtx.attrsz[VBO_ATTRIB_NORMAL], + normal ); + + } + else { + _math_horner_bezier_surf(map->Points, vertex, uu, vv, + exec->eval.map2[0].sz, + map->Uorder, map->Vorder); + } + + if (exec->vtx.attrsz[0] == 4) + CALL_Vertex4fv(GET_DISPATCH(), ( vertex )); + else + CALL_Vertex3fv(GET_DISPATCH(), ( vertex )); + } +} + + diff --git a/src/mesa/vbo/vbo_save.c b/src/mesa/vbo/vbo_save.c new file mode 100644 index 0000000000..0a5b705400 --- /dev/null +++ b/src/mesa/vbo/vbo_save.c @@ -0,0 +1,94 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 1999-2005 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 + */ + + +#include "mtypes.h" +#include "dlist.h" +#include "vtxfmt.h" +#include "imports.h" + +#include "vbo_context.h" + + + +void vbo_save_init( GLcontext *ctx ) +{ + struct vbo_save_context *save = &vbo_context(ctx)->save; + + save->ctx = ctx; + + vbo_save_api_init( save ); + vbo_save_wakeup(ctx); + + ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN; +} + + +void vbo_save_destroy( GLcontext *ctx ) +{ +} + + + + +/* Note that this can occur during the playback of a display list: + */ +void vbo_save_fallback( GLcontext *ctx, GLboolean fallback ) +{ + struct vbo_save_context *save = &vbo_context(ctx)->save; + + if (fallback) + save->replay_flags |= VBO_SAVE_FALLBACK; + else + save->replay_flags &= ~VBO_SAVE_FALLBACK; +} + + +/* I don't see any reason to swap this code out on fallbacks. It + * wouldn't really mean anything to do so anyway as the old lists are + * still around from pre-fallback. Instead, the above code ensures + * that vertices are routed back through immediate mode dispatch on + * fallback. + * + * The below can be moved into init or removed: + */ +void vbo_save_wakeup( GLcontext *ctx ) +{ + ctx->Driver.NewList = vbo_save_NewList; + ctx->Driver.EndList = vbo_save_EndList; + ctx->Driver.SaveFlushVertices = vbo_save_SaveFlushVertices; + ctx->Driver.BeginCallList = vbo_save_BeginCallList; + ctx->Driver.EndCallList = vbo_save_EndCallList; + ctx->Driver.NotifySaveBegin = vbo_save_NotifyBegin; + + /* Assume we haven't been getting state updates either: + */ + vbo_save_invalidate_state( ctx, ~0 ); +} + + + diff --git a/src/mesa/vbo/vbo_save.h b/src/mesa/vbo/vbo_save.h new file mode 100644 index 0000000000..dbe5cafb99 --- /dev/null +++ b/src/mesa/vbo/vbo_save.h @@ -0,0 +1,180 @@ +/************************************************************************** + +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 + * + */ + +#ifndef VBO_SAVE_H +#define VBO_SAVE_H + +#include "mtypes.h" +#include "vbo_attrib.h" + + +struct vbo_save_copied_vtx { + GLfloat buffer[VBO_ATTRIB_MAX * 4 * VBO_MAX_COPIED_VERTS]; + GLuint nr; +}; + + +/* 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 vbo_save_vertex_list { + GLubyte attrsz[VBO_ATTRIB_MAX]; + GLuint vertex_size; + + GLuint buffer_offset; + GLuint count; + GLuint wrap_count; /* number of copied vertices at start */ + GLboolean dangling_attr_ref; /* current attr implicitly referenced + outside the list */ + + struct _mesa_prim *prim; + GLuint prim_count; + + struct vbo_save_vertex_store *vertex_store; + struct vbo_save_primitive_store *prim_store; +}; + +/* These buffers should be a reasonable size to support upload to + * hardware. Current vbo implementation will re-upload on any + * changes, so don't make too big or apps which dynamically create + * dlists and use only a few times will suffer. + * + * Consider stategy of uploading regions from the VBO on demand in the + * case of dynamic vbos. Then make the dlist code signal that + * likelyhood as it occurs. No reason we couldn't change usage + * internally even though this probably isn't allowed for client VBOs? + */ +#define VBO_SAVE_BUFFER_SIZE (8*1024) /* dwords */ +#define VBO_SAVE_PRIM_SIZE 128 +#define VBO_SAVE_PRIM_WEAK 0x40 + +#define VBO_SAVE_FALLBACK 0x10000000 + +/* Storage to be shared among several vertex_lists. + */ +struct vbo_save_vertex_store { + struct gl_buffer_object *bufferobj; + GLfloat *buffer; + GLuint used; + GLuint refcount; +}; + +struct vbo_save_primitive_store { + struct _mesa_prim buffer[VBO_SAVE_PRIM_SIZE]; + GLuint used; + GLuint refcount; +}; + + +struct vbo_save_context { + GLcontext *ctx; + GLvertexformat vtxfmt; + struct gl_client_array arrays[VBO_ATTRIB_MAX]; + const struct gl_client_array *inputs[VBO_ATTRIB_MAX]; + + GLubyte attrsz[VBO_ATTRIB_MAX]; + GLubyte active_sz[VBO_ATTRIB_MAX]; + GLuint vertex_size; + + GLfloat *buffer; + GLuint count; + GLuint wrap_count; + GLuint replay_flags; + + struct _mesa_prim *prim; + GLuint prim_count, prim_max; + + struct vbo_save_vertex_store *vertex_store; + struct vbo_save_primitive_store *prim_store; + + GLfloat *vbptr; /* cursor, points into buffer */ + GLfloat vertex[VBO_ATTRIB_MAX*4]; /* current values */ + GLfloat *attrptr[VBO_ATTRIB_MAX]; + GLuint vert_count; + GLuint max_vert; + GLboolean dangling_attr_ref; + GLboolean have_materials; + + GLuint opcode_vertex_list; + + struct vbo_save_copied_vtx copied; + + GLfloat CurrentFloatEdgeFlag; + + GLfloat *current[VBO_ATTRIB_MAX]; /* points into ctx->ListState */ + GLubyte *currentsz[VBO_ATTRIB_MAX]; +}; + + +void vbo_save_init( GLcontext *ctx ); +void vbo_save_destroy( GLcontext *ctx ); +void vbo_save_wakeup( GLcontext *ctx ); +void vbo_save_invalidate_state( GLcontext *ctx, GLuint new_state ); +void vbo_save_fallback( GLcontext *ctx, GLboolean fallback ); + +/* save_loopback.c: + */ +void vbo_loopback_vertex_list( GLcontext *ctx, + const GLfloat *buffer, + const GLubyte *attrsz, + const struct _mesa_prim *prim, + GLuint prim_count, + GLuint wrap_count, + GLuint vertex_size); + +/* Callbacks: + */ +void vbo_save_EndList( GLcontext *ctx ); +void vbo_save_NewList( GLcontext *ctx, GLuint list, GLenum mode ); +void vbo_save_EndCallList( GLcontext *ctx ); +void vbo_save_BeginCallList( GLcontext *ctx, struct mesa_display_list *list ); +void vbo_save_SaveFlushVertices( GLcontext *ctx ); +GLboolean vbo_save_NotifyBegin( GLcontext *ctx, GLenum mode ); + +void vbo_save_playback_vertex_list( GLcontext *ctx, void *data ); + +void vbo_save_api_init( struct vbo_save_context *save ); + +#endif diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c new file mode 100644 index 0000000000..8ceba2b832 --- /dev/null +++ b/src/mesa/vbo/vbo_save_api.c @@ -0,0 +1,1160 @@ +/************************************************************************** + +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 + */ + + + +/* Display list compiler attempts to store lists of vertices with the + * same vertex layout. Additionally it attempts to minimize the need + * for execute-time fixup of these vertex lists, allowing them to be + * cached on hardware. + * + * There are still some circumstances where this can be thwarted, for + * example by building a list that consists of one very long primitive + * (eg Begin(Triangles), 1000 vertices, End), and calling that list + * from inside a different begin/end object (Begin(Lines), CallList, + * End). + * + * In that case the code will have to replay the list as individual + * commands through the Exec dispatch table, or fix up the copied + * vertices at execute-time. + * + * The other case where fixup is required is when a vertex attribute + * is introduced in the middle of a primitive. Eg: + * Begin(Lines) + * TexCoord1f() Vertex2f() + * TexCoord1f() Color3f() Vertex2f() + * End() + * + * If the current value of Color isn't known at compile-time, this + * primitive will require fixup. + * + * + * The list compiler currently doesn't attempt to compile lists + * containing EvalCoord or EvalPoint commands. On encountering one of + * these, compilation falls back to opcodes. + * + * This could be improved to fallback only when a mix of EvalCoord and + * Vertex commands are issued within a single primitive. + */ + + +#include "glheader.h" +#include "context.h" +#include "dlist.h" +#include "enums.h" +#include "macros.h" +#include "api_validate.h" +#include "api_arrayelt.h" +#include "vtxfmt.h" +#include "dispatch.h" + +#include "vbo_context.h" + + + +/* + * NOTE: Old 'parity' issue is gone, but copying can still be + * wrong-footed on replay. + */ +static GLuint _save_copy_vertices( GLcontext *ctx, + const struct vbo_save_vertex_list *node, + const GLfloat *src_buffer) +{ + struct vbo_save_context *save = &vbo_context( ctx )->save; + const struct _mesa_prim *prim = &node->prim[node->prim_count-1]; + GLuint nr = prim->count; + GLuint sz = save->vertex_size; + const GLfloat *src = src_buffer + prim->start * sz; + GLfloat *dst = save->copied.buffer; + GLuint ovf, i; + + if (prim->end) + return 0; + + switch( prim->mode ) + { + 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; + default: + assert(0); + return 0; + } +} + + +static struct vbo_save_vertex_store *alloc_vertex_store( GLcontext *ctx ) +{ + struct vbo_save_vertex_store *vertex_store = CALLOC_STRUCT(vbo_save_vertex_store); + + /* obj->Name needs to be non-zero, but won't ever be examined more + * closely than that. In particular these buffers won't be entered + * into the hash and can never be confused with ones visible to the + * user. Perhaps there could be a special number for internal + * buffers: + */ + vertex_store->bufferobj = ctx->Driver.NewBufferObject(ctx, 1, GL_ARRAY_BUFFER_ARB); + + ctx->Driver.BufferData( ctx, + GL_ARRAY_BUFFER_ARB, + VBO_SAVE_BUFFER_SIZE * sizeof(GLfloat), + NULL, + GL_STATIC_DRAW_ARB, + vertex_store->bufferobj); + + vertex_store->buffer = NULL; + vertex_store->used = 0; + vertex_store->refcount = 1; + + return vertex_store; +} + +static void free_vertex_store( GLcontext *ctx, struct vbo_save_vertex_store *vertex_store ) +{ + assert(!vertex_store->buffer); + + if (vertex_store->bufferobj) + ctx->Driver.DeleteBuffer( ctx, vertex_store->bufferobj ); + + FREE( vertex_store ); +} + +static GLfloat *map_vertex_store( GLcontext *ctx, struct vbo_save_vertex_store *vertex_store ) +{ + assert(vertex_store->bufferobj); + assert(!vertex_store->buffer); + vertex_store->buffer = (GLfloat *)ctx->Driver.MapBuffer(ctx, + GL_ARRAY_BUFFER_ARB, /* not used */ + GL_STATIC_DRAW_ARB, /* not used */ + vertex_store->bufferobj); + + assert(vertex_store->buffer); + return vertex_store->buffer + vertex_store->used; +} + +static void unmap_vertex_store( GLcontext *ctx, struct vbo_save_vertex_store *vertex_store ) +{ + ctx->Driver.UnmapBuffer( ctx, GL_ARRAY_BUFFER_ARB, vertex_store->bufferobj ); + vertex_store->buffer = NULL; +} + + +static struct vbo_save_primitive_store *alloc_prim_store( GLcontext *ctx ) +{ + struct vbo_save_primitive_store *store = CALLOC_STRUCT(vbo_save_primitive_store); + (void) ctx; + store->used = 0; + store->refcount = 1; + return store; +} + +static void _save_reset_counters( GLcontext *ctx ) +{ + struct vbo_save_context *save = &vbo_context(ctx)->save; + + save->prim = save->prim_store->buffer + save->prim_store->used; + save->buffer = (save->vertex_store->buffer + + save->vertex_store->used); + + assert(save->buffer == save->vbptr); + + if (save->vertex_size) + save->max_vert = ((VBO_SAVE_BUFFER_SIZE - save->vertex_store->used) / + save->vertex_size); + else + save->max_vert = 0; + + save->vert_count = 0; + save->prim_count = 0; + save->prim_max = VBO_SAVE_PRIM_SIZE - save->prim_store->used; + save->dangling_attr_ref = 0; +} + + +/* Insert the active immediate struct onto the display list currently + * being built. + */ +static void _save_compile_vertex_list( GLcontext *ctx ) +{ + struct vbo_save_context *save = &vbo_context(ctx)->save; + struct vbo_save_vertex_list *node; + + /* Allocate space for this structure in the display list currently + * being compiled. + */ + node = (struct vbo_save_vertex_list *) + _mesa_alloc_instruction(ctx, save->opcode_vertex_list, sizeof(*node)); + + if (!node) + return; + + /* Duplicate our template, increment refcounts to the storage structs: + */ + _mesa_memcpy(node->attrsz, save->attrsz, sizeof(node->attrsz)); + node->vertex_size = save->vertex_size; + node->buffer_offset = (save->buffer - save->vertex_store->buffer) * sizeof(GLfloat); + node->count = save->vert_count; + node->wrap_count = save->copied.nr; + node->dangling_attr_ref = save->dangling_attr_ref; + node->prim = save->prim; + node->prim_count = save->prim_count; + node->vertex_store = save->vertex_store; + node->prim_store = save->prim_store; + + node->vertex_store->refcount++; + node->prim_store->refcount++; + + assert(node->attrsz[VBO_ATTRIB_POS] != 0 || + node->count == 0); + + if (save->dangling_attr_ref) + ctx->ListState.CurrentList->flags |= MESA_DLIST_DANGLING_REFS; + + save->vertex_store->used += save->vertex_size * node->count; + save->prim_store->used += node->prim_count; + + + /* Copy duplicated vertices + */ + save->copied.nr = _save_copy_vertices( ctx, node, save->buffer ); + + + /* Deal with GL_COMPILE_AND_EXECUTE: + */ + if (ctx->ExecuteFlag) { + struct _glapi_table *dispatch = GET_DISPATCH(); + + _glapi_set_dispatch(ctx->Exec); + + vbo_loopback_vertex_list( ctx, + (const GLfloat *)((const char *)save->vertex_store->buffer + + node->buffer_offset), + node->attrsz, + node->prim, + node->prim_count, + node->wrap_count, + node->vertex_size); + + _glapi_set_dispatch(dispatch); + } + + + /* Decide whether the storage structs are full, or can be used for + * the next vertex lists as well. + */ + if (save->vertex_store->used > + VBO_SAVE_BUFFER_SIZE - 16 * (save->vertex_size + 4)) { + + /* Unmap old store: + */ + unmap_vertex_store( ctx, save->vertex_store ); + + /* Release old reference: + */ + save->vertex_store->refcount--; + assert(save->vertex_store->refcount != 0); + save->vertex_store = NULL; + + /* Allocate and map new store: + */ + save->vertex_store = alloc_vertex_store( ctx ); + save->vbptr = map_vertex_store( ctx, save->vertex_store ); + } + + if (save->prim_store->used > VBO_SAVE_PRIM_SIZE - 6) { + save->prim_store->refcount--; + assert(save->prim_store->refcount != 0); + save->prim_store = alloc_prim_store( ctx ); + } + + /* Reset our structures for the next run of vertices: + */ + _save_reset_counters( ctx ); +} + + +/* TODO -- If no new vertices have been stored, don't bother saving + * it. + */ +static void _save_wrap_buffers( GLcontext *ctx ) +{ + struct vbo_save_context *save = &vbo_context(ctx)->save; + GLint i = save->prim_count - 1; + GLenum mode; + GLboolean weak; + + assert(i < (GLint) save->prim_max); + assert(i >= 0); + + /* Close off in-progress primitive. + */ + save->prim[i].count = (save->vert_count - + save->prim[i].start); + mode = save->prim[i].mode; + weak = save->prim[i].weak; + + /* store the copied vertices, and allocate a new list. + */ + _save_compile_vertex_list( ctx ); + + /* Restart interrupted primitive + */ + save->prim[0].mode = mode; + save->prim[0].weak = weak; + save->prim[0].begin = 0; + save->prim[0].end = 0; + save->prim[0].pad = 0; + save->prim[0].start = 0; + save->prim[0].count = 0; + save->prim_count = 1; +} + + + +/* Called only when buffers are wrapped as the result of filling the + * vertex_store struct. + */ +static void _save_wrap_filled_vertex( GLcontext *ctx ) +{ + struct vbo_save_context *save = &vbo_context(ctx)->save; + GLfloat *data = save->copied.buffer; + GLuint i; + + /* Emit a glEnd to close off the last vertex list. + */ + _save_wrap_buffers( ctx ); + + /* Copy stored stored vertices to start of new list. + */ + assert(save->max_vert - save->vert_count > save->copied.nr); + + for (i = 0 ; i < save->copied.nr ; i++) { + _mesa_memcpy( save->vbptr, data, save->vertex_size * sizeof(GLfloat)); + data += save->vertex_size; + save->vbptr += save->vertex_size; + save->vert_count++; + } +} + + +static void _save_copy_to_current( GLcontext *ctx ) +{ + struct vbo_save_context *save = &vbo_context(ctx)->save; + GLuint i; + + for (i = VBO_ATTRIB_POS+1 ; i <= VBO_ATTRIB_INDEX ; i++) { + if (save->attrsz[i]) { + save->currentsz[i][0] = save->attrsz[i]; + COPY_CLEAN_4V(save->current[i], + save->attrsz[i], + save->attrptr[i]); + } + } + + /* Edgeflag requires special treatment: + * + * TODO: change edgeflag to GLfloat in Mesa. + */ + if (save->attrsz[VBO_ATTRIB_EDGEFLAG]) { + ctx->ListState.ActiveEdgeFlag = 1; + save->CurrentFloatEdgeFlag = + save->attrptr[VBO_ATTRIB_EDGEFLAG][0]; + ctx->ListState.CurrentEdgeFlag = + (save->CurrentFloatEdgeFlag == 1.0); + } +} + + +static void _save_copy_from_current( GLcontext *ctx ) +{ + struct vbo_save_context *save = &vbo_context(ctx)->save; + GLint i; + + for (i = VBO_ATTRIB_POS+1 ; i <= VBO_ATTRIB_INDEX ; i++) + switch (save->attrsz[i]) { + case 4: save->attrptr[i][3] = save->current[i][3]; + case 3: save->attrptr[i][2] = save->current[i][2]; + case 2: save->attrptr[i][1] = save->current[i][1]; + case 1: save->attrptr[i][0] = save->current[i][0]; + case 0: break; + } + + /* Edgeflag requires special treatment: + */ + if (save->attrsz[VBO_ATTRIB_EDGEFLAG]) { + save->CurrentFloatEdgeFlag = (GLfloat)ctx->ListState.CurrentEdgeFlag; + save->attrptr[VBO_ATTRIB_EDGEFLAG][0] = save->CurrentFloatEdgeFlag; + } +} + + + + +/* Flush existing data, set new attrib size, replay copied vertices. + */ +static void _save_upgrade_vertex( GLcontext *ctx, + GLuint attr, + GLuint newsz ) +{ + struct vbo_save_context *save = &vbo_context(ctx)->save; + GLuint oldsz; + GLuint i; + GLfloat *tmp; + + /* Store the current run of vertices, and emit a GL_END. Emit a + * BEGIN in the new buffer. + */ + if (save->vert_count) + _save_wrap_buffers( ctx ); + else + assert( save->copied.nr == 0 ); + + /* Do a COPY_TO_CURRENT to ensure back-copying works for the case + * when the attribute already exists in the vertex and is having + * its size increased. + */ + _save_copy_to_current( ctx ); + + /* Fix up sizes: + */ + oldsz = save->attrsz[attr]; + save->attrsz[attr] = newsz; + + save->vertex_size += newsz - oldsz; + save->max_vert = ((VBO_SAVE_BUFFER_SIZE - save->vertex_store->used) / + save->vertex_size); + save->vert_count = 0; + + /* Recalculate all the attrptr[] values: + */ + for (i = 0, tmp = save->vertex ; i < VBO_ATTRIB_MAX ; i++) { + if (save->attrsz[i]) { + save->attrptr[i] = tmp; + tmp += save->attrsz[i]; + } + else + save->attrptr[i] = NULL; /* will not be dereferenced. */ + } + + /* Copy from current to repopulate the vertex with correct values. + */ + _save_copy_from_current( ctx ); + + /* Replay stored vertices to translate them to new format here. + * + * If there are copied vertices and the new (upgraded) attribute + * has not been defined before, this list is somewhat degenerate, + * and will need fixup at runtime. + */ + if (save->copied.nr) + { + GLfloat *data = save->copied.buffer; + GLfloat *dest = save->buffer; + GLuint j; + + /* Need to note this and fix up at runtime (or loopback): + */ + if (save->currentsz[attr][0] == 0) { + assert(oldsz == 0); + save->dangling_attr_ref = GL_TRUE; + } + + for (i = 0 ; i < save->copied.nr ; i++) { + for (j = 0 ; j < VBO_ATTRIB_MAX ; j++) { + if (save->attrsz[j]) { + if (j == attr) { + if (oldsz) { + COPY_CLEAN_4V( dest, oldsz, data ); + data += oldsz; + dest += newsz; + } + else { + COPY_SZ_4V( dest, newsz, save->current[attr] ); + dest += newsz; + } + } + else { + GLint sz = save->attrsz[j]; + COPY_SZ_4V( dest, sz, data ); + data += sz; + dest += sz; + } + } + } + } + + save->vbptr = dest; + save->vert_count += save->copied.nr; + } +} + +static void save_fixup_vertex( GLcontext *ctx, GLuint attr, GLuint sz ) +{ + struct vbo_save_context *save = &vbo_context(ctx)->save; + + if (sz > save->attrsz[attr]) { + /* New size is larger. Need to flush existing vertices and get + * an enlarged vertex format. + */ + _save_upgrade_vertex( ctx, attr, sz ); + } + else if (sz < save->active_sz[attr]) { + static GLfloat id[4] = { 0, 0, 0, 1 }; + GLuint i; + + /* New size is equal or smaller - just need to fill in some + * zeros. + */ + for (i = sz ; i <= save->attrsz[attr] ; i++) + save->attrptr[attr][i-1] = id[i-1]; + } + + save->active_sz[attr] = sz; +} + +static void _save_reset_vertex( GLcontext *ctx ) +{ + struct vbo_save_context *save = &vbo_context(ctx)->save; + GLuint i; + + for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) { + save->attrsz[i] = 0; + save->active_sz[i] = 0; + } + + save->vertex_size = 0; +} + + + +#define ERROR() _mesa_compile_error( ctx, GL_INVALID_ENUM, __FUNCTION__ ); + + +/* 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 ATTR( A, N, V0, V1, V2, V3 ) \ +do { \ + struct vbo_save_context *save = &vbo_context(ctx)->save; \ + \ + if (save->active_sz[A] != N) \ + save_fixup_vertex(ctx, A, N); \ + \ + { \ + GLfloat *dest = save->attrptr[A]; \ + if (N>0) dest[0] = V0; \ + if (N>1) dest[1] = V1; \ + if (N>2) dest[2] = V2; \ + if (N>3) dest[3] = V3; \ + } \ + \ + if ((A) == 0) { \ + GLuint i; \ + \ + for (i = 0; i < save->vertex_size; i++) \ + save->vbptr[i] = save->vertex[i]; \ + \ + save->vbptr += save->vertex_size; \ + \ + if (++save->vert_count >= save->max_vert) \ + _save_wrap_filled_vertex( ctx ); \ + } \ +} while (0) + +#define TAG(x) _save_##x + +#include "vbo_attrib_tmp.h" + + + + +/* Cope with EvalCoord/CallList called within a begin/end object: + * -- Flush current buffer + * -- Fallback to opcodes for the rest of the begin/end object. + */ +#define DO_FALLBACK(ctx) \ +do { \ + struct vbo_save_context *save = &vbo_context(ctx)->save; \ + \ + if (save->vert_count || save->prim_count) \ + _save_compile_vertex_list( ctx ); \ + \ + _save_copy_to_current( ctx ); \ + _save_reset_vertex( ctx ); \ + _save_reset_counters( ctx ); \ + _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); \ + ctx->Driver.SaveNeedFlush = 0; \ +} while (0) + +static void GLAPIENTRY _save_EvalCoord1f( GLfloat u ) +{ + GET_CURRENT_CONTEXT(ctx); + DO_FALLBACK(ctx); + ctx->Save->EvalCoord1f( u ); +} + +static void GLAPIENTRY _save_EvalCoord1fv( const GLfloat *v ) +{ + GET_CURRENT_CONTEXT(ctx); + DO_FALLBACK(ctx); + ctx->Save->EvalCoord1fv( v ); +} + +static void GLAPIENTRY _save_EvalCoord2f( GLfloat u, GLfloat v ) +{ + GET_CURRENT_CONTEXT(ctx); + DO_FALLBACK(ctx); + ctx->Save->EvalCoord2f( u, v ); +} + +static void GLAPIENTRY _save_EvalCoord2fv( const GLfloat *v ) +{ + GET_CURRENT_CONTEXT(ctx); + DO_FALLBACK(ctx); + ctx->Save->EvalCoord2fv( v ); +} + +static void GLAPIENTRY _save_EvalPoint1( GLint i ) +{ + GET_CURRENT_CONTEXT(ctx); + DO_FALLBACK(ctx); + ctx->Save->EvalPoint1( i ); +} + +static void GLAPIENTRY _save_EvalPoint2( GLint i, GLint j ) +{ + GET_CURRENT_CONTEXT(ctx); + DO_FALLBACK(ctx); + ctx->Save->EvalPoint2( i, j ); +} + +static void GLAPIENTRY _save_CallList( GLuint l ) +{ + GET_CURRENT_CONTEXT(ctx); + DO_FALLBACK(ctx); + ctx->Save->CallList( l ); +} + +static void GLAPIENTRY _save_CallLists( GLsizei n, GLenum type, const GLvoid *v ) +{ + GET_CURRENT_CONTEXT(ctx); + DO_FALLBACK(ctx); + ctx->Save->CallLists( n, type, v ); +} + + + + +/* This begin is hooked into ... Updating of + * ctx->Driver.CurrentSavePrimitive is already taken care of. + */ +GLboolean vbo_save_NotifyBegin( GLcontext *ctx, GLenum mode ) +{ + struct vbo_save_context *save = &vbo_context(ctx)->save; + + GLuint i = save->prim_count++; + + assert(i < save->prim_max); + save->prim[i].mode = mode & ~VBO_SAVE_PRIM_WEAK; + save->prim[i].begin = 1; + save->prim[i].end = 0; + save->prim[i].weak = (mode & VBO_SAVE_PRIM_WEAK) ? 1 : 0; + save->prim[i].pad = 0; + save->prim[i].start = save->vert_count; + save->prim[i].count = 0; + + _mesa_install_save_vtxfmt( ctx, &save->vtxfmt ); + ctx->Driver.SaveNeedFlush = 1; + return GL_TRUE; +} + + + +static void GLAPIENTRY _save_End( void ) +{ + GET_CURRENT_CONTEXT( ctx ); + struct vbo_save_context *save = &vbo_context(ctx)->save; + GLint i = save->prim_count - 1; + + ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END; + save->prim[i].end = 1; + save->prim[i].count = (save->vert_count - + save->prim[i].start); + + if (i == (GLint) save->prim_max - 1) { + _save_compile_vertex_list( ctx ); + assert(save->copied.nr == 0); + } + + /* Swap out this vertex format while outside begin/end. Any color, + * etc. received between here and the next begin will be compiled + * as opcodes. + */ + _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); +} + + +/* These are all errors as this vtxfmt is only installed inside + * begin/end pairs. + */ +static void GLAPIENTRY _save_DrawElements(GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices) +{ + GET_CURRENT_CONTEXT(ctx); + (void) mode; (void) count; (void) type; (void) indices; + _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawElements" ); +} + + +static void GLAPIENTRY _save_DrawRangeElements(GLenum mode, + GLuint start, GLuint end, + GLsizei count, GLenum type, + const GLvoid *indices) +{ + GET_CURRENT_CONTEXT(ctx); + (void) mode; (void) start; (void) end; (void) count; (void) type; (void) indices; + _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawRangeElements" ); +} + +static void GLAPIENTRY _save_DrawArrays(GLenum mode, GLint start, GLsizei count) +{ + GET_CURRENT_CONTEXT(ctx); + (void) mode; (void) start; (void) count; + _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawArrays" ); +} + +static void GLAPIENTRY _save_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) +{ + GET_CURRENT_CONTEXT(ctx); + (void) x1; (void) y1; (void) x2; (void) y2; + _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glRectf" ); +} + +static void GLAPIENTRY _save_EvalMesh1( GLenum mode, GLint i1, GLint i2 ) +{ + GET_CURRENT_CONTEXT(ctx); + (void) mode; (void) i1; (void) i2; + _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glEvalMesh1" ); +} + +static void GLAPIENTRY _save_EvalMesh2( GLenum mode, GLint i1, GLint i2, + GLint j1, GLint j2 ) +{ + GET_CURRENT_CONTEXT(ctx); + (void) mode; (void) i1; (void) i2; (void) j1; (void) j2; + _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glEvalMesh2" ); +} + +static void GLAPIENTRY _save_Begin( GLenum mode ) +{ + GET_CURRENT_CONTEXT( ctx ); + (void) mode; + _mesa_compile_error( ctx, GL_INVALID_OPERATION, "Recursive glBegin" ); +} + + +/* Unlike the functions above, these are to be hooked into the vtxfmt + * maintained in ctx->ListState, active when the list is known or + * suspected to be outside any begin/end primitive. + */ +static void GLAPIENTRY _save_OBE_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) +{ + GET_CURRENT_CONTEXT(ctx); + vbo_save_NotifyBegin( ctx, GL_QUADS | VBO_SAVE_PRIM_WEAK ); + CALL_Vertex2f(GET_DISPATCH(), ( x1, y1 )); + CALL_Vertex2f(GET_DISPATCH(), ( x2, y1 )); + CALL_Vertex2f(GET_DISPATCH(), ( x2, y2 )); + CALL_Vertex2f(GET_DISPATCH(), ( x1, y2 )); + CALL_End(GET_DISPATCH(), ()); +} + + +static void GLAPIENTRY _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei count) +{ + GET_CURRENT_CONTEXT(ctx); + GLint i; + + if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) + return; + + vbo_save_NotifyBegin( ctx, mode | VBO_SAVE_PRIM_WEAK ); + for (i = 0; i < count; i++) + CALL_ArrayElement(GET_DISPATCH(), (start + i)); + CALL_End(GET_DISPATCH(), ()); +} + +/* Could do better by copying the arrays and element list intact and + * then emitting an indexed prim at runtime. + */ +static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices) +{ + GET_CURRENT_CONTEXT(ctx); + GLint i; + + if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) + return; + + vbo_save_NotifyBegin( ctx, mode | VBO_SAVE_PRIM_WEAK ); + + switch (type) { + case GL_UNSIGNED_BYTE: + for (i = 0 ; i < count ; i++) + CALL_ArrayElement(GET_DISPATCH(), ( ((GLubyte *)indices)[i] )); + break; + case GL_UNSIGNED_SHORT: + for (i = 0 ; i < count ; i++) + CALL_ArrayElement(GET_DISPATCH(), ( ((GLushort *)indices)[i] )); + break; + case GL_UNSIGNED_INT: + for (i = 0 ; i < count ; i++) + CALL_ArrayElement(GET_DISPATCH(), ( ((GLuint *)indices)[i] )); + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" ); + break; + } + + CALL_End(GET_DISPATCH(), ()); +} + +static void GLAPIENTRY _save_OBE_DrawRangeElements(GLenum mode, + GLuint start, GLuint end, + GLsizei count, GLenum type, + const GLvoid *indices) +{ + GET_CURRENT_CONTEXT(ctx); + if (_mesa_validate_DrawRangeElements( ctx, mode, + start, end, + count, type, indices )) + _save_OBE_DrawElements( mode, count, type, indices ); +} + + + + + +static void _save_vtxfmt_init( GLcontext *ctx ) +{ + struct vbo_save_context *save = &vbo_context(ctx)->save; + GLvertexformat *vfmt = &save->vtxfmt; + + vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ + vfmt->Begin = _save_Begin; + vfmt->Color3f = _save_Color3f; + vfmt->Color3fv = _save_Color3fv; + vfmt->Color4f = _save_Color4f; + vfmt->Color4fv = _save_Color4fv; + vfmt->EdgeFlag = _save_EdgeFlag; + vfmt->End = _save_End; + vfmt->FogCoordfEXT = _save_FogCoordfEXT; + vfmt->FogCoordfvEXT = _save_FogCoordfvEXT; + vfmt->Indexf = _save_Indexf; + vfmt->Indexfv = _save_Indexfv; + vfmt->Materialfv = _save_Materialfv; + vfmt->MultiTexCoord1fARB = _save_MultiTexCoord1f; + vfmt->MultiTexCoord1fvARB = _save_MultiTexCoord1fv; + vfmt->MultiTexCoord2fARB = _save_MultiTexCoord2f; + vfmt->MultiTexCoord2fvARB = _save_MultiTexCoord2fv; + vfmt->MultiTexCoord3fARB = _save_MultiTexCoord3f; + vfmt->MultiTexCoord3fvARB = _save_MultiTexCoord3fv; + vfmt->MultiTexCoord4fARB = _save_MultiTexCoord4f; + vfmt->MultiTexCoord4fvARB = _save_MultiTexCoord4fv; + vfmt->Normal3f = _save_Normal3f; + vfmt->Normal3fv = _save_Normal3fv; + vfmt->SecondaryColor3fEXT = _save_SecondaryColor3fEXT; + vfmt->SecondaryColor3fvEXT = _save_SecondaryColor3fvEXT; + vfmt->TexCoord1f = _save_TexCoord1f; + vfmt->TexCoord1fv = _save_TexCoord1fv; + vfmt->TexCoord2f = _save_TexCoord2f; + vfmt->TexCoord2fv = _save_TexCoord2fv; + vfmt->TexCoord3f = _save_TexCoord3f; + vfmt->TexCoord3fv = _save_TexCoord3fv; + vfmt->TexCoord4f = _save_TexCoord4f; + vfmt->TexCoord4fv = _save_TexCoord4fv; + vfmt->Vertex2f = _save_Vertex2f; + vfmt->Vertex2fv = _save_Vertex2fv; + vfmt->Vertex3f = _save_Vertex3f; + vfmt->Vertex3fv = _save_Vertex3fv; + vfmt->Vertex4f = _save_Vertex4f; + vfmt->Vertex4fv = _save_Vertex4fv; + vfmt->VertexAttrib1fARB = _save_VertexAttrib1fARB; + vfmt->VertexAttrib1fvARB = _save_VertexAttrib1fvARB; + vfmt->VertexAttrib2fARB = _save_VertexAttrib2fARB; + vfmt->VertexAttrib2fvARB = _save_VertexAttrib2fvARB; + vfmt->VertexAttrib3fARB = _save_VertexAttrib3fARB; + vfmt->VertexAttrib3fvARB = _save_VertexAttrib3fvARB; + vfmt->VertexAttrib4fARB = _save_VertexAttrib4fARB; + vfmt->VertexAttrib4fvARB = _save_VertexAttrib4fvARB; + + vfmt->VertexAttrib1fNV = _save_VertexAttrib1fNV; + vfmt->VertexAttrib1fvNV = _save_VertexAttrib1fvNV; + vfmt->VertexAttrib2fNV = _save_VertexAttrib2fNV; + vfmt->VertexAttrib2fvNV = _save_VertexAttrib2fvNV; + vfmt->VertexAttrib3fNV = _save_VertexAttrib3fNV; + vfmt->VertexAttrib3fvNV = _save_VertexAttrib3fvNV; + vfmt->VertexAttrib4fNV = _save_VertexAttrib4fNV; + vfmt->VertexAttrib4fvNV = _save_VertexAttrib4fvNV; + + /* This will all require us to fallback to saving the list as opcodes: + */ + vfmt->CallList = _save_CallList; /* inside begin/end */ + vfmt->CallLists = _save_CallLists; /* inside begin/end */ + vfmt->EvalCoord1f = _save_EvalCoord1f; + vfmt->EvalCoord1fv = _save_EvalCoord1fv; + vfmt->EvalCoord2f = _save_EvalCoord2f; + vfmt->EvalCoord2fv = _save_EvalCoord2fv; + vfmt->EvalPoint1 = _save_EvalPoint1; + vfmt->EvalPoint2 = _save_EvalPoint2; + + /* These are all errors as we at least know we are in some sort of + * begin/end pair: + */ + vfmt->EvalMesh1 = _save_EvalMesh1; + vfmt->EvalMesh2 = _save_EvalMesh2; + vfmt->Begin = _save_Begin; + vfmt->Rectf = _save_Rectf; + vfmt->DrawArrays = _save_DrawArrays; + vfmt->DrawElements = _save_DrawElements; + vfmt->DrawRangeElements = _save_DrawRangeElements; + +} + + +void vbo_save_SaveFlushVertices( GLcontext *ctx ) +{ + struct vbo_save_context *save = &vbo_context(ctx)->save; + + /* Noop when we are actually active: + */ + if (ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM || + ctx->Driver.CurrentSavePrimitive <= GL_POLYGON) + return; + + if (save->vert_count || + save->prim_count) + _save_compile_vertex_list( ctx ); + + _save_copy_to_current( ctx ); + _save_reset_vertex( ctx ); + _save_reset_counters( ctx ); + ctx->Driver.SaveNeedFlush = 0; +} + +void vbo_save_NewList( GLcontext *ctx, GLuint list, GLenum mode ) +{ + struct vbo_save_context *save = &vbo_context(ctx)->save; + + (void) list; (void) mode; + + if (!save->prim_store) + save->prim_store = alloc_prim_store( ctx ); + + if (!save->vertex_store) + save->vertex_store = alloc_vertex_store( ctx ); + + save->vbptr = map_vertex_store( ctx, save->vertex_store ); + + _save_reset_vertex( ctx ); + _save_reset_counters( ctx ); + ctx->Driver.SaveNeedFlush = 0; +} + +void vbo_save_EndList( GLcontext *ctx ) +{ + struct vbo_save_context *save = &vbo_context(ctx)->save; + unmap_vertex_store( ctx, save->vertex_store ); + + assert(save->vertex_size == 0); +} + +void vbo_save_BeginCallList( GLcontext *ctx, struct mesa_display_list *dlist ) +{ + struct vbo_save_context *save = &vbo_context(ctx)->save; + save->replay_flags |= dlist->flags; +} + +void vbo_save_EndCallList( GLcontext *ctx ) +{ + struct vbo_save_context *save = &vbo_context(ctx)->save; + + if (ctx->ListState.CallDepth == 1) { + /* This is correct: want to keep only the VBO_SAVE_FALLBACK + * flag, if it is set: + */ + save->replay_flags &= VBO_SAVE_FALLBACK; + } +} + + +static void vbo_destroy_vertex_list( GLcontext *ctx, void *data ) +{ + struct vbo_save_vertex_list *node = (struct vbo_save_vertex_list *)data; + (void) ctx; + + if ( --node->vertex_store->refcount == 0 ) + free_vertex_store( ctx, node->vertex_store ); + + if ( --node->prim_store->refcount == 0 ) + FREE( node->prim_store ); +} + + +static void vbo_print_vertex_list( GLcontext *ctx, void *data ) +{ + struct vbo_save_vertex_list *node = (struct vbo_save_vertex_list *)data; + GLuint i; + (void) ctx; + + _mesa_debug(NULL, "VBO-VERTEX-LIST, %u vertices %d primitives, %d vertsize\n", + node->count, + node->prim_count, + node->vertex_size); + + for (i = 0 ; i < node->prim_count ; i++) { + struct _mesa_prim *prim = &node->prim[i]; + _mesa_debug(NULL, " prim %d: %s%s %d..%d %s %s\n", + i, + _mesa_lookup_enum_by_nr(prim->mode), + prim->weak ? " (weak)" : "", + prim->start, + prim->start + prim->count, + (prim->begin) ? "BEGIN" : "(wrap)", + (prim->end) ? "END" : "(wrap)"); + } +} + + +static void _save_current_init( GLcontext *ctx ) +{ + struct vbo_save_context *save = &vbo_context(ctx)->save; + GLint i; + + for (i = 0; i < VBO_ATTRIB_FIRST_MATERIAL; i++) { + save->currentsz[i] = &ctx->ListState.ActiveAttribSize[i]; + save->current[i] = ctx->ListState.CurrentAttrib[i]; + } + + for (i = VBO_ATTRIB_FIRST_MATERIAL; i < VBO_ATTRIB_INDEX; i++) { + const GLuint j = i - VBO_ATTRIB_FIRST_MATERIAL; + ASSERT(j < MAT_ATTRIB_MAX); + save->currentsz[i] = &ctx->ListState.ActiveMaterialSize[j]; + save->current[i] = ctx->ListState.CurrentMaterial[j]; + } + + save->currentsz[VBO_ATTRIB_INDEX] = &ctx->ListState.ActiveIndex; + save->current[VBO_ATTRIB_INDEX] = &ctx->ListState.CurrentIndex; + + save->currentsz[VBO_ATTRIB_EDGEFLAG] = &ctx->ListState.ActiveEdgeFlag; + save->current[VBO_ATTRIB_EDGEFLAG] = &save->CurrentFloatEdgeFlag; +} + +/** + * Initialize the display list compiler + */ +void vbo_save_api_init( struct vbo_save_context *save ) +{ + GLcontext *ctx = save->ctx; + GLuint i; + + save->opcode_vertex_list = + _mesa_alloc_opcode( ctx, + sizeof(struct vbo_save_vertex_list), + vbo_save_playback_vertex_list, + vbo_destroy_vertex_list, + vbo_print_vertex_list ); + + ctx->Driver.NotifySaveBegin = vbo_save_NotifyBegin; + + _save_vtxfmt_init( ctx ); + _save_current_init( ctx ); + + for (i = 0; i < VBO_ATTRIB_MAX; i++) + save->inputs[i] = &save->arrays[i]; + + /* Hook our array functions into the outside-begin-end vtxfmt in + * ctx->ListState. + */ + ctx->ListState.ListVtxfmt.Rectf = _save_OBE_Rectf; + ctx->ListState.ListVtxfmt.DrawArrays = _save_OBE_DrawArrays; + ctx->ListState.ListVtxfmt.DrawElements = _save_OBE_DrawElements; + ctx->ListState.ListVtxfmt.DrawRangeElements = _save_OBE_DrawRangeElements; + _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); +} + diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c new file mode 100644 index 0000000000..44e0171233 --- /dev/null +++ b/src/mesa/vbo/vbo_save_draw.c @@ -0,0 +1,202 @@ +/* + * 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 + */ + +#include "glheader.h" +#include "context.h" +#include "imports.h" +#include "mtypes.h" +#include "macros.h" +#include "light.h" +#include "state.h" + +#include "vbo_context.h" + + + +static void _playback_copy_to_current( GLcontext *ctx, + const struct vbo_save_vertex_list *node ) +{ + struct vbo_save_context *save = &vbo_context(ctx)->save; + GLfloat vertex[VBO_ATTRIB_MAX * 4], *data = vertex; + GLuint i, offset; + + if (node->count) + offset = node->buffer_offset + (node->count-1) * node->vertex_size; + else + offset = node->buffer_offset; + + ctx->Driver.GetBufferSubData( ctx, 0, offset, node->vertex_size, + data, node->vertex_store->bufferobj ); + + for (i = VBO_ATTRIB_POS+1 ; i <= VBO_ATTRIB_INDEX ; i++) { + if (node->attrsz[i]) { + COPY_CLEAN_4V(save->current[i], node->attrsz[i], data); + data += node->attrsz[i]; + + if (i >= VBO_ATTRIB_MAT_FRONT_AMBIENT && + i <= VBO_ATTRIB_MAT_BACK_INDEXES) + ctx->NewState |= _NEW_LIGHT; + } + } + + /* Edgeflag requires special treatment: + */ + if (node->attrsz[VBO_ATTRIB_EDGEFLAG]) { + ctx->Current.EdgeFlag = (data[0] == 1.0); + } + + +#if 1 + /* Colormaterial -- this kindof sucks. + */ + if (ctx->Light.ColorMaterialEnabled) { + _mesa_update_color_material(ctx, ctx->Current.Attrib[VBO_ATTRIB_COLOR0]); + } +#endif + + /* CurrentExecPrimitive + */ + if (node->prim_count) { + const struct _mesa_prim *prim = &node->prim[node->prim_count - 1]; + if (prim->end) + ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; + else + ctx->Driver.CurrentExecPrimitive = prim->mode; + } +} + + + +/* Treat the vertex storage as a VBO, define vertex arrays pointing + * into it: + */ +static void vbo_bind_vertex_list( struct vbo_save_context *save, + const struct vbo_save_vertex_list *node ) +{ + struct gl_client_array *arrays = save->arrays; + GLuint data = node->buffer_offset; + GLuint attr; + + memset(arrays, 0, VBO_ATTRIB_MAX * sizeof(arrays[0])); + + for (attr = 0; attr <= VBO_ATTRIB_INDEX; attr++) { + if (node->attrsz[attr]) { + arrays[attr].Ptr = (const GLubyte *)data; + arrays[attr].Size = node->attrsz[attr]; + arrays[attr].StrideB = node->vertex_size * sizeof(GLfloat); + arrays[attr].Stride = node->vertex_size * sizeof(GLfloat); + arrays[attr].Type = GL_FLOAT; + arrays[attr].Enabled = 1; + arrays[attr].BufferObj = node->vertex_store->bufferobj; + arrays[attr]._MaxElement = node->count; /* ??? */ + + assert(arrays[attr].BufferObj->Name); + + data += node->attrsz[attr] * sizeof(GLfloat); + } + } +} + +static void vbo_save_loopback_vertex_list( GLcontext *ctx, + const struct vbo_save_vertex_list *list ) +{ + const char *buffer = ctx->Driver.MapBuffer(ctx, + GL_ARRAY_BUFFER_ARB, + GL_DYNAMIC_READ_ARB, /* ? */ + list->vertex_store->bufferobj); + + vbo_loopback_vertex_list( ctx, + (const GLfloat *)(buffer + list->buffer_offset), + list->attrsz, + list->prim, + list->prim_count, + list->wrap_count, + list->vertex_size); + + ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER_ARB, + list->vertex_store->bufferobj); +} + + +/** + * Execute the buffer and save copied verts. + */ +void vbo_save_playback_vertex_list( GLcontext *ctx, void *data ) +{ + const struct vbo_save_vertex_list *node = (const struct vbo_save_vertex_list *) data; + struct vbo_save_context *save = &vbo_context(ctx)->save; + + FLUSH_CURRENT(ctx, 0); + + if (node->prim_count > 0 && node->count > 0) { + + if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END && + node->prim[0].begin) { + + /* Degenerate case: list is called inside begin/end pair and + * includes operations such as glBegin or glDrawArrays. + */ + if (0) + _mesa_printf("displaylist recursive begin"); + + vbo_save_loopback_vertex_list( ctx, node ); + return; + } + else if (save->replay_flags) { + /* Various degnerate cases: translate into immediate mode + * calls rather than trying to execute in place. + */ + vbo_save_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; + } + + vbo_bind_vertex_list( save, node ); + + vbo_context(ctx)->draw_prims( ctx, + save->inputs, + node->prim, + node->prim_count, + NULL, + 0, /* Node is a VBO, so this is ok */ + node->count ); + } + + /* Copy to current? + */ + _playback_copy_to_current( ctx, node ); +} diff --git a/src/mesa/vbo/vbo_save_loopback.c b/src/mesa/vbo/vbo_save_loopback.c new file mode 100644 index 0000000000..941c4beea9 --- /dev/null +++ b/src/mesa/vbo/vbo_save_loopback.c @@ -0,0 +1,327 @@ +/************************************************************************** + * + * Copyright 2005 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 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 ITS 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. + * + **************************************************************************/ + +#include "swrast_setup/swrast_setup.h" +#include "swrast/swrast.h" +#include "tnl/tnl.h" +#include "context.h" + +#include "vbo_context.h" + +#include "glheader.h" +#include "enums.h" +#include "glapi.h" +#include "imports.h" +#include "macros.h" +#include "mtypes.h" +#include "dispatch.h" + + +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 +}; + +#if 0 +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 +}; +#endif + + + + + + +static void mat_attr1fv( GLcontext *ctx, GLint target, const GLfloat *v ) +{ + switch (target) { + case VBO_ATTRIB_MAT_FRONT_SHININESS: + CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_SHININESS, v )); + break; + case VBO_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 VBO_ATTRIB_MAT_FRONT_INDEXES: + CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_COLOR_INDEXES, v )); + break; + case VBO_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 VBO_ATTRIB_MAT_FRONT_EMISSION: + CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_EMISSION, v )); + break; + case VBO_ATTRIB_MAT_BACK_EMISSION: + CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_EMISSION, v )); + break; + case VBO_ATTRIB_MAT_FRONT_AMBIENT: + CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_AMBIENT, v )); + break; + case VBO_ATTRIB_MAT_BACK_AMBIENT: + CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_AMBIENT, v )); + break; + case VBO_ATTRIB_MAT_FRONT_DIFFUSE: + CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_DIFFUSE, v )); + break; + case VBO_ATTRIB_MAT_BACK_DIFFUSE: + CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_DIFFUSE, v )); + break; + case VBO_ATTRIB_MAT_FRONT_SPECULAR: + CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_SPECULAR, v )); + break; + case VBO_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 index_attr1fv(GLcontext *ctx, GLint target, const GLfloat *v) +{ + (void) target; + CALL_Indexf(ctx->Exec, (v[0])); +} + +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 GLfloat *buffer, + const struct _mesa_prim *prim, + GLuint wrap_count, + GLuint vertex_size, + const struct loopback_attr *la, GLuint nr ) +{ + GLint start = prim->start; + GLint end = start + prim->count; + const GLfloat *data; + GLint j; + GLuint k; + + if (0) + _mesa_printf("loopback prim %s(%s,%s) verts %d..%d\n", + _mesa_lookup_enum_by_nr(prim->mode), + prim->begin ? "begin" : "..", + prim->end ? "end" : "..", + start, + end); + + if (prim->begin) { + CALL_Begin(GET_DISPATCH(), ( prim->mode )); + } + else { + assert(start == 0); + start += wrap_count; + } + + data = buffer + start * vertex_size; + + for (j = start ; j < end ; j++) { + const 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, VBO_ATTRIB_POS, data ); + data = tmp; + } + + if (prim->end) { + CALL_End(GET_DISPATCH(), ()); + } +} + +/* 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 _mesa_prim *prim ) +{ + /* 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->begin) + ctx->Driver.CurrentExecPrimitive |= VBO_SAVE_PRIM_WEAK; + if (prim->end) + ctx->Driver.CurrentExecPrimitive &= ~VBO_SAVE_PRIM_WEAK; +} + + +void vbo_loopback_vertex_list( GLcontext *ctx, + const GLfloat *buffer, + const GLubyte *attrsz, + const struct _mesa_prim *prim, + GLuint prim_count, + GLuint wrap_count, + GLuint vertex_size) +{ + struct loopback_attr la[VBO_ATTRIB_MAX]; + GLuint i, nr = 0; + + for (i = 0 ; i <= VBO_ATTRIB_TEX7 ; i++) { + if (attrsz[i]) { + la[nr].target = i; + la[nr].sz = attrsz[i]; + la[nr].func = vert_attrfunc[attrsz[i]-1]; + nr++; + } + } + + for (i = VBO_ATTRIB_MAT_FRONT_AMBIENT ; + i <= VBO_ATTRIB_MAT_BACK_INDEXES ; + i++) { + if (attrsz[i]) { + la[nr].target = i; + la[nr].sz = attrsz[i]; + la[nr].func = mat_attrfunc[attrsz[i]-1]; + nr++; + } + } + + if (attrsz[VBO_ATTRIB_EDGEFLAG]) { + la[nr].target = VBO_ATTRIB_EDGEFLAG; + la[nr].sz = attrsz[VBO_ATTRIB_EDGEFLAG]; + la[nr].func = edgeflag_attr1fv; + nr++; + } + + if (attrsz[VBO_ATTRIB_INDEX]) { + la[nr].target = VBO_ATTRIB_INDEX; + la[nr].sz = attrsz[VBO_ATTRIB_INDEX]; + la[nr].func = index_attr1fv; + nr++; + } + + /* XXX ARB vertex attribs */ + + for (i = 0 ; i < prim_count ; i++) { + if ((prim[i].mode & VBO_SAVE_PRIM_WEAK) && + (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END)) + { + loopback_weak_prim( ctx, &prim[i] ); + } + else + { + loopback_prim( ctx, buffer, &prim[i], wrap_count, vertex_size, la, nr ); + } + } +} -- cgit v1.2.3 From b1f176039ae3690b38e3ccacb079b3d7c3e50402 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 29 Oct 2006 09:48:15 +0000 Subject: 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. --- src/mesa/tnl/sources | 12 +- src/mesa/tnl/t_array_api.c | 432 ---------- src/mesa/tnl/t_array_api.h | 46 -- src/mesa/tnl/t_array_import.c | 376 --------- src/mesa/tnl/t_array_import.h | 36 - src/mesa/tnl/t_context.c | 102 +-- src/mesa/tnl/t_context.h | 340 ++------ src/mesa/tnl/t_save_api.c | 1733 ---------------------------------------- src/mesa/tnl/t_save_api.h | 57 -- src/mesa/tnl/t_save_loopback.c | 330 -------- src/mesa/tnl/t_save_playback.c | 215 ----- src/mesa/tnl/t_vb_render.c | 2 +- src/mesa/tnl/t_vb_rendertmp.h | 4 +- src/mesa/tnl/t_vtx_api.c | 1045 ------------------------ src/mesa/tnl/t_vtx_api.h | 86 -- src/mesa/tnl/t_vtx_eval.c | 265 ------ src/mesa/tnl/t_vtx_exec.c | 288 ------- src/mesa/tnl/t_vtx_generic.c | 615 -------------- src/mesa/tnl/t_vtx_x86.c | 396 --------- src/mesa/tnl/t_vtx_x86_gcc.S | 561 ------------- src/mesa/tnl/tnl.h | 30 +- 21 files changed, 78 insertions(+), 6893 deletions(-) delete mode 100644 src/mesa/tnl/t_array_api.c delete mode 100644 src/mesa/tnl/t_array_api.h delete mode 100644 src/mesa/tnl/t_array_import.c delete mode 100644 src/mesa/tnl/t_array_import.h delete mode 100644 src/mesa/tnl/t_save_api.c delete mode 100644 src/mesa/tnl/t_save_api.h delete mode 100644 src/mesa/tnl/t_save_loopback.c delete mode 100644 src/mesa/tnl/t_save_playback.c delete mode 100644 src/mesa/tnl/t_vtx_api.c delete mode 100644 src/mesa/tnl/t_vtx_api.h delete mode 100644 src/mesa/tnl/t_vtx_eval.c delete mode 100644 src/mesa/tnl/t_vtx_exec.c delete mode 100644 src/mesa/tnl/t_vtx_generic.c delete mode 100644 src/mesa/tnl/t_vtx_x86.c delete mode 100644 src/mesa/tnl/t_vtx_x86_gcc.S (limited to 'src') diff --git a/src/mesa/tnl/sources b/src/mesa/tnl/sources index 2c4f4c49ea..50f2f3a96d 100644 --- a/src/mesa/tnl/sources +++ b/src/mesa/tnl/sources @@ -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 diff --git a/src/mesa/tnl/t_array_api.c b/src/mesa/tnl/t_array_api.c deleted file mode 100644 index 6826cf7e24..0000000000 --- a/src/mesa/tnl/t_array_api.c +++ /dev/null @@ -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; -} diff --git a/src/mesa/tnl/t_array_api.h b/src/mesa/tnl/t_array_api.h deleted file mode 100644 index 61d1f696b0..0000000000 --- a/src/mesa/tnl/t_array_api.h +++ /dev/null @@ -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 diff --git a/src/mesa/tnl/t_array_import.c b/src/mesa/tnl/t_array_import.c deleted file mode 100644 index 13c5689ceb..0000000000 --- a/src/mesa/tnl/t_array_import.c +++ /dev/null @@ -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 - */ - -#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]; - } -} diff --git a/src/mesa/tnl/t_array_import.h b/src/mesa/tnl/t_array_import.h deleted file mode 100644 index 39b77641d5..0000000000 --- a/src/mesa/tnl/t_array_import.h +++ /dev/null @@ -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 diff --git a/src/mesa/tnl/t_context.c b/src/mesa/tnl/t_context.c index 55b40c0531..ff05ac0318 100644 --- a/src/mesa/tnl/t_context.c +++ b/src/mesa/tnl/t_context.c @@ -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 ) { diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h index d5414bd730..28d1b7faab 100644 --- a/src/mesa/tnl/t_context.h +++ b/src/mesa/tnl/t_context.h @@ -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,221 +169,22 @@ 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]; +static INLINE GLuint _tnl_translate_prim( const struct _mesa_prim *prim ) +{ + GLuint flag; + flag = prim->mode; + if (prim->begin) flag |= PRIM_BEGIN; + if (prim->end) flag |= PRIM_END; + return flag; +} - void (*tabfv[_TNL_ATTRIB_MAX][4])( const GLfloat * ); -}; -/** - * A collection of vertex arrays. - */ -struct tnl_vertex_arrays -{ - /* Conventional vertex attribute arrays */ - GLvector4f Obj; - GLvector4f Normal; - GLvector4f Color; - GLvector4f SecondaryColor; - GLvector4f FogCoord; - GLvector4f TexCoord[MAX_TEXTURE_COORD_UNITS]; - GLvector4f Index; - - 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]; -}; - /** * Contains the current state of a running pipeline. @@ -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; diff --git a/src/mesa/tnl/t_save_api.c b/src/mesa/tnl/t_save_api.c deleted file mode 100644 index 11d21301d9..0000000000 --- a/src/mesa/tnl/t_save_api.c +++ /dev/null @@ -1,1733 +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 - */ - - - -/** - * The display list compiler attempts to store lists of vertices with the - * same vertex layout. Additionally it attempts to minimize the need - * for execute-time fixup of these vertex lists, allowing them to be - * cached on hardware. - * - * There are still some circumstances where this can be thwarted, for - * example by building a list that consists of one very long primitive - * (eg Begin(Triangles), 1000 vertices, End), and calling that list - * from inside a different begin/end object (Begin(Lines), CallList, - * End). - * - * In that case the code will have to replay the list as individual - * commands through the Exec dispatch table, or fix up the copied - * vertices at execute-time. - * - * The other case where fixup is required is when a vertex attribute - * is introduced in the middle of a primitive. Eg: - * Begin(Lines) - * TexCoord1f() Vertex2f() - * TexCoord1f() Color3f() Vertex2f() - * End() - * - * If the current value of Color isn't known at compile-time, this - * primitive will require fixup. - * - * - * The list compiler currently doesn't attempt to compile lists - * containing EvalCoord or EvalPoint commands. On encountering one of - * these, compilation falls back to opcodes. - * - * This could be improved to fallback only when a mix of EvalCoord and - * Vertex commands are issued within a single primitive. - */ - - -#include "glheader.h" -#include "context.h" -#include "dlist.h" -#include "enums.h" -#include "macros.h" -#include "api_validate.h" -#include "api_arrayelt.h" -#include "vtxfmt.h" -#include "t_save_api.h" -#include "dispatch.h" - -/* - * NOTE: Old 'parity' issue is gone, but copying can still be - * wrong-footed on replay. - */ -static GLuint _save_copy_vertices( GLcontext *ctx, - const struct tnl_vertex_list *node ) -{ - TNLcontext *tnl = TNL_CONTEXT( ctx ); - const struct tnl_prim *prim = &node->prim[node->prim_count-1]; - GLuint nr = prim->count; - GLuint sz = tnl->save.vertex_size; - const GLfloat *src = node->buffer + prim->start * sz; - GLfloat *dst = tnl->save.copied.buffer; - GLuint ovf, i; - - if (prim->mode & PRIM_END) - return 0; - - switch( prim->mode & PRIM_MODE_MASK ) - { - 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; - default: - assert(0); - return 0; - } -} - - -static void -build_normal_lengths( struct tnl_vertex_list *node ) -{ - GLuint i; - GLfloat *len; - GLfloat *n = node->buffer; - GLuint stride = node->vertex_size; - GLuint count = node->count; - - len = node->normal_lengths = (GLfloat *) MALLOC( count * sizeof(GLfloat) ); - if (!len) - return; - - /* Find the normal of the first vertex: - */ - for (i = 0 ; i < _TNL_ATTRIB_NORMAL ; i++) - n += node->attrsz[i]; - - for (i = 0 ; i < count ; i++, n += stride) { - len[i] = LEN_3FV( n ); - if (len[i] > 0.0F) len[i] = 1.0F / len[i]; - } -} - -static struct tnl_vertex_store *alloc_vertex_store( GLcontext *ctx ) -{ - struct tnl_vertex_store *store = MALLOC_STRUCT(tnl_vertex_store); - (void) ctx; - store->used = 0; - store->refcount = 1; - return store; -} - -static struct tnl_primitive_store *alloc_prim_store( GLcontext *ctx ) -{ - struct tnl_primitive_store *store = MALLOC_STRUCT(tnl_primitive_store); - (void) ctx; - store->used = 0; - store->refcount = 1; - return store; -} - -static void _save_reset_counters( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - - tnl->save.prim = tnl->save.prim_store->buffer + tnl->save.prim_store->used; - tnl->save.buffer = (tnl->save.vertex_store->buffer + - tnl->save.vertex_store->used); - - if (tnl->save.vertex_size) - tnl->save.initial_counter = ((SAVE_BUFFER_SIZE - - tnl->save.vertex_store->used) / - tnl->save.vertex_size); - else - tnl->save.initial_counter = 0; - - if (tnl->save.initial_counter > ctx->Const.MaxArrayLockSize ) - tnl->save.initial_counter = ctx->Const.MaxArrayLockSize; - - tnl->save.counter = tnl->save.initial_counter; - tnl->save.prim_count = 0; - tnl->save.prim_max = SAVE_PRIM_SIZE - tnl->save.prim_store->used; - tnl->save.copied.nr = 0; - tnl->save.dangling_attr_ref = 0; -} - - -/* Insert the active immediate struct onto the display list currently - * being built. - */ -static void _save_compile_vertex_list( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct tnl_vertex_list *node; - - /* Allocate space for this structure in the display list currently - * being compiled. - */ - node = (struct tnl_vertex_list *) - _mesa_alloc_instruction(ctx, tnl->save.opcode_vertex_list, sizeof(*node)); - - if (!node) - return; - - /* Duplicate our template, increment refcounts to the storage structs: - */ - _mesa_memcpy(node->attrsz, tnl->save.attrsz, sizeof(node->attrsz)); - node->vertex_size = tnl->save.vertex_size; - node->buffer = tnl->save.buffer; - node->count = tnl->save.initial_counter - tnl->save.counter; - node->wrap_count = tnl->save.copied.nr; - node->have_materials = tnl->save.have_materials; - node->dangling_attr_ref = tnl->save.dangling_attr_ref; - node->normal_lengths = NULL; - node->prim = tnl->save.prim; - node->prim_count = tnl->save.prim_count; - node->vertex_store = tnl->save.vertex_store; - node->prim_store = tnl->save.prim_store; - - node->vertex_store->refcount++; - node->prim_store->refcount++; - - assert(node->attrsz[_TNL_ATTRIB_POS] != 0 || - node->count == 0); - - if (tnl->save.dangling_attr_ref) - ctx->ListState.CurrentList->flags |= MESA_DLIST_DANGLING_REFS; - - /* Maybe calculate normal lengths: - */ - if (tnl->CalcDListNormalLengths && - node->attrsz[_TNL_ATTRIB_NORMAL] == 3 && - !(ctx->ListState.CurrentList->flags & MESA_DLIST_DANGLING_REFS)) - build_normal_lengths( node ); - - - tnl->save.vertex_store->used += tnl->save.vertex_size * node->count; - tnl->save.prim_store->used += node->prim_count; - - /* Decide whether the storage structs are full, or can be used for - * the next vertex lists as well. - */ - if (tnl->save.vertex_store->used > - SAVE_BUFFER_SIZE - 16 * (tnl->save.vertex_size + 4)) { - - tnl->save.vertex_store->refcount--; - assert(tnl->save.vertex_store->refcount != 0); - tnl->save.vertex_store = alloc_vertex_store( ctx ); - tnl->save.vbptr = tnl->save.vertex_store->buffer; - } - - if (tnl->save.prim_store->used > SAVE_PRIM_SIZE - 6) { - tnl->save.prim_store->refcount--; - assert(tnl->save.prim_store->refcount != 0); - tnl->save.prim_store = alloc_prim_store( ctx ); - } - - /* Reset our structures for the next run of vertices: - */ - _save_reset_counters( ctx ); - - /* Copy duplicated vertices - */ - tnl->save.copied.nr = _save_copy_vertices( ctx, node ); - - - /* Deal with GL_COMPILE_AND_EXECUTE: - */ - if (ctx->ExecuteFlag) { - _tnl_playback_vertex_list( ctx, (void *) node ); - } -} - - -/* TODO -- If no new vertices have been stored, don't bother saving - * it. - */ -static void _save_wrap_buffers( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLint i = tnl->save.prim_count - 1; - GLenum mode; - - assert(i < (GLint) tnl->save.prim_max); - assert(i >= 0); - - /* Close off in-progress primitive. - */ - tnl->save.prim[i].count = ((tnl->save.initial_counter - tnl->save.counter) - - tnl->save.prim[i].start); - mode = tnl->save.prim[i].mode & ~(PRIM_BEGIN|PRIM_END); - - /* store the copied vertices, and allocate a new list. - */ - _save_compile_vertex_list( ctx ); - - /* Restart interrupted primitive - */ - tnl->save.prim[0].mode = mode; - tnl->save.prim[0].start = 0; - tnl->save.prim[0].count = 0; - tnl->save.prim_count = 1; -} - - - -/* Called only when buffers are wrapped as the result of filling the - * vertex_store struct. - */ -static void _save_wrap_filled_vertex( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLfloat *data = tnl->save.copied.buffer; - GLuint i; - - /* Emit a glEnd to close off the last vertex list. - */ - _save_wrap_buffers( ctx ); - - /* Copy stored stored vertices to start of new list. - */ - assert(tnl->save.counter > tnl->save.copied.nr); - - for (i = 0 ; i < tnl->save.copied.nr ; i++) { - _mesa_memcpy( tnl->save.vbptr, data, tnl->save.vertex_size * sizeof(GLfloat)); - data += tnl->save.vertex_size; - tnl->save.vbptr += tnl->save.vertex_size; - tnl->save.counter--; - } -} - - -static void _save_copy_to_current( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint i; - - /* XXX Use _TNL_FIRST_* and _TNL_LAST_* values instead? */ - for (i = _TNL_ATTRIB_POS+1 ; i <= _TNL_ATTRIB_EDGEFLAG ; i++) { - if (tnl->save.attrsz[i]) { - tnl->save.currentsz[i][0] = tnl->save.attrsz[i]; - COPY_CLEAN_4V(tnl->save.current[i], - tnl->save.attrsz[i], - tnl->save.attrptr[i]); - } - } - - /* Edgeflag requires special treatment: - * - * TODO: change edgeflag to GLfloat in Mesa. - */ - if (tnl->save.attrsz[_TNL_ATTRIB_EDGEFLAG]) { - ctx->ListState.ActiveEdgeFlag = 1; - tnl->save.CurrentFloatEdgeFlag = - tnl->save.attrptr[_TNL_ATTRIB_EDGEFLAG][0]; - ctx->ListState.CurrentEdgeFlag = - (tnl->save.CurrentFloatEdgeFlag == 1.0); - } -} - - -static void _save_copy_from_current( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLint i; - - for (i = _TNL_ATTRIB_POS+1 ; i <= _TNL_ATTRIB_EDGEFLAG ; i++) - switch (tnl->save.attrsz[i]) { - case 4: tnl->save.attrptr[i][3] = tnl->save.current[i][3]; - case 3: tnl->save.attrptr[i][2] = tnl->save.current[i][2]; - case 2: tnl->save.attrptr[i][1] = tnl->save.current[i][1]; - case 1: tnl->save.attrptr[i][0] = tnl->save.current[i][0]; - case 0: break; - } - - /* Edgeflag requires special treatment: - */ - if (tnl->save.attrsz[_TNL_ATTRIB_EDGEFLAG]) { - tnl->save.CurrentFloatEdgeFlag = (GLfloat)ctx->ListState.CurrentEdgeFlag; - tnl->save.attrptr[_TNL_ATTRIB_EDGEFLAG][0] = tnl->save.CurrentFloatEdgeFlag; - } -} - - - - -/* Flush existing data, set new attrib size, replay copied vertices. - */ -static void _save_upgrade_vertex( GLcontext *ctx, - GLuint attr, - GLuint newsz ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint oldsz; - GLuint i; - GLfloat *tmp; - - /* Store the current run of vertices, and emit a GL_END. Emit a - * BEGIN in the new buffer. - */ - if (tnl->save.initial_counter != tnl->save.counter) - _save_wrap_buffers( ctx ); - else - assert( tnl->save.copied.nr == 0 ); - - /* Do a COPY_TO_CURRENT to ensure back-copying works for the case - * when the attribute already exists in the vertex and is having - * its size increased. - */ - _save_copy_to_current( ctx ); - - /* Fix up sizes: - */ - oldsz = tnl->save.attrsz[attr]; - tnl->save.attrsz[attr] = newsz; - - tnl->save.vertex_size += newsz - oldsz; - tnl->save.counter = ((SAVE_BUFFER_SIZE - tnl->save.vertex_store->used) / - tnl->save.vertex_size); - if (tnl->save.counter > ctx->Const.MaxArrayLockSize ) - tnl->save.counter = ctx->Const.MaxArrayLockSize; - tnl->save.initial_counter = tnl->save.counter; - - /* Recalculate all the attrptr[] values: - */ - for (i = 0, tmp = tnl->save.vertex ; i < _TNL_ATTRIB_MAX ; i++) { - if (tnl->save.attrsz[i]) { - tnl->save.attrptr[i] = tmp; - tmp += tnl->save.attrsz[i]; - } - else - tnl->save.attrptr[i] = NULL; /* will not be dereferenced. */ - } - - /* Copy from current to repopulate the vertex with correct values. - */ - _save_copy_from_current( ctx ); - - /* Replay stored vertices to translate them to new format here. - * - * If there are copied vertices and the new (upgraded) attribute - * has not been defined before, this list is somewhat degenerate, - * and will need fixup at runtime. - */ - if (tnl->save.copied.nr) - { - GLfloat *data = tnl->save.copied.buffer; - GLfloat *dest = tnl->save.buffer; - GLuint j; - - /* Need to note this and fix up at runtime (or loopback): - */ - if (tnl->save.currentsz[attr][0] == 0) { - assert(oldsz == 0); - tnl->save.dangling_attr_ref = GL_TRUE; - -/* _mesa_debug(NULL, "_save_upgrade_vertex: dangling reference attr %d\n", */ -/* attr); */ - -#if 0 - /* The current strategy is to punt these degenerate cases - * through _tnl_loopback_vertex_list(), a lower-performance - * option. To minimize the impact of this, artificially - * reduce the size of this vertex_list. - */ - if (t->save.counter > 10) { - t->save.initial_counter = 10; - t->save.counter = 10; - } -#endif - } - - for (i = 0 ; i < tnl->save.copied.nr ; i++) { - for (j = 0 ; j < _TNL_ATTRIB_MAX ; j++) { - if (tnl->save.attrsz[j]) { - if (j == attr) { - if (oldsz) { - COPY_CLEAN_4V( dest, oldsz, data ); - data += oldsz; - dest += newsz; - } - else { - COPY_SZ_4V( dest, newsz, tnl->save.current[attr] ); - dest += newsz; - } - } - else { - GLint sz = tnl->save.attrsz[j]; - COPY_SZ_4V( dest, sz, data ); - data += sz; - dest += sz; - } - } - } - } - - tnl->save.vbptr = dest; - tnl->save.counter -= tnl->save.copied.nr; - } -} - - - - -/* Helper function for 'CHOOSE' macro. Do what's necessary when an - * entrypoint is called for the first time. - */ -static void do_choose( GLuint attr, GLuint sz, - void (*attr_func)( const GLfloat *), - void (*choose1)( const GLfloat *), - void (*choose2)( const GLfloat *), - void (*choose3)( const GLfloat *), - void (*choose4)( const GLfloat *), - const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - TNLcontext *tnl = TNL_CONTEXT(ctx); - static GLfloat id[4] = { 0, 0, 0, 1 }; - int i; - - if (tnl->save.attrsz[attr] < sz) { - /* New size is larger. Need to flush existing vertices and get - * an enlarged vertex format. - */ - _save_upgrade_vertex( ctx, attr, sz ); - } - else { - /* New size is equal or smaller - just need to fill in some - * zeros. - */ - for (i = sz ; i <= tnl->save.attrsz[attr] ; i++) - tnl->save.attrptr[attr][i-1] = id[i-1]; - } - - /* Reset any active pointers for this attribute - */ - tnl->save.tabfv[attr][0] = choose1; - tnl->save.tabfv[attr][1] = choose2; - tnl->save.tabfv[attr][2] = choose3; - tnl->save.tabfv[attr][3] = choose4; - - /* Update the secondary dispatch table with the new function - */ - tnl->save.tabfv[attr][sz-1] = attr_func; - - (*attr_func)(v); -} - - - -/* 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 save_choose_##ATTR##_##N( const GLfloat *v ); \ - \ -static void save_attrib_##ATTR##_##N( const GLfloat *v ) \ -{ \ - GET_CURRENT_CONTEXT( ctx ); \ - TNLcontext *tnl = TNL_CONTEXT(ctx); \ - \ - if ((ATTR) == 0) { \ - GLuint i; \ - \ - if (N>0) tnl->save.vbptr[0] = v[0]; \ - if (N>1) tnl->save.vbptr[1] = v[1]; \ - if (N>2) tnl->save.vbptr[2] = v[2]; \ - if (N>3) tnl->save.vbptr[3] = v[3]; \ - \ - for (i = N; i < tnl->save.vertex_size; i++) \ - tnl->save.vbptr[i] = tnl->save.vertex[i]; \ - \ - tnl->save.vbptr += tnl->save.vertex_size; \ - \ - if (--tnl->save.counter == 0) \ - _save_wrap_filled_vertex( ctx ); \ - } \ - else { \ - GLfloat *dest = tnl->save.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 CHOOSE( ATTR, N ) \ -static void save_choose_##ATTR##_##N( const GLfloat *v ) \ -{ \ - do_choose(ATTR, N, \ - save_attrib_##ATTR##_##N, \ - save_choose_##ATTR##_1, \ - save_choose_##ATTR##_2, \ - save_choose_##ATTR##_3, \ - save_choose_##ATTR##_4, \ - v ); \ -} - -#define INIT(ATTR) \ -static void save_init_##ATTR( TNLcontext *tnl ) \ -{ \ - tnl->save.tabfv[ATTR][0] = save_choose_##ATTR##_1; \ - tnl->save.tabfv[ATTR][1] = save_choose_##ATTR##_2; \ - tnl->save.tabfv[ATTR][2] = save_choose_##ATTR##_3; \ - tnl->save.tabfv[ATTR][3] = save_choose_##ATTR##_4; \ -} - -#define ATTRS( ATTRIB ) \ - ATTRFV( ATTRIB, 1 ) \ - ATTRFV( ATTRIB, 2 ) \ - ATTRFV( ATTRIB, 3 ) \ - ATTRFV( ATTRIB, 4 ) \ - CHOOSE( ATTRIB, 1 ) \ - CHOOSE( ATTRIB, 2 ) \ - CHOOSE( ATTRIB, 3 ) \ - CHOOSE( ATTRIB, 4 ) \ - INIT( ATTRIB ) \ - - -/* Generate a lot of functions. These are the actual worker - * functions, which are equivalent to those generated via codegen - * elsewhere. - */ -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 ) - - -static void _save_reset_vertex( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint i; - - save_init_0( tnl ); - save_init_1( tnl ); - save_init_2( tnl ); - save_init_3( tnl ); - save_init_4( tnl ); - save_init_5( tnl ); - save_init_6( tnl ); - save_init_7( tnl ); - save_init_8( tnl ); - save_init_9( tnl ); - save_init_10( tnl ); - save_init_11( tnl ); - save_init_12( tnl ); - save_init_13( tnl ); - save_init_14( tnl ); - save_init_15( tnl ); - - for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) - tnl->save.attrsz[i] = 0; - - tnl->save.vertex_size = 0; - tnl->save.have_materials = 0; - - _save_reset_counters( ctx ); -} - - - -/* Cope with aliasing of classic Vertex, Normal, etc. and the fan-out - * of glMultTexCoord and glProgramParamterNV by routing all these - * through a second level dispatch table. - */ -#define DISPATCH_ATTRFV( ATTR, COUNT, P ) \ -do { \ - GET_CURRENT_CONTEXT( ctx ); \ - TNLcontext *tnl = TNL_CONTEXT(ctx); \ - tnl->save.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 enum_error( void ) -{ - GET_CURRENT_CONTEXT( ctx ); - _mesa_compile_error( ctx, GL_INVALID_ENUM, "glVertexAttrib" ); -} - -static void GLAPIENTRY _save_Vertex2f( GLfloat x, GLfloat y ) -{ - DISPATCH_ATTR2F( _TNL_ATTRIB_POS, x, y ); -} - -static void GLAPIENTRY _save_Vertex2fv( const GLfloat *v ) -{ - DISPATCH_ATTR2FV( _TNL_ATTRIB_POS, v ); -} - -static void GLAPIENTRY _save_Vertex3f( GLfloat x, GLfloat y, GLfloat z ) -{ - DISPATCH_ATTR3F( _TNL_ATTRIB_POS, x, y, z ); -} - -static void GLAPIENTRY _save_Vertex3fv( const GLfloat *v ) -{ - DISPATCH_ATTR3FV( _TNL_ATTRIB_POS, v ); -} - -static void GLAPIENTRY _save_Vertex4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) -{ - DISPATCH_ATTR4F( _TNL_ATTRIB_POS, x, y, z, w ); -} - -static void GLAPIENTRY _save_Vertex4fv( const GLfloat *v ) -{ - DISPATCH_ATTR4FV( _TNL_ATTRIB_POS, v ); -} - -static void GLAPIENTRY _save_TexCoord1f( GLfloat x ) -{ - DISPATCH_ATTR1F( _TNL_ATTRIB_TEX0, x ); -} - -static void GLAPIENTRY _save_TexCoord1fv( const GLfloat *v ) -{ - DISPATCH_ATTR1FV( _TNL_ATTRIB_TEX0, v ); -} - -static void GLAPIENTRY _save_TexCoord2f( GLfloat x, GLfloat y ) -{ - DISPATCH_ATTR2F( _TNL_ATTRIB_TEX0, x, y ); -} - -static void GLAPIENTRY _save_TexCoord2fv( const GLfloat *v ) -{ - DISPATCH_ATTR2FV( _TNL_ATTRIB_TEX0, v ); -} - -static void GLAPIENTRY _save_TexCoord3f( GLfloat x, GLfloat y, GLfloat z ) -{ - DISPATCH_ATTR3F( _TNL_ATTRIB_TEX0, x, y, z ); -} - -static void GLAPIENTRY _save_TexCoord3fv( const GLfloat *v ) -{ - DISPATCH_ATTR3FV( _TNL_ATTRIB_TEX0, v ); -} - -static void GLAPIENTRY _save_TexCoord4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) -{ - DISPATCH_ATTR4F( _TNL_ATTRIB_TEX0, x, y, z, w ); -} - -static void GLAPIENTRY _save_TexCoord4fv( const GLfloat *v ) -{ - DISPATCH_ATTR4FV( _TNL_ATTRIB_TEX0, v ); -} - -static void GLAPIENTRY _save_Normal3f( GLfloat x, GLfloat y, GLfloat z ) -{ - DISPATCH_ATTR3F( _TNL_ATTRIB_NORMAL, x, y, z ); -} - -static void GLAPIENTRY _save_Normal3fv( const GLfloat *v ) -{ - DISPATCH_ATTR3FV( _TNL_ATTRIB_NORMAL, v ); -} - -static void GLAPIENTRY _save_FogCoordfEXT( GLfloat x ) -{ - DISPATCH_ATTR1F( _TNL_ATTRIB_FOG, x ); -} - -static void GLAPIENTRY _save_FogCoordfvEXT( const GLfloat *v ) -{ - DISPATCH_ATTR1FV( _TNL_ATTRIB_FOG, v ); -} - -static void GLAPIENTRY _save_Color3f( GLfloat x, GLfloat y, GLfloat z ) -{ - DISPATCH_ATTR3F( _TNL_ATTRIB_COLOR0, x, y, z ); -} - -static void GLAPIENTRY _save_Color3fv( const GLfloat *v ) -{ - DISPATCH_ATTR3FV( _TNL_ATTRIB_COLOR0, v ); -} - -static void GLAPIENTRY _save_Color4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) -{ - DISPATCH_ATTR4F( _TNL_ATTRIB_COLOR0, x, y, z, w ); -} - -static void GLAPIENTRY _save_Color4fv( const GLfloat *v ) -{ - DISPATCH_ATTR4FV( _TNL_ATTRIB_COLOR0, v ); -} - -static void GLAPIENTRY _save_SecondaryColor3fEXT( GLfloat x, GLfloat y, GLfloat z ) -{ - DISPATCH_ATTR3F( _TNL_ATTRIB_COLOR1, x, y, z ); -} - -static void GLAPIENTRY _save_SecondaryColor3fvEXT( const GLfloat *v ) -{ - DISPATCH_ATTR3FV( _TNL_ATTRIB_COLOR1, v ); -} - -static void GLAPIENTRY _save_MultiTexCoord1f( GLenum target, GLfloat x ) -{ - GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; - DISPATCH_ATTR1F( attr, x ); -} - -static void GLAPIENTRY _save_MultiTexCoord1fv( GLenum target, const GLfloat *v ) -{ - GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; - DISPATCH_ATTR1FV( attr, v ); -} - -static void GLAPIENTRY _save_MultiTexCoord2f( GLenum target, GLfloat x, GLfloat y ) -{ - GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; - DISPATCH_ATTR2F( attr, x, y ); -} - -static void GLAPIENTRY _save_MultiTexCoord2fv( GLenum target, const GLfloat *v ) -{ - GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; - DISPATCH_ATTR2FV( attr, v ); -} - -static void GLAPIENTRY _save_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 _save_MultiTexCoord3fv( GLenum target, const GLfloat *v ) -{ - GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; - DISPATCH_ATTR3FV( attr, v ); -} - -static void GLAPIENTRY _save_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 _save_MultiTexCoord4fv( GLenum target, const GLfloat *v ) -{ - GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; - DISPATCH_ATTR4FV( attr, v ); -} - -static void GLAPIENTRY _save_VertexAttrib1fNV( GLuint index, GLfloat x ) -{ - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) - DISPATCH_ATTR1F( index, x ); - else - enum_error(); -} - -static void GLAPIENTRY _save_VertexAttrib1fvNV( GLuint index, const GLfloat *v ) -{ - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) - DISPATCH_ATTR1FV( index, v ); - else - enum_error(); -} - -static void GLAPIENTRY _save_VertexAttrib2fNV( GLuint index, GLfloat x, GLfloat y ) -{ - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) - DISPATCH_ATTR2F( index, x, y ); - else - enum_error(); -} - -static void GLAPIENTRY _save_VertexAttrib2fvNV( GLuint index, const GLfloat *v ) -{ - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) - DISPATCH_ATTR2FV( index, v ); - else - enum_error(); -} - -static void GLAPIENTRY _save_VertexAttrib3fNV( GLuint index, GLfloat x, GLfloat y, - GLfloat z ) -{ - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) - DISPATCH_ATTR3F( index, x, y, z ); - else - enum_error(); -} - -static void GLAPIENTRY _save_VertexAttrib3fvNV( GLuint index, const GLfloat *v ) -{ - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) - DISPATCH_ATTR3FV( index, v ); - else - enum_error(); -} - -static void GLAPIENTRY _save_VertexAttrib4fNV( GLuint index, GLfloat x, GLfloat y, - GLfloat z, GLfloat w ) -{ - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) - DISPATCH_ATTR4F( index, x, y, z, w ); - else - enum_error(); -} - -static void GLAPIENTRY _save_VertexAttrib4fvNV( GLuint index, const GLfloat *v ) -{ - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) - DISPATCH_ATTR4FV( index, v ); - else - enum_error(); -} - - -static void GLAPIENTRY -_save_VertexAttrib1fARB( GLuint index, GLfloat x ) -{ - if (index < MAX_VERTEX_ATTRIBS) - DISPATCH_ATTR1F( index, x ); - else - enum_error(); -} - -static void GLAPIENTRY -_save_VertexAttrib1fvARB( GLuint index, const GLfloat *v ) -{ - if (index < MAX_VERTEX_ATTRIBS) - DISPATCH_ATTR1FV( index, v ); - else - enum_error(); -} - -static void GLAPIENTRY -_save_VertexAttrib2fARB( GLuint index, GLfloat x, GLfloat y ) -{ - if (index < MAX_VERTEX_ATTRIBS) - DISPATCH_ATTR2F( index, x, y ); - else - enum_error(); -} - -static void GLAPIENTRY -_save_VertexAttrib2fvARB( GLuint index, const GLfloat *v ) -{ - if (index < MAX_VERTEX_ATTRIBS) - DISPATCH_ATTR2FV( index, v ); - else - enum_error(); -} - -static void GLAPIENTRY -_save_VertexAttrib3fARB( GLuint index, GLfloat x, GLfloat y, GLfloat z ) -{ - if (index < MAX_VERTEX_ATTRIBS) - DISPATCH_ATTR3F( index, x, y, z ); - else - enum_error(); -} - -static void GLAPIENTRY -_save_VertexAttrib3fvARB( GLuint index, const GLfloat *v ) -{ - if (index < MAX_VERTEX_ATTRIBS) - DISPATCH_ATTR3FV( index, v ); - else - enum_error(); -} - -static void GLAPIENTRY -_save_VertexAttrib4fARB( GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w ) -{ - if (index < MAX_VERTEX_ATTRIBS) - DISPATCH_ATTR4F( index, x, y, z, w ); - else - enum_error(); -} - -static void GLAPIENTRY -_save_VertexAttrib4fvARB( GLuint index, const GLfloat *v ) -{ - if (index < MAX_VERTEX_ATTRIBS) - DISPATCH_ATTR4FV( index, v ); - else - enum_error(); -} - - -/* Materials: - * - * These are treated as per-vertex attributes, at indices above where - * the NV_vertex_program leaves off. There are a lot of good things - * about treating materials this way. - * - * However: I don't want to double the number of generated functions - * just to cope with this, so I unroll the 'C' varients of CHOOSE and - * ATTRF into this function, and dispense with codegen and - * second-level dispatch. - * - * There is no aliasing of material attributes with other entrypoints. - */ -#define MAT_ATTR( A, N, params ) \ -do { \ - if (tnl->save.attrsz[A] < N) { \ - _save_upgrade_vertex( ctx, A, N ); \ - tnl->save.have_materials = GL_TRUE; \ - } \ - \ - { \ - GLfloat *dest = tnl->save.attrptr[A]; \ - if (N>0) dest[0] = params[0]; \ - if (N>1) dest[1] = params[1]; \ - if (N>2) dest[2] = params[2]; \ - if (N>3) dest[3] = params[3]; \ - } \ -} while (0) - - -#define MAT( ATTR, N, face, params ) \ -do { \ - if (face != GL_BACK) \ - MAT_ATTR( ATTR, N, params ); /* front */ \ - if (face != GL_FRONT) \ - MAT_ATTR( ATTR + 1, N, params ); /* back */ \ -} while (0) - - -/* NOTE: Have to remove/deal-with colormaterial crossovers, probably - * later on - in the meantime just store everything. - */ -static void GLAPIENTRY _save_Materialfv( GLenum face, GLenum pname, - const GLfloat *params ) -{ - GET_CURRENT_CONTEXT( ctx ); - TNLcontext *tnl = TNL_CONTEXT(ctx); - - switch (pname) { - case GL_EMISSION: - MAT( _TNL_ATTRIB_MAT_FRONT_EMISSION, 4, face, params ); - break; - case GL_AMBIENT: - MAT( _TNL_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params ); - break; - case GL_DIFFUSE: - MAT( _TNL_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params ); - break; - case GL_SPECULAR: - MAT( _TNL_ATTRIB_MAT_FRONT_SPECULAR, 4, face, params ); - break; - case GL_SHININESS: - MAT( _TNL_ATTRIB_MAT_FRONT_SHININESS, 1, face, params ); - break; - case GL_COLOR_INDEXES: - MAT( _TNL_ATTRIB_MAT_FRONT_INDEXES, 3, face, params ); - break; - case GL_AMBIENT_AND_DIFFUSE: - MAT( _TNL_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params ); - MAT( _TNL_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params ); - break; - default: - _mesa_compile_error( ctx, GL_INVALID_ENUM, "glMaterialfv" ); - return; - } -} - - -#define IDX_ATTR( A, IDX ) \ -do { \ - GET_CURRENT_CONTEXT( ctx ); \ - TNLcontext *tnl = TNL_CONTEXT(ctx); \ - \ - if (tnl->save.attrsz[A] < 1) { \ - _save_upgrade_vertex( ctx, A, 1 ); \ - } \ - \ - { \ - GLfloat *dest = tnl->save.attrptr[A]; \ - dest[0] = IDX; \ - } \ -} while (0) - - -static void GLAPIENTRY _save_EdgeFlag( GLboolean b ) -{ - IDX_ATTR( _TNL_ATTRIB_EDGEFLAG, (GLfloat)b ); -} - - -static void GLAPIENTRY _save_Indexf( GLfloat f ) -{ - IDX_ATTR( _TNL_ATTRIB_COLOR_INDEX, f ); -} - -static void GLAPIENTRY _save_Indexfv( const GLfloat *f ) -{ - IDX_ATTR( _TNL_ATTRIB_COLOR_INDEX, f[0] ); -} - - - - -/* Cope with EvalCoord/CallList called within a begin/end object: - * -- Flush current buffer - * -- Fallback to opcodes for the rest of the begin/end object. - */ -#define FALLBACK(ctx) \ -do { \ - TNLcontext *tnl = TNL_CONTEXT(ctx); \ - \ - if (tnl->save.initial_counter != tnl->save.counter || \ - tnl->save.prim_count) \ - _save_compile_vertex_list( ctx ); \ - \ - _save_copy_to_current( ctx ); \ - _save_reset_vertex( ctx ); \ - _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); \ - ctx->Driver.SaveNeedFlush = 0; \ -} while (0) - -static void GLAPIENTRY _save_EvalCoord1f( GLfloat u ) -{ - GET_CURRENT_CONTEXT(ctx); - FALLBACK(ctx); - CALL_EvalCoord1f(ctx->Save, ( u )); -} - -static void GLAPIENTRY _save_EvalCoord1fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - FALLBACK(ctx); - CALL_EvalCoord1fv(ctx->Save, ( v )); -} - -static void GLAPIENTRY _save_EvalCoord2f( GLfloat u, GLfloat v ) -{ - GET_CURRENT_CONTEXT(ctx); - FALLBACK(ctx); - CALL_EvalCoord2f(ctx->Save, ( u, v )); -} - -static void GLAPIENTRY _save_EvalCoord2fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - FALLBACK(ctx); - CALL_EvalCoord2fv(ctx->Save, ( v )); -} - -static void GLAPIENTRY _save_EvalPoint1( GLint i ) -{ - GET_CURRENT_CONTEXT(ctx); - FALLBACK(ctx); - CALL_EvalPoint1(ctx->Save, ( i )); -} - -static void GLAPIENTRY _save_EvalPoint2( GLint i, GLint j ) -{ - GET_CURRENT_CONTEXT(ctx); - FALLBACK(ctx); - CALL_EvalPoint2(ctx->Save, ( i, j )); -} - -static void GLAPIENTRY _save_CallList( GLuint l ) -{ - GET_CURRENT_CONTEXT(ctx); - FALLBACK(ctx); - CALL_CallList(ctx->Save, ( l )); -} - -static void GLAPIENTRY _save_CallLists( GLsizei n, GLenum type, const GLvoid *v ) -{ - GET_CURRENT_CONTEXT(ctx); - FALLBACK(ctx); - CALL_CallLists(ctx->Save, ( n, type, v )); -} - - - - -/** - * Called via ctx->Driver.NotifySaveBegin(ctx, mode) when we get a - * glBegin() call while compiling a display list. - * See save_Begin() in dlist.c - * - * This plugs in our special TNL-related display list functions. - * All subsequent glBegin/glVertex/glEnd()s found while compiling a - * display list will get routed to the functions in this file. - * - * Updating of ctx->Driver.CurrentSavePrimitive is already taken care of. - */ -static GLboolean _save_NotifyBegin( GLcontext *ctx, GLenum mode ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - - if (1) { - GLuint i = tnl->save.prim_count++; - - assert(i < tnl->save.prim_max); - tnl->save.prim[i].mode = mode | PRIM_BEGIN; - tnl->save.prim[i].start = tnl->save.initial_counter - tnl->save.counter; - tnl->save.prim[i].count = 0; - - _mesa_install_save_vtxfmt( ctx, &tnl->save_vtxfmt ); - ctx->Driver.SaveNeedFlush = 1; - return GL_TRUE; - } - else - return GL_FALSE; -} - - - -static void GLAPIENTRY _save_End( void ) -{ - GET_CURRENT_CONTEXT( ctx ); - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLint i = tnl->save.prim_count - 1; - - ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END; - if (ctx->ExecuteFlag) - ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; - - tnl->save.prim[i].mode |= PRIM_END; - tnl->save.prim[i].count = ((tnl->save.initial_counter - tnl->save.counter) - - tnl->save.prim[i].start); - - if (i == (GLint) tnl->save.prim_max - 1) { - _save_compile_vertex_list( ctx ); - assert(tnl->save.copied.nr == 0); - } - - /* Swap out this vertex format while outside begin/end. Any color, - * etc. received between here and the next begin will be compiled - * as opcodes. - */ - _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); -} - - -/* These are all errors as this vtxfmt is only installed inside - * begin/end pairs. - */ -static void GLAPIENTRY _save_DrawElements(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) count; (void) type; (void) indices; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawElements" ); -} - - -static void GLAPIENTRY _save_DrawRangeElements(GLenum mode, - GLuint start, GLuint end, - GLsizei count, GLenum type, - const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) start; (void) end; (void) count; (void) type; (void) indices; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawRangeElements" ); -} - -static void GLAPIENTRY _save_DrawArrays(GLenum mode, GLint start, GLsizei count) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) start; (void) count; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawArrays" ); -} - -static void GLAPIENTRY _save_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) -{ - GET_CURRENT_CONTEXT(ctx); - (void) x1; (void) y1; (void) x2; (void) y2; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glRectf" ); -} - -static void GLAPIENTRY _save_EvalMesh1( GLenum mode, GLint i1, GLint i2 ) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) i1; (void) i2; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glEvalMesh1" ); -} - -static void GLAPIENTRY _save_EvalMesh2( GLenum mode, GLint i1, GLint i2, - GLint j1, GLint j2 ) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) i1; (void) i2; (void) j1; (void) j2; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glEvalMesh2" ); -} - -/** - * This is only called if someone tries to compile nested glBegin()s - * in their display list. - */ -static void GLAPIENTRY _save_Begin( GLenum mode ) -{ - GET_CURRENT_CONTEXT( ctx ); - (void) mode; - _mesa_compile_error(ctx, GL_INVALID_OPERATION, - "glBegin(called inside glBegin/End)"); -} - - -/* Unlike the functions above, these are to be hooked into the vtxfmt - * maintained in ctx->ListState, active when the list is known or - * suspected to be outside any begin/end primitive. - */ -static void GLAPIENTRY _save_OBE_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) -{ - GET_CURRENT_CONTEXT(ctx); - _save_NotifyBegin( ctx, GL_QUADS | PRIM_WEAK ); - CALL_Vertex2f(GET_DISPATCH(), ( x1, y1 )); - CALL_Vertex2f(GET_DISPATCH(), ( x2, y1 )); - CALL_Vertex2f(GET_DISPATCH(), ( x2, y2 )); - CALL_Vertex2f(GET_DISPATCH(), ( x1, y2 )); - CALL_End(GET_DISPATCH(), ()); -} - - -static void GLAPIENTRY _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei count) -{ - GET_CURRENT_CONTEXT(ctx); - GLint i; - - if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) - return; - - _save_NotifyBegin( ctx, mode | PRIM_WEAK ); - for (i = 0; i < count; i++) - CALL_ArrayElement(GET_DISPATCH(), (start + i)); - CALL_End(GET_DISPATCH(), ()); -} - - -static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - GLint i; - - if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) - return; - - _save_NotifyBegin( ctx, mode | PRIM_WEAK ); - - switch (type) { - case GL_UNSIGNED_BYTE: - for (i = 0 ; i < count ; i++) - CALL_ArrayElement(GET_DISPATCH(), ( ((GLubyte *)indices)[i] )); - break; - case GL_UNSIGNED_SHORT: - for (i = 0 ; i < count ; i++) - CALL_ArrayElement(GET_DISPATCH(), ( ((GLushort *)indices)[i] )); - break; - case GL_UNSIGNED_INT: - for (i = 0 ; i < count ; i++) - CALL_ArrayElement(GET_DISPATCH(), ( ((GLuint *)indices)[i] )); - break; - default: - _mesa_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" ); - break; - } - - CALL_End(GET_DISPATCH(), ()); -} - -static void GLAPIENTRY _save_OBE_DrawRangeElements(GLenum mode, - GLuint start, GLuint end, - GLsizei count, GLenum type, - const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - if (_mesa_validate_DrawRangeElements( ctx, mode, - start, end, - count, type, indices )) - _save_OBE_DrawElements( mode, count, type, indices ); -} - - - - - -static void _save_vtxfmt_init( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLvertexformat *vfmt = &tnl->save_vtxfmt; - - vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ - vfmt->Begin = _save_Begin; - vfmt->Color3f = _save_Color3f; - vfmt->Color3fv = _save_Color3fv; - vfmt->Color4f = _save_Color4f; - vfmt->Color4fv = _save_Color4fv; - vfmt->EdgeFlag = _save_EdgeFlag; - vfmt->End = _save_End; - vfmt->FogCoordfEXT = _save_FogCoordfEXT; - vfmt->FogCoordfvEXT = _save_FogCoordfvEXT; - vfmt->Indexf = _save_Indexf; - vfmt->Indexfv = _save_Indexfv; - vfmt->Materialfv = _save_Materialfv; - vfmt->MultiTexCoord1fARB = _save_MultiTexCoord1f; - vfmt->MultiTexCoord1fvARB = _save_MultiTexCoord1fv; - vfmt->MultiTexCoord2fARB = _save_MultiTexCoord2f; - vfmt->MultiTexCoord2fvARB = _save_MultiTexCoord2fv; - vfmt->MultiTexCoord3fARB = _save_MultiTexCoord3f; - vfmt->MultiTexCoord3fvARB = _save_MultiTexCoord3fv; - vfmt->MultiTexCoord4fARB = _save_MultiTexCoord4f; - vfmt->MultiTexCoord4fvARB = _save_MultiTexCoord4fv; - vfmt->Normal3f = _save_Normal3f; - vfmt->Normal3fv = _save_Normal3fv; - vfmt->SecondaryColor3fEXT = _save_SecondaryColor3fEXT; - vfmt->SecondaryColor3fvEXT = _save_SecondaryColor3fvEXT; - vfmt->TexCoord1f = _save_TexCoord1f; - vfmt->TexCoord1fv = _save_TexCoord1fv; - vfmt->TexCoord2f = _save_TexCoord2f; - vfmt->TexCoord2fv = _save_TexCoord2fv; - vfmt->TexCoord3f = _save_TexCoord3f; - vfmt->TexCoord3fv = _save_TexCoord3fv; - vfmt->TexCoord4f = _save_TexCoord4f; - vfmt->TexCoord4fv = _save_TexCoord4fv; - vfmt->Vertex2f = _save_Vertex2f; - vfmt->Vertex2fv = _save_Vertex2fv; - vfmt->Vertex3f = _save_Vertex3f; - vfmt->Vertex3fv = _save_Vertex3fv; - vfmt->Vertex4f = _save_Vertex4f; - vfmt->Vertex4fv = _save_Vertex4fv; - vfmt->VertexAttrib1fNV = _save_VertexAttrib1fNV; - vfmt->VertexAttrib1fvNV = _save_VertexAttrib1fvNV; - vfmt->VertexAttrib2fNV = _save_VertexAttrib2fNV; - vfmt->VertexAttrib2fvNV = _save_VertexAttrib2fvNV; - vfmt->VertexAttrib3fNV = _save_VertexAttrib3fNV; - vfmt->VertexAttrib3fvNV = _save_VertexAttrib3fvNV; - vfmt->VertexAttrib4fNV = _save_VertexAttrib4fNV; - vfmt->VertexAttrib4fvNV = _save_VertexAttrib4fvNV; - vfmt->VertexAttrib1fARB = _save_VertexAttrib1fARB; - vfmt->VertexAttrib1fvARB = _save_VertexAttrib1fvARB; - vfmt->VertexAttrib2fARB = _save_VertexAttrib2fARB; - vfmt->VertexAttrib2fvARB = _save_VertexAttrib2fvARB; - vfmt->VertexAttrib3fARB = _save_VertexAttrib3fARB; - vfmt->VertexAttrib3fvARB = _save_VertexAttrib3fvARB; - vfmt->VertexAttrib4fARB = _save_VertexAttrib4fARB; - vfmt->VertexAttrib4fvARB = _save_VertexAttrib4fvARB; - - /* This will all require us to fallback to saving the list as opcodes: - */ - vfmt->CallList = _save_CallList; /* inside begin/end */ - vfmt->CallLists = _save_CallLists; /* inside begin/end */ - vfmt->EvalCoord1f = _save_EvalCoord1f; - vfmt->EvalCoord1fv = _save_EvalCoord1fv; - vfmt->EvalCoord2f = _save_EvalCoord2f; - vfmt->EvalCoord2fv = _save_EvalCoord2fv; - vfmt->EvalPoint1 = _save_EvalPoint1; - vfmt->EvalPoint2 = _save_EvalPoint2; - - /* These are all errors as we at least know we are in some sort of - * begin/end pair: - */ - vfmt->EvalMesh1 = _save_EvalMesh1; - vfmt->EvalMesh2 = _save_EvalMesh2; - vfmt->Begin = _save_Begin; - vfmt->Rectf = _save_Rectf; - vfmt->DrawArrays = _save_DrawArrays; - vfmt->DrawElements = _save_DrawElements; - vfmt->DrawRangeElements = _save_DrawRangeElements; - -} - - -void _tnl_SaveFlushVertices( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - - /* Noop when we are actually active: - */ - if (ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM || - ctx->Driver.CurrentSavePrimitive <= GL_POLYGON) - return; - - if (tnl->save.initial_counter != tnl->save.counter || - tnl->save.prim_count) - _save_compile_vertex_list( ctx ); - - _save_copy_to_current( ctx ); - _save_reset_vertex( ctx ); - ctx->Driver.SaveNeedFlush = 0; -} - -void _tnl_NewList( GLcontext *ctx, GLuint list, GLenum mode ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - - (void) list; (void) mode; - - if (!tnl->save.prim_store) - tnl->save.prim_store = alloc_prim_store( ctx ); - - if (!tnl->save.vertex_store) { - tnl->save.vertex_store = alloc_vertex_store( ctx ); - tnl->save.vbptr = tnl->save.vertex_store->buffer; - } - - _save_reset_vertex( ctx ); - ctx->Driver.SaveNeedFlush = 0; -} - -void _tnl_EndList( GLcontext *ctx ) -{ - (void) ctx; - assert(TNL_CONTEXT(ctx)->save.vertex_size == 0); -} - -void _tnl_BeginCallList( GLcontext *ctx, struct mesa_display_list *dlist ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - tnl->save.replay_flags |= dlist->flags; - tnl->save.replay_flags |= tnl->LoopbackDListCassettes; -} - -void _tnl_EndCallList( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - - if (ctx->ListState.CallDepth == 1) - tnl->save.replay_flags = 0; -} - - -static void _tnl_destroy_vertex_list( GLcontext *ctx, void *data ) -{ - struct tnl_vertex_list *node = (struct tnl_vertex_list *)data; - (void) ctx; - - if ( --node->vertex_store->refcount == 0 ) - FREE( node->vertex_store ); - - if ( --node->prim_store->refcount == 0 ) - FREE( node->prim_store ); - - if ( node->normal_lengths ) - FREE( node->normal_lengths ); -} - - -static void _tnl_print_vertex_list( GLcontext *ctx, void *data ) -{ - struct tnl_vertex_list *node = (struct tnl_vertex_list *)data; - GLuint i; - (void) ctx; - - _mesa_debug(NULL, "TNL-VERTEX-LIST, %u vertices %d primitives, %d vertsize\n", - node->count, - node->prim_count, - node->vertex_size); - - for (i = 0 ; i < node->prim_count ; i++) { - struct tnl_prim *prim = &node->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)"); - } -} - - -static void _save_current_init( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLint i; - - for (i = 0; i < _TNL_ATTRIB_MAT_FRONT_AMBIENT; i++) { - ASSERT(i < VERT_ATTRIB_MAX); - tnl->save.currentsz[i] = &ctx->ListState.ActiveAttribSize[i]; - tnl->save.current[i] = ctx->ListState.CurrentAttrib[i]; - } - - for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) { - const GLuint j = i - _TNL_FIRST_MAT; - ASSERT(j < MAT_ATTRIB_MAX); - tnl->save.currentsz[i] = &ctx->ListState.ActiveMaterialSize[j]; - tnl->save.current[i] = ctx->ListState.CurrentMaterial[j]; - } - - tnl->save.currentsz[_TNL_ATTRIB_EDGEFLAG] = &ctx->ListState.ActiveEdgeFlag; - tnl->save.current[_TNL_ATTRIB_EDGEFLAG] = &tnl->save.CurrentFloatEdgeFlag; -} - -/** - * Initialize the display list compiler - */ -void _tnl_save_init( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct tnl_vertex_arrays *tmp = &tnl->save_inputs; - GLuint i; - - - for (i = 0; i < _TNL_ATTRIB_MAX; i++) - _mesa_vector4f_init( &tmp->Attribs[i], 0, NULL); - - tnl->save.opcode_vertex_list = - _mesa_alloc_opcode( ctx, - sizeof(struct tnl_vertex_list), - _tnl_playback_vertex_list, - _tnl_destroy_vertex_list, - _tnl_print_vertex_list ); - - ctx->Driver.NotifySaveBegin = _save_NotifyBegin; - - _save_vtxfmt_init( ctx ); - _save_current_init( ctx ); - - /* Hook our array functions into the outside-begin-end vtxfmt in - * ctx->ListState. - */ - ctx->ListState.ListVtxfmt.Rectf = _save_OBE_Rectf; - ctx->ListState.ListVtxfmt.DrawArrays = _save_OBE_DrawArrays; - ctx->ListState.ListVtxfmt.DrawElements = _save_OBE_DrawElements; - ctx->ListState.ListVtxfmt.DrawRangeElements = _save_OBE_DrawRangeElements; - _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); -} - - -/** - * Deallocate the immediate-mode buffer for the given context, if - * its reference count goes to zero. - */ -void _tnl_save_destroy( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - - /* Decrement the refcounts. References may still be held by - * display lists yet to be destroyed, so it may not yet be time to - * free these items. - */ - if (tnl->save.prim_store && - --tnl->save.prim_store->refcount == 0 ) - FREE( tnl->save.prim_store ); - - if (tnl->save.vertex_store && - --tnl->save.vertex_store->refcount == 0 ) - FREE( tnl->save.vertex_store ); -} diff --git a/src/mesa/tnl/t_save_api.h b/src/mesa/tnl/t_save_api.h deleted file mode 100644 index c30e0e8ecd..0000000000 --- a/src/mesa/tnl/t_save_api.h +++ /dev/null @@ -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 - * - */ - -#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 diff --git a/src/mesa/tnl/t_save_loopback.c b/src/mesa/tnl/t_save_loopback.c deleted file mode 100644 index b96bb4ec55..0000000000 --- a/src/mesa/tnl/t_save_loopback.c +++ /dev/null @@ -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 - */ - -#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 ); - } -} diff --git a/src/mesa/tnl/t_save_playback.c b/src/mesa/tnl/t_save_playback.c deleted file mode 100644 index 9504f0fe68..0000000000 --- a/src/mesa/tnl/t_save_playback.c +++ /dev/null @@ -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 - */ - -#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 ); -} diff --git a/src/mesa/tnl/t_vb_render.c b/src/mesa/tnl/t_vb_render.c index 163fa31257..c38f0745e1 100644 --- a/src/mesa/tnl/t_vb_render.c +++ b/src/mesa/tnl/t_vb_render.c @@ -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; diff --git a/src/mesa/tnl/t_vb_rendertmp.h b/src/mesa/tnl/t_vb_rendertmp.h index 90319eddfc..2b5f4e93b2 100644 --- a/src/mesa/tnl/t_vb_rendertmp.h +++ b/src/mesa/tnl/t_vb_rendertmp.h @@ -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 diff --git a/src/mesa/tnl/t_vtx_api.c b/src/mesa/tnl/t_vtx_api.c deleted file mode 100644 index cc00dfda30..0000000000 --- a/src/mesa/tnl/t_vtx_api.c +++ /dev/null @@ -1,1045 +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 - */ - -#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" - -#include "dispatch.h" - -static void reset_attrfv( TNLcontext *tnl ); - -/** Note extra space for error index: */ -static tnl_attrfv_func choose[_TNL_ATTRIB_ERROR+1][4]; -static tnl_attrfv_func generic_attr_func[_TNL_MAX_ATTR_CODEGEN][4]; - - -/* Close off the last primitive, execute the buffer, restart the - * primitive. - */ -static void _tnl_wrap_buffers( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - - - if (tnl->vtx.prim_count == 0) { - tnl->vtx.copied.nr = 0; - tnl->vtx.counter = tnl->vtx.initial_counter; - tnl->vtx.vbptr = tnl->vtx.buffer; - } - else { - GLuint last_prim = tnl->vtx.prim[tnl->vtx.prim_count-1].mode; - GLuint last_count; - - if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) { - GLint i = tnl->vtx.prim_count - 1; - assert(i >= 0); - tnl->vtx.prim[i].count = ((tnl->vtx.initial_counter - - tnl->vtx.counter) - - tnl->vtx.prim[i].start); - } - - last_count = tnl->vtx.prim[tnl->vtx.prim_count-1].count; - - /* Execute the buffer and save copied vertices. - */ - if (tnl->vtx.counter != tnl->vtx.initial_counter) - _tnl_flush_vtx( ctx ); - else { - tnl->vtx.prim_count = 0; - tnl->vtx.copied.nr = 0; - } - - /* Emit a glBegin to start the new list. - */ - assert(tnl->vtx.prim_count == 0); - - if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) { - tnl->vtx.prim[0].mode = ctx->Driver.CurrentExecPrimitive; - tnl->vtx.prim[0].start = 0; - tnl->vtx.prim[0].count = 0; - tnl->vtx.prim_count++; - - if (tnl->vtx.copied.nr == last_count) - tnl->vtx.prim[0].mode |= last_prim & PRIM_BEGIN; - } - } -} - - -/* Deal with buffer wrapping where provoked by the vertex buffer - * filling up, as opposed to upgrade_vertex(). - * - * Make it GLAPIENTRY, so we can tail from the codegen'ed Vertex*fv - */ -void GLAPIENTRY _tnl_wrap_filled_vertex( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLfloat *data = tnl->vtx.copied.buffer; - GLuint i; - - /* Run pipeline on current vertices, copy wrapped vertices - * to tnl->copied. - */ - _tnl_wrap_buffers( ctx ); - - /* Copy stored stored vertices to start of new list. - */ - assert(tnl->vtx.counter > tnl->vtx.copied.nr); - - for (i = 0 ; i < tnl->vtx.copied.nr ; i++) { - _mesa_memcpy( tnl->vtx.vbptr, data, - tnl->vtx.vertex_size * sizeof(GLfloat)); - tnl->vtx.vbptr += tnl->vtx.vertex_size; - data += tnl->vtx.vertex_size; - tnl->vtx.counter--; - } - - tnl->vtx.copied.nr = 0; -} - - -/* - * Copy the active vertex's values to the ctx->Current fields. - */ -static void _tnl_copy_to_current( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint i; - - for (i = _TNL_ATTRIB_POS+1 ; i < _TNL_ATTRIB_EDGEFLAG ; i++) { - if (tnl->vtx.attrsz[i]) { - /* Note: the tnl->vtx.current[i] pointers points to - * the ctx->Current fields. The first 16 or so, anyway. - */ - COPY_CLEAN_4V(tnl->vtx.current[i], - tnl->vtx.attrsz[i], - tnl->vtx.attrptr[i]); - } - } - - /* Edgeflag requires additional treatment: - */ - if (tnl->vtx.attrsz[_TNL_ATTRIB_EDGEFLAG]) { - ctx->Current.EdgeFlag = - (tnl->vtx.CurrentFloatEdgeFlag == 1.0); - } - - /* Colormaterial -- this kindof sucks. - */ - if (ctx->Light.ColorMaterialEnabled) { - _mesa_update_color_material(ctx, - ctx->Current.Attrib[VERT_ATTRIB_COLOR0]); - } - - if (tnl->vtx.have_materials) { - tnl->Driver.NotifyMaterialChange( ctx ); - } - - ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT; -} - - -static void _tnl_copy_from_current( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLint i; - - /* Edgeflag requires additional treatment: - */ - tnl->vtx.CurrentFloatEdgeFlag = (GLfloat) ctx->Current.EdgeFlag; - - for (i = _TNL_ATTRIB_POS+1 ; i < _TNL_ATTRIB_MAX ; i++) - switch (tnl->vtx.attrsz[i]) { - case 4: tnl->vtx.attrptr[i][3] = tnl->vtx.current[i][3]; - case 3: tnl->vtx.attrptr[i][2] = tnl->vtx.current[i][2]; - case 2: tnl->vtx.attrptr[i][1] = tnl->vtx.current[i][1]; - case 1: tnl->vtx.attrptr[i][0] = tnl->vtx.current[i][0]; - break; - } - - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; -} - - -/* Flush existing data, set new attrib size, replay copied vertices. - */ -static void _tnl_wrap_upgrade_vertex( GLcontext *ctx, - GLuint attr, - GLuint newsz ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint oldsz; - GLuint i; - GLfloat *tmp; - GLint lastcount = tnl->vtx.initial_counter - tnl->vtx.counter; - - /* Run pipeline on current vertices, copy wrapped vertices - * to tnl->vtx.copied. - */ - _tnl_wrap_buffers( ctx ); - - - /* Do a COPY_TO_CURRENT to ensure back-copying works for the case - * when the attribute already exists in the vertex and is having - * its size increased. - */ - _tnl_copy_to_current( ctx ); - - - /* Heuristic: Attempt to isolate attributes received outside - * begin/end so that they don't bloat the vertices. - */ - if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END && - tnl->vtx.attrsz[attr] == 0 && - lastcount > 8 && - tnl->vtx.vertex_size) { - reset_attrfv( tnl ); - } - - /* Fix up sizes: - */ - oldsz = tnl->vtx.attrsz[attr]; - tnl->vtx.attrsz[attr] = newsz; - - tnl->vtx.vertex_size += newsz - oldsz; - tnl->vtx.counter = MIN2( VERT_BUFFER_SIZE / tnl->vtx.vertex_size, - ctx->Const.MaxArrayLockSize ); - tnl->vtx.initial_counter = tnl->vtx.counter; - tnl->vtx.vbptr = tnl->vtx.buffer; - - - /* Recalculate all the attrptr[] values - */ - for (i = 0, tmp = tnl->vtx.vertex ; i < _TNL_ATTRIB_MAX ; i++) { - if (tnl->vtx.attrsz[i]) { - tnl->vtx.attrptr[i] = tmp; - tmp += tnl->vtx.attrsz[i]; - } - else - tnl->vtx.attrptr[i] = NULL; /* will not be dereferenced */ - } - - /* Copy from current to repopulate the vertex with correct values. - */ - _tnl_copy_from_current( ctx ); - - /* Replay stored vertices to translate them - * to new format here. - * - * -- No need to replay - just copy piecewise - */ - if (tnl->vtx.copied.nr) - { - const GLfloat *data = tnl->vtx.copied.buffer; - GLfloat *dest = tnl->vtx.buffer; - GLuint j; - - for (i = 0 ; i < tnl->vtx.copied.nr ; i++) { - for (j = 0 ; j < _TNL_ATTRIB_MAX ; j++) { - if (tnl->vtx.attrsz[j]) { - if (j == attr) { - if (oldsz) { - COPY_CLEAN_4V( dest, oldsz, data ); - data += oldsz; - dest += newsz; - } else { - COPY_SZ_4V( dest, newsz, tnl->vtx.current[j] ); - dest += newsz; - } - } - else { - GLuint sz = tnl->vtx.attrsz[j]; - COPY_SZ_4V( dest, sz, data ); - dest += sz; - data += sz; - } - } - } - } - - tnl->vtx.vbptr = dest; - tnl->vtx.counter -= tnl->vtx.copied.nr; - tnl->vtx.copied.nr = 0; - } - - /* For codegen - attrptr's may have changed, so need to redo - * codegen. Might be a reasonable place to try & detect attributes - * in the vertex which aren't being submitted any more. - */ - for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) - if (tnl->vtx.attrsz[i]) { - GLuint j = tnl->vtx.attrsz[i] - 1; - - if (i < _TNL_MAX_ATTR_CODEGEN) - tnl->vtx.tabfv[i][j] = choose[i][j]; - } - -} - - -static void _tnl_fixup_vertex( GLcontext *ctx, GLuint attr, GLuint sz ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - static const GLfloat id[4] = { 0, 0, 0, 1 }; - int i; - - if (0) - _mesa_printf("%s attr %d sz %d -> %d\n", - __FUNCTION__, attr, tnl->vtx.attrsz[attr], sz); - - if (tnl->vtx.attrsz[attr] < sz) { - /* New size is larger. Need to flush existing vertices and get - * an enlarged vertex format. - */ - _tnl_wrap_upgrade_vertex( ctx, attr, sz ); - } - else if (sz < tnl->vtx.active_sz[attr]) { - /* New size is smaller - just need to fill in some - * zeros. Don't need to flush or wrap. - */ - for (i = sz ; i <= tnl->vtx.attrsz[attr] ; i++) - tnl->vtx.attrptr[attr][i-1] = id[i-1]; - } - - tnl->vtx.active_sz[attr] = sz; - - /* Does setting NeedFlush belong here? Necessitates resetting - * vtxfmt on each flush (otherwise flags won't get reset - * afterwards). - */ - if (attr == 0) - ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; - else - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; -} - -#ifdef USE_X86_ASM - -static struct _tnl_dynfn *lookup( struct _tnl_dynfn *l, GLuint key ) -{ - struct _tnl_dynfn *f; - - foreach( f, l ) { - if (f->key == key) - return f; - } - - return NULL; -} - - -static tnl_attrfv_func do_codegen( GLcontext *ctx, GLuint attr, GLuint sz ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct _tnl_dynfn *dfn = NULL; - - if (attr == 0) { - GLuint key = tnl->vtx.vertex_size; - - dfn = lookup( &tnl->vtx.cache.Vertex[sz-1], key ); - - if (!dfn) - dfn = tnl->vtx.gen.Vertex[sz-1]( ctx, key ); - } - else { - GLuint key = (GLuint) tnl->vtx.attrptr[attr]; - - dfn = lookup( &tnl->vtx.cache.Attribute[sz-1], key ); - - if (!dfn) - dfn = tnl->vtx.gen.Attribute[sz-1]( ctx, key ); - } - - if (dfn) - return *(tnl_attrfv_func *) &dfn->code; - else - return NULL; -} - -#endif /* USE_X86_ASM */ - -/* Helper function for 'CHOOSE' macro. Do what's necessary when an - * entrypoint is called for the first time. - */ - -static tnl_attrfv_func do_choose( GLuint attr, GLuint sz ) -{ - GET_CURRENT_CONTEXT( ctx ); - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint oldsz = tnl->vtx.active_sz[attr]; - - assert(attr < _TNL_MAX_ATTR_CODEGEN); - - if (oldsz != sz) { - /* Reset any active pointers for this attribute - */ - if (oldsz) - tnl->vtx.tabfv[attr][oldsz-1] = choose[attr][oldsz-1]; - - _tnl_fixup_vertex( ctx, attr, sz ); - - } - - - /* Try to use codegen: - */ -#ifdef USE_X86_ASM - if (tnl->AllowCodegen) - tnl->vtx.tabfv[attr][sz-1] = do_codegen( ctx, attr, sz ); - else -#endif - tnl->vtx.tabfv[attr][sz-1] = NULL; - - /* Else use generic version: - */ - if (!tnl->vtx.tabfv[attr][sz-1]) - tnl->vtx.tabfv[attr][sz-1] = generic_attr_func[attr][sz-1]; - - ASSERT(tnl->vtx.tabfv[attr][sz-1]); - return tnl->vtx.tabfv[attr][sz-1]; -} - - - -#define CHOOSE( ATTR, N ) \ -static void choose_##ATTR##_##N( const GLfloat *v ) \ -{ \ - tnl_attrfv_func f = do_choose(ATTR, N); \ - ASSERT(f); \ - f( v ); \ -} - -#define CHOOSERS( ATTRIB ) \ - CHOOSE( ATTRIB, 1 ) \ - CHOOSE( ATTRIB, 2 ) \ - CHOOSE( ATTRIB, 3 ) \ - CHOOSE( ATTRIB, 4 ) \ - - -#define INIT_CHOOSERS(ATTR) \ - ASSERT(ATTR <= _TNL_ATTRIB_ERROR);\ - choose[ATTR][0] = choose_##ATTR##_1; \ - choose[ATTR][1] = choose_##ATTR##_2; \ - choose[ATTR][2] = choose_##ATTR##_3; \ - choose[ATTR][3] = choose_##ATTR##_4; - -/* conventional attributes */ -CHOOSERS( 0 ) -CHOOSERS( 1 ) -CHOOSERS( 2 ) -CHOOSERS( 3 ) -CHOOSERS( 4 ) -CHOOSERS( 5 ) -CHOOSERS( 6 ) -CHOOSERS( 7 ) -CHOOSERS( 8 ) -CHOOSERS( 9 ) -CHOOSERS( 10 ) -CHOOSERS( 11 ) -CHOOSERS( 12 ) -CHOOSERS( 13 ) -CHOOSERS( 14 ) -CHOOSERS( 15 ) - -/* generic attributes */ -CHOOSERS( 16 ) -CHOOSERS( 17 ) -CHOOSERS( 18 ) -CHOOSERS( 19 ) -CHOOSERS( 20 ) -CHOOSERS( 21 ) -CHOOSERS( 22 ) -CHOOSERS( 23 ) -CHOOSERS( 24 ) -CHOOSERS( 25 ) -CHOOSERS( 26 ) -CHOOSERS( 27 ) -CHOOSERS( 28 ) -CHOOSERS( 29 ) -CHOOSERS( 30 ) -CHOOSERS( 31 ) - - -/** - * This function will get called when glVertexAttribNV/ARB() is called - * with an invalid index parameter. - */ -static void -error_attrib(const GLfloat *unused) -{ - GET_CURRENT_CONTEXT( ctx ); - (void) unused; - _mesa_error( ctx, GL_INVALID_VALUE, "glVertexAttrib(index)" ); -} - - - -/** - * Reset all the per-vertex functions pointers to point to the default - * "chooser" functions. - */ -static void -reset_attrfv(TNLcontext *tnl) -{ - GLuint i; - - for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) - if (tnl->vtx.attrsz[i]) { - GLint j = tnl->vtx.attrsz[i] - 1; - tnl->vtx.attrsz[i] = 0; - tnl->vtx.active_sz[i] = 0; - - if (i < _TNL_MAX_ATTR_CODEGEN) { - while (j >= 0) { - tnl->vtx.tabfv[i][j] = choose[i][j]; - j--; - } - } - } - - tnl->vtx.vertex_size = 0; - tnl->vtx.have_materials = 0; -} - - - -/** - * Materials: - * - * These are treated as per-vertex attributes, at indices above where - * the NV_vertex_program leaves off. There are a lot of good things - * about treating materials this way. - * - * However: I don't want to double the number of generated functions - * just to cope with this, so I unroll the 'C' varients of CHOOSE and - * ATTRF into this function, and dispense with codegen and - * second-level dispatch. - * - * There is no aliasing of material attributes with other entrypoints. - */ -#define OTHER_ATTR( A, N, params ) \ -do { \ - if (tnl->vtx.active_sz[A] != N) { \ - _tnl_fixup_vertex( ctx, A, N ); \ - } \ - \ - { \ - GLfloat *dest = tnl->vtx.attrptr[A]; \ - if (N>0) dest[0] = (params)[0]; \ - if (N>1) dest[1] = (params)[1]; \ - if (N>2) dest[2] = (params)[2]; \ - if (N>3) dest[3] = (params)[3]; \ - } \ -} while (0) - - -#define MAT( ATTR, N, face, params ) \ -do { \ - if (face != GL_BACK) \ - OTHER_ATTR( ATTR, N, params ); /* front */ \ - if (face != GL_FRONT) \ - OTHER_ATTR( ATTR + 1, N, params ); /* back */ \ -} while (0) - - -/** - * Called by glMaterialfv(). - * Colormaterial is dealt with later on. - */ -static void GLAPIENTRY -_tnl_Materialfv( GLenum face, GLenum pname, const GLfloat *params ) -{ - GET_CURRENT_CONTEXT( ctx ); - TNLcontext *tnl = TNL_CONTEXT(ctx); - - switch (face) { - case GL_FRONT: - case GL_BACK: - case GL_FRONT_AND_BACK: - break; - default: - _mesa_error( ctx, GL_INVALID_ENUM, "glMaterialfv" ); - return; - } - - switch (pname) { - case GL_EMISSION: - MAT( _TNL_ATTRIB_MAT_FRONT_EMISSION, 4, face, params ); - break; - case GL_AMBIENT: - MAT( _TNL_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params ); - break; - case GL_DIFFUSE: - MAT( _TNL_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params ); - break; - case GL_SPECULAR: - MAT( _TNL_ATTRIB_MAT_FRONT_SPECULAR, 4, face, params ); - break; - case GL_SHININESS: - MAT( _TNL_ATTRIB_MAT_FRONT_SHININESS, 1, face, params ); - break; - case GL_COLOR_INDEXES: - MAT( _TNL_ATTRIB_MAT_FRONT_INDEXES, 3, face, params ); - break; - case GL_AMBIENT_AND_DIFFUSE: - MAT( _TNL_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params ); - MAT( _TNL_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params ); - break; - default: - _mesa_error( ctx, GL_INVALID_ENUM, "glMaterialfv" ); - return; - } - - tnl->vtx.have_materials = GL_TRUE; -} - - -static void GLAPIENTRY _tnl_EdgeFlag( GLboolean b ) -{ - GET_CURRENT_CONTEXT( ctx ); - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLfloat f = (GLfloat)b; - - OTHER_ATTR( _TNL_ATTRIB_EDGEFLAG, 1, &f ); -} - - -/* Eval - */ -static void GLAPIENTRY _tnl_EvalCoord1f( GLfloat u ) -{ - GET_CURRENT_CONTEXT( ctx ); - TNLcontext *tnl = TNL_CONTEXT(ctx); - - /* TODO: use a CHOOSE() function for this: */ - { - GLint i; - if (tnl->vtx.eval.new_state) - _tnl_update_eval( ctx ); - - for (i = 0; i < _TNL_NUM_EVAL; i++) { - if (tnl->vtx.eval.map1[i].map) - if (tnl->vtx.active_sz[i] != tnl->vtx.eval.map1[i].sz) - _tnl_fixup_vertex( ctx, i, tnl->vtx.eval.map1[i].sz ); - } - } - - - _mesa_memcpy( tnl->vtx.copied.buffer, tnl->vtx.vertex, - tnl->vtx.vertex_size * sizeof(GLfloat)); - - _tnl_do_EvalCoord1f( ctx, u ); - - _mesa_memcpy( tnl->vtx.vertex, tnl->vtx.copied.buffer, - tnl->vtx.vertex_size * sizeof(GLfloat)); -} - -static void GLAPIENTRY _tnl_EvalCoord2f( GLfloat u, GLfloat v ) -{ - GET_CURRENT_CONTEXT( ctx ); - TNLcontext *tnl = TNL_CONTEXT(ctx); - - /* TODO: use a CHOOSE() function for this: */ - { - GLint i; - if (tnl->vtx.eval.new_state) - _tnl_update_eval( ctx ); - - for (i = 0; i < _TNL_NUM_EVAL; i++) { - if (tnl->vtx.eval.map2[i].map) - if (tnl->vtx.active_sz[i] != tnl->vtx.eval.map2[i].sz) - _tnl_fixup_vertex( ctx, i, tnl->vtx.eval.map2[i].sz ); - } - - if (ctx->Eval.AutoNormal) - if (tnl->vtx.active_sz[_TNL_ATTRIB_NORMAL] != 3) - _tnl_fixup_vertex( ctx, _TNL_ATTRIB_NORMAL, 3 ); - } - - _mesa_memcpy( tnl->vtx.copied.buffer, tnl->vtx.vertex, - tnl->vtx.vertex_size * sizeof(GLfloat)); - - _tnl_do_EvalCoord2f( ctx, u, v ); - - _mesa_memcpy( tnl->vtx.vertex, tnl->vtx.copied.buffer, - tnl->vtx.vertex_size * sizeof(GLfloat)); -} - -static void GLAPIENTRY _tnl_EvalCoord1fv( const GLfloat *u ) -{ - _tnl_EvalCoord1f( u[0] ); -} - -static void GLAPIENTRY _tnl_EvalCoord2fv( const GLfloat *u ) -{ - _tnl_EvalCoord2f( u[0], u[1] ); -} - -static void GLAPIENTRY _tnl_EvalPoint1( GLint i ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLfloat du = ((ctx->Eval.MapGrid1u2 - ctx->Eval.MapGrid1u1) / - (GLfloat) ctx->Eval.MapGrid1un); - GLfloat u = i * du + ctx->Eval.MapGrid1u1; - - _tnl_EvalCoord1f( u ); -} - - -static void GLAPIENTRY _tnl_EvalPoint2( GLint i, GLint j ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLfloat du = ((ctx->Eval.MapGrid2u2 - ctx->Eval.MapGrid2u1) / - (GLfloat) ctx->Eval.MapGrid2un); - GLfloat dv = ((ctx->Eval.MapGrid2v2 - ctx->Eval.MapGrid2v1) / - (GLfloat) ctx->Eval.MapGrid2vn); - GLfloat u = i * du + ctx->Eval.MapGrid2u1; - GLfloat v = j * dv + ctx->Eval.MapGrid2v1; - - _tnl_EvalCoord2f( u, v ); -} - - -/** - * Called from glBegin. - * ctx->Driver.CurrentExecPrimitive will be set to . - */ -static void GLAPIENTRY _tnl_Begin( GLenum mode ) -{ - GET_CURRENT_CONTEXT( ctx ); - - if (mode > GL_POLYGON) { - _mesa_error(ctx, GL_INVALID_ENUM, "glBegin(mode)"); - return; - } - - if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) { - /* we're not inside a glBegin/End pair */ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint i; - - 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)"); - tnl->DiscardPrimitive = GL_TRUE; - return; - } - - if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { - _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, - "glBegin(incomplete framebuffer)"); - tnl->DiscardPrimitive = GL_TRUE; - return; - } - - tnl->DiscardPrimitive = GL_FALSE; - - if (!(tnl->Driver.NotifyBegin && - tnl->Driver.NotifyBegin( ctx, mode ))) - CALL_Begin(ctx->Exec, (mode)); - return; - } - - /* Heuristic: attempt to isolate attributes occuring outside - * begin/end pairs. - */ - if (tnl->vtx.vertex_size && !tnl->vtx.attrsz[0]) - _tnl_FlushVertices( ctx, ~0 ); - - i = tnl->vtx.prim_count++; - tnl->vtx.prim[i].mode = mode | PRIM_BEGIN; - tnl->vtx.prim[i].start = tnl->vtx.initial_counter - tnl->vtx.counter; - tnl->vtx.prim[i].count = 0; - - ctx->Driver.CurrentExecPrimitive = mode; - } - else { - /* already inside glBegin/End */ - _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" ); - } -} - - -/** - * Called from glEnd. - */ -static void GLAPIENTRY _tnl_End( void ) -{ - GET_CURRENT_CONTEXT( ctx ); - - if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) { - /* closing an open glBegin primitive */ - TNLcontext *tnl = TNL_CONTEXT(ctx); - int idx = tnl->vtx.initial_counter - tnl->vtx.counter; - int i = tnl->vtx.prim_count - 1; - - tnl->vtx.prim[i].mode |= PRIM_END; - tnl->vtx.prim[i].count = idx - tnl->vtx.prim[i].start; - - ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; - - /* Two choices which effect the way vertex attributes are - * carried over (or not) between adjacent primitives. - */ -#if 0 - if (tnl->vtx.prim_count == TNL_MAX_PRIM) - _tnl_FlushVertices( ctx, ~0 ); -#else - if (tnl->vtx.prim_count == TNL_MAX_PRIM) - _tnl_flush_vtx( ctx ); -#endif - - } - else { - /* glBegin hasn't been called! */ - _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" ); - } -} - - -/** - * XXX why aren't all members initialized here?? - */ -static void _tnl_exec_vtxfmt_init( GLcontext *ctx ) -{ - GLvertexformat *vfmt = &(TNL_CONTEXT(ctx)->exec_vtxfmt); - - vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ - vfmt->Begin = _tnl_Begin; - vfmt->CallList = _mesa_CallList; - vfmt->CallLists = _mesa_CallLists; - vfmt->EdgeFlag = _tnl_EdgeFlag; - vfmt->End = _tnl_End; - vfmt->EvalCoord1f = _tnl_EvalCoord1f; - vfmt->EvalCoord1fv = _tnl_EvalCoord1fv; - vfmt->EvalCoord2f = _tnl_EvalCoord2f; - vfmt->EvalCoord2fv = _tnl_EvalCoord2fv; - vfmt->EvalPoint1 = _tnl_EvalPoint1; - vfmt->EvalPoint2 = _tnl_EvalPoint2; - vfmt->Materialfv = _tnl_Materialfv; - - vfmt->Rectf = _mesa_noop_Rectf; - vfmt->EvalMesh1 = _mesa_noop_EvalMesh1; - vfmt->EvalMesh2 = _mesa_noop_EvalMesh2; -} - - - -void _tnl_FlushVertices( GLcontext *ctx, GLuint flags ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - (void) flags; - - if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) { - /* still inside a glBegin/End pair. How'd we get here??? */ - return; - } - - if (tnl->DiscardPrimitive) { - /* discard any primitives */ - tnl->vtx.prim_count = 0; - tnl->vtx.counter = tnl->vtx.initial_counter; - tnl->vtx.vbptr = tnl->vtx.buffer; - } - - if (tnl->vtx.counter != tnl->vtx.initial_counter) { - _tnl_flush_vtx( ctx ); - } - - if (tnl->vtx.vertex_size) { - _tnl_copy_to_current( ctx ); - reset_attrfv( tnl ); - } - - ctx->Driver.NeedFlush = 0; -} - - -/** - * Init the tnl->vtx->current[] pointers to point to the corresponding - * fields in ctx->Current attribute group. - */ -static void _tnl_current_init( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLint i; - - /* setup the pointers for the typical (32) vertex attributes */ - for (i = 0; i < VERT_ATTRIB_MAX; i++) - tnl->vtx.current[i] = ctx->Current.Attrib[i]; - - /* setup pointers for the 12 material attributes */ - for (i = 0; i < MAT_ATTRIB_MAX; i++) - tnl->vtx.current[_TNL_ATTRIB_MAT_FRONT_AMBIENT + i] = - ctx->Light.Material.Attrib[i]; - - /* special case */ - tnl->vtx.current[_TNL_ATTRIB_EDGEFLAG] = &tnl->vtx.CurrentFloatEdgeFlag; -} - -static struct _tnl_dynfn *no_codegen( GLcontext *ctx, int key ) -{ - (void) ctx; (void) key; - return NULL; -} - -void _tnl_vtx_init( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct tnl_vertex_arrays *tmp = &tnl->vtx_inputs; - GLuint i; - static int firsttime = 1; - - if (firsttime) { - firsttime = 0; - - /* conventional attributes */ - INIT_CHOOSERS( 0 ); - INIT_CHOOSERS( 1 ); - INIT_CHOOSERS( 2 ); - INIT_CHOOSERS( 3 ); - INIT_CHOOSERS( 4 ); - INIT_CHOOSERS( 5 ); - INIT_CHOOSERS( 6 ); - INIT_CHOOSERS( 7 ); - INIT_CHOOSERS( 8 ); - INIT_CHOOSERS( 9 ); - INIT_CHOOSERS( 10 ); - INIT_CHOOSERS( 11 ); - INIT_CHOOSERS( 12 ); - INIT_CHOOSERS( 13 ); - INIT_CHOOSERS( 14 ); - INIT_CHOOSERS( 15 ); - - /* generic attributes */ - INIT_CHOOSERS( 16 ); - INIT_CHOOSERS( 17 ); - INIT_CHOOSERS( 18 ); - INIT_CHOOSERS( 19 ); - INIT_CHOOSERS( 20 ); - INIT_CHOOSERS( 21 ); - INIT_CHOOSERS( 22 ); - INIT_CHOOSERS( 23 ); - INIT_CHOOSERS( 24 ); - INIT_CHOOSERS( 25 ); - INIT_CHOOSERS( 26 ); - INIT_CHOOSERS( 27 ); - INIT_CHOOSERS( 28 ); - INIT_CHOOSERS( 29 ); - INIT_CHOOSERS( 30 ); - INIT_CHOOSERS( 31 ); - - choose[_TNL_ATTRIB_ERROR][0] = error_attrib; - choose[_TNL_ATTRIB_ERROR][1] = error_attrib; - choose[_TNL_ATTRIB_ERROR][2] = error_attrib; - choose[_TNL_ATTRIB_ERROR][3] = error_attrib; - -#ifdef USE_X86_ASM - if (tnl->AllowCodegen) { - _tnl_x86choosers(choose, do_choose); /* x86 INIT_CHOOSERS */ - } -#endif - - _tnl_generic_attr_table_init( generic_attr_func ); - } - - for (i = 0; i < _TNL_ATTRIB_EDGEFLAG; i++) - _mesa_vector4f_init( &tmp->Attribs[i], 0, NULL); - - for (i = 0; i < 4; i++) { - make_empty_list( &tnl->vtx.cache.Vertex[i] ); - make_empty_list( &tnl->vtx.cache.Attribute[i] ); - tnl->vtx.gen.Vertex[i] = no_codegen; - tnl->vtx.gen.Attribute[i] = no_codegen; - } - -#ifdef USE_X86_ASM - _tnl_InitX86Codegen( &tnl->vtx.gen ); -#endif - - _tnl_current_init( ctx ); - _tnl_exec_vtxfmt_init( ctx ); - _tnl_generic_exec_vtxfmt_init( ctx ); -#ifdef USE_X86_ASM - if (tnl->AllowCodegen) { - _tnl_x86_exec_vtxfmt_init( ctx ); /* x86 DISPATCH_ATTRFV */ - } -#endif - - _mesa_install_exec_vtxfmt( ctx, &tnl->exec_vtxfmt ); - - _mesa_memcpy( tnl->vtx.tabfv, choose, sizeof(choose) ); - - for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) { - tnl->vtx.attrsz[i] = 0; - tnl->vtx.active_sz[i] = 0; - } - - tnl->vtx.vertex_size = 0; - tnl->vtx.have_materials = 0; -} - -static void free_funcs( struct _tnl_dynfn *l ) -{ - struct _tnl_dynfn *f, *tmp; - foreach_s (f, tmp, l) { - remove_from_list( f ); - ALIGN_FREE( f->code ); - FREE( f ); - } -} - - -void _tnl_vtx_destroy( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint i; - - for (i = 0; i < 4; i++) { - free_funcs( &tnl->vtx.cache.Vertex[i] ); - free_funcs( &tnl->vtx.cache.Attribute[i] ); - } -} - diff --git a/src/mesa/tnl/t_vtx_api.h b/src/mesa/tnl/t_vtx_api.h deleted file mode 100644 index 5311f40a85..0000000000 --- a/src/mesa/tnl/t_vtx_api.h +++ /dev/null @@ -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 - * - */ - -#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 diff --git a/src/mesa/tnl/t_vtx_eval.c b/src/mesa/tnl/t_vtx_eval.c deleted file mode 100644 index 71564076e3..0000000000 --- a/src/mesa/tnl/t_vtx_eval.c +++ /dev/null @@ -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 - */ - -#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 )); - } -} - - diff --git a/src/mesa/tnl/t_vtx_exec.c b/src/mesa/tnl/t_vtx_exec.c deleted file mode 100644 index 57d842f05f..0000000000 --- a/src/mesa/tnl/t_vtx_exec.c +++ /dev/null @@ -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 - */ - -#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; -} diff --git a/src/mesa/tnl/t_vtx_generic.c b/src/mesa/tnl/t_vtx_generic.c deleted file mode 100644 index 28de445ed4..0000000000 --- a/src/mesa/tnl/t_vtx_generic.c +++ /dev/null @@ -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 - */ - -#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; -} diff --git a/src/mesa/tnl/t_vtx_x86.c b/src/mesa/tnl/t_vtx_x86.c deleted file mode 100644 index 99a0550932..0000000000 --- a/src/mesa/tnl/t_vtx_x86.c +++ /dev/null @@ -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 - * Daniel Borca - */ - - -#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 diff --git a/src/mesa/tnl/t_vtx_x86_gcc.S b/src/mesa/tnl/t_vtx_x86_gcc.S deleted file mode 100644 index 93753be759..0000000000 --- a/src/mesa/tnl/t_vtx_x86_gcc.S +++ /dev/null @@ -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 - * Daniel Borca - */ - -#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 diff --git a/src/mesa/tnl/tnl.h b/src/mesa/tnl/tnl.h index dab422429a..17cb30adc7 100644 --- a/src/mesa/tnl/tnl.h +++ b/src/mesa/tnl/tnl.h @@ -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 -- cgit v1.2.3 From 72b68455eb02460e2e9a64fff2448596a183923b Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 29 Oct 2006 09:48:36 +0000 Subject: remove this module --- src/mesa/array_cache/ac_context.c | 375 ---------------- src/mesa/array_cache/ac_context.h | 99 ---- src/mesa/array_cache/ac_import.c | 922 -------------------------------------- src/mesa/array_cache/acache.h | 132 ------ src/mesa/array_cache/descrip.mms | 37 -- src/mesa/array_cache/sources | 3 - 6 files changed, 1568 deletions(-) delete mode 100644 src/mesa/array_cache/ac_context.c delete mode 100644 src/mesa/array_cache/ac_context.h delete mode 100644 src/mesa/array_cache/ac_import.c delete mode 100644 src/mesa/array_cache/acache.h delete mode 100644 src/mesa/array_cache/descrip.mms delete mode 100644 src/mesa/array_cache/sources (limited to 'src') diff --git a/src/mesa/array_cache/ac_context.c b/src/mesa/array_cache/ac_context.c deleted file mode 100644 index 5d5ad5e363..0000000000 --- a/src/mesa/array_cache/ac_context.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 5.1 - * - * Copyright (C) 1999-2002 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 - */ - -#include "glheader.h" -#include "macros.h" -#include "imports.h" -#include "mtypes.h" - -#include "array_cache/ac_context.h" - - -/* - * Initialize the array fallbacks. That is, by default the fallback arrays - * point into the current vertex attribute values in ctx->Current.Attrib[] - */ -static void _ac_fallbacks_init( GLcontext *ctx ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - struct gl_client_array *cl; - GLuint i; - - cl = &ac->Fallback.Normal; - cl->Size = 3; - cl->Type = GL_FLOAT; - cl->Stride = 0; - cl->StrideB = 0; - cl->Ptr = (GLubyte *) ctx->Current.Attrib[VERT_ATTRIB_NORMAL]; - cl->Enabled = 1; - cl->Flags = CA_CLIENT_DATA; /* hack */ -#if FEATURE_ARB_vertex_buffer_object - cl->BufferObj = ctx->Array.NullBufferObj; -#endif - - cl = &ac->Fallback.Color; - cl->Size = 4; - cl->Type = GL_FLOAT; - cl->Stride = 0; - cl->StrideB = 0; - cl->Ptr = (GLubyte *) ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; - cl->Enabled = 1; - cl->Flags = CA_CLIENT_DATA; /* hack */ -#if FEATURE_ARB_vertex_buffer_object - cl->BufferObj = ctx->Array.NullBufferObj; -#endif - - cl = &ac->Fallback.SecondaryColor; - cl->Size = 3; - cl->Type = GL_FLOAT; - cl->Stride = 0; - cl->StrideB = 0; - cl->Ptr = (GLubyte *) ctx->Current.Attrib[VERT_ATTRIB_COLOR1]; - cl->Enabled = 1; - cl->Flags = CA_CLIENT_DATA; /* hack */ -#if FEATURE_ARB_vertex_buffer_object - cl->BufferObj = ctx->Array.NullBufferObj; -#endif - - cl = &ac->Fallback.FogCoord; - cl->Size = 1; - cl->Type = GL_FLOAT; - cl->Stride = 0; - cl->StrideB = 0; - cl->Ptr = (GLubyte *) &ctx->Current.Attrib[VERT_ATTRIB_FOG]; - cl->Enabled = 1; - cl->Flags = CA_CLIENT_DATA; /* hack */ -#if FEATURE_ARB_vertex_buffer_object - cl->BufferObj = ctx->Array.NullBufferObj; -#endif - - cl = &ac->Fallback.Index; - cl->Size = 1; - cl->Type = GL_FLOAT; - cl->Stride = 0; - cl->StrideB = 0; - cl->Ptr = (GLubyte *) &ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX]; - cl->Enabled = 1; - cl->Flags = CA_CLIENT_DATA; /* hack */ -#if FEATURE_ARB_vertex_buffer_object - cl->BufferObj = ctx->Array.NullBufferObj; -#endif - - for (i = 0 ; i < MAX_TEXTURE_COORD_UNITS ; i++) { - cl = &ac->Fallback.TexCoord[i]; - cl->Size = 4; - cl->Type = GL_FLOAT; - cl->Stride = 0; - cl->StrideB = 0; - cl->Ptr = (GLubyte *) ctx->Current.Attrib[VERT_ATTRIB_TEX0 + i]; - cl->Enabled = 1; - cl->Flags = CA_CLIENT_DATA; /* hack */ -#if FEATURE_ARB_vertex_buffer_object - cl->BufferObj = ctx->Array.NullBufferObj; -#endif - } - - cl = &ac->Fallback.EdgeFlag; - cl->Size = 1; - cl->Type = GL_UNSIGNED_BYTE; - cl->Stride = 0; - cl->StrideB = 0; - cl->Ptr = (GLubyte *) &ctx->Current.EdgeFlag; - cl->Enabled = 1; - cl->Flags = CA_CLIENT_DATA; /* hack */ -#if FEATURE_ARB_vertex_buffer_object - cl->BufferObj = ctx->Array.NullBufferObj; -#endif - - for (i = 0; i < VERT_ATTRIB_MAX; i++) { - cl = &ac->Fallback.Attrib[i]; - cl->Size = 4; - cl->Type = GL_FLOAT; - cl->Stride = 0; - cl->StrideB = 0; - cl->Ptr = (GLubyte *) ctx->Current.Attrib[i]; - cl->Enabled = 1; - cl->Flags = CA_CLIENT_DATA; /* hack */ -#if FEATURE_ARB_vertex_buffer_object - cl->BufferObj = ctx->Array.NullBufferObj; -#endif - } -} - - -/* - * Initialize the array cache pointers, types, strides, etc. - */ -static void _ac_cache_init( GLcontext *ctx ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - struct gl_client_array *cl; - GLuint size = ctx->Const.MaxArrayLockSize + MAX_CLIPPED_VERTICES; - GLuint i; - - cl = &ac->Cache.Vertex; - cl->Size = 4; - cl->Type = GL_FLOAT; - cl->Stride = 0; - cl->StrideB = 4 * sizeof(GLfloat); - cl->Ptr = (GLubyte *) MALLOC( cl->StrideB * size ); - cl->Enabled = 1; - cl->Flags = 0; -#if FEATURE_ARB_vertex_buffer_object - cl->BufferObj = ctx->Array.NullBufferObj; -#endif - - cl = &ac->Cache.Normal; - cl->Size = 3; - cl->Type = GL_FLOAT; - cl->Stride = 0; - cl->StrideB = 3 * sizeof(GLfloat); - cl->Ptr = (GLubyte *) MALLOC( cl->StrideB * size ); - cl->Enabled = 1; - cl->Flags = 0; -#if FEATURE_ARB_vertex_buffer_object - cl->BufferObj = ctx->Array.NullBufferObj; -#endif - - cl = &ac->Cache.Color; - cl->Size = 4; - cl->Type = GL_FLOAT; - cl->Stride = 0; - cl->StrideB = 4 * sizeof(GLfloat); - cl->Ptr = (GLubyte *) MALLOC( cl->StrideB * size ); - cl->Enabled = 1; - cl->Flags = 0; -#if FEATURE_ARB_vertex_buffer_object - cl->BufferObj = ctx->Array.NullBufferObj; -#endif - - cl = &ac->Cache.SecondaryColor; - cl->Size = 3; - cl->Type = GL_FLOAT; - cl->Stride = 0; - cl->StrideB = 4 * sizeof(GLfloat); - cl->Ptr = (GLubyte *) MALLOC( cl->StrideB * size ); - cl->Enabled = 1; - cl->Flags = 0; -#if FEATURE_ARB_vertex_buffer_object - cl->BufferObj = ctx->Array.NullBufferObj; -#endif - - cl = &ac->Cache.FogCoord; - cl->Size = 1; - cl->Type = GL_FLOAT; - cl->Stride = 0; - cl->StrideB = sizeof(GLfloat); - cl->Ptr = (GLubyte *) MALLOC( cl->StrideB * size ); - cl->Enabled = 1; - cl->Flags = 0; -#if FEATURE_ARB_vertex_buffer_object - cl->BufferObj = ctx->Array.NullBufferObj; -#endif - - cl = &ac->Cache.Index; - cl->Size = 1; - cl->Type = GL_FLOAT; - cl->Stride = 0; - cl->StrideB = sizeof(GLfloat); - cl->Ptr = (GLubyte *) MALLOC( cl->StrideB * size ); - cl->Enabled = 1; - cl->Flags = 0; -#if FEATURE_ARB_vertex_buffer_object - cl->BufferObj = ctx->Array.NullBufferObj; -#endif - - for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) { - cl = &ac->Cache.TexCoord[i]; - cl->Size = 4; - cl->Type = GL_FLOAT; - cl->Stride = 0; - cl->StrideB = 4 * sizeof(GLfloat); - cl->Ptr = (GLubyte *) MALLOC( cl->StrideB * size ); - cl->Enabled = 1; - cl->Flags = 0; -#if FEATURE_ARB_vertex_buffer_object - cl->BufferObj = ctx->Array.NullBufferObj; -#endif - } - - cl = &ac->Cache.EdgeFlag; - cl->Size = 1; - cl->Type = GL_UNSIGNED_BYTE; - cl->Stride = 0; - cl->StrideB = sizeof(GLubyte); - cl->Ptr = (GLubyte *) MALLOC( cl->StrideB * size ); - cl->Enabled = 1; - cl->Flags = 0; -#if FEATURE_ARB_vertex_buffer_object - cl->BufferObj = ctx->Array.NullBufferObj; -#endif - - for (i = 0 ; i < VERT_ATTRIB_MAX; i++) { - cl = &ac->Cache.Attrib[i]; - cl->Size = 4; - cl->Type = GL_FLOAT; - cl->Stride = 0; - cl->StrideB = 4 * sizeof(GLfloat); - cl->Ptr = (GLubyte *) MALLOC( cl->StrideB * size ); - cl->Enabled = 1; - cl->Flags = 0; -#if FEATURE_ARB_vertex_buffer_object - cl->BufferObj = ctx->Array.NullBufferObj; -#endif - } -} - - -/* This storage used to hold translated client data if type or stride - * need to be fixed. - */ -static void _ac_elts_init( GLcontext *ctx ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - GLuint size = 1000; - - ac->Elts = (GLuint *)MALLOC( sizeof(GLuint) * size ); - ac->elt_size = size; -} - -static void _ac_raw_init( GLcontext *ctx ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - GLuint i; - - ac->Raw.Color = ac->Fallback.Color; - ac->Raw.EdgeFlag = ac->Fallback.EdgeFlag; - ac->Raw.FogCoord = ac->Fallback.FogCoord; - ac->Raw.Index = ac->Fallback.Index; - ac->Raw.Normal = ac->Fallback.Normal; - ac->Raw.SecondaryColor = ac->Fallback.SecondaryColor; - ac->Raw.Vertex = ctx->Array.ArrayObj->Vertex; - - ac->IsCached.Color = GL_FALSE; - ac->IsCached.EdgeFlag = GL_FALSE; - ac->IsCached.FogCoord = GL_FALSE; - ac->IsCached.Index = GL_FALSE; - ac->IsCached.Normal = GL_FALSE; - ac->IsCached.SecondaryColor = GL_FALSE; - ac->IsCached.Vertex = GL_FALSE; - - for (i = 0 ; i < MAX_TEXTURE_COORD_UNITS ; i++) { - ac->Raw.TexCoord[i] = ac->Fallback.TexCoord[i]; - ac->IsCached.TexCoord[i] = GL_FALSE; - } - - for (i = 0 ; i < VERT_ATTRIB_MAX ; i++) { - ac->Raw.Attrib[i] = ac->Fallback.Attrib[i]; - ac->IsCached.Attrib[i] = GL_FALSE; - } -} - -GLboolean _ac_CreateContext( GLcontext *ctx ) -{ - ctx->acache_context = CALLOC(sizeof(ACcontext)); - if (ctx->acache_context) { - _ac_cache_init( ctx ); - _ac_fallbacks_init( ctx ); - _ac_raw_init( ctx ); - _ac_elts_init( ctx ); - return GL_TRUE; - } - return GL_FALSE; -} - -void _ac_DestroyContext( GLcontext *ctx ) -{ - struct gl_buffer_object *nullObj = ctx->Array.NullBufferObj; - ACcontext *ac = AC_CONTEXT(ctx); - GLint i; - - /* only free vertex data if it's really a pointer to vertex data and - * not an offset into a buffer object. - */ - if (ac->Cache.Vertex.Ptr && ac->Cache.Vertex.BufferObj == nullObj) - FREE( (void *) ac->Cache.Vertex.Ptr ); - if (ac->Cache.Normal.Ptr && ac->Cache.Normal.BufferObj == nullObj) - FREE( (void *) ac->Cache.Normal.Ptr ); - if (ac->Cache.Color.Ptr && ac->Cache.Color.BufferObj == nullObj) - FREE( (void *) ac->Cache.Color.Ptr ); - if (ac->Cache.SecondaryColor.Ptr && ac->Cache.SecondaryColor.BufferObj == nullObj) - FREE( (void *) ac->Cache.SecondaryColor.Ptr ); - if (ac->Cache.EdgeFlag.Ptr && ac->Cache.EdgeFlag.BufferObj == nullObj) - FREE( (void *) ac->Cache.EdgeFlag.Ptr ); - if (ac->Cache.Index.Ptr && ac->Cache.Index.BufferObj == nullObj) - FREE( (void *) ac->Cache.Index.Ptr ); - if (ac->Cache.FogCoord.Ptr && ac->Cache.FogCoord.BufferObj == nullObj) - FREE( (void *) ac->Cache.FogCoord.Ptr ); - - for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) { - if (ac->Cache.TexCoord[i].Ptr && ac->Cache.TexCoord[i].BufferObj == nullObj) - FREE( (void *) ac->Cache.TexCoord[i].Ptr ); - } - - for (i = 0; i < VERT_ATTRIB_MAX; i++) { - if (ac->Cache.Attrib[i].Ptr && ac->Cache.Attrib[i].BufferObj == nullObj) - FREE( (void *) ac->Cache.Attrib[i].Ptr ); - } - - if (ac->Elts) - FREE( ac->Elts ); - - /* Free the context structure itself */ - FREE(ac); - ctx->acache_context = NULL; -} - -void _ac_InvalidateState( GLcontext *ctx, GLuint new_state ) -{ - AC_CONTEXT(ctx)->NewState |= new_state; - AC_CONTEXT(ctx)->NewArrayState |= ctx->Array.NewState; -} diff --git a/src/mesa/array_cache/ac_context.h b/src/mesa/array_cache/ac_context.h deleted file mode 100644 index 36aded3152..0000000000 --- a/src/mesa/array_cache/ac_context.h +++ /dev/null @@ -1,99 +0,0 @@ - -/* - * Mesa 3-D graphics library - * Version: 5.1 - * - * Copyright (C) 1999-2002 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 - */ - -#ifndef _AC_CONTEXT_H -#define _AC_CONTEXT_H - -#include "glheader.h" -#include "mtypes.h" - -#include "array_cache/acache.h" - -/* These are used to make the ctx->Current values look like - * arrays (with zero StrideB). - */ -struct ac_arrays { - struct gl_client_array Vertex; - struct gl_client_array Normal; - struct gl_client_array Color; - struct gl_client_array SecondaryColor; - struct gl_client_array FogCoord; - struct gl_client_array Index; - struct gl_client_array TexCoord[MAX_TEXTURE_COORD_UNITS]; - struct gl_client_array EdgeFlag; - struct gl_client_array Attrib[VERT_ATTRIB_MAX]; /* GL_NV_vertex_program */ -}; - -struct ac_array_pointers { - struct gl_client_array *Vertex; - struct gl_client_array *Normal; - struct gl_client_array *Color; - struct gl_client_array *SecondaryColor; - struct gl_client_array *FogCoord; - struct gl_client_array *Index; - struct gl_client_array *TexCoord[MAX_TEXTURE_COORD_UNITS]; - struct gl_client_array *EdgeFlag; - struct gl_client_array *Attrib[VERT_ATTRIB_MAX]; /* GL_NV_vertex_program */ -}; - -struct ac_array_flags { - GLboolean Vertex; - GLboolean Normal; - GLboolean Color; - GLboolean SecondaryColor; - GLboolean FogCoord; - GLboolean Index; - GLboolean TexCoord[MAX_TEXTURE_COORD_UNITS]; - GLboolean EdgeFlag; - GLboolean Attrib[VERT_ATTRIB_MAX]; /* GL_NV_vertex_program */ -}; - - -typedef struct { - GLuint NewState; /* not needed? */ - GLuint NewArrayState; - - /* Facility for importing and caching array data: - */ - struct ac_arrays Fallback; - struct ac_arrays Cache; - struct ac_arrays Raw; - struct ac_array_flags IsCached; - GLuint start; - GLuint count; - - /* Facility for importing element lists: - */ - GLuint *Elts; - GLuint elt_size; - -} ACcontext; - -#define AC_CONTEXT(ctx) ((ACcontext *)ctx->acache_context) - -#endif diff --git a/src/mesa/array_cache/ac_import.c b/src/mesa/array_cache/ac_import.c deleted file mode 100644 index 119e58bf24..0000000000 --- a/src/mesa/array_cache/ac_import.c +++ /dev/null @@ -1,922 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * 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 - */ - -#include "glheader.h" -#include "macros.h" -#include "imports.h" -#include "mtypes.h" - -#include "math/m_translate.h" -#include "array_cache/ac_context.h" -#include "math/m_translate.h" - -#define STRIDE_ARRAY( array, offset ) \ -do { \ - GLubyte *tmp = ADD_POINTERS( (array).BufferObj->Data, (array).Ptr ) \ - + (offset) * (array).StrideB; \ - (array).Ptr = tmp; \ -} while (0) - - -/* Set the array pointer back to its source when the cached data is - * invalidated: - */ -static void -reset_texcoord( GLcontext *ctx, GLuint unit ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - - if (ctx->Array.ArrayObj->TexCoord[unit].Enabled) { - ac->Raw.TexCoord[unit] = ctx->Array.ArrayObj->TexCoord[unit]; - STRIDE_ARRAY(ac->Raw.TexCoord[unit], ac->start); - } - else { - ac->Raw.TexCoord[unit] = ac->Fallback.TexCoord[unit]; - - if (ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][3] != 1.0) - ac->Raw.TexCoord[unit].Size = 4; - else if (ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][2] != 0.0) - ac->Raw.TexCoord[unit].Size = 3; - else - ac->Raw.TexCoord[unit].Size = 2; - } - - ac->IsCached.TexCoord[unit] = GL_FALSE; - ac->NewArrayState &= ~_NEW_ARRAY_TEXCOORD(unit); -} - -static void -reset_vertex( GLcontext *ctx ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - ASSERT(ctx->Array.ArrayObj->Vertex.Enabled - || (ctx->VertexProgram._Enabled && ctx->Array.ArrayObj->VertexAttrib[0].Enabled)); - ac->Raw.Vertex = ctx->Array.ArrayObj->Vertex; - STRIDE_ARRAY(ac->Raw.Vertex, ac->start); - ac->IsCached.Vertex = GL_FALSE; - ac->NewArrayState &= ~_NEW_ARRAY_VERTEX; -} - - -static void -reset_normal( GLcontext *ctx ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - - if (ctx->Array.ArrayObj->Normal.Enabled) { - ac->Raw.Normal = ctx->Array.ArrayObj->Normal; - STRIDE_ARRAY(ac->Raw.Normal, ac->start); - } - else { - ac->Raw.Normal = ac->Fallback.Normal; - } - - ac->IsCached.Normal = GL_FALSE; - ac->NewArrayState &= ~_NEW_ARRAY_NORMAL; -} - - -static void -reset_color( GLcontext *ctx ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - - if (ctx->Array.ArrayObj->Color.Enabled) { - ac->Raw.Color = ctx->Array.ArrayObj->Color; - STRIDE_ARRAY(ac->Raw.Color, ac->start); - } - else - ac->Raw.Color = ac->Fallback.Color; - - ac->IsCached.Color = GL_FALSE; - ac->NewArrayState &= ~_NEW_ARRAY_COLOR0; -} - - -static void -reset_secondarycolor( GLcontext *ctx ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - - if (ctx->Array.ArrayObj->SecondaryColor.Enabled) { - ac->Raw.SecondaryColor = ctx->Array.ArrayObj->SecondaryColor; - STRIDE_ARRAY(ac->Raw.SecondaryColor, ac->start); - } - else - ac->Raw.SecondaryColor = ac->Fallback.SecondaryColor; - - ac->IsCached.SecondaryColor = GL_FALSE; - ac->NewArrayState &= ~_NEW_ARRAY_COLOR1; -} - - -static void -reset_index( GLcontext *ctx ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - - if (ctx->Array.ArrayObj->Index.Enabled) { - ac->Raw.Index = ctx->Array.ArrayObj->Index; - STRIDE_ARRAY(ac->Raw.Index, ac->start); - } - else - ac->Raw.Index = ac->Fallback.Index; - - ac->IsCached.Index = GL_FALSE; - ac->NewArrayState &= ~_NEW_ARRAY_INDEX; -} - - -static void -reset_fogcoord( GLcontext *ctx ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - - if (ctx->Array.ArrayObj->FogCoord.Enabled) { - ac->Raw.FogCoord = ctx->Array.ArrayObj->FogCoord; - STRIDE_ARRAY(ac->Raw.FogCoord, ac->start); - } - else - ac->Raw.FogCoord = ac->Fallback.FogCoord; - - ac->IsCached.FogCoord = GL_FALSE; - ac->NewArrayState &= ~_NEW_ARRAY_FOGCOORD; -} - - -static void -reset_edgeflag( GLcontext *ctx ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - - if (ctx->Array.ArrayObj->EdgeFlag.Enabled) { - ac->Raw.EdgeFlag = ctx->Array.ArrayObj->EdgeFlag; - STRIDE_ARRAY(ac->Raw.EdgeFlag, ac->start); - } - else - ac->Raw.EdgeFlag = ac->Fallback.EdgeFlag; - - ac->IsCached.EdgeFlag = GL_FALSE; - ac->NewArrayState &= ~_NEW_ARRAY_EDGEFLAG; -} - - -/** - * \param index the generic vertex array number. - */ -static void -reset_attrib( GLcontext *ctx, GLuint index ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - - if (ctx->Array.ArrayObj->VertexAttrib[index].Enabled) { - ac->Raw.Attrib[index] = ctx->Array.ArrayObj->VertexAttrib[index]; - STRIDE_ARRAY(ac->Raw.Attrib[index], ac->start); - } - else - ac->Raw.Attrib[index] = ac->Fallback.Attrib[index]; - - ac->IsCached.Attrib[index] = GL_FALSE; - ac->NewArrayState &= ~_NEW_ARRAY_ATTRIB(index); -} - - -/** - * Generic import function for color data - */ -static void -import( const GLcontext *ctx, - GLenum destType, - struct gl_client_array *to, - const struct gl_client_array *from ) -{ - const ACcontext *ac = AC_CONTEXT(ctx); - - if (destType == 0) - destType = from->Type; - - switch (destType) { - case GL_FLOAT: - _math_trans_4fn( (GLfloat (*)[4]) to->Ptr, - from->Ptr, - from->StrideB, - from->Type, - from->Size, - 0, - ac->count - ac->start); - - to->StrideB = 4 * sizeof(GLfloat); - to->Type = GL_FLOAT; - break; - - case GL_UNSIGNED_BYTE: - _math_trans_4ub( (GLubyte (*)[4]) to->Ptr, - from->Ptr, - from->StrideB, - from->Type, - from->Size, - 0, - ac->count - ac->start); - - to->StrideB = 4 * sizeof(GLubyte); - to->Type = GL_UNSIGNED_BYTE; - break; - - case GL_UNSIGNED_SHORT: - _math_trans_4us( (GLushort (*)[4]) to->Ptr, - from->Ptr, - from->StrideB, - from->Type, - from->Size, - 0, - ac->count - ac->start); - - to->StrideB = 4 * sizeof(GLushort); - to->Type = GL_UNSIGNED_SHORT; - break; - - default: - _mesa_problem(ctx, "Unexpected dest format in import()"); - break; - } -} - - - -/* - * Functions to import array ranges with specified types and strides. - * For example, if the vertex data is GLshort[2] and we want GLfloat[3] - * we'll use an import function to do the data conversion. - */ - -static void -import_texcoord( GLcontext *ctx, GLuint unit, GLenum type, GLuint stride ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - const struct gl_client_array *from = &ac->Raw.TexCoord[unit]; - struct gl_client_array *to = &ac->Cache.TexCoord[unit]; - (void) type; (void) stride; - - ASSERT(unit < ctx->Const.MaxTextureCoordUnits); - - /* Limited choices at this stage: - */ - ASSERT(type == GL_FLOAT); - ASSERT(stride == 4*sizeof(GLfloat) || stride == 0); - ASSERT(ac->count - ac->start < ctx->Const.MaxArrayLockSize); - - _math_trans_4f( (GLfloat (*)[4]) to->Ptr, - from->Ptr, - from->StrideB, - from->Type, - from->Size, - 0, - ac->count - ac->start); - - to->Size = from->Size; - to->StrideB = 4 * sizeof(GLfloat); - to->Type = GL_FLOAT; - ac->IsCached.TexCoord[unit] = GL_TRUE; -} - -static void -import_vertex( GLcontext *ctx, GLenum type, GLuint stride ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - const struct gl_client_array *from = &ac->Raw.Vertex; - struct gl_client_array *to = &ac->Cache.Vertex; - (void) type; (void) stride; - - /* Limited choices at this stage: - */ - ASSERT(type == GL_FLOAT); - ASSERT(stride == 4*sizeof(GLfloat) || stride == 0); - - _math_trans_4f( (GLfloat (*)[4]) to->Ptr, - from->Ptr, - from->StrideB, - from->Type, - from->Size, - 0, - ac->count - ac->start); - - to->Size = from->Size; - to->StrideB = 4 * sizeof(GLfloat); - to->Type = GL_FLOAT; - ac->IsCached.Vertex = GL_TRUE; -} - -static void -import_normal( GLcontext *ctx, GLenum type, GLuint stride ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - const struct gl_client_array *from = &ac->Raw.Normal; - struct gl_client_array *to = &ac->Cache.Normal; - (void) type; (void) stride; - - /* Limited choices at this stage: - */ - ASSERT(type == GL_FLOAT); - ASSERT(stride == 3*sizeof(GLfloat) || stride == 0); - - _math_trans_3fn((GLfloat (*)[3]) to->Ptr, - from->Ptr, - from->StrideB, - from->Type, - 0, - ac->count - ac->start); - - to->StrideB = 3 * sizeof(GLfloat); - to->Type = GL_FLOAT; - ac->IsCached.Normal = GL_TRUE; -} - -static void -import_color( GLcontext *ctx, GLenum type, GLuint stride ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - const struct gl_client_array *from = &ac->Raw.Color; - struct gl_client_array *to = &ac->Cache.Color; - (void) stride; - - import( ctx, type, to, from ); - - ac->IsCached.Color = GL_TRUE; -} - -static void -import_index( GLcontext *ctx, GLenum type, GLuint stride ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - const struct gl_client_array *from = &ac->Raw.Index; - struct gl_client_array *to = &ac->Cache.Index; - (void) type; (void) stride; - - /* Limited choices at this stage: - */ - ASSERT(type == GL_UNSIGNED_INT); - ASSERT(stride == sizeof(GLuint) || stride == 0); - - _math_trans_1ui( (GLuint *) to->Ptr, - from->Ptr, - from->StrideB, - from->Type, - 0, - ac->count - ac->start); - - to->StrideB = sizeof(GLuint); - to->Type = GL_UNSIGNED_INT; - ac->IsCached.Index = GL_TRUE; -} - -static void -import_secondarycolor( GLcontext *ctx, GLenum type, GLuint stride ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - const struct gl_client_array *from = &ac->Raw.SecondaryColor; - struct gl_client_array *to = &ac->Cache.SecondaryColor; - (void) stride; - - import( ctx, type, to, from ); - - ac->IsCached.SecondaryColor = GL_TRUE; -} - -static void -import_fogcoord( GLcontext *ctx, GLenum type, GLuint stride ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - const struct gl_client_array *from = &ac->Raw.FogCoord; - struct gl_client_array *to = &ac->Cache.FogCoord; - (void) type; (void) stride; - - /* Limited choices at this stage: - */ - ASSERT(type == GL_FLOAT); - ASSERT(stride == sizeof(GLfloat) || stride == 0); - - _math_trans_1f( (GLfloat *) to->Ptr, - from->Ptr, - from->StrideB, - from->Type, - 0, - ac->count - ac->start); - - to->StrideB = sizeof(GLfloat); - to->Type = GL_FLOAT; - ac->IsCached.FogCoord = GL_TRUE; -} - -static void -import_edgeflag( GLcontext *ctx, GLenum type, GLuint stride ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - const struct gl_client_array *from = &ac->Raw.EdgeFlag; - struct gl_client_array *to = &ac->Cache.EdgeFlag; - (void) type; (void) stride; - - /* Limited choices at this stage: - */ - ASSERT(type == GL_UNSIGNED_BYTE); - ASSERT(stride == sizeof(GLubyte) || stride == 0); - - _math_trans_1ub( (GLubyte *) to->Ptr, - from->Ptr, - from->StrideB, - from->Type, - 0, - ac->count - ac->start); - - to->StrideB = sizeof(GLubyte); - to->Type = GL_UNSIGNED_BYTE; - ac->IsCached.EdgeFlag = GL_TRUE; -} - -/** - * \param index the generic vertex array number - */ -static void -import_attrib( GLcontext *ctx, GLuint index, GLenum type, GLuint stride ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - const struct gl_client_array *from = &ac->Raw.Attrib[index]; - struct gl_client_array *to = &ac->Cache.Attrib[index]; - (void) type; (void) stride; - - ASSERT(index < MAX_VERTEX_PROGRAM_ATTRIBS); - - /* Limited choices at this stage: - */ - ASSERT(type == GL_FLOAT); - ASSERT(stride == 4*sizeof(GLfloat) || stride == 0); - ASSERT(ac->count - ac->start < ctx->Const.MaxArrayLockSize); - - if (from->Normalized) { - _math_trans_4fn( (GLfloat (*)[4]) to->Ptr, - from->Ptr, - from->StrideB, - from->Type, - from->Size, - 0, - ac->count - ac->start); - } - else { - _math_trans_4f( (GLfloat (*)[4]) to->Ptr, - from->Ptr, - from->StrideB, - from->Type, - from->Size, - 0, - ac->count - ac->start); - } - - to->Size = from->Size; - to->StrideB = 4 * sizeof(GLfloat); - to->Type = GL_FLOAT; - ac->IsCached.Attrib[index] = GL_TRUE; -} - - - -/* - * Externals to request arrays with specific properties: - */ - - -struct gl_client_array * -_ac_import_texcoord( GLcontext *ctx, - GLuint unit, - GLenum type, - GLuint reqstride, - GLuint reqsize, - GLboolean reqwriteable, - GLboolean *writeable ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - - ASSERT(unit < MAX_TEXTURE_COORD_UNITS); - - /* Can we keep the existing version? - */ - if (ac->NewArrayState & _NEW_ARRAY_TEXCOORD(unit)) - reset_texcoord( ctx, unit ); - - /* Is the request impossible? - */ - if (reqsize != 0 && ac->Raw.TexCoord[unit].Size > (GLint) reqsize) - return NULL; - - /* Do we need to pull in a copy of the client data: - */ - if (ac->Raw.TexCoord[unit].Type != type || - (reqstride != 0 && ac->Raw.TexCoord[unit].StrideB != (GLint)reqstride) || - reqwriteable) - { - if (!ac->IsCached.TexCoord[unit]) - import_texcoord(ctx, unit, type, reqstride ); - *writeable = GL_TRUE; - return &ac->Cache.TexCoord[unit]; - } - else { - *writeable = GL_FALSE; - return &ac->Raw.TexCoord[unit]; - } -} - -struct gl_client_array * -_ac_import_vertex( GLcontext *ctx, - GLenum type, - GLuint reqstride, - GLuint reqsize, - GLboolean reqwriteable, - GLboolean *writeable ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - - /* Can we keep the existing version? - */ - if (ac->NewArrayState & _NEW_ARRAY_VERTEX) - reset_vertex( ctx ); - - /* Is the request impossible? - */ - if (reqsize != 0 && ac->Raw.Vertex.Size > (GLint) reqsize) - return NULL; - - /* Do we need to pull in a copy of the client data: - */ - if (ac->Raw.Vertex.Type != type || - (reqstride != 0 && ac->Raw.Vertex.StrideB != (GLint) reqstride) || - reqwriteable) - { - if (!ac->IsCached.Vertex) - import_vertex(ctx, type, reqstride ); - *writeable = GL_TRUE; - return &ac->Cache.Vertex; - } - else { - *writeable = GL_FALSE; - return &ac->Raw.Vertex; - } -} - -struct gl_client_array * -_ac_import_normal( GLcontext *ctx, - GLenum type, - GLuint reqstride, - GLboolean reqwriteable, - GLboolean *writeable ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - - /* Can we keep the existing version? - */ - if (ac->NewArrayState & _NEW_ARRAY_NORMAL) - reset_normal( ctx ); - - /* Do we need to pull in a copy of the client data: - */ - if (ac->Raw.Normal.Type != type || - (reqstride != 0 && ac->Raw.Normal.StrideB != (GLint) reqstride) || - reqwriteable) - { - if (!ac->IsCached.Normal) - import_normal(ctx, type, reqstride ); - *writeable = GL_TRUE; - return &ac->Cache.Normal; - } - else { - *writeable = GL_FALSE; - return &ac->Raw.Normal; - } -} - -struct gl_client_array * -_ac_import_color( GLcontext *ctx, - GLenum type, - GLuint reqstride, - GLuint reqsize, - GLboolean reqwriteable, - GLboolean *writeable ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - - /* Can we keep the existing version? - */ - if (ac->NewArrayState & _NEW_ARRAY_COLOR0) - reset_color( ctx ); - - /* Is the request impossible? - */ - if (reqsize != 0 && ac->Raw.Color.Size > (GLint) reqsize) { - return NULL; - } - - /* Do we need to pull in a copy of the client data: - */ - if ((type != 0 && ac->Raw.Color.Type != type) || - (reqstride != 0 && ac->Raw.Color.StrideB != (GLint) reqstride) || - reqwriteable) - { - if (!ac->IsCached.Color) { - import_color(ctx, type, reqstride ); - } - *writeable = GL_TRUE; - return &ac->Cache.Color; - } - else { - *writeable = GL_FALSE; - return &ac->Raw.Color; - } -} - -struct gl_client_array * -_ac_import_index( GLcontext *ctx, - GLenum type, - GLuint reqstride, - GLboolean reqwriteable, - GLboolean *writeable ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - - /* Can we keep the existing version? - */ - if (ac->NewArrayState & _NEW_ARRAY_INDEX) - reset_index( ctx ); - - - /* Do we need to pull in a copy of the client data: - */ - if (ac->Raw.Index.Type != type || - (reqstride != 0 && ac->Raw.Index.StrideB != (GLint) reqstride) || - reqwriteable) - { - if (!ac->IsCached.Index) - import_index(ctx, type, reqstride ); - *writeable = GL_TRUE; - return &ac->Cache.Index; - } - else { - *writeable = GL_FALSE; - return &ac->Raw.Index; - } -} - -struct gl_client_array * -_ac_import_secondarycolor( GLcontext *ctx, - GLenum type, - GLuint reqstride, - GLuint reqsize, - GLboolean reqwriteable, - GLboolean *writeable ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - - /* Can we keep the existing version? - */ - if (ac->NewArrayState & _NEW_ARRAY_COLOR1) - reset_secondarycolor( ctx ); - - /* Is the request impossible? - */ - if (reqsize != 0 && ac->Raw.SecondaryColor.Size > (GLint) reqsize) - return NULL; - - /* Do we need to pull in a copy of the client data: - */ - if ((type != 0 && ac->Raw.SecondaryColor.Type != type) || - (reqstride != 0 && ac->Raw.SecondaryColor.StrideB != (GLint)reqstride) || - reqwriteable) - { - if (!ac->IsCached.SecondaryColor) - import_secondarycolor(ctx, type, reqstride ); - *writeable = GL_TRUE; - return &ac->Cache.SecondaryColor; - } - else { - *writeable = GL_FALSE; - return &ac->Raw.SecondaryColor; - } -} - -struct gl_client_array * -_ac_import_fogcoord( GLcontext *ctx, - GLenum type, - GLuint reqstride, - GLboolean reqwriteable, - GLboolean *writeable ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - - /* Can we keep the existing version? - */ - if (ac->NewArrayState & _NEW_ARRAY_FOGCOORD) - reset_fogcoord( ctx ); - - /* Do we need to pull in a copy of the client data: - */ - if (ac->Raw.FogCoord.Type != type || - (reqstride != 0 && ac->Raw.FogCoord.StrideB != (GLint) reqstride) || - reqwriteable) - { - if (!ac->IsCached.FogCoord) - import_fogcoord(ctx, type, reqstride ); - *writeable = GL_TRUE; - return &ac->Cache.FogCoord; - } - else { - *writeable = GL_FALSE; - return &ac->Raw.FogCoord; - } -} - -struct gl_client_array * -_ac_import_edgeflag( GLcontext *ctx, - GLenum type, - GLuint reqstride, - GLboolean reqwriteable, - GLboolean *writeable ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - - /* Can we keep the existing version? - */ - if (ac->NewArrayState & _NEW_ARRAY_EDGEFLAG) - reset_edgeflag( ctx ); - - /* Do we need to pull in a copy of the client data: - */ - if (ac->Raw.EdgeFlag.Type != type || - (reqstride != 0 && ac->Raw.EdgeFlag.StrideB != (GLint) reqstride) || - reqwriteable) - { - if (!ac->IsCached.EdgeFlag) - import_edgeflag(ctx, type, reqstride ); - *writeable = GL_TRUE; - return &ac->Cache.EdgeFlag; - } - else { - *writeable = GL_FALSE; - return &ac->Raw.EdgeFlag; - } -} - -/** - * For GL_ARB/NV_vertex_program - * \param index index of the vertex array, starting at zero. - */ -struct gl_client_array * -_ac_import_attrib( GLcontext *ctx, - GLuint index, - GLenum type, - GLuint reqstride, - GLuint reqsize, - GLboolean reqwriteable, - GLboolean *writeable ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - - ASSERT(index < VERT_ATTRIB_MAX); - - /* Can we keep the existing version? - */ - if (ac->NewArrayState & _NEW_ARRAY_ATTRIB(index)) - reset_attrib( ctx, index ); - - /* Is the request impossible? - */ - if (reqsize != 0 && ac->Raw.Attrib[index].Size > (GLint) reqsize) - return NULL; - - /* Do we need to pull in a copy of the client data: - */ - if (ac->Raw.Attrib[index].Type != type || - (reqstride != 0 && ac->Raw.Attrib[index].StrideB != (GLint)reqstride) || - reqwriteable) - { - if (!ac->IsCached.Attrib[index]) - import_attrib(ctx, index, type, reqstride ); - *writeable = GL_TRUE; - return &ac->Cache.Attrib[index]; - } - else { - *writeable = GL_FALSE; - return &ac->Raw.Attrib[index]; - } -} - - -/* Clients must call this function to validate state and set bounds - * before importing any data: - */ -void -_ac_import_range( GLcontext *ctx, GLuint start, GLuint count ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - - if (!ctx->Array.LockCount) { - /* Not locked, discard cached data. Changes to lock - * status are caught via. _ac_invalidate_state(). - */ - ac->NewArrayState = _NEW_ARRAY_ALL; - ac->start = start; - ac->count = count; - } - else { - /* Locked, discard data for any disabled arrays. Require that - * the whole locked range always be dealt with, otherwise hard to - * maintain cached data in the face of clipping. - */ - ac->NewArrayState |= ~ctx->Array.ArrayObj->_Enabled; - ac->start = ctx->Array.LockFirst; - ac->count = ctx->Array.LockCount; - ASSERT(ac->start == start); /* hmm? */ - ASSERT(ac->count == count); - } -} - - - -/* Additional convienence function for importing the element list - * for glDrawElements() and glDrawRangeElements(). - */ -CONST void * -_ac_import_elements( GLcontext *ctx, - GLenum new_type, - GLuint count, - GLenum old_type, - CONST void *indices ) -{ - ACcontext *ac = AC_CONTEXT(ctx); - - if (old_type == new_type) - return indices; - - if (ac->elt_size < count * sizeof(GLuint)) { - if (ac->Elts) FREE(ac->Elts); - while (ac->elt_size < count * sizeof(GLuint)) - ac->elt_size *= 2; - ac->Elts = (GLuint *) MALLOC(ac->elt_size); - } - - switch (new_type) { - case GL_UNSIGNED_BYTE: - ASSERT(0); - return NULL; - case GL_UNSIGNED_SHORT: - ASSERT(0); - return NULL; - case GL_UNSIGNED_INT: { - GLuint *out = (GLuint *)ac->Elts; - GLuint i; - - switch (old_type) { - case GL_UNSIGNED_BYTE: { - CONST GLubyte *in = (CONST GLubyte *)indices; - for (i = 0 ; i < count ; i++) - out[i] = in[i]; - break; - } - case GL_UNSIGNED_SHORT: { - CONST GLushort *in = (CONST GLushort *)indices; - for (i = 0 ; i < count ; i++) - out[i] = in[i]; - break; - } - default: - ASSERT(0); - } - - return (CONST void *)out; - } - default: - ASSERT(0); - break; - } - - return NULL; -} diff --git a/src/mesa/array_cache/acache.h b/src/mesa/array_cache/acache.h deleted file mode 100644 index 2bb64f3656..0000000000 --- a/src/mesa/array_cache/acache.h +++ /dev/null @@ -1,132 +0,0 @@ - -/* - * Mesa 3-D graphics library - * Version: 4.1 - * - * Copyright (C) 1999-2002 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 - */ - -#ifndef _ARRAYCACHE_H -#define _ARRAYCACHE_H - -#include "mtypes.h" - - -extern GLboolean -_ac_CreateContext( GLcontext *ctx ); - -extern void -_ac_DestroyContext( GLcontext *ctx ); - -extern void -_ac_InvalidateState( GLcontext *ctx, GLuint new_state ); - -extern struct gl_client_array * -_ac_import_vertex( GLcontext *ctx, - GLenum type, - GLuint reqstride, - GLuint reqsize, - GLboolean reqwritable, - GLboolean *writable ); - -extern struct gl_client_array * -_ac_import_normal( GLcontext *ctx, - GLenum type, - GLuint reqstride, - GLboolean reqwritable, - GLboolean *writable ); - -extern struct gl_client_array * -_ac_import_color( GLcontext *ctx, - GLenum type, - GLuint reqstride, - GLuint reqsize, - GLboolean reqwritable, - GLboolean *writable ); - -extern struct gl_client_array * -_ac_import_index( GLcontext *ctx, - GLenum type, - GLuint reqstride, - GLboolean reqwritable, - GLboolean *writable ); - -extern struct gl_client_array * -_ac_import_secondarycolor( GLcontext *ctx, - GLenum type, - GLuint reqstride, - GLuint reqsize, - GLboolean reqwritable, - GLboolean *writable ); - -extern struct gl_client_array * -_ac_import_fogcoord( GLcontext *ctx, - GLenum type, - GLuint reqstride, - GLboolean reqwritable, - GLboolean *writable ); - -extern struct gl_client_array * -_ac_import_edgeflag( GLcontext *ctx, - GLenum type, - GLuint reqstride, - GLboolean reqwritable, - GLboolean *writable ); - -extern struct gl_client_array * -_ac_import_texcoord( GLcontext *ctx, - GLuint unit, - GLenum type, - GLuint reqstride, - GLuint reqsize, - GLboolean reqwritable, - GLboolean *writable ); - -extern struct gl_client_array * -_ac_import_attrib( GLcontext *ctx, - GLuint index, - GLenum type, - GLuint reqstride, - GLuint reqsize, - GLboolean reqwritable, - GLboolean *writable ); - - -/* Clients must call this function to validate state and set bounds - * before importing any data: - */ -extern void -_ac_import_range( GLcontext *ctx, GLuint start, GLuint count ); - - -/* Additional convenience function: - */ -extern CONST void * -_ac_import_elements( GLcontext *ctx, - GLenum new_type, - GLuint count, - GLenum old_type, - CONST void *indices ); - - -#endif diff --git a/src/mesa/array_cache/descrip.mms b/src/mesa/array_cache/descrip.mms deleted file mode 100644 index 0607a01d1f..0000000000 --- a/src/mesa/array_cache/descrip.mms +++ /dev/null @@ -1,37 +0,0 @@ -# Makefile for core library for VMS -# contributed by Jouk Jansen joukj@hrem.stm.tudelft.nl -# Last revision : 16 June 2003 - -.first - define gl [---.include.gl] - define math [-.math] - define array_cache [-.array_cache] - -.include [---]mms-config. - -##### MACROS ##### - -VPATH = RCS - -INCDIR = [---.include],[-.main],[-.glapi] -LIBDIR = [---.lib] -CFLAGS = /include=($(INCDIR),[])/define=(PTHREADS=1)/name=(as_is,short)/float=ieee/ieee=denorm - -SOURCES = ac_context.c ac_import.c - -OBJECTS = ac_context.obj,ac_import.obj -##### RULES ##### - -VERSION=Mesa V3.4 - -##### TARGETS ##### -# Make the library -$(LIBDIR)$(GL_LIB) : $(OBJECTS) - @ library $(LIBDIR)$(GL_LIB) $(OBJECTS) - -clean : - purge - delete *.obj;* - -ac_context.obj : ac_context.c -ac_import.obj : ac_import.c diff --git a/src/mesa/array_cache/sources b/src/mesa/array_cache/sources deleted file mode 100644 index 210ec202d6..0000000000 --- a/src/mesa/array_cache/sources +++ /dev/null @@ -1,3 +0,0 @@ -MESA_ARRAY_CACHE_SOURCES = \ -ac_context.c \ -ac_import.c -- cgit v1.2.3 From 0a0fb5e0b3cfe61749af41d4200d42982b551cef Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 29 Oct 2006 09:52:36 +0000 Subject: switch over to vbo module --- src/mesa/drivers/osmesa/osmesa.c | 7 +++---- src/mesa/drivers/x11/xm_api.c | 6 +++--- src/mesa/drivers/x11/xm_dd.c | 2 -- 3 files changed, 6 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/osmesa/osmesa.c b/src/mesa/drivers/osmesa/osmesa.c index 0b027eddec..42a1bb5123 100644 --- a/src/mesa/drivers/osmesa/osmesa.c +++ b/src/mesa/drivers/osmesa/osmesa.c @@ -41,7 +41,6 @@ #include "imports.h" #include "mtypes.h" #include "renderbuffer.h" -#include "array_cache/acache.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "swrast/s_context.h" @@ -51,6 +50,7 @@ #include "tnl/t_context.h" #include "tnl/t_pipeline.h" #include "drivers/common/driverfuncs.h" +#include "vbo/vbo_context.h" @@ -110,7 +110,6 @@ osmesa_update_state( GLcontext *ctx, GLuint new_state ) /* easy - just propogate */ _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); } @@ -1261,7 +1260,7 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits, TNLcontext *tnl; if (!_swrast_CreateContext( ctx ) || - !_ac_CreateContext( ctx ) || + !_vbo_CreateContext( ctx ) || !_tnl_CreateContext( ctx ) || !_swsetup_CreateContext( ctx )) { _mesa_destroy_visual(osmesa->gl_visual); @@ -1299,7 +1298,7 @@ OSMesaDestroyContext( OSMesaContext osmesa ) if (osmesa) { _swsetup_DestroyContext( &osmesa->mesa ); _tnl_DestroyContext( &osmesa->mesa ); - _ac_DestroyContext( &osmesa->mesa ); + _vbo_DestroyContext( &osmesa->mesa ); _swrast_DestroyContext( &osmesa->mesa ); _mesa_destroy_visual( osmesa->gl_visual ); diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c index b50c4757af..6fb0d9bbbd 100644 --- a/src/mesa/drivers/x11/xm_api.c +++ b/src/mesa/drivers/x11/xm_api.c @@ -74,7 +74,7 @@ #include "renderbuffer.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo_context.h" #include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" @@ -1555,7 +1555,7 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) /* Initialize the software rasterizer and helper modules. */ if (!_swrast_CreateContext( mesaCtx ) || - !_ac_CreateContext( mesaCtx ) || + !_vbo_CreateContext( mesaCtx ) || !_tnl_CreateContext( mesaCtx ) || !_swsetup_CreateContext( mesaCtx )) { _mesa_free_context_data(&c->mesa); @@ -1587,7 +1587,7 @@ void XMesaDestroyContext( XMesaContext c ) _swsetup_DestroyContext( mesaCtx ); _swrast_DestroyContext( mesaCtx ); _tnl_DestroyContext( mesaCtx ); - _ac_DestroyContext( mesaCtx ); + _vbo_DestroyContext( mesaCtx ); _mesa_free_context_data( mesaCtx ); _mesa_free( c ); } diff --git a/src/mesa/drivers/x11/xm_dd.c b/src/mesa/drivers/x11/xm_dd.c index abad300cc3..39cec1dc9f 100644 --- a/src/mesa/drivers/x11/xm_dd.c +++ b/src/mesa/drivers/x11/xm_dd.c @@ -47,7 +47,6 @@ #include "texstore.h" #include "texformat.h" #include "xmesaP.h" -#include "array_cache/acache.h" #include "swrast/swrast.h" #include "swrast/s_context.h" #include "swrast_setup/swrast_setup.h" @@ -831,7 +830,6 @@ xmesa_update_state( GLcontext *ctx, GLbitfield new_state ) * modules. The X11 driver has no internal GL-dependent state. */ _swrast_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); -- cgit v1.2.3 From a3c86828edc971319455d16153ea1657585d863f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 29 Oct 2006 09:54:17 +0000 Subject: Fix compiler warning --- src/mesa/main/texcompress_s3tc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/main/texcompress_s3tc.c b/src/mesa/main/texcompress_s3tc.c index 3ccc8a8df7..65ecaba3a3 100644 --- a/src/mesa/main/texcompress_s3tc.c +++ b/src/mesa/main/texcompress_s3tc.c @@ -89,7 +89,7 @@ _mesa_dlopen(const char *libname, int flags) return dlopen(libname, flags); #endif #else - return (GenericFunc) NULL; + return (void *) NULL; #endif /* USE_EXTERNAL_DXTN_LIB */ } -- cgit v1.2.3 From efef291dc71eb57f90785a26957f4b3e01733156 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 30 Oct 2006 16:43:39 +0000 Subject: checkpoint - remove dead files, otherwise untested --- src/mesa/drivers/dri/i965/Makefile | 8 - src/mesa/drivers/dri/i965/brw_attrib.h | 113 --- src/mesa/drivers/dri/i965/brw_attrib_tmp.h | 485 ----------- src/mesa/drivers/dri/i965/brw_context.c | 5 - src/mesa/drivers/dri/i965/brw_draw.c | 55 +- src/mesa/drivers/dri/i965/brw_draw.h | 47 +- src/mesa/drivers/dri/i965/brw_draw_upload.c | 4 +- src/mesa/drivers/dri/i965/brw_exec.c | 125 --- src/mesa/drivers/dri/i965/brw_exec.h | 150 ---- src/mesa/drivers/dri/i965/brw_exec_api.c | 716 ----------------- src/mesa/drivers/dri/i965/brw_exec_array.c | 283 ------- src/mesa/drivers/dri/i965/brw_exec_draw.c | 227 ------ src/mesa/drivers/dri/i965/brw_exec_eval.c | 255 ------ src/mesa/drivers/dri/i965/brw_fallback.c | 6 +- src/mesa/drivers/dri/i965/brw_fallback.h | 4 +- src/mesa/drivers/dri/i965/brw_metaops.c | 5 +- src/mesa/drivers/dri/i965/brw_save.c | 126 --- src/mesa/drivers/dri/i965/brw_save.h | 171 ---- src/mesa/drivers/dri/i965/brw_save_api.c | 1162 --------------------------- src/mesa/drivers/dri/i965/brw_save_draw.c | 209 ----- 20 files changed, 42 insertions(+), 4114 deletions(-) delete mode 100644 src/mesa/drivers/dri/i965/brw_attrib.h delete mode 100644 src/mesa/drivers/dri/i965/brw_attrib_tmp.h delete mode 100644 src/mesa/drivers/dri/i965/brw_exec.c delete mode 100644 src/mesa/drivers/dri/i965/brw_exec.h delete mode 100644 src/mesa/drivers/dri/i965/brw_exec_api.c delete mode 100644 src/mesa/drivers/dri/i965/brw_exec_array.c delete mode 100644 src/mesa/drivers/dri/i965/brw_exec_draw.c delete mode 100644 src/mesa/drivers/dri/i965/brw_exec_eval.c delete mode 100644 src/mesa/drivers/dri/i965/brw_save.c delete mode 100644 src/mesa/drivers/dri/i965/brw_save.h delete mode 100644 src/mesa/drivers/dri/i965/brw_save_api.c delete mode 100644 src/mesa/drivers/dri/i965/brw_save_draw.c (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile index 213eac895c..8ec422509f 100644 --- a/src/mesa/drivers/dri/i965/Makefile +++ b/src/mesa/drivers/dri/i965/Makefile @@ -40,11 +40,6 @@ DRIVER_SOURCES = \ brw_eu_debug.c \ brw_eu_emit.c \ brw_eu_util.c \ - brw_exec.c \ - brw_exec_api.c \ - brw_exec_array.c \ - brw_exec_draw.c \ - brw_exec_eval.c \ brw_fallback.c \ brw_gs.c \ brw_gs_emit.c \ @@ -53,9 +48,6 @@ DRIVER_SOURCES = \ brw_metaops.c \ brw_misc_state.c \ brw_program.c \ - brw_save.c \ - brw_save_api.c \ - brw_save_draw.c \ brw_sf.c \ brw_sf_emit.c \ brw_sf_state.c \ diff --git a/src/mesa/drivers/dri/i965/brw_attrib.h b/src/mesa/drivers/dri/i965/brw_attrib.h deleted file mode 100644 index a8efc3a528..0000000000 --- a/src/mesa/drivers/dri/i965/brw_attrib.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - Copyright (C) Intel Corp. 2006. All Rights Reserved. - Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to - develop this 3D driver. - - 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 (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 NONINFRINGEMENT. - IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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 - */ - -#ifndef BRW_ATTRIB_H -#define BRW_ATTRIB_H - - -/* - * Note: The first attributes match the VERT_ATTRIB_* definitions - * in mtypes.h. However, the tnl module has additional attributes - * for materials, color indexes, edge flags, etc. - */ -/* Although it's nice to use these as bit indexes in a DWORD flag, we - * could manage without if necessary. Another limit currently is the - * number of bits allocated for these numbers in places like vertex - * program instruction formats and register layouts. - */ -enum { - BRW_ATTRIB_POS = 0, - BRW_ATTRIB_WEIGHT = 1, - BRW_ATTRIB_NORMAL = 2, - BRW_ATTRIB_COLOR0 = 3, - BRW_ATTRIB_COLOR1 = 4, - BRW_ATTRIB_FOG = 5, - BRW_ATTRIB_INDEX = 6, - BRW_ATTRIB_EDGEFLAG = 7, - BRW_ATTRIB_TEX0 = 8, - BRW_ATTRIB_TEX1 = 9, - BRW_ATTRIB_TEX2 = 10, - BRW_ATTRIB_TEX3 = 11, - BRW_ATTRIB_TEX4 = 12, - BRW_ATTRIB_TEX5 = 13, - BRW_ATTRIB_TEX6 = 14, - BRW_ATTRIB_TEX7 = 15, - - BRW_ATTRIB_GENERIC0 = 16, /* Not used? */ - BRW_ATTRIB_GENERIC1 = 17, - BRW_ATTRIB_GENERIC2 = 18, - BRW_ATTRIB_GENERIC3 = 19, - BRW_ATTRIB_GENERIC4 = 20, - BRW_ATTRIB_GENERIC5 = 21, - BRW_ATTRIB_GENERIC6 = 22, - BRW_ATTRIB_GENERIC7 = 23, - BRW_ATTRIB_GENERIC8 = 24, - BRW_ATTRIB_GENERIC9 = 25, - BRW_ATTRIB_GENERIC10 = 26, - BRW_ATTRIB_GENERIC11 = 27, - BRW_ATTRIB_GENERIC12 = 28, - BRW_ATTRIB_GENERIC13 = 29, - BRW_ATTRIB_GENERIC14 = 30, - BRW_ATTRIB_GENERIC15 = 31, - - BRW_ATTRIB_MAT_FRONT_AMBIENT = 32, - BRW_ATTRIB_MAT_BACK_AMBIENT = 33, - BRW_ATTRIB_MAT_FRONT_DIFFUSE = 34, - BRW_ATTRIB_MAT_BACK_DIFFUSE = 35, - BRW_ATTRIB_MAT_FRONT_SPECULAR = 36, - BRW_ATTRIB_MAT_BACK_SPECULAR = 37, - BRW_ATTRIB_MAT_FRONT_EMISSION = 38, - BRW_ATTRIB_MAT_BACK_EMISSION = 39, - BRW_ATTRIB_MAT_FRONT_SHININESS = 40, - BRW_ATTRIB_MAT_BACK_SHININESS = 41, - BRW_ATTRIB_MAT_FRONT_INDEXES = 42, - BRW_ATTRIB_MAT_BACK_INDEXES = 43, - - BRW_ATTRIB_MAX = 44 -} ; - -#define BRW_ATTRIB_FIRST_MATERIAL BRW_ATTRIB_MAT_FRONT_AMBIENT - -#define BRW_MAX_COPIED_VERTS 3 - - -static inline GLuint64EXT brw_translate_inputs( GLboolean vp_enabled, - GLuint mesa_inputs ) -{ - GLuint64EXT inputs = mesa_inputs; - if (vp_enabled) - return inputs; - else - return (inputs & 0xffff) | ((inputs & 0xffff0000) << 16); -} - - -#endif diff --git a/src/mesa/drivers/dri/i965/brw_attrib_tmp.h b/src/mesa/drivers/dri/i965/brw_attrib_tmp.h deleted file mode 100644 index 3089bd6cac..0000000000 --- a/src/mesa/drivers/dri/i965/brw_attrib_tmp.h +++ /dev/null @@ -1,485 +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. - -**************************************************************************/ - -#define ATTR1FV( A, V ) ATTR( A, 1, (V)[0], 0, 0, 1 ) -#define ATTR2FV( A, V ) ATTR( A, 2, (V)[0], (V)[1], 0, 1 ) -#define ATTR3FV( A, V ) ATTR( A, 3, (V)[0], (V)[1], (V)[2], 1 ) -#define ATTR4FV( A, V ) ATTR( A, 4, (V)[0], (V)[1], (V)[2], (V)[3] ) - -#define ATTR1F( A, X ) ATTR( A, 1, X, 0, 0, 1 ) -#define ATTR2F( A, X, Y ) ATTR( A, 2, X, Y, 0, 1 ) -#define ATTR3F( A, X, Y, Z ) ATTR( A, 3, X, Y, Z, 1 ) -#define ATTR4F( A, X, Y, Z, W ) ATTR( A, 4, X, Y, Z, W ) - -#define MAT_ATTR( A, N, V ) ATTR( A, N, (V)[0], (V)[1], (V)[2], (V)[3] ) - -static void GLAPIENTRY TAG(Vertex2f)( GLfloat x, GLfloat y ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR2F( BRW_ATTRIB_POS, x, y ); -} - -static void GLAPIENTRY TAG(Vertex2fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR2FV( BRW_ATTRIB_POS, v ); -} - -static void GLAPIENTRY TAG(Vertex3f)( GLfloat x, GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3F( BRW_ATTRIB_POS, x, y, z ); -} - -static void GLAPIENTRY TAG(Vertex3fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3FV( BRW_ATTRIB_POS, v ); -} - -static void GLAPIENTRY TAG(Vertex4f)( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR4F( BRW_ATTRIB_POS, x, y, z, w ); -} - -static void GLAPIENTRY TAG(Vertex4fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR4FV( BRW_ATTRIB_POS, v ); -} - -static void GLAPIENTRY TAG(TexCoord1f)( GLfloat x ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR1F( BRW_ATTRIB_TEX0, x ); -} - -static void GLAPIENTRY TAG(TexCoord1fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR1FV( BRW_ATTRIB_TEX0, v ); -} - -static void GLAPIENTRY TAG(TexCoord2f)( GLfloat x, GLfloat y ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR2F( BRW_ATTRIB_TEX0, x, y ); -} - -static void GLAPIENTRY TAG(TexCoord2fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR2FV( BRW_ATTRIB_TEX0, v ); -} - -static void GLAPIENTRY TAG(TexCoord3f)( GLfloat x, GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3F( BRW_ATTRIB_TEX0, x, y, z ); -} - -static void GLAPIENTRY TAG(TexCoord3fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3FV( BRW_ATTRIB_TEX0, v ); -} - -static void GLAPIENTRY TAG(TexCoord4f)( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR4F( BRW_ATTRIB_TEX0, x, y, z, w ); -} - -static void GLAPIENTRY TAG(TexCoord4fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR4FV( BRW_ATTRIB_TEX0, v ); -} - -static void GLAPIENTRY TAG(Normal3f)( GLfloat x, GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3F( BRW_ATTRIB_NORMAL, x, y, z ); -} - -static void GLAPIENTRY TAG(Normal3fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3FV( BRW_ATTRIB_NORMAL, v ); -} - -static void GLAPIENTRY TAG(FogCoordfEXT)( GLfloat x ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR1F( BRW_ATTRIB_FOG, x ); -} - -static void GLAPIENTRY TAG(FogCoordfvEXT)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR1FV( BRW_ATTRIB_FOG, v ); -} - -static void GLAPIENTRY TAG(Color3f)( GLfloat x, GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3F( BRW_ATTRIB_COLOR0, x, y, z ); -} - -static void GLAPIENTRY TAG(Color3fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3FV( BRW_ATTRIB_COLOR0, v ); -} - -static void GLAPIENTRY TAG(Color4f)( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR4F( BRW_ATTRIB_COLOR0, x, y, z, w ); -} - -static void GLAPIENTRY TAG(Color4fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR4FV( BRW_ATTRIB_COLOR0, v ); -} - -static void GLAPIENTRY TAG(SecondaryColor3fEXT)( GLfloat x, GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3F( BRW_ATTRIB_COLOR1, x, y, z ); -} - -static void GLAPIENTRY TAG(SecondaryColor3fvEXT)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3FV( BRW_ATTRIB_COLOR1, v ); -} - - -static void GLAPIENTRY TAG(EdgeFlag)( GLboolean b ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR1F( BRW_ATTRIB_EDGEFLAG, (GLfloat)b ); -} - -static void GLAPIENTRY TAG(Indexf)( GLfloat f ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR1F( BRW_ATTRIB_INDEX, f ); -} - -static void GLAPIENTRY TAG(Indexfv)( const GLfloat *f ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR1FV( BRW_ATTRIB_INDEX, f ); -} - - -static void GLAPIENTRY TAG(MultiTexCoord1f)( GLenum target, GLfloat x ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0; - ATTR1F( attr, x ); -} - -static void GLAPIENTRY TAG(MultiTexCoord1fv)( GLenum target, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0; - ATTR1FV( attr, v ); -} - -static void GLAPIENTRY TAG(MultiTexCoord2f)( GLenum target, GLfloat x, GLfloat y ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0; - ATTR2F( attr, x, y ); -} - -static void GLAPIENTRY TAG(MultiTexCoord2fv)( GLenum target, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0; - ATTR2FV( attr, v ); -} - -static void GLAPIENTRY TAG(MultiTexCoord3f)( GLenum target, GLfloat x, GLfloat y, - GLfloat z) -{ - GET_CURRENT_CONTEXT( ctx ); - GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0; - ATTR3F( attr, x, y, z ); -} - -static void GLAPIENTRY TAG(MultiTexCoord3fv)( GLenum target, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0; - ATTR3FV( attr, v ); -} - -static void GLAPIENTRY TAG(MultiTexCoord4f)( GLenum target, GLfloat x, GLfloat y, - GLfloat z, GLfloat w ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0; - ATTR4F( attr, x, y, z, w ); -} - -static void GLAPIENTRY TAG(MultiTexCoord4fv)( GLenum target, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0; - ATTR4FV( attr, v ); -} - - -static void GLAPIENTRY TAG(VertexAttrib1fARB)( GLuint index, GLfloat x ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index == 0) - ATTR1F(0, x); - else if (index < MAX_VERTEX_ATTRIBS) - ATTR1F(BRW_ATTRIB_GENERIC0 + index, x); - else - ERROR(); -} - -static void GLAPIENTRY TAG(VertexAttrib1fvARB)( GLuint index, - const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index == 0) - ATTR1FV(0, v); - else if (index < MAX_VERTEX_ATTRIBS) - ATTR1FV(BRW_ATTRIB_GENERIC0 + index, v); - else - ERROR(); -} - -static void GLAPIENTRY TAG(VertexAttrib2fARB)( GLuint index, GLfloat x, - GLfloat y ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index == 0) - ATTR2F(0, x, y); - else if (index < MAX_VERTEX_ATTRIBS) - ATTR2F(BRW_ATTRIB_GENERIC0 + index, x, y); - else - ERROR(); -} - -static void GLAPIENTRY TAG(VertexAttrib2fvARB)( GLuint index, - const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index == 0) - ATTR2FV(0, v); - else if (index < MAX_VERTEX_ATTRIBS) - ATTR2FV(BRW_ATTRIB_GENERIC0 + index, v); - else - ERROR(); -} - -static void GLAPIENTRY TAG(VertexAttrib3fARB)( GLuint index, GLfloat x, - GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index == 0) - ATTR3F(0, x, y, z); - else if (index < MAX_VERTEX_ATTRIBS) - ATTR3F(BRW_ATTRIB_GENERIC0 + index, x, y, z); - else - ERROR(); -} - -static void GLAPIENTRY TAG(VertexAttrib3fvARB)( GLuint index, - const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index == 0) - ATTR3FV(0, v); - else if (index < MAX_VERTEX_ATTRIBS) - ATTR3FV(BRW_ATTRIB_GENERIC0 + index, v); - else - ERROR(); -} - -static void GLAPIENTRY TAG(VertexAttrib4fARB)( GLuint index, GLfloat x, - GLfloat y, GLfloat z, - GLfloat w ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index == 0) - ATTR4F(0, x, y, z, w); - else if (index < MAX_VERTEX_ATTRIBS) - ATTR4F(BRW_ATTRIB_GENERIC0 + index, x, y, z, w); - else - ERROR(); -} - -static void GLAPIENTRY TAG(VertexAttrib4fvARB)( GLuint index, - const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index == 0) - ATTR4FV(0, v); - else if (index < MAX_VERTEX_ATTRIBS) - ATTR4FV(BRW_ATTRIB_GENERIC0 + index, v); - else - ERROR(); -} - - -/* Although we don't export NV_vertex_program, these entrypoints are - * used by the display list and other code specifically because of - * their property of aliasing with other attributes. - */ -static void GLAPIENTRY TAG(VertexAttrib1fNV)( GLuint index, GLfloat x ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index < BRW_ATTRIB_MAX) - ATTR1F(index, x); -} - -static void GLAPIENTRY TAG(VertexAttrib1fvNV)( GLuint index, - const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index < BRW_ATTRIB_MAX) - ATTR1FV(index, v); -} - -static void GLAPIENTRY TAG(VertexAttrib2fNV)( GLuint index, GLfloat x, - GLfloat y ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index < BRW_ATTRIB_MAX) - ATTR2F(index, x, y); -} - -static void GLAPIENTRY TAG(VertexAttrib2fvNV)( GLuint index, - const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index < BRW_ATTRIB_MAX) - ATTR2FV(index, v); -} - -static void GLAPIENTRY TAG(VertexAttrib3fNV)( GLuint index, GLfloat x, - GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index < BRW_ATTRIB_MAX) - ATTR3F(index, x, y, z); -} - -static void GLAPIENTRY TAG(VertexAttrib3fvNV)( GLuint index, - const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index < BRW_ATTRIB_MAX) - ATTR3FV(index, v); -} - -static void GLAPIENTRY TAG(VertexAttrib4fNV)( GLuint index, GLfloat x, - GLfloat y, GLfloat z, - GLfloat w ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index < BRW_ATTRIB_MAX) - ATTR4F(index, x, y, z, w); -} - -static void GLAPIENTRY TAG(VertexAttrib4fvNV)( GLuint index, - const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index < BRW_ATTRIB_MAX) - ATTR4FV(index, v); -} - - -#define MAT( ATTR, N, face, params ) \ -do { \ - if (face != GL_BACK) \ - MAT_ATTR( ATTR, N, params ); /* front */ \ - if (face != GL_FRONT) \ - MAT_ATTR( ATTR + 1, N, params ); /* back */ \ -} while (0) - - -/* Colormaterial conflicts are dealt with later. - */ -static void GLAPIENTRY TAG(Materialfv)( GLenum face, GLenum pname, - const GLfloat *params ) -{ - GET_CURRENT_CONTEXT( ctx ); - switch (pname) { - case GL_EMISSION: - MAT( BRW_ATTRIB_MAT_FRONT_EMISSION, 4, face, params ); - break; - case GL_AMBIENT: - MAT( BRW_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params ); - break; - case GL_DIFFUSE: - MAT( BRW_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params ); - break; - case GL_SPECULAR: - MAT( BRW_ATTRIB_MAT_FRONT_SPECULAR, 4, face, params ); - break; - case GL_SHININESS: - MAT( BRW_ATTRIB_MAT_FRONT_SHININESS, 1, face, params ); - break; - case GL_COLOR_INDEXES: - MAT( BRW_ATTRIB_MAT_FRONT_INDEXES, 3, face, params ); - break; - case GL_AMBIENT_AND_DIFFUSE: - MAT( BRW_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params ); - MAT( BRW_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params ); - break; - default: - ERROR(); - return; - } -} - - -#undef ATTR1FV -#undef ATTR2FV -#undef ATTR3FV -#undef ATTR4FV - -#undef ATTR1F -#undef ATTR2F -#undef ATTR3F -#undef ATTR4F - -#undef MAT -#undef MAT_ATTR diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c index c1f6617f3f..b9256d5185 100644 --- a/src/mesa/drivers/dri/i965/brw_context.c +++ b/src/mesa/drivers/dri/i965/brw_context.c @@ -156,11 +156,6 @@ GLboolean brwCreateContext( const __GLcontextModes *mesaVis, brw_ProgramCacheInit( ctx ); - /* Hook our functions into exec and compile dispatch tables. Only - * fallback on out-of-memory situations. - */ - brw_exec_init( ctx ); - brw_save_init( ctx ); { const char *filename = getenv("INTEL_REPLAY"); diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index 5c0c5da7ea..1bc39762bc 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -143,7 +143,7 @@ static void brw_emit_cliprect( struct brw_context *brw, static void brw_emit_prim( struct brw_context *brw, - const struct brw_draw_prim *prim ) + const struct vbo_prim *prim ) { struct brw_3d_primitive prim_packet; @@ -230,7 +230,7 @@ static void brw_merge_inputs( struct brw_context *brw, } static GLboolean check_fallbacks( struct brw_context *brw, - const struct brw_draw_prim *prim, + const struct vbo_prim *prim, GLuint nr_prims ) { GLuint i; @@ -284,12 +284,11 @@ static GLboolean check_fallbacks( struct brw_context *brw, static GLboolean brw_try_draw_prims( GLcontext *ctx, const struct gl_client_array *arrays[], - const struct brw_draw_prim *prim, + const struct vbo_prim *prim, GLuint nr_prims, - const struct brw_draw_index_buffer *ib, + const struct _mesa_index_buffer *ib, GLuint min_index, - GLuint max_index, - GLuint flags ) + GLuint max_index ) { struct intel_context *intel = intel_context(ctx); struct brw_context *brw = brw_context(ctx); @@ -412,43 +411,47 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, } -GLboolean brw_draw_prims( GLcontext *ctx, - const struct gl_client_array *arrays[], - const struct brw_draw_prim *prim, - GLuint nr_prims, - const struct brw_draw_index_buffer *ib, - GLuint min_index, - GLuint max_index, - GLuint flags ) +void brw_draw_prims( GLcontext *ctx, + const struct gl_client_array *arrays[], + const struct vbo_prim *prim, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLuint min_index, + GLuint max_index ) { struct intel_context *intel = intel_context(ctx); GLboolean retval; - retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index, flags); + retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index); + /* This looks like out-of-memory but potentially we have + * situation where there is enough memory but it has become + * fragmented. Clear out all heaps and start from scratch by + * faking a contended lock event: (done elsewhere) + */ if (!retval && bmError(intel)) { - DBG("retrying\n"); - /* This looks like out-of-memory but potentially we have - * situation where there is enough memory but it has become - * fragmented. Clear out all heaps and start from scratch by - * faking a contended lock event: (done elsewhere) - */ - /* Then try a second time only to upload textures and draw the * primitives: */ - retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index, flags); + retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index); + } + + /* Otherwise, we really are out of memory. Pass the drawing + * command to the software tnl module and which will in turn call + * swrast to do the drawing. + */ + if (!retval) { + brw_fallback(); + _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index); + brw_unfallback(); } if (intel->aub_file && (INTEL_DEBUG & DEBUG_SYNC)) { intelFinish( &intel->ctx ); intel->aub_wrap = 1; } - - - return retval; } diff --git a/src/mesa/drivers/dri/i965/brw_draw.h b/src/mesa/drivers/dri/i965/brw_draw.h index 92640bf725..b68cd86115 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.h +++ b/src/mesa/drivers/dri/i965/brw_draw.h @@ -33,40 +33,14 @@ struct brw_context; -struct brw_draw_prim { - GLuint mode:8; - GLuint indexed:1; - GLuint begin:1; - GLuint end:1; - GLuint weak:1; - GLuint pad:20; - - GLuint start; - GLuint count; -}; - -struct brw_draw_index_buffer { - GLuint count; - GLenum type; - struct gl_buffer_object *obj; - const void *ptr; - GLuint rebase; -}; - - -#define BRW_DRAW_SORTED 0x1 -#define BRW_DRAW_ALL_INTERLEAVED 0x2 -#define BRW_DRAW_NON_INTERLEAVED 0x4 -#define BRW_DRAW_LOCKED 0x8 GLboolean brw_draw_prims( GLcontext *ctx, const struct gl_client_array *arrays[], - const struct brw_draw_prim *prims, + const struct vbo_prim *prims, GLuint nr_prims, - const struct brw_draw_index_buffer *ib, + const struct _mesa_index_buffer *ib, GLuint min_index, - GLuint max_index, - GLuint flags ); + GLuint max_index ); void brw_draw_init( struct brw_context *brw ); void brw_draw_destroy( struct brw_context *brw ); @@ -80,25 +54,12 @@ void brw_init_current_values(GLcontext *ctx, /* brw_draw_upload.c */ void brw_upload_indices( struct brw_context *brw, - const struct brw_draw_index_buffer *index_buffer); + const struct _mesa_index_buffer *index_buffer); GLboolean brw_upload_vertices( struct brw_context *brw, GLuint min_index, GLuint max_index ); -/* Helpers for save, exec. Should probably have their own file: - */ -struct brw_exec_context; -struct brw_save_context; - -struct brw_exec_save { - struct brw_exec_context *exec; - struct brw_save_context *save; -}; - -/* Doesn't really belong here: - */ -#define IMM_CONTEXT(ctx) ((struct brw_exec_save *)((ctx)->swtnl_im)) #endif diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index cde0aa6481..4d930c6c9e 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -568,7 +568,7 @@ static GLuint element_size( GLenum type ) static void rebase_indices_to_vbo_indices( struct brw_context *brw, - const struct brw_draw_index_buffer *index_buffer, + const struct vbo_index_buffer *index_buffer, struct gl_buffer_object **vbo_return, GLuint *offset_return ) { @@ -642,7 +642,7 @@ static void rebase_indices_to_vbo_indices( struct brw_context *brw, void brw_upload_indices( struct brw_context *brw, - const struct brw_draw_index_buffer *index_buffer) + const struct vbo_index_buffer *index_buffer) { struct intel_context *intel = &brw->intel; GLuint ib_size = get_size(index_buffer->type) * index_buffer->count; diff --git a/src/mesa/drivers/dri/i965/brw_exec.c b/src/mesa/drivers/dri/i965/brw_exec.c deleted file mode 100644 index fc06c3c361..0000000000 --- a/src/mesa/drivers/dri/i965/brw_exec.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.3 - * - * Copyright (C) 1999-2005 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 - */ - - -#include "api_arrayelt.h" -#include "glheader.h" -#include "imports.h" -#include "context.h" -#include "macros.h" -#include "mtypes.h" -#include "dlist.h" -#include "vtxfmt.h" - -#include "brw_exec.h" - - -void brw_exec_init( GLcontext *ctx ) -{ - struct brw_exec_context *exec = CALLOC_STRUCT(brw_exec_context); - - if (ctx->swtnl_im == NULL) { - ctx->swtnl_im = CALLOC_STRUCT(brw_exec_save); - } - - exec->ctx = ctx; - IMM_CONTEXT(ctx)->exec = exec; - - /* Initialize the arrayelt helper - */ - if (!ctx->aelt_context && - !_ae_create_context( ctx )) - return; - - brw_exec_vtx_init( exec ); - brw_exec_array_init( exec ); - - ctx->Driver.NeedFlush = 0; - ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; - ctx->Driver.FlushVertices = brw_exec_FlushVertices; - - exec->eval.recalculate_maps = 1; -} - - -void brw_exec_destroy( GLcontext *ctx ) -{ - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - - if (ctx->aelt_context) { - _ae_destroy_context( ctx ); - ctx->aelt_context = NULL; - } - - brw_exec_vtx_destroy( exec ); - brw_exec_array_destroy( exec ); - - if (exec) { - FREE(exec); - IMM_CONTEXT(ctx)->exec = NULL; - } - - if (IMM_CONTEXT(ctx)->exec == NULL && - IMM_CONTEXT(ctx)->save == NULL) { - FREE(IMM_CONTEXT(ctx)); - ctx->swtnl_im = NULL; - } -} - -/* Really want to install these callbacks to a central facility to be - * invoked according to the state flags. That will have to wait for a - * mesa rework: - */ -void brw_exec_invalidate_state( GLcontext *ctx, GLuint new_state ) -{ - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - - if (new_state & (_NEW_PROGRAM|_NEW_EVAL)) - exec->eval.recalculate_maps = 1; - - _ae_invalidate_state(ctx, new_state); -} - - -void brw_exec_wakeup( GLcontext *ctx ) -{ - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - - ctx->Driver.FlushVertices = brw_exec_FlushVertices; - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; - - /* Hook our functions into exec and compile dispatch tables. - */ - _mesa_install_exec_vtxfmt( ctx, &exec->vtxfmt ); - - /* Assume we haven't been getting state updates either: - */ - brw_exec_invalidate_state( ctx, ~0 ); -} - - - diff --git a/src/mesa/drivers/dri/i965/brw_exec.h b/src/mesa/drivers/dri/i965/brw_exec.h deleted file mode 100644 index f07b448587..0000000000 --- a/src/mesa/drivers/dri/i965/brw_exec.h +++ /dev/null @@ -1,150 +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 - * - */ - -#ifndef __BRW_EXEC_H__ -#define __BRW_EXEC_H__ - -#include "mtypes.h" -#include "brw_attrib.h" -#include "brw_draw.h" - - -#define BRW_MAX_PRIM 64 - -/* Wierd implementation stuff: - */ -#define BRW_VERT_BUFFER_SIZE (1024*16) /* dwords == 64k */ -#define BRW_MAX_ATTR_CODEGEN 16 -#define ERROR_ATTRIB 16 - - - - -struct brw_exec_eval1_map { - struct gl_1d_map *map; - GLuint sz; -}; - -struct brw_exec_eval2_map { - struct gl_2d_map *map; - GLuint sz; -}; - - - -struct brw_exec_copied_vtx { - GLfloat buffer[BRW_ATTRIB_MAX * 4 * BRW_MAX_COPIED_VERTS]; - GLuint nr; -}; - - -typedef void (*brw_attrfv_func)( const GLfloat * ); - - -struct brw_exec_context -{ - GLcontext *ctx; - GLvertexformat vtxfmt; - - struct { - struct gl_buffer_object *bufferobj; - GLubyte *buffer_map; - - GLuint vertex_size; - - struct brw_draw_prim prim[BRW_MAX_PRIM]; - GLuint prim_count; - - GLfloat *vbptr; /* cursor, points into buffer */ - GLfloat vertex[BRW_ATTRIB_MAX*4]; /* current vertex */ - - GLfloat *current[BRW_ATTRIB_MAX]; /* points into ctx->Current, ctx->Light.Material */ - GLfloat CurrentFloatEdgeFlag; - - GLuint vert_count; - GLuint max_vert; - struct brw_exec_copied_vtx copied; - - GLubyte attrsz[BRW_ATTRIB_MAX]; - GLubyte active_sz[BRW_ATTRIB_MAX]; - - GLfloat *attrptr[BRW_ATTRIB_MAX]; - struct gl_client_array arrays[BRW_ATTRIB_MAX]; - const struct gl_client_array *inputs[BRW_ATTRIB_MAX]; - } vtx; - - - struct { - GLboolean recalculate_maps; - struct brw_exec_eval1_map map1[BRW_ATTRIB_MAX]; - struct brw_exec_eval2_map map2[BRW_ATTRIB_MAX]; - } eval; - - struct { - const struct gl_client_array *inputs[BRW_ATTRIB_MAX]; - - struct gl_buffer_object *index_obj; - } array; -}; - - - -/* External API: - */ -void brw_exec_init( GLcontext *ctx ); -void brw_exec_destroy( GLcontext *ctx ); -void brw_exec_invalidate_state( GLcontext *ctx, GLuint new_state ); -void brw_exec_FlushVertices( GLcontext *ctx, GLuint flags ); -void brw_exec_wakeup( GLcontext *ctx ); - - -/* Internal functions: - */ -void brw_exec_array_init( struct brw_exec_context *exec ); -void brw_exec_array_destroy( struct brw_exec_context *exec ); - - -void brw_exec_vtx_init( struct brw_exec_context *exec ); -void brw_exec_vtx_destroy( struct brw_exec_context *exec ); -void brw_exec_vtx_flush( struct brw_exec_context *exec ); -void brw_exec_vtx_wrap( struct brw_exec_context *exec ); - -void brw_exec_eval_update( struct brw_exec_context *exec ); - -void brw_exec_do_EvalCoord2f( struct brw_exec_context *exec, - GLfloat u, GLfloat v ); - -void brw_exec_do_EvalCoord1f( struct brw_exec_context *exec, - GLfloat u); - -#endif diff --git a/src/mesa/drivers/dri/i965/brw_exec_api.c b/src/mesa/drivers/dri/i965/brw_exec_api.c deleted file mode 100644 index 470fa6f417..0000000000 --- a/src/mesa/drivers/dri/i965/brw_exec_api.c +++ /dev/null @@ -1,716 +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 - */ - -#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 "dispatch.h" - -#include "brw_exec.h" - -static void reset_attrfv( struct brw_exec_context *exec ); - - -/* Close off the last primitive, execute the buffer, restart the - * primitive. - */ -static void brw_exec_wrap_buffers( struct brw_exec_context *exec ) -{ - if (exec->vtx.prim_count == 0) { - exec->vtx.copied.nr = 0; - exec->vtx.vert_count = 0; - exec->vtx.vbptr = (GLfloat *)exec->vtx.buffer_map; - } - else { - GLuint last_begin = exec->vtx.prim[exec->vtx.prim_count-1].begin; - GLuint last_count; - - if (exec->ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) { - GLint i = exec->vtx.prim_count - 1; - assert(i >= 0); - exec->vtx.prim[i].count = (exec->vtx.vert_count - - exec->vtx.prim[i].start); - } - - last_count = exec->vtx.prim[exec->vtx.prim_count-1].count; - - /* Execute the buffer and save copied vertices. - */ - if (exec->vtx.vert_count) - brw_exec_vtx_flush( exec ); - else { - exec->vtx.prim_count = 0; - exec->vtx.copied.nr = 0; - } - - /* Emit a glBegin to start the new list. - */ - assert(exec->vtx.prim_count == 0); - - if (exec->ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) { - exec->vtx.prim[0].mode = exec->ctx->Driver.CurrentExecPrimitive; - exec->vtx.prim[0].start = 0; - exec->vtx.prim[0].count = 0; - exec->vtx.prim_count++; - - if (exec->vtx.copied.nr == last_count) - exec->vtx.prim[0].begin = last_begin; - } - } -} - - -/* Deal with buffer wrapping where provoked by the vertex buffer - * filling up, as opposed to upgrade_vertex(). - */ -void brw_exec_vtx_wrap( struct brw_exec_context *exec ) -{ - GLfloat *data = exec->vtx.copied.buffer; - GLuint i; - - /* Run pipeline on current vertices, copy wrapped vertices - * to exec->vtx.copied. - */ - brw_exec_wrap_buffers( exec ); - - /* Copy stored stored vertices to start of new list. - */ - assert(exec->vtx.max_vert - exec->vtx.vert_count > exec->vtx.copied.nr); - - for (i = 0 ; i < exec->vtx.copied.nr ; i++) { - _mesa_memcpy( exec->vtx.vbptr, data, - exec->vtx.vertex_size * sizeof(GLfloat)); - exec->vtx.vbptr += exec->vtx.vertex_size; - data += exec->vtx.vertex_size; - exec->vtx.vert_count++; - } - - exec->vtx.copied.nr = 0; -} - - -/* - * Copy the active vertex's values to the ctx->Current fields. - */ -static void brw_exec_copy_to_current( struct brw_exec_context *exec ) -{ - GLcontext *ctx = exec->ctx; - GLuint i; - - for (i = BRW_ATTRIB_POS+1 ; i < BRW_ATTRIB_MAX ; i++) { - if (exec->vtx.attrsz[i]) { - /* Note: the exec->vtx.current[i] pointers point into the - * ctx->Current.Attrib and ctx->Light.Material.Attrib arrays. - */ - COPY_CLEAN_4V(exec->vtx.current[i], - exec->vtx.attrsz[i], - exec->vtx.attrptr[i]); - - /* This triggers rather too much recalculation of Mesa state - * that doesn't get used (eg light positions). - */ - if (i >= BRW_ATTRIB_MAT_FRONT_AMBIENT && - i <= BRW_ATTRIB_MAT_BACK_INDEXES) - ctx->NewState |= _NEW_LIGHT; - } - } - - /* color index is special (it's not a float[4] so COPY_CLEAN_4V above - * will trash adjacent memory!) - */ - if (exec->vtx.attrsz[BRW_ATTRIB_INDEX]) { - ctx->Current.Index = exec->vtx.attrptr[BRW_ATTRIB_INDEX][0]; - } - - /* Edgeflag requires additional treatment: - */ - if (exec->vtx.attrsz[BRW_ATTRIB_EDGEFLAG]) { - ctx->Current.EdgeFlag = (exec->vtx.CurrentFloatEdgeFlag == 1.0); - } - - /* Colormaterial -- this kindof sucks. - */ - if (ctx->Light.ColorMaterialEnabled && - exec->vtx.attrsz[BRW_ATTRIB_COLOR0]) { - _mesa_update_color_material(ctx, - ctx->Current.Attrib[BRW_ATTRIB_COLOR0]); - } - - ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT; -} - - -static void brw_exec_copy_from_current( struct brw_exec_context *exec ) -{ - GLcontext *ctx = exec->ctx; - GLint i; - - /* Edgeflag requires additional treatment: - */ - exec->vtx.CurrentFloatEdgeFlag = - (GLfloat)ctx->Current.EdgeFlag; - - for (i = BRW_ATTRIB_POS+1 ; i < BRW_ATTRIB_MAX ; i++) - switch (exec->vtx.attrsz[i]) { - case 4: exec->vtx.attrptr[i][3] = exec->vtx.current[i][3]; - case 3: exec->vtx.attrptr[i][2] = exec->vtx.current[i][2]; - case 2: exec->vtx.attrptr[i][1] = exec->vtx.current[i][1]; - case 1: exec->vtx.attrptr[i][0] = exec->vtx.current[i][0]; - break; - } - - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; -} - - -/* Flush existing data, set new attrib size, replay copied vertices. - */ -static void brw_exec_wrap_upgrade_vertex( struct brw_exec_context *exec, - GLuint attr, - GLuint newsz ) -{ - GLcontext *ctx = exec->ctx; - GLint lastcount = exec->vtx.vert_count; - GLfloat *tmp; - GLuint oldsz; - GLuint i; - - /* Run pipeline on current vertices, copy wrapped vertices - * to exec->vtx.copied. - */ - brw_exec_wrap_buffers( exec ); - - - /* Do a COPY_TO_CURRENT to ensure back-copying works for the case - * when the attribute already exists in the vertex and is having - * its size increased. - */ - brw_exec_copy_to_current( exec ); - - - /* Heuristic: Attempt to isolate attributes received outside - * begin/end so that they don't bloat the vertices. - */ - if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END && - exec->vtx.attrsz[attr] == 0 && - lastcount > 8 && - exec->vtx.vertex_size) { - reset_attrfv( exec ); - } - - /* Fix up sizes: - */ - oldsz = exec->vtx.attrsz[attr]; - exec->vtx.attrsz[attr] = newsz; - - exec->vtx.vertex_size += newsz - oldsz; - exec->vtx.max_vert = BRW_VERT_BUFFER_SIZE / exec->vtx.vertex_size; - exec->vtx.vert_count = 0; - exec->vtx.vbptr = (GLfloat *)exec->vtx.buffer_map; - - - /* Recalculate all the attrptr[] values - */ - for (i = 0, tmp = exec->vtx.vertex ; i < BRW_ATTRIB_MAX ; i++) { - if (exec->vtx.attrsz[i]) { - exec->vtx.attrptr[i] = tmp; - tmp += exec->vtx.attrsz[i]; - } - else - exec->vtx.attrptr[i] = NULL; /* will not be dereferenced */ - } - - /* Copy from current to repopulate the vertex with correct values. - */ - brw_exec_copy_from_current( exec ); - - /* Replay stored vertices to translate them - * to new format here. - * - * -- No need to replay - just copy piecewise - */ - if (exec->vtx.copied.nr) - { - GLfloat *data = exec->vtx.copied.buffer; - GLfloat *dest = exec->vtx.vbptr; - GLuint j; - - assert(exec->vtx.vbptr == (GLfloat *)exec->vtx.buffer_map); - - for (i = 0 ; i < exec->vtx.copied.nr ; i++) { - for (j = 0 ; j < BRW_ATTRIB_MAX ; j++) { - if (exec->vtx.attrsz[j]) { - if (j == attr) { - if (oldsz) { - COPY_CLEAN_4V( dest, oldsz, data ); - data += oldsz; - dest += newsz; - } else { - COPY_SZ_4V( dest, newsz, exec->vtx.current[j] ); - dest += newsz; - } - } - else { - GLuint sz = exec->vtx.attrsz[j]; - COPY_SZ_4V( dest, sz, data ); - dest += sz; - data += sz; - } - } - } - } - - exec->vtx.vbptr = dest; - exec->vtx.vert_count += exec->vtx.copied.nr; - exec->vtx.copied.nr = 0; - } -} - - -static void brw_exec_fixup_vertex( GLcontext *ctx, - GLuint attr, GLuint sz ) -{ - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - int i; - - if (sz > exec->vtx.attrsz[attr]) { - /* New size is larger. Need to flush existing vertices and get - * an enlarged vertex format. - */ - brw_exec_wrap_upgrade_vertex( exec, attr, sz ); - } - else if (sz < exec->vtx.active_sz[attr]) { - static const GLfloat id[4] = { 0, 0, 0, 1 }; - - /* New size is smaller - just need to fill in some - * zeros. Don't need to flush or wrap. - */ - for (i = sz ; i <= exec->vtx.attrsz[attr] ; i++) - exec->vtx.attrptr[attr][i-1] = id[i-1]; - } - - exec->vtx.active_sz[attr] = sz; - - /* Does setting NeedFlush belong here? Necessitates resetting - * vtxfmt on each flush (otherwise flags won't get reset - * afterwards). - */ - if (attr == 0) - exec->ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; - else - exec->ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; -} - - - - -/* - */ -#define ATTR( A, N, V0, V1, V2, V3 ) \ -do { \ - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; \ - \ - if (exec->vtx.active_sz[A] != N) \ - brw_exec_fixup_vertex(ctx, A, N); \ - \ - { \ - GLfloat *dest = exec->vtx.attrptr[A]; \ - if (N>0) dest[0] = V0; \ - if (N>1) dest[1] = V1; \ - if (N>2) dest[2] = V2; \ - if (N>3) dest[3] = V3; \ - } \ - \ - if ((A) == 0) { \ - GLuint i; \ - \ - for (i = 0; i < exec->vtx.vertex_size; i++) \ - exec->vtx.vbptr[i] = exec->vtx.vertex[i]; \ - \ - exec->vtx.vbptr += exec->vtx.vertex_size; \ - exec->ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; \ - \ - if (++exec->vtx.vert_count >= exec->vtx.max_vert) \ - brw_exec_vtx_wrap( exec ); \ - } \ -} while (0) - - -#define ERROR() _mesa_error( ctx, GL_INVALID_ENUM, __FUNCTION__ ) -#define TAG(x) brw_##x - -#include "brw_attrib_tmp.h" - - - - - -/* Eval - */ -static void GLAPIENTRY brw_exec_EvalCoord1f( GLfloat u ) -{ - GET_CURRENT_CONTEXT( ctx ); - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - - { - GLint i; - if (exec->eval.recalculate_maps) - brw_exec_eval_update( exec ); - - for (i = 0 ; i <= BRW_ATTRIB_INDEX ; i++) { - if (exec->eval.map1[i].map) - if (exec->vtx.active_sz[i] != exec->eval.map1[i].sz) - brw_exec_fixup_vertex( ctx, i, exec->eval.map1[i].sz ); - } - } - - - _mesa_memcpy( exec->vtx.copied.buffer, exec->vtx.vertex, - exec->vtx.vertex_size * sizeof(GLfloat)); - - brw_exec_do_EvalCoord1f( exec, u ); - - _mesa_memcpy( exec->vtx.vertex, exec->vtx.copied.buffer, - exec->vtx.vertex_size * sizeof(GLfloat)); -} - -static void GLAPIENTRY brw_exec_EvalCoord2f( GLfloat u, GLfloat v ) -{ - GET_CURRENT_CONTEXT( ctx ); - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - - { - GLint i; - if (exec->eval.recalculate_maps) - brw_exec_eval_update( exec ); - - for (i = 0 ; i <= BRW_ATTRIB_INDEX ; i++) { - if (exec->eval.map2[i].map) - if (exec->vtx.active_sz[i] != exec->eval.map2[i].sz) - brw_exec_fixup_vertex( ctx, i, exec->eval.map2[i].sz ); - } - - if (ctx->Eval.AutoNormal) - if (exec->vtx.active_sz[BRW_ATTRIB_NORMAL] != 3) - brw_exec_fixup_vertex( ctx, BRW_ATTRIB_NORMAL, 3 ); - } - - _mesa_memcpy( exec->vtx.copied.buffer, exec->vtx.vertex, - exec->vtx.vertex_size * sizeof(GLfloat)); - - brw_exec_do_EvalCoord2f( exec, u, v ); - - _mesa_memcpy( exec->vtx.vertex, exec->vtx.copied.buffer, - exec->vtx.vertex_size * sizeof(GLfloat)); -} - -static void GLAPIENTRY brw_exec_EvalCoord1fv( const GLfloat *u ) -{ - brw_exec_EvalCoord1f( u[0] ); -} - -static void GLAPIENTRY brw_exec_EvalCoord2fv( const GLfloat *u ) -{ - brw_exec_EvalCoord2f( u[0], u[1] ); -} - -static void GLAPIENTRY brw_exec_EvalPoint1( GLint i ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLfloat du = ((ctx->Eval.MapGrid1u2 - ctx->Eval.MapGrid1u1) / - (GLfloat) ctx->Eval.MapGrid1un); - GLfloat u = i * du + ctx->Eval.MapGrid1u1; - - brw_exec_EvalCoord1f( u ); -} - - -static void GLAPIENTRY brw_exec_EvalPoint2( GLint i, GLint j ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLfloat du = ((ctx->Eval.MapGrid2u2 - ctx->Eval.MapGrid2u1) / - (GLfloat) ctx->Eval.MapGrid2un); - GLfloat dv = ((ctx->Eval.MapGrid2v2 - ctx->Eval.MapGrid2v1) / - (GLfloat) ctx->Eval.MapGrid2vn); - GLfloat u = i * du + ctx->Eval.MapGrid2u1; - GLfloat v = j * dv + ctx->Eval.MapGrid2v1; - - brw_exec_EvalCoord2f( u, v ); -} - - -/* Build a list of primitives on the fly. Keep - * ctx->Driver.CurrentExecPrimitive uptodate as well. - */ -static void GLAPIENTRY brw_exec_Begin( GLenum mode ) -{ - GET_CURRENT_CONTEXT( ctx ); - - if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) { - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - int i; - - 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; - } - - CALL_Begin(ctx->Exec, (mode)); - return; - } - - /* Heuristic: attempt to isolate attributes occuring outside - * begin/end pairs. - */ - if (exec->vtx.vertex_size && !exec->vtx.attrsz[0]) - brw_exec_FlushVertices( ctx, ~0 ); - - i = exec->vtx.prim_count++; - exec->vtx.prim[i].mode = mode; - exec->vtx.prim[i].begin = 1; - exec->vtx.prim[i].end = 0; - exec->vtx.prim[i].indexed = 0; - exec->vtx.prim[i].weak = 0; - exec->vtx.prim[i].pad = 0; - exec->vtx.prim[i].start = exec->vtx.vert_count; - exec->vtx.prim[i].count = 0; - - ctx->Driver.CurrentExecPrimitive = mode; - } - else - _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" ); - -} - -static void GLAPIENTRY brw_exec_End( void ) -{ - GET_CURRENT_CONTEXT( ctx ); - - if (ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) { - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - int idx = exec->vtx.vert_count; - int i = exec->vtx.prim_count - 1; - - exec->vtx.prim[i].end = 1; - exec->vtx.prim[i].count = idx - exec->vtx.prim[i].start; - - ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1; - - if (exec->vtx.prim_count == BRW_MAX_PRIM) - brw_exec_vtx_flush( exec ); - } - else - _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" ); -} - - -static void brw_exec_vtxfmt_init( struct brw_exec_context *exec ) -{ - GLvertexformat *vfmt = &exec->vtxfmt; - - vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ - vfmt->Begin = brw_exec_Begin; - vfmt->CallList = _mesa_CallList; - vfmt->CallLists = _mesa_CallLists; - vfmt->End = brw_exec_End; - vfmt->EvalCoord1f = brw_exec_EvalCoord1f; - vfmt->EvalCoord1fv = brw_exec_EvalCoord1fv; - vfmt->EvalCoord2f = brw_exec_EvalCoord2f; - vfmt->EvalCoord2fv = brw_exec_EvalCoord2fv; - vfmt->EvalPoint1 = brw_exec_EvalPoint1; - vfmt->EvalPoint2 = brw_exec_EvalPoint2; - - vfmt->Rectf = _mesa_noop_Rectf; - vfmt->EvalMesh1 = _mesa_noop_EvalMesh1; - vfmt->EvalMesh2 = _mesa_noop_EvalMesh2; - - - /* from attrib_tmp.h: - */ - vfmt->Color3f = brw_Color3f; - vfmt->Color3fv = brw_Color3fv; - vfmt->Color4f = brw_Color4f; - vfmt->Color4fv = brw_Color4fv; - vfmt->FogCoordfEXT = brw_FogCoordfEXT; - vfmt->FogCoordfvEXT = brw_FogCoordfvEXT; - vfmt->MultiTexCoord1fARB = brw_MultiTexCoord1f; - vfmt->MultiTexCoord1fvARB = brw_MultiTexCoord1fv; - vfmt->MultiTexCoord2fARB = brw_MultiTexCoord2f; - vfmt->MultiTexCoord2fvARB = brw_MultiTexCoord2fv; - vfmt->MultiTexCoord3fARB = brw_MultiTexCoord3f; - vfmt->MultiTexCoord3fvARB = brw_MultiTexCoord3fv; - vfmt->MultiTexCoord4fARB = brw_MultiTexCoord4f; - vfmt->MultiTexCoord4fvARB = brw_MultiTexCoord4fv; - vfmt->Normal3f = brw_Normal3f; - vfmt->Normal3fv = brw_Normal3fv; - vfmt->SecondaryColor3fEXT = brw_SecondaryColor3fEXT; - vfmt->SecondaryColor3fvEXT = brw_SecondaryColor3fvEXT; - vfmt->TexCoord1f = brw_TexCoord1f; - vfmt->TexCoord1fv = brw_TexCoord1fv; - vfmt->TexCoord2f = brw_TexCoord2f; - vfmt->TexCoord2fv = brw_TexCoord2fv; - vfmt->TexCoord3f = brw_TexCoord3f; - vfmt->TexCoord3fv = brw_TexCoord3fv; - vfmt->TexCoord4f = brw_TexCoord4f; - vfmt->TexCoord4fv = brw_TexCoord4fv; - vfmt->Vertex2f = brw_Vertex2f; - vfmt->Vertex2fv = brw_Vertex2fv; - vfmt->Vertex3f = brw_Vertex3f; - vfmt->Vertex3fv = brw_Vertex3fv; - vfmt->Vertex4f = brw_Vertex4f; - vfmt->Vertex4fv = brw_Vertex4fv; - - vfmt->VertexAttrib1fARB = brw_VertexAttrib1fARB; - vfmt->VertexAttrib1fvARB = brw_VertexAttrib1fvARB; - vfmt->VertexAttrib2fARB = brw_VertexAttrib2fARB; - vfmt->VertexAttrib2fvARB = brw_VertexAttrib2fvARB; - vfmt->VertexAttrib3fARB = brw_VertexAttrib3fARB; - vfmt->VertexAttrib3fvARB = brw_VertexAttrib3fvARB; - vfmt->VertexAttrib4fARB = brw_VertexAttrib4fARB; - vfmt->VertexAttrib4fvARB = brw_VertexAttrib4fvARB; - - vfmt->VertexAttrib1fNV = brw_VertexAttrib1fNV; - vfmt->VertexAttrib1fvNV = brw_VertexAttrib1fvNV; - vfmt->VertexAttrib2fNV = brw_VertexAttrib2fNV; - vfmt->VertexAttrib2fvNV = brw_VertexAttrib2fvNV; - vfmt->VertexAttrib3fNV = brw_VertexAttrib3fNV; - vfmt->VertexAttrib3fvNV = brw_VertexAttrib3fvNV; - vfmt->VertexAttrib4fNV = brw_VertexAttrib4fNV; - vfmt->VertexAttrib4fvNV = brw_VertexAttrib4fvNV; - - vfmt->Materialfv = brw_Materialfv; - - vfmt->EdgeFlag = brw_EdgeFlag; - vfmt->Indexf = brw_Indexf; - vfmt->Indexfv = brw_Indexfv; - -} - - -static void brw_exec_current_init( struct brw_exec_context *exec ) -{ - GLcontext *ctx = exec->ctx; - GLint i; - - /* setup the pointers for the typical 16 vertex attributes */ - for (i = 0; i < BRW_ATTRIB_FIRST_MATERIAL; i++) - exec->vtx.current[i] = ctx->Current.Attrib[i]; - - /* setup pointers for the 12 material attributes */ - for (i = 0; i < MAT_ATTRIB_MAX; i++) - exec->vtx.current[BRW_ATTRIB_FIRST_MATERIAL + i] = - ctx->Light.Material.Attrib[i]; - - exec->vtx.current[BRW_ATTRIB_INDEX] = &ctx->Current.Index; - exec->vtx.current[BRW_ATTRIB_EDGEFLAG] = &exec->vtx.CurrentFloatEdgeFlag; -} - -void brw_exec_vtx_init( struct brw_exec_context *exec ) -{ - GLcontext *ctx = exec->ctx; - GLuint i; - - /* Allocate a buffer object. Will just reuse this object - * continuously. - */ - exec->vtx.bufferobj = ctx->Array.NullBufferObj; - exec->vtx.buffer_map = ALIGN_MALLOC(BRW_VERT_BUFFER_SIZE * sizeof(GLfloat), 64); - - brw_exec_current_init( exec ); - brw_exec_vtxfmt_init( exec ); - - /* Hook our functions into the dispatch table. - */ - _mesa_install_exec_vtxfmt( exec->ctx, &exec->vtxfmt ); - - for (i = 0 ; i < BRW_ATTRIB_MAX ; i++) { - exec->vtx.attrsz[i] = 0; - exec->vtx.active_sz[i] = 0; - exec->vtx.inputs[i] = &exec->vtx.arrays[i]; - } - - exec->vtx.vertex_size = 0; -} - - -void brw_exec_vtx_destroy( struct brw_exec_context *exec ) -{ - if (exec->vtx.buffer_map) { - ALIGN_FREE(exec->vtx.buffer_map); - exec->vtx.buffer_map = NULL; - } -} - - -void brw_exec_FlushVertices( GLcontext *ctx, GLuint flags ) -{ - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - - if (exec->ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) - return; - - if (exec->vtx.vert_count) { - brw_exec_vtx_flush( exec ); - } - - if (exec->vtx.vertex_size) { - brw_exec_copy_to_current( exec ); - reset_attrfv( exec ); - } - - exec->ctx->Driver.NeedFlush = 0; -} - - -static void reset_attrfv( struct brw_exec_context *exec ) -{ - GLuint i; - - for (i = 0 ; i < BRW_ATTRIB_MAX ; i++) { - exec->vtx.attrsz[i] = 0; - exec->vtx.active_sz[i] = 0; - } - - exec->vtx.vertex_size = 0; -} - diff --git a/src/mesa/drivers/dri/i965/brw_exec_array.c b/src/mesa/drivers/dri/i965/brw_exec_array.c deleted file mode 100644 index ca19a19837..0000000000 --- a/src/mesa/drivers/dri/i965/brw_exec_array.c +++ /dev/null @@ -1,283 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 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 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 ITS 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. - * - **************************************************************************/ - -#include "glheader.h" -#include "context.h" -#include "state.h" -#include "api_validate.h" -#include "api_noop.h" -#include "dispatch.h" - -#include "brw_attrib.h" -#include "brw_draw.h" -#include "brw_exec.h" -#include "brw_fallback.h" - -static GLuint get_max_index( GLuint count, GLuint type, - const GLvoid *indices ) -{ - GLint i; - - /* Compute max element. This is only needed for upload of non-VBO, - * non-constant data elements. - * - * XXX: Postpone this calculation until it is known that it is - * needed. Otherwise could scan this pointlessly in the all-vbo - * case. - */ - switch(type) { - case GL_UNSIGNED_INT: { - const GLuint *ui_indices = (const GLuint *)indices; - GLuint max_ui = 0; - for (i = 0; i < count; i++) - if (ui_indices[i] > max_ui) - max_ui = ui_indices[i]; - return max_ui; - } - case GL_UNSIGNED_SHORT: { - const GLushort *us_indices = (const GLushort *)indices; - GLuint max_us = 0; - for (i = 0; i < count; i++) - if (us_indices[i] > max_us) - max_us = us_indices[i]; - return max_us; - } - case GL_UNSIGNED_BYTE: { - const GLubyte *ub_indices = (const GLubyte *)indices; - GLuint max_ub = 0; - for (i = 0; i < count; i++) - if (ub_indices[i] > max_ub) - max_ub = ub_indices[i]; - return max_ub; - } - default: - return 0; - } -} - - - - -/*********************************************************************** - * API functions. - */ - -static void GLAPIENTRY -brw_exec_DrawArrays(GLenum mode, GLint start, GLsizei count) -{ - GET_CURRENT_CONTEXT(ctx); - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - struct brw_draw_prim prim[1]; - GLboolean ok; - - if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) - return; - - FLUSH_CURRENT( ctx, 0 ); - - if (ctx->NewState) - _mesa_update_state( ctx ); - - prim[0].begin = 1; - prim[0].end = 1; - prim[0].weak = 0; - prim[0].pad = 0; - - if (exec->array.inputs[0]->BufferObj->Name) { - /* Use vertex attribute as a hint to tell us if we expect all - * arrays to be in VBO's and if so, don't worry about avoiding - * the upload of elements < start. - */ - prim[0].mode = mode; - prim[0].start = start; - prim[0].count = count; - prim[0].indexed = 0; - - ok = brw_draw_prims( ctx, exec->array.inputs, prim, 1, NULL, 0, start + count, 0 ); - } - else { - /* If not using VBO's, we don't want to upload any more elements - * than necessary from the arrays as they will not be valid next - * time the application tries to draw with them. - */ - prim[0].mode = mode; - prim[0].start = 0; - prim[0].count = count; - prim[0].indexed = 0; - - ok = brw_draw_prims( ctx, exec->array.inputs, prim, 1, NULL, start, start + count, 0 ); - } - - if (!ok) { - brw_fallback(ctx); - CALL_DrawArrays(ctx->Exec, ( mode, start, count )); - brw_unfallback(ctx); - } -} - - - -static void GLAPIENTRY -brw_exec_DrawRangeElements(GLenum mode, - GLuint start, GLuint end, - GLsizei count, GLenum type, const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - struct brw_draw_index_buffer ib; - struct brw_draw_prim prim[1]; - - if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count, type, indices )) - return; - - FLUSH_CURRENT( ctx, 0 ); - - if (ctx->NewState) - _mesa_update_state( ctx ); - - ib.count = count; - ib.type = type; - ib.obj = ctx->Array.ElementArrayBufferObj; - ib.ptr = indices; - - if (ctx->Array.ElementArrayBufferObj->Name) { - /* Use the fact that indices are in a VBO as a hint that the - * program has put all the arrays in VBO's and we don't have to - * worry about performance implications of start > 0. - * - * XXX: consider passing start as min_index to draw_prims instead. - */ - ib.rebase = 0; - } - else { - ib.rebase = start; - } - - prim[0].begin = 1; - prim[0].end = 1; - prim[0].weak = 0; - prim[0].pad = 0; - prim[0].mode = mode; - prim[0].start = 0; - prim[0].count = count; - prim[0].indexed = 1; - - if (!brw_draw_prims( ctx, exec->array.inputs, prim, 1, &ib, ib.rebase, end+1, 0 )) { - brw_fallback(ctx); - CALL_DrawRangeElements(ctx->Exec, (mode, start, end, count, type, indices)); - brw_unfallback(ctx); - } -} - - -static void GLAPIENTRY -brw_exec_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - GLuint max_index; - - if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) - return; - - if (ctx->Array.ElementArrayBufferObj->Name) { - const GLvoid *map = ctx->Driver.MapBuffer(ctx, - GL_ELEMENT_ARRAY_BUFFER_ARB, - GL_DYNAMIC_READ_ARB, - ctx->Array.ElementArrayBufferObj); - - max_index = get_max_index(count, type, ADD_POINTERS(map, indices)); - - ctx->Driver.UnmapBuffer(ctx, - GL_ELEMENT_ARRAY_BUFFER_ARB, - ctx->Array.ElementArrayBufferObj); - } - else { - max_index = get_max_index(count, type, indices); - } - - brw_exec_DrawRangeElements(mode, 0, max_index, count, type, indices); -} - - -/*********************************************************************** - * Initialization - */ - - -static void init_arrays( GLcontext *ctx, - const struct gl_client_array *arrays[] ) -{ - struct gl_array_object *obj = ctx->Array.ArrayObj; - GLuint i; - - memset(arrays, 0, sizeof(*arrays) * BRW_ATTRIB_MAX); - - arrays[BRW_ATTRIB_POS] = &obj->Vertex; - arrays[BRW_ATTRIB_NORMAL] = &obj->Normal; - arrays[BRW_ATTRIB_COLOR0] = &obj->Color; - arrays[BRW_ATTRIB_COLOR1] = &obj->SecondaryColor; - arrays[BRW_ATTRIB_FOG] = &obj->FogCoord; - - for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) - arrays[BRW_ATTRIB_TEX0 + i] = &obj->TexCoord[i]; - - arrays[BRW_ATTRIB_INDEX] = &obj->Index; - arrays[BRW_ATTRIB_EDGEFLAG] = &obj->EdgeFlag; - - for (i = BRW_ATTRIB_GENERIC0; i <= BRW_ATTRIB_GENERIC15; i++) - arrays[i] = &obj->VertexAttrib[i - BRW_ATTRIB_GENERIC0]; -} - - - - -void brw_exec_array_init( struct brw_exec_context *exec ) -{ - GLcontext *ctx = exec->ctx; - - init_arrays(ctx, exec->array.inputs); - -#if 1 - exec->vtxfmt.DrawArrays = brw_exec_DrawArrays; - exec->vtxfmt.DrawElements = brw_exec_DrawElements; - exec->vtxfmt.DrawRangeElements = brw_exec_DrawRangeElements; -#else - exec->vtxfmt.DrawArrays = _mesa_noop_DrawArrays; - exec->vtxfmt.DrawElements = _mesa_noop_DrawElements; - exec->vtxfmt.DrawRangeElements = _mesa_noop_DrawRangeElements; -#endif - - exec->array.index_obj = ctx->Driver.NewBufferObject(ctx, 1, GL_ARRAY_BUFFER_ARB); -} - - -void brw_exec_array_destroy( struct brw_exec_context *exec ) -{ - GLcontext *ctx = exec->ctx; - - ctx->Driver.DeleteBuffer(ctx, exec->array.index_obj); -} diff --git a/src/mesa/drivers/dri/i965/brw_exec_draw.c b/src/mesa/drivers/dri/i965/brw_exec_draw.c deleted file mode 100644 index 62bda9845b..0000000000 --- a/src/mesa/drivers/dri/i965/brw_exec_draw.c +++ /dev/null @@ -1,227 +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 - */ - -#include "glheader.h" -#include "context.h" -#include "enums.h" -#include "state.h" -#include "macros.h" - -#include "brw_exec.h" -#include "brw_draw.h" -#include "brw_fallback.h" - - -static void brw_exec_debug_verts( struct brw_exec_context *exec ) -{ - GLuint count = exec->vtx.vert_count; - GLuint i; - - _mesa_printf("%s: %u vertices %d primitives, %d vertsize\n", - __FUNCTION__, - count, - exec->vtx.prim_count, - exec->vtx.vertex_size); - - for (i = 0 ; i < exec->vtx.prim_count ; i++) { - struct brw_draw_prim *prim = &exec->vtx.prim[i]; - _mesa_printf(" prim %d: %s%s %d..%d %s %s\n", - i, - _mesa_lookup_enum_by_nr(prim->mode), - prim->weak ? " (weak)" : "", - prim->start, - prim->start + prim->count, - prim->begin ? "BEGIN" : "(wrap)", - prim->end ? "END" : "(wrap)"); - } -} - - -/* - * NOTE: Need to have calculated primitives by this point -- do it on the fly. - * NOTE: Old 'parity' issue is gone. - */ -static GLuint brw_copy_vertices( struct brw_exec_context *exec ) -{ - GLuint nr = exec->vtx.prim[exec->vtx.prim_count-1].count; - GLuint ovf, i; - GLuint sz = exec->vtx.vertex_size; - GLfloat *dst = exec->vtx.copied.buffer; - GLfloat *src = ((GLfloat *)exec->vtx.buffer_map + - exec->vtx.prim[exec->vtx.prim_count-1].start * - exec->vtx.vertex_size); - - - switch( exec->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 GL_POLYGON+1: - return 0; - default: - assert(0); - return 0; - } -} - - -/* TODO: populate these as the vertex is defined: - */ -static void brw_exec_bind_arrays( struct brw_exec_context *exec ) -{ - struct gl_client_array *arrays = exec->vtx.arrays; - GLuint count = exec->vtx.vert_count; - GLubyte *data = exec->vtx.buffer_map; - GLuint attr; - - memset(arrays, 0, BRW_ATTRIB_MAX * sizeof(arrays[0])); - - /* Make all active attributes (including edgeflag) available as - * arrays of floats. - */ - for (attr = 0; attr < BRW_ATTRIB_MAX ; attr++) { - if (exec->vtx.attrsz[attr]) { - arrays[attr].Ptr = (void *)data; - arrays[attr].Size = exec->vtx.attrsz[attr]; - arrays[attr].StrideB = exec->vtx.vertex_size * sizeof(GLfloat); - arrays[attr].Stride = exec->vtx.vertex_size * sizeof(GLfloat); - arrays[attr].Type = GL_FLOAT; - arrays[attr].Enabled = 1; - arrays[attr].BufferObj = exec->vtx.bufferobj; /* NullBufferObj */ - arrays[attr]._MaxElement = count; /* ??? */ - - data += exec->vtx.attrsz[attr] * sizeof(GLfloat); - } - } -} - - -static -void brw_exec_loopback_vertex_list( GLcontext *ctx, - struct brw_exec_context *exec ) -{ - const GLfloat *buffer = (const GLfloat *)exec->vtx.buffer_map; - - brw_fallback(ctx); - - brw_loopback_vertex_list( ctx, - buffer, - exec->vtx.attrsz, - exec->vtx.prim, - exec->vtx.prim_count, - 0, /* XXX - copied.nr */ - exec->vtx.vertex_size); - - - brw_unfallback(ctx); -} - - -/** - * Execute the buffer and save copied verts. - */ -void brw_exec_vtx_flush( struct brw_exec_context *exec ) -{ - if (0) - brw_exec_debug_verts( exec ); - - - if (exec->vtx.prim_count && - exec->vtx.vert_count) { - - exec->vtx.copied.nr = brw_copy_vertices( exec ); - - if (exec->vtx.copied.nr != exec->vtx.vert_count) { - GLcontext *ctx = exec->ctx; - - brw_exec_bind_arrays( exec ); - - - if (!brw_draw_prims( ctx, - exec->vtx.inputs, - exec->vtx.prim, - exec->vtx.prim_count, - NULL, - 0, - exec->vtx.vert_count, - 0 )) { - /* Fallback path: - */ - brw_exec_loopback_vertex_list(ctx, exec); - } - } - } - - exec->vtx.prim_count = 0; - exec->vtx.vert_count = 0; - exec->vtx.vbptr = (GLfloat *)exec->vtx.buffer_map; -} diff --git a/src/mesa/drivers/dri/i965/brw_exec_eval.c b/src/mesa/drivers/dri/i965/brw_exec_eval.c deleted file mode 100644 index 9dbeb1b58e..0000000000 --- a/src/mesa/drivers/dri/i965/brw_exec_eval.c +++ /dev/null @@ -1,255 +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. - * - * Authors: - * Keith Whitwell - */ - -#include "glheader.h" -#include "api_eval.h" -#include "context.h" -#include "macros.h" -#include "math/m_eval.h" -#include "brw_exec.h" -#include "dispatch.h" - - -static void clear_active_eval1( struct brw_exec_context *exec, GLuint attr ) -{ - exec->eval.map1[attr].map = NULL; -} - -static void clear_active_eval2( struct brw_exec_context *exec, GLuint attr ) -{ - exec->eval.map2[attr].map = NULL; -} - -static void set_active_eval1( struct brw_exec_context *exec, GLuint attr, GLuint dim, - struct gl_1d_map *map ) -{ - if (!exec->eval.map1[attr].map) { - exec->eval.map1[attr].map = map; - exec->eval.map1[attr].sz = dim; - } -} - -static void set_active_eval2( struct brw_exec_context *exec, GLuint attr, GLuint dim, - struct gl_2d_map *map ) -{ - if (!exec->eval.map2[attr].map) { - exec->eval.map2[attr].map = map; - exec->eval.map2[attr].sz = dim; - } -} - -void brw_exec_eval_update( struct brw_exec_context *exec ) -{ - GLcontext *ctx = exec->ctx; - GLuint attr; - - /* Vertex program maps have priority over conventional attribs */ - - for (attr = 0; attr < BRW_ATTRIB_FIRST_MATERIAL; attr++) { - clear_active_eval1( exec, attr ); - clear_active_eval2( exec, attr ); - } - - /* _NEW_PROGRAM */ - if (ctx->VertexProgram._Enabled) { - for (attr = 0; attr < BRW_ATTRIB_FIRST_MATERIAL; attr++) { - /* _NEW_EVAL */ - if (ctx->Eval.Map1Attrib[attr]) - set_active_eval1( exec, attr, 4, &ctx->EvalMap.Map1Attrib[attr] ); - - if (ctx->Eval.Map2Attrib[attr]) - set_active_eval2( exec, attr, 4, &ctx->EvalMap.Map2Attrib[attr] ); - } - } - - if (ctx->Eval.Map1Color4) - set_active_eval1( exec, BRW_ATTRIB_COLOR0, 4, &ctx->EvalMap.Map1Color4 ); - - if (ctx->Eval.Map2Color4) - set_active_eval2( exec, BRW_ATTRIB_COLOR0, 4, &ctx->EvalMap.Map2Color4 ); - - if (ctx->Eval.Map1TextureCoord4) - set_active_eval1( exec, BRW_ATTRIB_TEX0, 4, &ctx->EvalMap.Map1Texture4 ); - else if (ctx->Eval.Map1TextureCoord3) - set_active_eval1( exec, BRW_ATTRIB_TEX0, 3, &ctx->EvalMap.Map1Texture3 ); - else if (ctx->Eval.Map1TextureCoord2) - set_active_eval1( exec, BRW_ATTRIB_TEX0, 2, &ctx->EvalMap.Map1Texture2 ); - else if (ctx->Eval.Map1TextureCoord1) - set_active_eval1( exec, BRW_ATTRIB_TEX0, 1, &ctx->EvalMap.Map1Texture1 ); - - if (ctx->Eval.Map2TextureCoord4) - set_active_eval2( exec, BRW_ATTRIB_TEX0, 4, &ctx->EvalMap.Map2Texture4 ); - else if (ctx->Eval.Map2TextureCoord3) - set_active_eval2( exec, BRW_ATTRIB_TEX0, 3, &ctx->EvalMap.Map2Texture3 ); - else if (ctx->Eval.Map2TextureCoord2) - set_active_eval2( exec, BRW_ATTRIB_TEX0, 2, &ctx->EvalMap.Map2Texture2 ); - else if (ctx->Eval.Map2TextureCoord1) - set_active_eval2( exec, BRW_ATTRIB_TEX0, 1, &ctx->EvalMap.Map2Texture1 ); - - if (ctx->Eval.Map1Normal) - set_active_eval1( exec, BRW_ATTRIB_NORMAL, 3, &ctx->EvalMap.Map1Normal ); - - if (ctx->Eval.Map2Normal) - set_active_eval2( exec, BRW_ATTRIB_NORMAL, 3, &ctx->EvalMap.Map2Normal ); - - if (ctx->Eval.Map1Vertex4) - set_active_eval1( exec, BRW_ATTRIB_POS, 4, &ctx->EvalMap.Map1Vertex4 ); - else if (ctx->Eval.Map1Vertex3) - set_active_eval1( exec, BRW_ATTRIB_POS, 3, &ctx->EvalMap.Map1Vertex3 ); - - if (ctx->Eval.Map2Vertex4) - set_active_eval2( exec, BRW_ATTRIB_POS, 4, &ctx->EvalMap.Map2Vertex4 ); - else if (ctx->Eval.Map2Vertex3) - set_active_eval2( exec, BRW_ATTRIB_POS, 3, &ctx->EvalMap.Map2Vertex3 ); - - exec->eval.recalculate_maps = 0; -} - - - -void brw_exec_do_EvalCoord1f(struct brw_exec_context *exec, GLfloat u) -{ - GLuint attr; - - for (attr = 1; attr <= BRW_ATTRIB_INDEX; attr++) { - struct gl_1d_map *map = exec->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, - exec->eval.map1[attr].sz, - map->Order); - - COPY_SZ_4V( exec->vtx.attrptr[attr], - exec->vtx.attrsz[attr], - data ); - } - } - - /** Vertex -- EvalCoord1f is a noop if this map not enabled: - **/ - if (exec->eval.map1[0].map) { - struct gl_1d_map *map = exec->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, - exec->eval.map1[0].sz, - map->Order); - - if (exec->eval.map1[0].sz == 4) - CALL_Vertex4fv(GET_DISPATCH(), ( vertex )); - else - CALL_Vertex3fv(GET_DISPATCH(), ( vertex )); - } -} - - - -void brw_exec_do_EvalCoord2f( struct brw_exec_context *exec, - GLfloat u, GLfloat v ) -{ - GLuint attr; - - for (attr = 1; attr <= BRW_ATTRIB_INDEX; attr++) { - struct gl_2d_map *map = exec->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, - exec->eval.map2[attr].sz, - map->Uorder, map->Vorder); - - COPY_SZ_4V( exec->vtx.attrptr[attr], - exec->vtx.attrsz[attr], - data ); - } - } - - /** Vertex -- EvalCoord2f is a noop if this map not enabled: - **/ - if (exec->eval.map2[0].map) { - struct gl_2d_map *map = exec->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 (exec->ctx->Eval.AutoNormal) { - GLfloat normal[4]; - GLfloat du[4], dv[4]; - - _math_de_casteljau_surf(map->Points, vertex, du, dv, uu, vv, - exec->eval.map2[0].sz, - map->Uorder, map->Vorder); - - if (exec->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( exec->vtx.attrptr[BRW_ATTRIB_NORMAL], - exec->vtx.attrsz[BRW_ATTRIB_NORMAL], - normal ); - - } - else { - _math_horner_bezier_surf(map->Points, vertex, uu, vv, - exec->eval.map2[0].sz, - map->Uorder, map->Vorder); - } - - if (exec->vtx.attrsz[0] == 4) - CALL_Vertex4fv(GET_DISPATCH(), ( vertex )); - else - CALL_Vertex3fv(GET_DISPATCH(), ( vertex )); - } -} - - diff --git a/src/mesa/drivers/dri/i965/brw_fallback.c b/src/mesa/drivers/dri/i965/brw_fallback.c index 4d84ba8813..aab30b6863 100644 --- a/src/mesa/drivers/dri/i965/brw_fallback.c +++ b/src/mesa/drivers/dri/i965/brw_fallback.c @@ -198,7 +198,7 @@ struct loopback_attr { */ static void loopback_prim( GLcontext *ctx, const GLfloat *buffer, - const struct brw_draw_prim *prim, + const struct vbo_prim *prim, GLuint wrap_count, GLuint vertex_size, const struct loopback_attr *la, GLuint nr ) @@ -252,7 +252,7 @@ static void loopback_prim( GLcontext *ctx, * primitives. */ static void loopback_weak_prim( GLcontext *ctx, - const struct brw_draw_prim *prim ) + const struct vbo_prim *prim ) { /* Use the prim_weak flag to ensure that if this primitive * wraps, we don't mistake future vertex_lists for part of the @@ -271,7 +271,7 @@ static void loopback_weak_prim( GLcontext *ctx, void brw_loopback_vertex_list( GLcontext *ctx, const GLfloat *buffer, const GLubyte *attrsz, - const struct brw_draw_prim *prim, + const struct vbo_prim *prim, GLuint prim_count, GLuint wrap_count, GLuint vertex_size) diff --git a/src/mesa/drivers/dri/i965/brw_fallback.h b/src/mesa/drivers/dri/i965/brw_fallback.h index 81a2d344b8..684a46cd17 100644 --- a/src/mesa/drivers/dri/i965/brw_fallback.h +++ b/src/mesa/drivers/dri/i965/brw_fallback.h @@ -31,7 +31,7 @@ #include "mtypes.h" /* for GLcontext... */ struct brw_context; -struct brw_draw_prim; +struct vbo_prim; void brw_fallback( GLcontext *ctx ); void brw_unfallback( GLcontext *ctx ); @@ -39,7 +39,7 @@ void brw_unfallback( GLcontext *ctx ); void brw_loopback_vertex_list( GLcontext *ctx, const GLfloat *buffer, const GLubyte *attrsz, - const struct brw_draw_prim *prim, + const struct vbo_prim *prim, GLuint prim_count, GLuint wrap_count, GLuint vertex_size); diff --git a/src/mesa/drivers/dri/i965/brw_metaops.c b/src/mesa/drivers/dri/i965/brw_metaops.c index 18ca7b1341..d8b6069cfc 100644 --- a/src/mesa/drivers/dri/i965/brw_metaops.c +++ b/src/mesa/drivers/dri/i965/brw_metaops.c @@ -303,7 +303,7 @@ static void meta_draw_quad(struct intel_context *intel, struct gl_client_array pos_array; struct gl_client_array color_array; struct gl_client_array *attribs[BRW_ATTRIB_MAX]; - struct brw_draw_prim prim[1]; + struct vbo_prim prim[1]; GLfloat pos[4][3]; GLubyte color[4]; @@ -395,8 +395,7 @@ static void meta_draw_quad(struct intel_context *intel, prim, 1, NULL, 0, - 4, - BRW_DRAW_LOCKED )) + 4 )) { /* This should not be possible: */ diff --git a/src/mesa/drivers/dri/i965/brw_save.c b/src/mesa/drivers/dri/i965/brw_save.c deleted file mode 100644 index 1af7791c4d..0000000000 --- a/src/mesa/drivers/dri/i965/brw_save.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.3 - * - * Copyright (C) 1999-2005 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 - */ - - -#include "mtypes.h" -#include "api_arrayelt.h" -#include "dlist.h" -#include "vtxfmt.h" -#include "imports.h" - -#include "brw_save.h" - - - -void brw_save_init( GLcontext *ctx ) -{ - struct brw_save_context *save = CALLOC_STRUCT(brw_save_context); - - if (ctx->swtnl_im == NULL) { - ctx->swtnl_im = CALLOC_STRUCT(brw_exec_save); - } - - save->ctx = ctx; - IMM_CONTEXT(ctx)->save = save; - - /* Initialize the arrayelt helper - */ - if (!ctx->aelt_context && - !_ae_create_context( ctx )) - return; - - brw_save_api_init( save ); - brw_save_wakeup(ctx); - - ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN; -} - - -void brw_save_destroy( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - if (save) { - FREE(save); - IMM_CONTEXT(ctx)->save = NULL; - } - - if (ctx->aelt_context) { - _ae_destroy_context( ctx ); - ctx->aelt_context = NULL; - } - - if (IMM_CONTEXT(ctx)->exec == NULL && - IMM_CONTEXT(ctx)->save == NULL) { - FREE(IMM_CONTEXT(ctx)); - ctx->swtnl_im = NULL; - } -} - - -void brw_save_invalidate_state( GLcontext *ctx, GLuint new_state ) -{ - _ae_invalidate_state(ctx, new_state); -} - - -/* Note that this can occur during the playback of a display list: - */ -void brw_save_fallback( GLcontext *ctx, GLboolean fallback ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - - if (fallback) - save->replay_flags |= BRW_SAVE_FALLBACK; - else - save->replay_flags &= ~BRW_SAVE_FALLBACK; -} - - -/* I don't see any reason to swap this code out on fallbacks. It - * wouldn't really mean anything to do so anyway as the old lists are - * still around from pre-fallback. Instead, the above code ensures - * that vertices are routed back through immediate mode dispatch on - * fallback. - * - * The below can be moved into init or removed: - */ -void brw_save_wakeup( GLcontext *ctx ) -{ - ctx->Driver.NewList = brw_save_NewList; - ctx->Driver.EndList = brw_save_EndList; - ctx->Driver.SaveFlushVertices = brw_save_SaveFlushVertices; - ctx->Driver.BeginCallList = brw_save_BeginCallList; - ctx->Driver.EndCallList = brw_save_EndCallList; - ctx->Driver.NotifySaveBegin = brw_save_NotifyBegin; - - /* Assume we haven't been getting state updates either: - */ - brw_save_invalidate_state( ctx, ~0 ); -} - - - diff --git a/src/mesa/drivers/dri/i965/brw_save.h b/src/mesa/drivers/dri/i965/brw_save.h deleted file mode 100644 index 41cabe6508..0000000000 --- a/src/mesa/drivers/dri/i965/brw_save.h +++ /dev/null @@ -1,171 +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 - * - */ - -#ifndef BRW_SAVE_H -#define BRW_SAVE_H - -#include "mtypes.h" -#include "brw_attrib.h" -#include "brw_draw.h" - - -struct brw_save_copied_vtx { - GLfloat buffer[BRW_ATTRIB_MAX * 4 * BRW_MAX_COPIED_VERTS]; - GLuint nr; -}; - - -/* 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 brw_save_vertex_list { - GLubyte attrsz[BRW_ATTRIB_MAX]; - GLuint vertex_size; - - GLuint buffer_offset; - GLuint count; - GLuint wrap_count; /* number of copied vertices at start */ - GLboolean dangling_attr_ref; /* current attr implicitly referenced - outside the list */ - - struct brw_draw_prim *prim; - GLuint prim_count; - - struct brw_save_vertex_store *vertex_store; - struct brw_save_primitive_store *prim_store; -}; - -/* These buffers should be a reasonable size to support upload to - * hardware. Current brw implementation will re-upload on any - * changes, so don't make too big or apps which dynamically create - * dlists and use only a few times will suffer. - * - * Consider stategy of uploading regions from the VBO on demand in the - * case of dynamic vbos. Then make the dlist code signal that - * likelyhood as it occurs. No reason we couldn't change usage - * internally even though this probably isn't allowed for client VBOs? - */ -#define BRW_SAVE_BUFFER_SIZE (8*1024) /* dwords */ -#define BRW_SAVE_PRIM_SIZE 128 -#define BRW_SAVE_PRIM_WEAK 0x40 - -#define BRW_SAVE_FALLBACK 0x10000000 - -/* Storage to be shared among several vertex_lists. - */ -struct brw_save_vertex_store { - struct gl_buffer_object *bufferobj; - GLfloat *buffer; - GLuint used; - GLuint refcount; -}; - -struct brw_save_primitive_store { - struct brw_draw_prim buffer[BRW_SAVE_PRIM_SIZE]; - GLuint used; - GLuint refcount; -}; - - -struct brw_save_context { - GLcontext *ctx; - GLvertexformat vtxfmt; - struct gl_client_array arrays[BRW_ATTRIB_MAX]; - const struct gl_client_array *inputs[BRW_ATTRIB_MAX]; - - GLubyte attrsz[BRW_ATTRIB_MAX]; - GLubyte active_sz[BRW_ATTRIB_MAX]; - GLuint vertex_size; - - GLfloat *buffer; - GLuint count; - GLuint wrap_count; - GLuint replay_flags; - - struct brw_draw_prim *prim; - GLuint prim_count, prim_max; - - struct brw_save_vertex_store *vertex_store; - struct brw_save_primitive_store *prim_store; - - GLfloat *vbptr; /* cursor, points into buffer */ - GLfloat vertex[BRW_ATTRIB_MAX*4]; /* current values */ - GLfloat *attrptr[BRW_ATTRIB_MAX]; - GLuint vert_count; - GLuint max_vert; - GLboolean dangling_attr_ref; - GLboolean have_materials; - - GLuint opcode_vertex_list; - - struct brw_save_copied_vtx copied; - - GLfloat CurrentFloatEdgeFlag; - - GLfloat *current[BRW_ATTRIB_MAX]; /* points into ctx->ListState */ - GLubyte *currentsz[BRW_ATTRIB_MAX]; -}; - - -void brw_save_init( GLcontext *ctx ); -void brw_save_destroy( GLcontext *ctx ); -void brw_save_wakeup( GLcontext *ctx ); -void brw_save_invalidate_state( GLcontext *ctx, GLuint new_state ); -void brw_save_fallback( GLcontext *ctx, GLboolean fallback ); - -/* Callbacks: - */ -void brw_save_EndList( GLcontext *ctx ); -void brw_save_NewList( GLcontext *ctx, GLuint list, GLenum mode ); -void brw_save_EndCallList( GLcontext *ctx ); -void brw_save_BeginCallList( GLcontext *ctx, struct mesa_display_list *list ); -void brw_save_SaveFlushVertices( GLcontext *ctx ); -GLboolean brw_save_NotifyBegin( GLcontext *ctx, GLenum mode ); - -void brw_save_playback_vertex_list( GLcontext *ctx, void *data ); - -void brw_save_api_init( struct brw_save_context *save ); - -#endif diff --git a/src/mesa/drivers/dri/i965/brw_save_api.c b/src/mesa/drivers/dri/i965/brw_save_api.c deleted file mode 100644 index 9c0e4af48a..0000000000 --- a/src/mesa/drivers/dri/i965/brw_save_api.c +++ /dev/null @@ -1,1162 +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 - */ - - - -/* Display list compiler attempts to store lists of vertices with the - * same vertex layout. Additionally it attempts to minimize the need - * for execute-time fixup of these vertex lists, allowing them to be - * cached on hardware. - * - * There are still some circumstances where this can be thwarted, for - * example by building a list that consists of one very long primitive - * (eg Begin(Triangles), 1000 vertices, End), and calling that list - * from inside a different begin/end object (Begin(Lines), CallList, - * End). - * - * In that case the code will have to replay the list as individual - * commands through the Exec dispatch table, or fix up the copied - * vertices at execute-time. - * - * The other case where fixup is required is when a vertex attribute - * is introduced in the middle of a primitive. Eg: - * Begin(Lines) - * TexCoord1f() Vertex2f() - * TexCoord1f() Color3f() Vertex2f() - * End() - * - * If the current value of Color isn't known at compile-time, this - * primitive will require fixup. - * - * - * The list compiler currently doesn't attempt to compile lists - * containing EvalCoord or EvalPoint commands. On encountering one of - * these, compilation falls back to opcodes. - * - * This could be improved to fallback only when a mix of EvalCoord and - * Vertex commands are issued within a single primitive. - */ - - -#include "glheader.h" -#include "context.h" -#include "dlist.h" -#include "enums.h" -#include "macros.h" -#include "api_validate.h" -#include "api_arrayelt.h" -#include "vtxfmt.h" -#include "dispatch.h" - -#include "brw_save.h" -#include "brw_fallback.h" - - - - -/* - * NOTE: Old 'parity' issue is gone, but copying can still be - * wrong-footed on replay. - */ -static GLuint _save_copy_vertices( GLcontext *ctx, - const struct brw_save_vertex_list *node, - const GLfloat *src_buffer) -{ - struct brw_save_context *save = IMM_CONTEXT( ctx )->save; - const struct brw_draw_prim *prim = &node->prim[node->prim_count-1]; - GLuint nr = prim->count; - GLuint sz = save->vertex_size; - const GLfloat *src = src_buffer + prim->start * sz; - GLfloat *dst = save->copied.buffer; - GLuint ovf, i; - - if (prim->end) - return 0; - - switch( prim->mode ) - { - 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; - default: - assert(0); - return 0; - } -} - - -static struct brw_save_vertex_store *alloc_vertex_store( GLcontext *ctx ) -{ - struct brw_save_vertex_store *vertex_store = CALLOC_STRUCT(brw_save_vertex_store); - - /* obj->Name needs to be non-zero, but won't ever be examined more - * closely than that. In particular these buffers won't be entered - * into the hash and can never be confused with ones visible to the - * user. Perhaps there could be a special number for internal - * buffers: - */ - vertex_store->bufferobj = ctx->Driver.NewBufferObject(ctx, 1, GL_ARRAY_BUFFER_ARB); - - ctx->Driver.BufferData( ctx, - GL_ARRAY_BUFFER_ARB, - BRW_SAVE_BUFFER_SIZE * sizeof(GLfloat), - NULL, - GL_STATIC_DRAW_ARB, - vertex_store->bufferobj); - - vertex_store->buffer = NULL; - vertex_store->used = 0; - vertex_store->refcount = 1; - - return vertex_store; -} - -static void free_vertex_store( GLcontext *ctx, struct brw_save_vertex_store *vertex_store ) -{ - assert(!vertex_store->buffer); - - if (vertex_store->bufferobj) - ctx->Driver.DeleteBuffer( ctx, vertex_store->bufferobj ); - - FREE( vertex_store ); -} - -static GLfloat *map_vertex_store( GLcontext *ctx, struct brw_save_vertex_store *vertex_store ) -{ - assert(vertex_store->bufferobj); - assert(!vertex_store->buffer); - vertex_store->buffer = (GLfloat *)ctx->Driver.MapBuffer(ctx, - GL_ARRAY_BUFFER_ARB, /* not used */ - GL_STATIC_DRAW_ARB, /* not used */ - vertex_store->bufferobj); - - assert(vertex_store->buffer); - return vertex_store->buffer + vertex_store->used; -} - -static void unmap_vertex_store( GLcontext *ctx, struct brw_save_vertex_store *vertex_store ) -{ - ctx->Driver.UnmapBuffer( ctx, GL_ARRAY_BUFFER_ARB, vertex_store->bufferobj ); - vertex_store->buffer = NULL; -} - - -static struct brw_save_primitive_store *alloc_prim_store( GLcontext *ctx ) -{ - struct brw_save_primitive_store *store = CALLOC_STRUCT(brw_save_primitive_store); - (void) ctx; - store->used = 0; - store->refcount = 1; - return store; -} - -static void _save_reset_counters( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - - save->prim = save->prim_store->buffer + save->prim_store->used; - save->buffer = (save->vertex_store->buffer + - save->vertex_store->used); - - assert(save->buffer == save->vbptr); - - if (save->vertex_size) - save->max_vert = ((BRW_SAVE_BUFFER_SIZE - save->vertex_store->used) / - save->vertex_size); - else - save->max_vert = 0; - - save->vert_count = 0; - save->prim_count = 0; - save->prim_max = BRW_SAVE_PRIM_SIZE - save->prim_store->used; - save->dangling_attr_ref = 0; -} - - -/* Insert the active immediate struct onto the display list currently - * being built. - */ -static void _save_compile_vertex_list( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - struct brw_save_vertex_list *node; - - /* Allocate space for this structure in the display list currently - * being compiled. - */ - node = (struct brw_save_vertex_list *) - _mesa_alloc_instruction(ctx, save->opcode_vertex_list, sizeof(*node)); - - if (!node) - return; - - /* Duplicate our template, increment refcounts to the storage structs: - */ - _mesa_memcpy(node->attrsz, save->attrsz, sizeof(node->attrsz)); - node->vertex_size = save->vertex_size; - node->buffer_offset = (save->buffer - save->vertex_store->buffer) * sizeof(GLfloat); - node->count = save->vert_count; - node->wrap_count = save->copied.nr; - node->dangling_attr_ref = save->dangling_attr_ref; - node->prim = save->prim; - node->prim_count = save->prim_count; - node->vertex_store = save->vertex_store; - node->prim_store = save->prim_store; - - node->vertex_store->refcount++; - node->prim_store->refcount++; - - assert(node->attrsz[BRW_ATTRIB_POS] != 0 || - node->count == 0); - - if (save->dangling_attr_ref) - ctx->ListState.CurrentList->flags |= MESA_DLIST_DANGLING_REFS; - - save->vertex_store->used += save->vertex_size * node->count; - save->prim_store->used += node->prim_count; - - - /* Copy duplicated vertices - */ - save->copied.nr = _save_copy_vertices( ctx, node, save->buffer ); - - - /* Deal with GL_COMPILE_AND_EXECUTE: - */ - if (ctx->ExecuteFlag) { - struct _glapi_table *dispatch = GET_DISPATCH(); - - _glapi_set_dispatch(ctx->Exec); - - brw_loopback_vertex_list( ctx, - (const GLfloat *)((const char *)save->vertex_store->buffer + - node->buffer_offset), - node->attrsz, - node->prim, - node->prim_count, - node->wrap_count, - node->vertex_size); - - _glapi_set_dispatch(dispatch); - } - - - /* Decide whether the storage structs are full, or can be used for - * the next vertex lists as well. - */ - if (save->vertex_store->used > - BRW_SAVE_BUFFER_SIZE - 16 * (save->vertex_size + 4)) { - - /* Unmap old store: - */ - unmap_vertex_store( ctx, save->vertex_store ); - - /* Release old reference: - */ - save->vertex_store->refcount--; - assert(save->vertex_store->refcount != 0); - save->vertex_store = NULL; - - /* Allocate and map new store: - */ - save->vertex_store = alloc_vertex_store( ctx ); - save->vbptr = map_vertex_store( ctx, save->vertex_store ); - } - - if (save->prim_store->used > BRW_SAVE_PRIM_SIZE - 6) { - save->prim_store->refcount--; - assert(save->prim_store->refcount != 0); - save->prim_store = alloc_prim_store( ctx ); - } - - /* Reset our structures for the next run of vertices: - */ - _save_reset_counters( ctx ); -} - - -/* TODO -- If no new vertices have been stored, don't bother saving - * it. - */ -static void _save_wrap_buffers( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLint i = save->prim_count - 1; - GLenum mode; - GLboolean weak; - - assert(i < (GLint) save->prim_max); - assert(i >= 0); - - /* Close off in-progress primitive. - */ - save->prim[i].count = (save->vert_count - - save->prim[i].start); - mode = save->prim[i].mode; - weak = save->prim[i].weak; - - /* store the copied vertices, and allocate a new list. - */ - _save_compile_vertex_list( ctx ); - - /* Restart interrupted primitive - */ - save->prim[0].mode = mode; - save->prim[0].weak = weak; - save->prim[0].begin = 0; - save->prim[0].end = 0; - save->prim[0].pad = 0; - save->prim[0].start = 0; - save->prim[0].count = 0; - save->prim_count = 1; -} - - - -/* Called only when buffers are wrapped as the result of filling the - * vertex_store struct. - */ -static void _save_wrap_filled_vertex( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLfloat *data = save->copied.buffer; - GLuint i; - - /* Emit a glEnd to close off the last vertex list. - */ - _save_wrap_buffers( ctx ); - - /* Copy stored stored vertices to start of new list. - */ - assert(save->max_vert - save->vert_count > save->copied.nr); - - for (i = 0 ; i < save->copied.nr ; i++) { - _mesa_memcpy( save->vbptr, data, save->vertex_size * sizeof(GLfloat)); - data += save->vertex_size; - save->vbptr += save->vertex_size; - save->vert_count++; - } -} - - -static void _save_copy_to_current( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLuint i; - - for (i = BRW_ATTRIB_POS+1 ; i <= BRW_ATTRIB_INDEX ; i++) { - if (save->attrsz[i]) { - save->currentsz[i][0] = save->attrsz[i]; - COPY_CLEAN_4V(save->current[i], - save->attrsz[i], - save->attrptr[i]); - } - } - - /* Edgeflag requires special treatment: - * - * TODO: change edgeflag to GLfloat in Mesa. - */ - if (save->attrsz[BRW_ATTRIB_EDGEFLAG]) { - ctx->ListState.ActiveEdgeFlag = 1; - save->CurrentFloatEdgeFlag = - save->attrptr[BRW_ATTRIB_EDGEFLAG][0]; - ctx->ListState.CurrentEdgeFlag = - (save->CurrentFloatEdgeFlag == 1.0); - } -} - - -static void _save_copy_from_current( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLint i; - - for (i = BRW_ATTRIB_POS+1 ; i <= BRW_ATTRIB_INDEX ; i++) - switch (save->attrsz[i]) { - case 4: save->attrptr[i][3] = save->current[i][3]; - case 3: save->attrptr[i][2] = save->current[i][2]; - case 2: save->attrptr[i][1] = save->current[i][1]; - case 1: save->attrptr[i][0] = save->current[i][0]; - case 0: break; - } - - /* Edgeflag requires special treatment: - */ - if (save->attrsz[BRW_ATTRIB_EDGEFLAG]) { - save->CurrentFloatEdgeFlag = (GLfloat)ctx->ListState.CurrentEdgeFlag; - save->attrptr[BRW_ATTRIB_EDGEFLAG][0] = save->CurrentFloatEdgeFlag; - } -} - - - - -/* Flush existing data, set new attrib size, replay copied vertices. - */ -static void _save_upgrade_vertex( GLcontext *ctx, - GLuint attr, - GLuint newsz ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLuint oldsz; - GLuint i; - GLfloat *tmp; - - /* Store the current run of vertices, and emit a GL_END. Emit a - * BEGIN in the new buffer. - */ - if (save->vert_count) - _save_wrap_buffers( ctx ); - else - assert( save->copied.nr == 0 ); - - /* Do a COPY_TO_CURRENT to ensure back-copying works for the case - * when the attribute already exists in the vertex and is having - * its size increased. - */ - _save_copy_to_current( ctx ); - - /* Fix up sizes: - */ - oldsz = save->attrsz[attr]; - save->attrsz[attr] = newsz; - - save->vertex_size += newsz - oldsz; - save->max_vert = ((BRW_SAVE_BUFFER_SIZE - save->vertex_store->used) / - save->vertex_size); - save->vert_count = 0; - - /* Recalculate all the attrptr[] values: - */ - for (i = 0, tmp = save->vertex ; i < BRW_ATTRIB_MAX ; i++) { - if (save->attrsz[i]) { - save->attrptr[i] = tmp; - tmp += save->attrsz[i]; - } - else - save->attrptr[i] = NULL; /* will not be dereferenced. */ - } - - /* Copy from current to repopulate the vertex with correct values. - */ - _save_copy_from_current( ctx ); - - /* Replay stored vertices to translate them to new format here. - * - * If there are copied vertices and the new (upgraded) attribute - * has not been defined before, this list is somewhat degenerate, - * and will need fixup at runtime. - */ - if (save->copied.nr) - { - GLfloat *data = save->copied.buffer; - GLfloat *dest = save->buffer; - GLuint j; - - /* Need to note this and fix up at runtime (or loopback): - */ - if (save->currentsz[attr][0] == 0) { - assert(oldsz == 0); - save->dangling_attr_ref = GL_TRUE; - } - - for (i = 0 ; i < save->copied.nr ; i++) { - for (j = 0 ; j < BRW_ATTRIB_MAX ; j++) { - if (save->attrsz[j]) { - if (j == attr) { - if (oldsz) { - COPY_CLEAN_4V( dest, oldsz, data ); - data += oldsz; - dest += newsz; - } - else { - COPY_SZ_4V( dest, newsz, save->current[attr] ); - dest += newsz; - } - } - else { - GLint sz = save->attrsz[j]; - COPY_SZ_4V( dest, sz, data ); - data += sz; - dest += sz; - } - } - } - } - - save->vbptr = dest; - save->vert_count += save->copied.nr; - } -} - -static void save_fixup_vertex( GLcontext *ctx, GLuint attr, GLuint sz ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - - if (sz > save->attrsz[attr]) { - /* New size is larger. Need to flush existing vertices and get - * an enlarged vertex format. - */ - _save_upgrade_vertex( ctx, attr, sz ); - } - else if (sz < save->active_sz[attr]) { - static GLfloat id[4] = { 0, 0, 0, 1 }; - GLuint i; - - /* New size is equal or smaller - just need to fill in some - * zeros. - */ - for (i = sz ; i <= save->attrsz[attr] ; i++) - save->attrptr[attr][i-1] = id[i-1]; - } - - save->active_sz[attr] = sz; -} - -static void _save_reset_vertex( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLuint i; - - for (i = 0 ; i < BRW_ATTRIB_MAX ; i++) { - save->attrsz[i] = 0; - save->active_sz[i] = 0; - } - - save->vertex_size = 0; -} - - - -#define ERROR() _mesa_compile_error( ctx, GL_INVALID_ENUM, __FUNCTION__ ); - - -/* 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 ATTR( A, N, V0, V1, V2, V3 ) \ -do { \ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; \ - \ - if (save->active_sz[A] != N) \ - save_fixup_vertex(ctx, A, N); \ - \ - { \ - GLfloat *dest = save->attrptr[A]; \ - if (N>0) dest[0] = V0; \ - if (N>1) dest[1] = V1; \ - if (N>2) dest[2] = V2; \ - if (N>3) dest[3] = V3; \ - } \ - \ - if ((A) == 0) { \ - GLuint i; \ - \ - for (i = 0; i < save->vertex_size; i++) \ - save->vbptr[i] = save->vertex[i]; \ - \ - save->vbptr += save->vertex_size; \ - \ - if (++save->vert_count >= save->max_vert) \ - _save_wrap_filled_vertex( ctx ); \ - } \ -} while (0) - -#define TAG(x) _save_##x - -#include "brw_attrib_tmp.h" - - - - -/* Cope with EvalCoord/CallList called within a begin/end object: - * -- Flush current buffer - * -- Fallback to opcodes for the rest of the begin/end object. - */ -#define DO_FALLBACK(ctx) \ -do { \ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; \ - \ - if (save->vert_count || save->prim_count) \ - _save_compile_vertex_list( ctx ); \ - \ - _save_copy_to_current( ctx ); \ - _save_reset_vertex( ctx ); \ - _save_reset_counters( ctx ); \ - _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); \ - ctx->Driver.SaveNeedFlush = 0; \ -} while (0) - -static void GLAPIENTRY _save_EvalCoord1f( GLfloat u ) -{ - GET_CURRENT_CONTEXT(ctx); - DO_FALLBACK(ctx); - ctx->Save->EvalCoord1f( u ); -} - -static void GLAPIENTRY _save_EvalCoord1fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - DO_FALLBACK(ctx); - ctx->Save->EvalCoord1fv( v ); -} - -static void GLAPIENTRY _save_EvalCoord2f( GLfloat u, GLfloat v ) -{ - GET_CURRENT_CONTEXT(ctx); - DO_FALLBACK(ctx); - ctx->Save->EvalCoord2f( u, v ); -} - -static void GLAPIENTRY _save_EvalCoord2fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - DO_FALLBACK(ctx); - ctx->Save->EvalCoord2fv( v ); -} - -static void GLAPIENTRY _save_EvalPoint1( GLint i ) -{ - GET_CURRENT_CONTEXT(ctx); - DO_FALLBACK(ctx); - ctx->Save->EvalPoint1( i ); -} - -static void GLAPIENTRY _save_EvalPoint2( GLint i, GLint j ) -{ - GET_CURRENT_CONTEXT(ctx); - DO_FALLBACK(ctx); - ctx->Save->EvalPoint2( i, j ); -} - -static void GLAPIENTRY _save_CallList( GLuint l ) -{ - GET_CURRENT_CONTEXT(ctx); - DO_FALLBACK(ctx); - ctx->Save->CallList( l ); -} - -static void GLAPIENTRY _save_CallLists( GLsizei n, GLenum type, const GLvoid *v ) -{ - GET_CURRENT_CONTEXT(ctx); - DO_FALLBACK(ctx); - ctx->Save->CallLists( n, type, v ); -} - - - - -/* This begin is hooked into ... Updating of - * ctx->Driver.CurrentSavePrimitive is already taken care of. - */ -GLboolean brw_save_NotifyBegin( GLcontext *ctx, GLenum mode ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - - GLuint i = save->prim_count++; - - assert(i < save->prim_max); - save->prim[i].mode = mode & ~BRW_SAVE_PRIM_WEAK; - save->prim[i].begin = 1; - save->prim[i].end = 0; - save->prim[i].weak = (mode & BRW_SAVE_PRIM_WEAK) ? 1 : 0; - save->prim[i].pad = 0; - save->prim[i].start = save->vert_count; - save->prim[i].count = 0; - - _mesa_install_save_vtxfmt( ctx, &save->vtxfmt ); - ctx->Driver.SaveNeedFlush = 1; - return GL_TRUE; -} - - - -static void GLAPIENTRY _save_End( void ) -{ - GET_CURRENT_CONTEXT( ctx ); - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLint i = save->prim_count - 1; - - ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END; - save->prim[i].end = 1; - save->prim[i].count = (save->vert_count - - save->prim[i].start); - - if (i == (GLint) save->prim_max - 1) { - _save_compile_vertex_list( ctx ); - assert(save->copied.nr == 0); - } - - /* Swap out this vertex format while outside begin/end. Any color, - * etc. received between here and the next begin will be compiled - * as opcodes. - */ - _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); -} - - -/* These are all errors as this vtxfmt is only installed inside - * begin/end pairs. - */ -static void GLAPIENTRY _save_DrawElements(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) count; (void) type; (void) indices; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawElements" ); -} - - -static void GLAPIENTRY _save_DrawRangeElements(GLenum mode, - GLuint start, GLuint end, - GLsizei count, GLenum type, - const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) start; (void) end; (void) count; (void) type; (void) indices; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawRangeElements" ); -} - -static void GLAPIENTRY _save_DrawArrays(GLenum mode, GLint start, GLsizei count) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) start; (void) count; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawArrays" ); -} - -static void GLAPIENTRY _save_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) -{ - GET_CURRENT_CONTEXT(ctx); - (void) x1; (void) y1; (void) x2; (void) y2; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glRectf" ); -} - -static void GLAPIENTRY _save_EvalMesh1( GLenum mode, GLint i1, GLint i2 ) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) i1; (void) i2; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glEvalMesh1" ); -} - -static void GLAPIENTRY _save_EvalMesh2( GLenum mode, GLint i1, GLint i2, - GLint j1, GLint j2 ) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) i1; (void) i2; (void) j1; (void) j2; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glEvalMesh2" ); -} - -static void GLAPIENTRY _save_Begin( GLenum mode ) -{ - GET_CURRENT_CONTEXT( ctx ); - (void) mode; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "Recursive glBegin" ); -} - - -/* Unlike the functions above, these are to be hooked into the vtxfmt - * maintained in ctx->ListState, active when the list is known or - * suspected to be outside any begin/end primitive. - */ -static void GLAPIENTRY _save_OBE_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) -{ - GET_CURRENT_CONTEXT(ctx); - brw_save_NotifyBegin( ctx, GL_QUADS | BRW_SAVE_PRIM_WEAK ); - CALL_Vertex2f(GET_DISPATCH(), ( x1, y1 )); - CALL_Vertex2f(GET_DISPATCH(), ( x2, y1 )); - CALL_Vertex2f(GET_DISPATCH(), ( x2, y2 )); - CALL_Vertex2f(GET_DISPATCH(), ( x1, y2 )); - CALL_End(GET_DISPATCH(), ()); -} - - -static void GLAPIENTRY _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei count) -{ - GET_CURRENT_CONTEXT(ctx); - GLint i; - - if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) - return; - - brw_save_NotifyBegin( ctx, mode | BRW_SAVE_PRIM_WEAK ); - for (i = 0; i < count; i++) - CALL_ArrayElement(GET_DISPATCH(), (start + i)); - CALL_End(GET_DISPATCH(), ()); -} - -/* Could do better by copying the arrays and element list intact and - * then emitting an indexed prim at runtime. - */ -static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - GLint i; - - if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) - return; - - brw_save_NotifyBegin( ctx, mode | BRW_SAVE_PRIM_WEAK ); - - switch (type) { - case GL_UNSIGNED_BYTE: - for (i = 0 ; i < count ; i++) - CALL_ArrayElement(GET_DISPATCH(), ( ((GLubyte *)indices)[i] )); - break; - case GL_UNSIGNED_SHORT: - for (i = 0 ; i < count ; i++) - CALL_ArrayElement(GET_DISPATCH(), ( ((GLushort *)indices)[i] )); - break; - case GL_UNSIGNED_INT: - for (i = 0 ; i < count ; i++) - CALL_ArrayElement(GET_DISPATCH(), ( ((GLuint *)indices)[i] )); - break; - default: - _mesa_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" ); - break; - } - - CALL_End(GET_DISPATCH(), ()); -} - -static void GLAPIENTRY _save_OBE_DrawRangeElements(GLenum mode, - GLuint start, GLuint end, - GLsizei count, GLenum type, - const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - if (_mesa_validate_DrawRangeElements( ctx, mode, - start, end, - count, type, indices )) - _save_OBE_DrawElements( mode, count, type, indices ); -} - - - - - -static void _save_vtxfmt_init( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLvertexformat *vfmt = &save->vtxfmt; - - vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ - vfmt->Begin = _save_Begin; - vfmt->Color3f = _save_Color3f; - vfmt->Color3fv = _save_Color3fv; - vfmt->Color4f = _save_Color4f; - vfmt->Color4fv = _save_Color4fv; - vfmt->EdgeFlag = _save_EdgeFlag; - vfmt->End = _save_End; - vfmt->FogCoordfEXT = _save_FogCoordfEXT; - vfmt->FogCoordfvEXT = _save_FogCoordfvEXT; - vfmt->Indexf = _save_Indexf; - vfmt->Indexfv = _save_Indexfv; - vfmt->Materialfv = _save_Materialfv; - vfmt->MultiTexCoord1fARB = _save_MultiTexCoord1f; - vfmt->MultiTexCoord1fvARB = _save_MultiTexCoord1fv; - vfmt->MultiTexCoord2fARB = _save_MultiTexCoord2f; - vfmt->MultiTexCoord2fvARB = _save_MultiTexCoord2fv; - vfmt->MultiTexCoord3fARB = _save_MultiTexCoord3f; - vfmt->MultiTexCoord3fvARB = _save_MultiTexCoord3fv; - vfmt->MultiTexCoord4fARB = _save_MultiTexCoord4f; - vfmt->MultiTexCoord4fvARB = _save_MultiTexCoord4fv; - vfmt->Normal3f = _save_Normal3f; - vfmt->Normal3fv = _save_Normal3fv; - vfmt->SecondaryColor3fEXT = _save_SecondaryColor3fEXT; - vfmt->SecondaryColor3fvEXT = _save_SecondaryColor3fvEXT; - vfmt->TexCoord1f = _save_TexCoord1f; - vfmt->TexCoord1fv = _save_TexCoord1fv; - vfmt->TexCoord2f = _save_TexCoord2f; - vfmt->TexCoord2fv = _save_TexCoord2fv; - vfmt->TexCoord3f = _save_TexCoord3f; - vfmt->TexCoord3fv = _save_TexCoord3fv; - vfmt->TexCoord4f = _save_TexCoord4f; - vfmt->TexCoord4fv = _save_TexCoord4fv; - vfmt->Vertex2f = _save_Vertex2f; - vfmt->Vertex2fv = _save_Vertex2fv; - vfmt->Vertex3f = _save_Vertex3f; - vfmt->Vertex3fv = _save_Vertex3fv; - vfmt->Vertex4f = _save_Vertex4f; - vfmt->Vertex4fv = _save_Vertex4fv; - vfmt->VertexAttrib1fARB = _save_VertexAttrib1fARB; - vfmt->VertexAttrib1fvARB = _save_VertexAttrib1fvARB; - vfmt->VertexAttrib2fARB = _save_VertexAttrib2fARB; - vfmt->VertexAttrib2fvARB = _save_VertexAttrib2fvARB; - vfmt->VertexAttrib3fARB = _save_VertexAttrib3fARB; - vfmt->VertexAttrib3fvARB = _save_VertexAttrib3fvARB; - vfmt->VertexAttrib4fARB = _save_VertexAttrib4fARB; - vfmt->VertexAttrib4fvARB = _save_VertexAttrib4fvARB; - - vfmt->VertexAttrib1fNV = _save_VertexAttrib1fNV; - vfmt->VertexAttrib1fvNV = _save_VertexAttrib1fvNV; - vfmt->VertexAttrib2fNV = _save_VertexAttrib2fNV; - vfmt->VertexAttrib2fvNV = _save_VertexAttrib2fvNV; - vfmt->VertexAttrib3fNV = _save_VertexAttrib3fNV; - vfmt->VertexAttrib3fvNV = _save_VertexAttrib3fvNV; - vfmt->VertexAttrib4fNV = _save_VertexAttrib4fNV; - vfmt->VertexAttrib4fvNV = _save_VertexAttrib4fvNV; - - /* This will all require us to fallback to saving the list as opcodes: - */ - vfmt->CallList = _save_CallList; /* inside begin/end */ - vfmt->CallLists = _save_CallLists; /* inside begin/end */ - vfmt->EvalCoord1f = _save_EvalCoord1f; - vfmt->EvalCoord1fv = _save_EvalCoord1fv; - vfmt->EvalCoord2f = _save_EvalCoord2f; - vfmt->EvalCoord2fv = _save_EvalCoord2fv; - vfmt->EvalPoint1 = _save_EvalPoint1; - vfmt->EvalPoint2 = _save_EvalPoint2; - - /* These are all errors as we at least know we are in some sort of - * begin/end pair: - */ - vfmt->EvalMesh1 = _save_EvalMesh1; - vfmt->EvalMesh2 = _save_EvalMesh2; - vfmt->Begin = _save_Begin; - vfmt->Rectf = _save_Rectf; - vfmt->DrawArrays = _save_DrawArrays; - vfmt->DrawElements = _save_DrawElements; - vfmt->DrawRangeElements = _save_DrawRangeElements; - -} - - -void brw_save_SaveFlushVertices( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - - /* Noop when we are actually active: - */ - if (ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM || - ctx->Driver.CurrentSavePrimitive <= GL_POLYGON) - return; - - if (save->vert_count || - save->prim_count) - _save_compile_vertex_list( ctx ); - - _save_copy_to_current( ctx ); - _save_reset_vertex( ctx ); - _save_reset_counters( ctx ); - ctx->Driver.SaveNeedFlush = 0; -} - -void brw_save_NewList( GLcontext *ctx, GLuint list, GLenum mode ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - - (void) list; (void) mode; - - if (!save->prim_store) - save->prim_store = alloc_prim_store( ctx ); - - if (!save->vertex_store) - save->vertex_store = alloc_vertex_store( ctx ); - - save->vbptr = map_vertex_store( ctx, save->vertex_store ); - - _save_reset_vertex( ctx ); - _save_reset_counters( ctx ); - ctx->Driver.SaveNeedFlush = 0; -} - -void brw_save_EndList( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - unmap_vertex_store( ctx, save->vertex_store ); - - assert(save->vertex_size == 0); -} - -void brw_save_BeginCallList( GLcontext *ctx, struct mesa_display_list *dlist ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - save->replay_flags |= dlist->flags; -} - -void brw_save_EndCallList( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - - if (ctx->ListState.CallDepth == 1) { - /* This is correct: want to keep only the BRW_SAVE_FALLBACK - * flag, if it is set: - */ - save->replay_flags &= BRW_SAVE_FALLBACK; - } -} - - -static void brw_destroy_vertex_list( GLcontext *ctx, void *data ) -{ - struct brw_save_vertex_list *node = (struct brw_save_vertex_list *)data; - (void) ctx; - - if ( --node->vertex_store->refcount == 0 ) - free_vertex_store( ctx, node->vertex_store ); - - if ( --node->prim_store->refcount == 0 ) - FREE( node->prim_store ); -} - - -static void brw_print_vertex_list( GLcontext *ctx, void *data ) -{ - struct brw_save_vertex_list *node = (struct brw_save_vertex_list *)data; - GLuint i; - (void) ctx; - - _mesa_debug(NULL, "BRW-VERTEX-LIST, %u vertices %d primitives, %d vertsize\n", - node->count, - node->prim_count, - node->vertex_size); - - for (i = 0 ; i < node->prim_count ; i++) { - struct brw_draw_prim *prim = &node->prim[i]; - _mesa_debug(NULL, " prim %d: %s%s %d..%d %s %s\n", - i, - _mesa_lookup_enum_by_nr(prim->mode), - prim->weak ? " (weak)" : "", - prim->start, - prim->start + prim->count, - (prim->begin) ? "BEGIN" : "(wrap)", - (prim->end) ? "END" : "(wrap)"); - } -} - - -static void _save_current_init( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLint i; - - for (i = 0; i < BRW_ATTRIB_FIRST_MATERIAL; i++) { - save->currentsz[i] = &ctx->ListState.ActiveAttribSize[i]; - save->current[i] = ctx->ListState.CurrentAttrib[i]; - } - - for (i = BRW_ATTRIB_FIRST_MATERIAL; i < BRW_ATTRIB_INDEX; i++) { - const GLuint j = i - BRW_ATTRIB_FIRST_MATERIAL; - ASSERT(j < MAT_ATTRIB_MAX); - save->currentsz[i] = &ctx->ListState.ActiveMaterialSize[j]; - save->current[i] = ctx->ListState.CurrentMaterial[j]; - } - - save->currentsz[BRW_ATTRIB_INDEX] = &ctx->ListState.ActiveIndex; - save->current[BRW_ATTRIB_INDEX] = &ctx->ListState.CurrentIndex; - - save->currentsz[BRW_ATTRIB_EDGEFLAG] = &ctx->ListState.ActiveEdgeFlag; - save->current[BRW_ATTRIB_EDGEFLAG] = &save->CurrentFloatEdgeFlag; -} - -/** - * Initialize the display list compiler - */ -void brw_save_api_init( struct brw_save_context *save ) -{ - GLcontext *ctx = save->ctx; - GLuint i; - - save->opcode_vertex_list = - _mesa_alloc_opcode( ctx, - sizeof(struct brw_save_vertex_list), - brw_save_playback_vertex_list, - brw_destroy_vertex_list, - brw_print_vertex_list ); - - ctx->Driver.NotifySaveBegin = brw_save_NotifyBegin; - - _save_vtxfmt_init( ctx ); - _save_current_init( ctx ); - - for (i = 0; i < BRW_ATTRIB_MAX; i++) - save->inputs[i] = &save->arrays[i]; - - /* Hook our array functions into the outside-begin-end vtxfmt in - * ctx->ListState. - */ - ctx->ListState.ListVtxfmt.Rectf = _save_OBE_Rectf; - ctx->ListState.ListVtxfmt.DrawArrays = _save_OBE_DrawArrays; - ctx->ListState.ListVtxfmt.DrawElements = _save_OBE_DrawElements; - ctx->ListState.ListVtxfmt.DrawRangeElements = _save_OBE_DrawRangeElements; - _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); -} - diff --git a/src/mesa/drivers/dri/i965/brw_save_draw.c b/src/mesa/drivers/dri/i965/brw_save_draw.c deleted file mode 100644 index 84f74d3f6c..0000000000 --- a/src/mesa/drivers/dri/i965/brw_save_draw.c +++ /dev/null @@ -1,209 +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 - */ - -#include "glheader.h" -#include "context.h" -#include "imports.h" -#include "mtypes.h" -#include "macros.h" -#include "light.h" -#include "state.h" - -#include "brw_save.h" -#include "brw_draw.h" -#include "brw_fallback.h" - - -static void _playback_copy_to_current( GLcontext *ctx, - const struct brw_save_vertex_list *node ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLfloat vertex[BRW_ATTRIB_MAX * 4], *data = vertex; - GLuint i, offset; - - if (node->count) - offset = node->buffer_offset + (node->count-1) * node->vertex_size; - else - offset = node->buffer_offset; - - ctx->Driver.GetBufferSubData( ctx, 0, offset, node->vertex_size, - data, node->vertex_store->bufferobj ); - - for (i = BRW_ATTRIB_POS+1 ; i <= BRW_ATTRIB_INDEX ; i++) { - if (node->attrsz[i]) { - COPY_CLEAN_4V(save->current[i], node->attrsz[i], data); - data += node->attrsz[i]; - - if (i >= BRW_ATTRIB_MAT_FRONT_AMBIENT && - i <= BRW_ATTRIB_MAT_BACK_INDEXES) - ctx->NewState |= _NEW_LIGHT; - } - } - - /* Edgeflag requires special treatment: - */ - if (node->attrsz[BRW_ATTRIB_EDGEFLAG]) { - ctx->Current.EdgeFlag = (data[0] == 1.0); - } - - -#if 1 - /* Colormaterial -- this kindof sucks. - */ - if (ctx->Light.ColorMaterialEnabled) { - _mesa_update_color_material(ctx, ctx->Current.Attrib[BRW_ATTRIB_COLOR0]); - } -#endif - - /* CurrentExecPrimitive - */ - if (node->prim_count) { - const struct brw_draw_prim *prim = &node->prim[node->prim_count - 1]; - if (prim->end) - ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; - else - ctx->Driver.CurrentExecPrimitive = prim->mode; - } -} - - - -/* Treat the vertex storage as a VBO, define vertex arrays pointing - * into it: - */ -static void brw_bind_vertex_list( struct brw_save_context *save, - const struct brw_save_vertex_list *node ) -{ - struct gl_client_array *arrays = save->arrays; - GLuint data = node->buffer_offset; - GLuint attr; - - memset(arrays, 0, BRW_ATTRIB_MAX * sizeof(arrays[0])); - - for (attr = 0; attr <= BRW_ATTRIB_INDEX; attr++) { - if (node->attrsz[attr]) { - arrays[attr].Ptr = (const GLubyte *)data; - arrays[attr].Size = node->attrsz[attr]; - arrays[attr].StrideB = node->vertex_size * sizeof(GLfloat); - arrays[attr].Stride = node->vertex_size * sizeof(GLfloat); - arrays[attr].Type = GL_FLOAT; - arrays[attr].Enabled = 1; - arrays[attr].BufferObj = node->vertex_store->bufferobj; - arrays[attr]._MaxElement = node->count; /* ??? */ - - assert(arrays[attr].BufferObj->Name); - - data += node->attrsz[attr] * sizeof(GLfloat); - } - } -} - -static void brw_save_loopback_vertex_list( GLcontext *ctx, - const struct brw_save_vertex_list *list ) -{ - const char *buffer = ctx->Driver.MapBuffer(ctx, - GL_ARRAY_BUFFER_ARB, - GL_DYNAMIC_READ_ARB, /* ? */ - list->vertex_store->bufferobj); - - brw_loopback_vertex_list( ctx, - (const GLfloat *)(buffer + list->buffer_offset), - list->attrsz, - list->prim, - list->prim_count, - list->wrap_count, - list->vertex_size); - - ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER_ARB, - list->vertex_store->bufferobj); -} - - -/** - * Execute the buffer and save copied verts. - */ -void brw_save_playback_vertex_list( GLcontext *ctx, void *data ) -{ - const struct brw_save_vertex_list *node = (const struct brw_save_vertex_list *) data; - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - - FLUSH_CURRENT(ctx, 0); - - if (node->prim_count > 0 && node->count > 0) { - - if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END && - node->prim[0].begin) { - - /* Degenerate case: list is called inside begin/end pair and - * includes operations such as glBegin or glDrawArrays. - */ - if (0) - _mesa_printf("displaylist recursive begin"); - - brw_save_loopback_vertex_list( ctx, node ); - return; - } - else if (save->replay_flags) { - /* Various degnerate cases: translate into immediate mode - * calls rather than trying to execute in place. - */ - brw_save_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; - } - - brw_bind_vertex_list( save, node ); - - if (!brw_draw_prims( save->ctx, - save->inputs, - node->prim, - node->prim_count, - NULL, - 0, /* Node is a VBO, so this is ok */ - node->count, - 0 )) { - brw_fallback(ctx); - brw_save_loopback_vertex_list( ctx, node ); - brw_unfallback(ctx); - return; - } - } - - /* Copy to current? - */ - _playback_copy_to_current( ctx, node ); -} -- cgit v1.2.3 From 99efde461d3b8615863bdb7308e05289e0db0422 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 30 Oct 2006 16:44:13 +0000 Subject: better handling of current attributes. Trivial dlist and varray tests work --- src/mesa/Makefile | 2 +- src/mesa/main/arrayobj.c | 9 --- src/mesa/main/enable.c | 2 +- src/mesa/main/mtypes.h | 10 +-- src/mesa/sources | 30 ++++----- src/mesa/tnl/t_context.c | 2 + src/mesa/vbo/vbo_context.c | 144 +++++++++++++++++++++++++++++++++++++++++- src/mesa/vbo/vbo_context.h | 7 ++ src/mesa/vbo/vbo_exec.c | 117 ---------------------------------- src/mesa/vbo/vbo_exec.h | 4 -- src/mesa/vbo/vbo_exec_array.c | 15 +++-- src/mesa/vbo/vbo_exec_draw.c | 38 +++++++++-- src/mesa/vbo/vbo_save_draw.c | 28 +++++++- 13 files changed, 235 insertions(+), 173 deletions(-) (limited to 'src') diff --git a/src/mesa/Makefile b/src/mesa/Makefile index 3f65ecf5cc..e06607b0f8 100644 --- a/src/mesa/Makefile +++ b/src/mesa/Makefile @@ -142,7 +142,7 @@ depend: $(ALL_SOURCES) @ echo "running $(MKDEP)" @ touch depend @$(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(ALL_SOURCES) \ - > /dev/null + > /dev/null 2>/dev/null subdirs: diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c index 852b9aaee9..d601ee461e 100644 --- a/src/mesa/main/arrayobj.c +++ b/src/mesa/main/arrayobj.c @@ -114,40 +114,34 @@ _mesa_initialize_array_object( GLcontext *ctx, obj->Vertex.StrideB = 0; obj->Vertex.Ptr = NULL; obj->Vertex.Enabled = GL_FALSE; - obj->Vertex.Flags = CA_CLIENT_DATA; obj->Normal.Type = GL_FLOAT; obj->Normal.Stride = 0; obj->Normal.StrideB = 0; obj->Normal.Ptr = NULL; obj->Normal.Enabled = GL_FALSE; - obj->Normal.Flags = CA_CLIENT_DATA; obj->Color.Size = 4; obj->Color.Type = GL_FLOAT; obj->Color.Stride = 0; obj->Color.StrideB = 0; obj->Color.Ptr = NULL; obj->Color.Enabled = GL_FALSE; - obj->Color.Flags = CA_CLIENT_DATA; obj->SecondaryColor.Size = 4; obj->SecondaryColor.Type = GL_FLOAT; obj->SecondaryColor.Stride = 0; obj->SecondaryColor.StrideB = 0; obj->SecondaryColor.Ptr = NULL; obj->SecondaryColor.Enabled = GL_FALSE; - obj->SecondaryColor.Flags = CA_CLIENT_DATA; obj->FogCoord.Size = 1; obj->FogCoord.Type = GL_FLOAT; obj->FogCoord.Stride = 0; obj->FogCoord.StrideB = 0; obj->FogCoord.Ptr = NULL; obj->FogCoord.Enabled = GL_FALSE; - obj->FogCoord.Flags = CA_CLIENT_DATA; obj->Index.Type = GL_FLOAT; obj->Index.Stride = 0; obj->Index.StrideB = 0; obj->Index.Ptr = NULL; obj->Index.Enabled = GL_FALSE; - obj->Index.Flags = CA_CLIENT_DATA; for (i = 0; i < MAX_TEXTURE_UNITS; i++) { obj->TexCoord[i].Size = 4; obj->TexCoord[i].Type = GL_FLOAT; @@ -155,13 +149,11 @@ _mesa_initialize_array_object( GLcontext *ctx, obj->TexCoord[i].StrideB = 0; obj->TexCoord[i].Ptr = NULL; obj->TexCoord[i].Enabled = GL_FALSE; - obj->TexCoord[i].Flags = CA_CLIENT_DATA; } obj->EdgeFlag.Stride = 0; obj->EdgeFlag.StrideB = 0; obj->EdgeFlag.Ptr = NULL; obj->EdgeFlag.Enabled = GL_FALSE; - obj->EdgeFlag.Flags = CA_CLIENT_DATA; for (i = 0; i < VERT_ATTRIB_MAX; i++) { obj->VertexAttrib[i].Size = 4; obj->VertexAttrib[i].Type = GL_FLOAT; @@ -170,7 +162,6 @@ _mesa_initialize_array_object( GLcontext *ctx, obj->VertexAttrib[i].Ptr = NULL; obj->VertexAttrib[i].Enabled = GL_FALSE; obj->VertexAttrib[i].Normalized = GL_FALSE; - obj->VertexAttrib[i].Flags = CA_CLIENT_DATA; } #if FEATURE_ARB_vertex_buffer_object diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c index 91268b596d..bf86e6db7d 100644 --- a/src/mesa/main/enable.c +++ b/src/mesa/main/enable.c @@ -53,7 +53,7 @@ static void client_state( GLcontext *ctx, GLenum cap, GLboolean state ) { GLuint flag; - GLuint *var; + GLboolean *var; switch (cap) { case GL_VERTEX_ARRAY: diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 5a326ff0dc..903779edae 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1640,8 +1640,6 @@ struct gl_pixelstore_attrib }; -#define CA_CLIENT_DATA 0x1 /**< Data not allocated by mesa */ - /** * Client vertex array attributes @@ -1653,14 +1651,12 @@ struct gl_client_array GLsizei Stride; /**< user-specified stride */ GLsizei StrideB; /**< actual stride in bytes */ const GLubyte *Ptr; /**< Points to array data */ - GLbitfield Enabled; /**< one of the _NEW_ARRAY_ bits */ + GLboolean Enabled; /**< Enabled flag is a boolean */ GLboolean Normalized; /**< GL_ARB_vertex_program */ /**< GL_ARB_vertex_buffer_object */ struct gl_buffer_object *BufferObj; GLuint _MaxElement; - - GLbitfield Flags; }; @@ -1681,8 +1677,8 @@ struct gl_array_object struct gl_client_array SecondaryColor; struct gl_client_array FogCoord; struct gl_client_array Index; - struct gl_client_array TexCoord[MAX_TEXTURE_COORD_UNITS]; struct gl_client_array EdgeFlag; + struct gl_client_array TexCoord[MAX_TEXTURE_COORD_UNITS]; /*@}*/ /** Generic arrays for vertex programs/shaders */ @@ -2617,7 +2613,7 @@ struct matrix_stack #define _NEW_ARRAY_TEXCOORD_5 VERT_BIT_TEX5 #define _NEW_ARRAY_TEXCOORD_6 VERT_BIT_TEX6 #define _NEW_ARRAY_TEXCOORD_7 VERT_BIT_TEX7 -#define _NEW_ARRAY_ATTRIB_0 0x10000 /* start at bit 16 */ +#define _NEW_ARRAY_ATTRIB_0 VERT_BIT_GENERIC0 /* start at bit 16 */ #define _NEW_ARRAY_ALL 0xffffffff diff --git a/src/mesa/sources b/src/mesa/sources index 09692c6f15..b589111a19 100644 --- a/src/mesa/sources +++ b/src/mesa/sources @@ -78,10 +78,6 @@ MATH_SOURCES = \ math/m_vector.c \ math/m_xform.c -ARRAY_CACHE_SOURCES = \ - array_cache/ac_context.c \ - array_cache/ac_import.c - SWRAST_SOURCES = \ swrast/s_aaline.c \ swrast/s_aatriangle.c \ @@ -119,13 +115,9 @@ SWRAST_SETUP_SOURCES = \ swrast_setup/ss_triangle.c TNL_SOURCES = \ - tnl/t_array_api.c \ - tnl/t_array_import.c \ tnl/t_context.c \ tnl/t_pipeline.c \ - tnl/t_save_api.c \ - tnl/t_save_loopback.c \ - tnl/t_save_playback.c \ + tnl/t_draw.c \ tnl/t_vb_arbprogram.c \ tnl/t_vb_arbprogram_sse.c \ tnl/t_vb_arbshader.c\ @@ -142,13 +134,19 @@ TNL_SOURCES = \ tnl/t_vp_build.c \ tnl/t_vertex.c \ tnl/t_vertex_sse.c \ - tnl/t_vertex_generic.c \ - tnl/t_vtx_api.c \ - tnl/t_vtx_generic.c \ - tnl/t_vtx_x86.c \ - tnl/t_vtx_eval.c \ - tnl/t_vtx_exec.c + tnl/t_vertex_generic.c +VBO_SOURCES = \ + vbo/vbo_context.c \ + vbo/vbo_exec.c \ + vbo/vbo_exec_api.c \ + vbo/vbo_exec_array.c \ + vbo/vbo_exec_draw.c \ + vbo/vbo_exec_eval.c \ + vbo/vbo_save.c \ + vbo/vbo_save_api.c \ + vbo/vbo_save_draw.c \ + vbo/vbo_save_loopback.c SHADER_SOURCES = \ @@ -317,7 +315,7 @@ ALL_SOURCES = \ SOLO_SOURCES = \ $(MAIN_SOURCES) \ $(MATH_SOURCES) \ - $(ARRAY_CACHE_SOURCES) \ + $(VBO_SOURCES) \ $(TNL_SOURCES) \ $(SHADER_SOURCES) \ $(SWRAST_SOURCES) \ diff --git a/src/mesa/tnl/t_context.c b/src/mesa/tnl/t_context.c index ff05ac0318..851a0672d4 100644 --- a/src/mesa/tnl/t_context.c +++ b/src/mesa/tnl/t_context.c @@ -77,6 +77,8 @@ _tnl_CreateContext( GLcontext *ctx ) tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; tnl->Driver.NotifyMaterialChange = _mesa_validate_all_lighting_tables; + tnl->nr_blocks = 0; + return GL_TRUE; } diff --git a/src/mesa/vbo/vbo_context.c b/src/mesa/vbo/vbo_context.c index 5f28e6b0e0..29dfe09d99 100644 --- a/src/mesa/vbo/vbo_context.c +++ b/src/mesa/vbo/vbo_context.c @@ -40,6 +40,123 @@ extern void _tnl_draw_prims( GLcontext *ctx, GLuint min_index, GLuint max_index ); + + +#define NR_LEGACY_ATTRIBS 16 +#define NR_GENERIC_ATTRIBS 16 +#define NR_MAT_ATTRIBS 12 + +static void init_legacy_currval(GLcontext *ctx) +{ + struct vbo_context *vbo = vbo_context(ctx); + struct gl_client_array *arrays = vbo->legacy_currval; + GLuint i; + + memset(arrays, 0, sizeof(*arrays) * NR_LEGACY_ATTRIBS); + + /* Set up a constant (StrideB == 0) array for each current + * attribute: + */ + for (i = 0; i < NR_LEGACY_ATTRIBS; i++) { + struct gl_client_array *cl = &arrays[i]; + + switch (i) { + case VBO_ATTRIB_EDGEFLAG: + cl->Type = GL_UNSIGNED_BYTE; + cl->Ptr = (const void *)&ctx->Current.EdgeFlag; + break; + case VBO_ATTRIB_INDEX: + cl->Type = GL_FLOAT; + cl->Ptr = (const void *)&ctx->Current.Index; + break; + default: + cl->Type = GL_FLOAT; + cl->Ptr = (const void *)ctx->Current.Attrib[i]; + break; + } + + /* This will have to be determined at runtime: + */ + cl->Size = 1; + cl->Stride = 0; + cl->StrideB = 0; + cl->Enabled = 1; + cl->BufferObj = ctx->Array.NullBufferObj; + } +} + + +static void init_generic_currval(GLcontext *ctx) +{ + struct vbo_context *vbo = vbo_context(ctx); + struct gl_client_array *arrays = vbo->generic_currval; + GLuint i; + + memset(arrays, 0, sizeof(*arrays) * NR_GENERIC_ATTRIBS); + + for (i = 0; i < NR_GENERIC_ATTRIBS; i++) { + struct gl_client_array *cl = &arrays[i]; + + /* This will have to be determined at runtime: + */ + cl->Size = 1; + + cl->Type = GL_FLOAT; + cl->Ptr = (const void *)ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + i]; + cl->Stride = 0; + cl->StrideB = 0; + cl->Enabled = 1; + cl->BufferObj = ctx->Array.NullBufferObj; + } +} + + +static void init_mat_currval(GLcontext *ctx) +{ + struct vbo_context *vbo = vbo_context(ctx); + struct gl_client_array *arrays = vbo->mat_currval; + GLuint i; + + memset(arrays, 0, sizeof(*arrays) * NR_GENERIC_ATTRIBS); + + /* Set up a constant (StrideB == 0) array for each current + * attribute: + */ + for (i = 0; i < NR_GENERIC_ATTRIBS; i++) { + struct gl_client_array *cl = &arrays[i]; + + /* Size is fixed for the material attributes, for others will + * be determined at runtime: + */ + switch (i - VERT_ATTRIB_GENERIC0) { + case MAT_ATTRIB_FRONT_SHININESS: + case MAT_ATTRIB_BACK_SHININESS: + cl->Size = 1; + break; + case MAT_ATTRIB_FRONT_INDEXES: + case MAT_ATTRIB_BACK_INDEXES: + cl->Size = 3; + break; + default: + cl->Size = 4; + break; + } + + if (i < MAT_ATTRIB_MAX) + cl->Ptr = (const void *)ctx->Light.Material.Attrib[i]; + else + cl->Ptr = (const void *)ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + i]; + + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 0; + cl->Enabled = 1; + cl->BufferObj = ctx->Array.NullBufferObj; + } +} + + + GLboolean _vbo_CreateContext( GLcontext *ctx ) { struct vbo_context *vbo = CALLOC_STRUCT(vbo_context); @@ -60,6 +177,32 @@ GLboolean _vbo_CreateContext( GLcontext *ctx ) vbo_exec_init( ctx ); vbo_save_init( ctx ); + + init_legacy_currval( ctx ); + init_generic_currval( ctx ); + init_mat_currval( ctx ); + + /* Build mappings from VERT_ATTRIB -> VBO_ATTRIB depending on type + * of vertex program active. + */ + { + GLuint i; + + /* When no vertex program, pull in the material attributes in + * the 16..32 generic range. + */ + for (i = 0; i < 16; i++) + vbo->map_vp_none[i] = i; + for (i = 0; i < 12; i++) + vbo->map_vp_none[16+i] = VBO_ATTRIB_MAT_FRONT_AMBIENT + i; + for (i = 0; i < 4; i++) + vbo->map_vp_none[28+i] = i; + + for (i = 0; i < VERT_ATTRIB_MAX; i++) + vbo->map_vp_arb[i] = i; + } + + /* By default: */ vbo->draw_prims = _tnl_draw_prims; @@ -82,5 +225,4 @@ void _vbo_DestroyContext( GLcontext *ctx ) FREE(vbo_context(ctx)); ctx->swtnl_im = NULL; - } diff --git a/src/mesa/vbo/vbo_context.h b/src/mesa/vbo/vbo_context.h index 6b0f14d70e..a20bfbd518 100644 --- a/src/mesa/vbo/vbo_context.h +++ b/src/mesa/vbo/vbo_context.h @@ -60,6 +60,13 @@ void _vbo_DestroyContext( GLcontext *ctx ); struct vbo_context { + struct gl_client_array legacy_currval[16]; + struct gl_client_array generic_currval[16]; + struct gl_client_array mat_currval[16]; + + GLuint map_vp_none[32]; + GLuint map_vp_arb[32]; + struct vbo_exec_context exec; struct vbo_save_context save; diff --git a/src/mesa/vbo/vbo_exec.c b/src/mesa/vbo/vbo_exec.c index 4499803b8c..270e5201d3 100644 --- a/src/mesa/vbo/vbo_exec.c +++ b/src/mesa/vbo/vbo_exec.c @@ -38,119 +38,6 @@ #include "vbo_context.h" -#define NR_LEGACY_ATTRIBS 16 -#define NR_GENERIC_ATTRIBS 16 -#define NR_MAT_ATTRIBS 12 - -static void init_legacy_currval(GLcontext *ctx) -{ - struct vbo_exec_context *exec = &vbo_context(ctx)->exec; - struct gl_client_array *arrays = exec->legacy_currval; - GLuint i; - - memset(arrays, 0, sizeof(*arrays) * NR_LEGACY_ATTRIBS); - - /* Set up a constant (StrideB == 0) array for each current - * attribute: - */ - for (i = 0; i < NR_LEGACY_ATTRIBS; i++) { - struct gl_client_array *cl = &arrays[i]; - - switch (i) { - case VBO_ATTRIB_EDGEFLAG: - cl->Type = GL_UNSIGNED_BYTE; - cl->Ptr = (const void *)&ctx->Current.EdgeFlag; - break; - case VBO_ATTRIB_INDEX: - cl->Type = GL_FLOAT; - cl->Ptr = (const void *)&ctx->Current.Index; - break; - default: - cl->Type = GL_FLOAT; - cl->Ptr = (const void *)ctx->Current.Attrib[i]; - break; - } - - /* This will have to be determined at runtime: - */ - cl->Size = 1; - cl->Stride = 0; - cl->StrideB = 0; - cl->Enabled = 1; - cl->BufferObj = ctx->Array.NullBufferObj; - } -} - - -static void init_generic_currval(GLcontext *ctx) -{ - struct vbo_exec_context *exec = &vbo_context(ctx)->exec; - struct gl_client_array *arrays = exec->generic_currval; - GLuint i; - - memset(arrays, 0, sizeof(*arrays) * NR_GENERIC_ATTRIBS); - - for (i = 0; i < NR_GENERIC_ATTRIBS; i++) { - struct gl_client_array *cl = &arrays[i]; - - /* This will have to be determined at runtime: - */ - cl->Size = 1; - - cl->Type = GL_FLOAT; - cl->Ptr = (const void *)ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + i]; - cl->Stride = 0; - cl->StrideB = 0; - cl->Enabled = 1; - cl->BufferObj = ctx->Array.NullBufferObj; - } -} - - -static void init_mat_currval(GLcontext *ctx) -{ - struct vbo_exec_context *exec = &vbo_context(ctx)->exec; - struct gl_client_array *arrays = exec->mat_currval; - GLuint i; - - memset(arrays, 0, sizeof(*arrays) * NR_GENERIC_ATTRIBS); - - /* Set up a constant (StrideB == 0) array for each current - * attribute: - */ - for (i = 0; i < NR_GENERIC_ATTRIBS; i++) { - struct gl_client_array *cl = &arrays[i]; - - /* Size is fixed for the material attributes, for others will - * be determined at runtime: - */ - switch (i - VERT_ATTRIB_GENERIC0) { - case MAT_ATTRIB_FRONT_SHININESS: - case MAT_ATTRIB_BACK_SHININESS: - cl->Size = 1; - break; - case MAT_ATTRIB_FRONT_INDEXES: - case MAT_ATTRIB_BACK_INDEXES: - cl->Size = 3; - break; - default: - cl->Size = 4; - break; - } - - if (i < MAT_ATTRIB_MAX) - cl->Ptr = (const void *)ctx->Light.Material.Attrib[i]; - else - cl->Ptr = (const void *)ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + i]; - - cl->Type = GL_FLOAT; - cl->Stride = 0; - cl->StrideB = 0; - cl->Enabled = 1; - cl->BufferObj = ctx->Array.NullBufferObj; - } -} - void vbo_exec_init( GLcontext *ctx ) { @@ -167,10 +54,6 @@ void vbo_exec_init( GLcontext *ctx ) vbo_exec_vtx_init( exec ); vbo_exec_array_init( exec ); - init_legacy_currval( ctx ); - init_generic_currval( ctx ); - init_mat_currval( ctx ); - ctx->Driver.NeedFlush = 0; ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; ctx->Driver.FlushVertices = vbo_exec_FlushVertices; diff --git a/src/mesa/vbo/vbo_exec.h b/src/mesa/vbo/vbo_exec.h index 4542d2807c..72855d267e 100644 --- a/src/mesa/vbo/vbo_exec.h +++ b/src/mesa/vbo/vbo_exec.h @@ -75,10 +75,6 @@ struct vbo_exec_context GLcontext *ctx; GLvertexformat vtxfmt; - struct gl_client_array legacy_currval[16]; - struct gl_client_array generic_currval[16]; - struct gl_client_array mat_currval[16]; - struct { struct gl_buffer_object *bufferobj; GLubyte *buffer_map; diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index 5cfa7a01a9..b3650e2697 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -107,7 +107,8 @@ static void bind_array_obj( GLcontext *ctx ) static void recalculate_input_bindings( GLcontext *ctx ) { - struct vbo_exec_context *exec = &vbo_context(ctx)->exec; + struct vbo_context *vbo = vbo_context(ctx); + struct vbo_exec_context *exec = &vbo->exec; const struct gl_client_array **inputs = &exec->array.inputs[0]; GLuint i; @@ -126,11 +127,11 @@ static void recalculate_input_bindings( GLcontext *ctx ) if (exec->array.legacy_array[i]->Enabled) inputs[i] = exec->array.legacy_array[i]; else - inputs[i] = &exec->legacy_currval[i]; + inputs[i] = &vbo->legacy_currval[i]; } for (i = 0; i < MAT_ATTRIB_MAX; i++) { - inputs[VERT_ATTRIB_GENERIC0 + i] = &exec->mat_currval[i]; + inputs[VERT_ATTRIB_GENERIC0 + i] = &vbo->mat_currval[i]; } break; case VP_NV: @@ -144,7 +145,7 @@ static void recalculate_input_bindings( GLcontext *ctx ) else if (exec->array.legacy_array[i]->Enabled) inputs[i] = exec->array.legacy_array[i]; else - inputs[i] = &exec->legacy_currval[i]; + inputs[i] = &vbo->legacy_currval[i]; } break; case VP_ARB: @@ -160,21 +161,21 @@ static void recalculate_input_bindings( GLcontext *ctx ) else if (exec->array.legacy_array[0]->Enabled) inputs[0] = exec->array.legacy_array[0]; else - inputs[0] = &exec->legacy_currval[0]; + inputs[0] = &vbo->legacy_currval[0]; for (i = 1; i <= VERT_ATTRIB_TEX7; i++) { if (exec->array.legacy_array[i]->Enabled) inputs[i] = exec->array.legacy_array[i]; else - inputs[i] = &exec->legacy_currval[i]; + inputs[i] = &vbo->legacy_currval[i]; } for (i = 0; i < 16; i++) { if (exec->array.generic_array[0]->Enabled) inputs[VERT_ATTRIB_GENERIC0 + i] = exec->array.generic_array[i]; else - inputs[VERT_ATTRIB_GENERIC0 + i] = &exec->generic_currval[i]; + inputs[VERT_ATTRIB_GENERIC0 + i] = &vbo->generic_currval[i]; } break; } diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c index f665c64c7a..c1898aea49 100644 --- a/src/mesa/vbo/vbo_exec_draw.c +++ b/src/mesa/vbo/vbo_exec_draw.c @@ -132,25 +132,49 @@ static GLuint vbo_copy_vertices( struct vbo_exec_context *exec ) } + /* TODO: populate these as the vertex is defined: */ -static void vbo_exec_bind_arrays( struct vbo_exec_context *exec ) +static void vbo_exec_bind_arrays( GLcontext *ctx ) { + struct vbo_context *vbo = vbo_context(ctx); + struct vbo_exec_context *exec = &vbo->exec; struct gl_client_array *arrays = exec->vtx.arrays; GLuint count = exec->vtx.vert_count; GLubyte *data = exec->vtx.buffer_map; + const GLuint *map; GLuint attr; - memcpy(arrays, exec->legacy_currval, 16 * sizeof(arrays[0])); - memcpy(arrays + 16, exec->mat_currval, 16 * sizeof(arrays[0])); + /* Install the default (ie Current) attributes first, then overlay + * all active ones. + */ + switch (get_program_mode(exec->ctx)) { + case VP_NONE: + memcpy(arrays, vbo->legacy_currval, 16 * sizeof(arrays[0])); + memcpy(arrays + 16, vbo->mat_currval, 16 * sizeof(arrays[0])); + map = vbo->map_vp_none; + break; + case VP_NV: + case VP_ARB: + /* The aliasing of attributes for NV vertex programs has already + * occurred. NV vertex programs cannot access material values, + * nor attributes greater than VERT_ATTRIB_TEX7. + */ + memcpy(arrays, vbo->legacy_currval, 16 * sizeof(arrays[0])); + memcpy(arrays + 16, vbo->generic_currval, 16 * sizeof(arrays[0])); + map = vbo->map_vp_arb; + break; + } /* Make all active attributes (including edgeflag) available as * arrays of floats. */ - for (attr = 0; attr < VBO_ATTRIB_MAX ; attr++) { - if (exec->vtx.attrsz[attr]) { + for (attr = 0; attr < VERT_ATTRIB_MAX ; attr++) { + GLuint src = map[attr]; + + if (exec->vtx.attrsz[src]) { arrays[attr].Ptr = (void *)data; - arrays[attr].Size = exec->vtx.attrsz[attr]; + arrays[attr].Size = exec->vtx.attrsz[src]; arrays[attr].StrideB = exec->vtx.vertex_size * sizeof(GLfloat); arrays[attr].Stride = exec->vtx.vertex_size * sizeof(GLfloat); arrays[attr].Type = GL_FLOAT; @@ -181,7 +205,7 @@ void vbo_exec_vtx_flush( struct vbo_exec_context *exec ) if (exec->vtx.copied.nr != exec->vtx.vert_count) { GLcontext *ctx = exec->ctx; - vbo_exec_bind_arrays( exec ); + vbo_exec_bind_arrays( ctx ); vbo_context(ctx)->draw_prims( ctx, exec->vtx.inputs, diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c index 44e0171233..18c770a41c 100644 --- a/src/mesa/vbo/vbo_save_draw.c +++ b/src/mesa/vbo/vbo_save_draw.c @@ -95,14 +95,36 @@ static void _playback_copy_to_current( GLcontext *ctx, /* Treat the vertex storage as a VBO, define vertex arrays pointing * into it: */ -static void vbo_bind_vertex_list( struct vbo_save_context *save, +static void vbo_bind_vertex_list( GLcontext *ctx, const struct vbo_save_vertex_list *node ) { + struct vbo_context *vbo = vbo_context(ctx); + struct vbo_save_context *save = &vbo->save; struct gl_client_array *arrays = save->arrays; GLuint data = node->buffer_offset; + const GLuint *map; GLuint attr; - memset(arrays, 0, VBO_ATTRIB_MAX * sizeof(arrays[0])); + /* Install the default (ie Current) attributes first, then overlay + * all active ones. + */ + switch (get_program_mode(ctx)) { + case VP_NONE: + memcpy(arrays, vbo->legacy_currval, 16 * sizeof(arrays[0])); + memcpy(arrays + 16, vbo->mat_currval, 16 * sizeof(arrays[0])); + map = vbo->map_vp_none; + break; + case VP_NV: + case VP_ARB: + /* The aliasing of attributes for NV vertex programs has already + * occurred. NV vertex programs cannot access material values, + * nor attributes greater than VERT_ATTRIB_TEX7. + */ + memcpy(arrays, vbo->legacy_currval, 16 * sizeof(arrays[0])); + memcpy(arrays + 16, vbo->generic_currval, 16 * sizeof(arrays[0])); + map = vbo->map_vp_arb; + break; + } for (attr = 0; attr <= VBO_ATTRIB_INDEX; attr++) { if (node->attrsz[attr]) { @@ -185,7 +207,7 @@ void vbo_save_playback_vertex_list( GLcontext *ctx, void *data ) return; } - vbo_bind_vertex_list( save, node ); + vbo_bind_vertex_list( ctx, node ); vbo_context(ctx)->draw_prims( ctx, save->inputs, -- cgit v1.2.3 From 48f5deab94be832a782a440f55a7bc742d50a62f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 30 Oct 2006 16:56:56 +0000 Subject: switch several dri drivers over --- src/mesa/drivers/dri/i810/i810context.c | 6 ++--- src/mesa/drivers/dri/i810/i810state.c | 4 ++-- src/mesa/drivers/dri/i915/i915_context.c | 5 ++-- src/mesa/drivers/dri/i915/intel_context.c | 8 +++---- src/mesa/drivers/dri/i965/brw_context.h | 1 - src/mesa/drivers/dri/i965/intel_context.c | 8 +++---- src/mesa/drivers/osmesa/osmesa.c | 3 ++- src/mesa/drivers/x11/xm_api.c | 2 +- src/mesa/drivers/x11/xm_dd.c | 1 + src/mesa/vbo/vbo.h | 40 +++++++++++++++++++++++++++++++ src/mesa/vbo/vbo_context.c | 3 ++- src/mesa/vbo/vbo_context.h | 3 --- 12 files changed, 62 insertions(+), 22 deletions(-) create mode 100644 src/mesa/vbo/vbo.h (limited to 'src') diff --git a/src/mesa/drivers/dri/i810/i810context.c b/src/mesa/drivers/dri/i810/i810context.c index c0f4efd7a3..db8f7a19a2 100644 --- a/src/mesa/drivers/dri/i810/i810context.c +++ b/src/mesa/drivers/dri/i810/i810context.c @@ -44,7 +44,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/t_pipeline.h" @@ -287,7 +287,7 @@ i810CreateContext( const __GLcontextModes *mesaVis, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -350,7 +350,7 @@ i810DestroyContext(__DRIcontextPrivate *driContextPriv) release_texture_heaps = (imesa->glCtx->Shared->RefCount == 1); _swsetup_DestroyContext( imesa->glCtx ); _tnl_DestroyContext( imesa->glCtx ); - _ac_DestroyContext( imesa->glCtx ); + _vbo_DestroyContext( imesa->glCtx ); _swrast_DestroyContext( imesa->glCtx ); i810FreeVB( imesa->glCtx ); diff --git a/src/mesa/drivers/dri/i810/i810state.c b/src/mesa/drivers/dri/i810/i810state.c index 6f9d4b5bd4..3ad25282d9 100644 --- a/src/mesa/drivers/dri/i810/i810state.c +++ b/src/mesa/drivers/dri/i810/i810state.c @@ -21,8 +21,8 @@ #include "i810ioctl.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" #include "tnl/tnl.h" +#include "vbo/vbo.h" #include "swrast_setup/swrast_setup.h" #include "tnl/t_pipeline.h" @@ -953,7 +953,7 @@ static void i810InvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); I810_CONTEXT(ctx)->new_state |= new_state; } diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c index 2f78fd60b2..6ec34e5bde 100644 --- a/src/mesa/drivers/dri/i915/i915_context.c +++ b/src/mesa/drivers/dri/i915/i915_context.c @@ -36,7 +36,8 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" + #include "utils.h" #include "i915_reg.h" @@ -63,7 +64,7 @@ static void i915InvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); _tnl_invalidate_vertex_state( ctx, new_state ); INTEL_CONTEXT(ctx)->NewGLState |= new_state; diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c index 4be95301c3..3d543b2485 100644 --- a/src/mesa/drivers/dri/i915/intel_context.c +++ b/src/mesa/drivers/dri/i915/intel_context.c @@ -37,7 +37,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/t_pipeline.h" #include "tnl/t_vertex.h" @@ -228,7 +228,7 @@ static void intelInvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); _tnl_invalidate_vertex_state( ctx, new_state ); INTEL_CONTEXT(ctx)->NewGLState |= new_state; @@ -305,7 +305,7 @@ GLboolean intelInitContext( intelContextPtr intel, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -424,7 +424,7 @@ void intelDestroyContext(__DRIcontextPrivate *driContextPriv) release_texture_heaps = (intel->ctx.Shared->RefCount == 1); _swsetup_DestroyContext (&intel->ctx); _tnl_DestroyContext (&intel->ctx); - _ac_DestroyContext (&intel->ctx); + _vbo_DestroyContext (&intel->ctx); _swrast_DestroyContext (&intel->ctx); intel->Fallback = 0; /* don't call _swrast_Flush later */ diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index 1137bfd2c7..e2279ca276 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -36,7 +36,6 @@ #include "intel_context.h" #include "brw_structs.h" #include "imports.h" -#include "brw_attrib.h" /* Glossary: diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 36edd7db7f..c4c5488cbb 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -37,7 +37,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/t_pipeline.h" #include "tnl/t_vertex.h" @@ -216,7 +216,7 @@ static void intelInvalidateState( GLcontext *ctx, GLuint new_state ) _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); _tnl_invalidate_vertex_state( ctx, new_state ); @@ -322,7 +322,7 @@ GLboolean intelInitContext( struct intel_context *intel, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -467,7 +467,7 @@ void intelDestroyContext(__DRIcontextPrivate *driContextPriv) release_texture_heaps = (intel->ctx.Shared->RefCount == 1); _swsetup_DestroyContext (&intel->ctx); _tnl_DestroyContext (&intel->ctx); - _ac_DestroyContext (&intel->ctx); + _vbo_DestroyContext (&intel->ctx); _swrast_DestroyContext (&intel->ctx); intel->Fallback = 0; /* don't call _swrast_Flush later */ diff --git a/src/mesa/drivers/osmesa/osmesa.c b/src/mesa/drivers/osmesa/osmesa.c index 42a1bb5123..c4fc8821e5 100644 --- a/src/mesa/drivers/osmesa/osmesa.c +++ b/src/mesa/drivers/osmesa/osmesa.c @@ -50,7 +50,7 @@ #include "tnl/t_context.h" #include "tnl/t_pipeline.h" #include "drivers/common/driverfuncs.h" -#include "vbo/vbo_context.h" +#include "vbo/vbo.h" @@ -111,6 +111,7 @@ osmesa_update_state( GLcontext *ctx, GLuint new_state ) _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); } diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c index 6fb0d9bbbd..98a68dd4f4 100644 --- a/src/mesa/drivers/x11/xm_api.c +++ b/src/mesa/drivers/x11/xm_api.c @@ -74,7 +74,7 @@ #include "renderbuffer.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "vbo/vbo_context.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" diff --git a/src/mesa/drivers/x11/xm_dd.c b/src/mesa/drivers/x11/xm_dd.c index 39cec1dc9f..87bd5e4a30 100644 --- a/src/mesa/drivers/x11/xm_dd.c +++ b/src/mesa/drivers/x11/xm_dd.c @@ -831,6 +831,7 @@ xmesa_update_state( GLcontext *ctx, GLbitfield new_state ) */ _swrast_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); if (ctx->DrawBuffer->Name != 0) diff --git a/src/mesa/vbo/vbo.h b/src/mesa/vbo/vbo.h new file mode 100644 index 0000000000..96b25f18ee --- /dev/null +++ b/src/mesa/vbo/vbo.h @@ -0,0 +1,40 @@ +/* + * mesa 3-D graphics library + * Version: 6.5 + * + * 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 vbo_context.h + * \brief VBO builder module datatypes and definitions. + * \author Keith Whitwell + */ + + +#ifndef _VBO_H +#define _VBO_H + +GLboolean _vbo_CreateContext( GLcontext *ctx ); +void _vbo_DestroyContext( GLcontext *ctx ); +void _vbo_InvalidateState( GLcontext *ctx, GLuint new_state ); + + +#endif diff --git a/src/mesa/vbo/vbo_context.c b/src/mesa/vbo/vbo_context.c index 29dfe09d99..5279b2e13c 100644 --- a/src/mesa/vbo/vbo_context.c +++ b/src/mesa/vbo/vbo_context.c @@ -26,6 +26,7 @@ */ #include "mtypes.h" +#include "vbo.h" #include "vbo_context.h" #include "imports.h" #include "api_arrayelt.h" @@ -210,7 +211,7 @@ GLboolean _vbo_CreateContext( GLcontext *ctx ) return GL_TRUE; } -void vbo_save_invalidate_state( GLcontext *ctx, GLuint new_state ) +void _vbo_InvalidateState( GLcontext *ctx, GLuint new_state ) { _ae_invalidate_state(ctx, new_state); } diff --git a/src/mesa/vbo/vbo_context.h b/src/mesa/vbo/vbo_context.h index a20bfbd518..982da00437 100644 --- a/src/mesa/vbo/vbo_context.h +++ b/src/mesa/vbo/vbo_context.h @@ -55,9 +55,6 @@ #include "vbo_save.h" #include "vbo_exec.h" -GLboolean _vbo_CreateContext( GLcontext *ctx ); -void _vbo_DestroyContext( GLcontext *ctx ); - struct vbo_context { struct gl_client_array legacy_currval[16]; -- cgit v1.2.3 From e8abd098b36c30d76b4c396970fd793ae58e0702 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 30 Oct 2006 17:12:05 +0000 Subject: Remove wakeup functions. This code is intended to be active all the time. --- src/mesa/vbo/vbo_context.c | 1 + src/mesa/vbo/vbo_exec.c | 23 +++++------------------ src/mesa/vbo/vbo_exec.h | 1 - src/mesa/vbo/vbo_save.c | 38 +++++++++++++------------------------- src/mesa/vbo/vbo_save.h | 2 -- 5 files changed, 19 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/mesa/vbo/vbo_context.c b/src/mesa/vbo/vbo_context.c index 5279b2e13c..291eb0bed3 100644 --- a/src/mesa/vbo/vbo_context.c +++ b/src/mesa/vbo/vbo_context.c @@ -214,6 +214,7 @@ GLboolean _vbo_CreateContext( GLcontext *ctx ) void _vbo_InvalidateState( GLcontext *ctx, GLuint new_state ) { _ae_invalidate_state(ctx, new_state); + vbo_exec_invalidate_state(ctx, new_state); } diff --git a/src/mesa/vbo/vbo_exec.c b/src/mesa/vbo/vbo_exec.c index 270e5201d3..7d95873247 100644 --- a/src/mesa/vbo/vbo_exec.c +++ b/src/mesa/vbo/vbo_exec.c @@ -37,8 +37,6 @@ #include "vbo_context.h" - - void vbo_exec_init( GLcontext *ctx ) { struct vbo_exec_context *exec = &vbo_context(ctx)->exec; @@ -54,11 +52,15 @@ void vbo_exec_init( GLcontext *ctx ) vbo_exec_vtx_init( exec ); vbo_exec_array_init( exec ); + /* Hook our functions into exec and compile dispatch tables. + */ + _mesa_install_exec_vtxfmt( ctx, &exec->vtxfmt ); + ctx->Driver.NeedFlush = 0; ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; ctx->Driver.FlushVertices = vbo_exec_FlushVertices; - exec->eval.recalculate_maps = 1; + vbo_exec_invalidate_state( ctx, ~0 ); } @@ -90,21 +92,6 @@ void vbo_exec_invalidate_state( GLcontext *ctx, GLuint new_state ) } -void vbo_exec_wakeup( GLcontext *ctx ) -{ - struct vbo_exec_context *exec = &vbo_context(ctx)->exec; - - ctx->Driver.FlushVertices = vbo_exec_FlushVertices; - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; - - /* Hook our functions into exec and compile dispatch tables. - */ - _mesa_install_exec_vtxfmt( ctx, &exec->vtxfmt ); - - /* Assume we haven't been getting state updates either: - */ - vbo_exec_invalidate_state( ctx, ~0 ); -} diff --git a/src/mesa/vbo/vbo_exec.h b/src/mesa/vbo/vbo_exec.h index 72855d267e..ef158de825 100644 --- a/src/mesa/vbo/vbo_exec.h +++ b/src/mesa/vbo/vbo_exec.h @@ -146,7 +146,6 @@ void vbo_exec_init( GLcontext *ctx ); void vbo_exec_destroy( GLcontext *ctx ); void vbo_exec_invalidate_state( GLcontext *ctx, GLuint new_state ); void vbo_exec_FlushVertices( GLcontext *ctx, GLuint flags ); -void vbo_exec_wakeup( GLcontext *ctx ); /* Internal functions: diff --git a/src/mesa/vbo/vbo_save.c b/src/mesa/vbo/vbo_save.c index 0a5b705400..3a97ea66a4 100644 --- a/src/mesa/vbo/vbo_save.c +++ b/src/mesa/vbo/vbo_save.c @@ -35,6 +35,18 @@ +static void vbo_save_callback_init( GLcontext *ctx ) +{ + ctx->Driver.NewList = vbo_save_NewList; + ctx->Driver.EndList = vbo_save_EndList; + ctx->Driver.SaveFlushVertices = vbo_save_SaveFlushVertices; + ctx->Driver.BeginCallList = vbo_save_BeginCallList; + ctx->Driver.EndCallList = vbo_save_EndCallList; + ctx->Driver.NotifySaveBegin = vbo_save_NotifyBegin; +} + + + void vbo_save_init( GLcontext *ctx ) { struct vbo_save_context *save = &vbo_context(ctx)->save; @@ -42,7 +54,7 @@ void vbo_save_init( GLcontext *ctx ) save->ctx = ctx; vbo_save_api_init( save ); - vbo_save_wakeup(ctx); + vbo_save_callback_init(ctx); ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN; } @@ -68,27 +80,3 @@ void vbo_save_fallback( GLcontext *ctx, GLboolean fallback ) } -/* I don't see any reason to swap this code out on fallbacks. It - * wouldn't really mean anything to do so anyway as the old lists are - * still around from pre-fallback. Instead, the above code ensures - * that vertices are routed back through immediate mode dispatch on - * fallback. - * - * The below can be moved into init or removed: - */ -void vbo_save_wakeup( GLcontext *ctx ) -{ - ctx->Driver.NewList = vbo_save_NewList; - ctx->Driver.EndList = vbo_save_EndList; - ctx->Driver.SaveFlushVertices = vbo_save_SaveFlushVertices; - ctx->Driver.BeginCallList = vbo_save_BeginCallList; - ctx->Driver.EndCallList = vbo_save_EndCallList; - ctx->Driver.NotifySaveBegin = vbo_save_NotifyBegin; - - /* Assume we haven't been getting state updates either: - */ - vbo_save_invalidate_state( ctx, ~0 ); -} - - - diff --git a/src/mesa/vbo/vbo_save.h b/src/mesa/vbo/vbo_save.h index dbe5cafb99..5a64429411 100644 --- a/src/mesa/vbo/vbo_save.h +++ b/src/mesa/vbo/vbo_save.h @@ -150,8 +150,6 @@ struct vbo_save_context { void vbo_save_init( GLcontext *ctx ); void vbo_save_destroy( GLcontext *ctx ); -void vbo_save_wakeup( GLcontext *ctx ); -void vbo_save_invalidate_state( GLcontext *ctx, GLuint new_state ); void vbo_save_fallback( GLcontext *ctx, GLboolean fallback ); /* save_loopback.c: -- cgit v1.2.3 From fd2756006a0baf63f60548d8f509de5b9a143608 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 30 Oct 2006 20:16:35 +0000 Subject: Move edgeflag into the VERT_ATTRIB_SEVEN slot. This means that our NV_vertex_program implementation has slightly incorrect aliasing behaviour. I think this is reasonable given the simplification and the fact that the mainstream ARB_vp continues to have the correct behaviour. --- src/mesa/main/api_noop.c | 2 +- src/mesa/main/context.c | 4 +-- src/mesa/main/get.c | 6 ++-- src/mesa/main/mtypes.h | 10 +++--- src/mesa/main/state.c | 4 +-- src/mesa/vbo/vbo_context.c | 57 +++++++++++++++++++-------------- src/mesa/vbo/vbo_context.h | 14 ++++++-- src/mesa/vbo/vbo_exec.h | 3 -- src/mesa/vbo/vbo_exec_api.c | 76 ++++++++++++++++++-------------------------- src/mesa/vbo/vbo_exec_draw.c | 2 +- src/mesa/vbo/vbo_save.c | 9 +++++- src/mesa/vbo/vbo_save_draw.c | 22 ++++++------- 12 files changed, 107 insertions(+), 102 deletions(-) (limited to 'src') diff --git a/src/mesa/main/api_noop.c b/src/mesa/main/api_noop.c index 33d44e4329..0c1a35361f 100644 --- a/src/mesa/main/api_noop.c +++ b/src/mesa/main/api_noop.c @@ -45,7 +45,7 @@ static void GLAPIENTRY _mesa_noop_EdgeFlag( GLboolean b ) { GET_CURRENT_CONTEXT(ctx); - ctx->Current.EdgeFlag = b; + ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0] = (GLfloat)b; } static void GLAPIENTRY _mesa_noop_Indexf( GLfloat f ) diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index e0630c33d0..15b69db595 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -967,8 +967,8 @@ _mesa_init_current( GLcontext *ctx ) ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 ); ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 1.0 ); ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_FOG], 0.0, 0.0, 0.0, 0.0 ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX][0] = 1.0; - ctx->Current.EdgeFlag = GL_TRUE; + ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX], 1.0, 0.0, 0.0, 1.0 ); + ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG], 1.0, 0.0, 0.0, 1.0 ); } diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index 61a76d000b..2a24b56974 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -323,7 +323,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) case GL_EDGE_FLAG: { FLUSH_CURRENT(ctx, 0); - params[0] = ctx->Current.EdgeFlag; + params[0] = (ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0] == 1.0F); } break; case GL_FEEDBACK_BUFFER_SIZE: @@ -2147,7 +2147,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) case GL_EDGE_FLAG: { FLUSH_CURRENT(ctx, 0); - params[0] = BOOLEAN_TO_FLOAT(ctx->Current.EdgeFlag); + params[0] = BOOLEAN_TO_FLOAT(ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0] == 1.0F); } break; case GL_FEEDBACK_BUFFER_SIZE: @@ -3971,7 +3971,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) case GL_EDGE_FLAG: { FLUSH_CURRENT(ctx, 0); - params[0] = BOOLEAN_TO_INT(ctx->Current.EdgeFlag); + params[0] = BOOLEAN_TO_INT(ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0] == 1.0F); } break; case GL_FEEDBACK_BUFFER_SIZE: diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 903779edae..bc7c6b8026 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -143,7 +143,7 @@ enum VERT_ATTRIB_COLOR1 = 4, VERT_ATTRIB_FOG = 5, VERT_ATTRIB_COLOR_INDEX = 6, - VERT_ATTRIB_SEVEN = 7, + VERT_ATTRIB_EDGEFLAG = 7, VERT_ATTRIB_TEX0 = 8, VERT_ATTRIB_TEX1 = 9, VERT_ATTRIB_TEX2 = 10, @@ -183,7 +183,7 @@ enum #define VERT_BIT_COLOR1 (1 << VERT_ATTRIB_COLOR1) #define VERT_BIT_FOG (1 << VERT_ATTRIB_FOG) #define VERT_BIT_COLOR_INDEX (1 << VERT_ATTRIB_COLOR_INDEX) -#define VERT_BIT_SEVEN (1 << VERT_ATTRIB_SEVEN) +#define VERT_BIT_EDGEFLAG (1 << VERT_ATTRIB_EDGEFLAG) #define VERT_BIT_TEX0 (1 << VERT_ATTRIB_TEX0) #define VERT_BIT_TEX1 (1 << VERT_ATTRIB_TEX1) #define VERT_BIT_TEX2 (1 << VERT_ATTRIB_TEX2) @@ -616,11 +616,11 @@ struct gl_current_attrib /** * \name Current vertex attributes. * \note Values are valid only after FLUSH_VERTICES has been called. + * \note Index and Edgeflag current values are stored as floats in the + * SIX and SEVEN attribute slots. */ /*@{*/ GLfloat Attrib[VERT_ATTRIB_MAX][4]; /**< Position, color, texcoords, etc */ - GLfloat Index; /**< Current color index */ - GLboolean EdgeFlag; /**< Current edge flag */ /*@}*/ /** @@ -2604,7 +2604,7 @@ struct matrix_stack #define _NEW_ARRAY_COLOR1 VERT_BIT_COLOR1 #define _NEW_ARRAY_FOGCOORD VERT_BIT_FOG #define _NEW_ARRAY_INDEX VERT_BIT_COLOR_INDEX -#define _NEW_ARRAY_EDGEFLAG VERT_BIT_SEVEN +#define _NEW_ARRAY_EDGEFLAG VERT_BIT_EDGEFLAG #define _NEW_ARRAY_TEXCOORD_0 VERT_BIT_TEX0 #define _NEW_ARRAY_TEXCOORD_1 VERT_BIT_TEX1 #define _NEW_ARRAY_TEXCOORD_2 VERT_BIT_TEX2 diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index 7dbcf8ad97..d57217d9c4 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -887,8 +887,8 @@ update_arrays( GLcontext *ctx ) /* 7 */ if (ctx->VertexProgram._Enabled - && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_SEVEN].Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_SEVEN]._MaxElement); + && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled) { + min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG]._MaxElement); } /* 8..15 */ diff --git a/src/mesa/vbo/vbo_context.c b/src/mesa/vbo/vbo_context.c index 291eb0bed3..165e32da8a 100644 --- a/src/mesa/vbo/vbo_context.c +++ b/src/mesa/vbo/vbo_context.c @@ -61,27 +61,14 @@ static void init_legacy_currval(GLcontext *ctx) for (i = 0; i < NR_LEGACY_ATTRIBS; i++) { struct gl_client_array *cl = &arrays[i]; - switch (i) { - case VBO_ATTRIB_EDGEFLAG: - cl->Type = GL_UNSIGNED_BYTE; - cl->Ptr = (const void *)&ctx->Current.EdgeFlag; - break; - case VBO_ATTRIB_INDEX: - cl->Type = GL_FLOAT; - cl->Ptr = (const void *)&ctx->Current.Index; - break; - default: - cl->Type = GL_FLOAT; - cl->Ptr = (const void *)ctx->Current.Attrib[i]; - break; - } - - /* This will have to be determined at runtime: + /* Size will have to be determined at runtime: */ cl->Size = 1; cl->Stride = 0; cl->StrideB = 0; cl->Enabled = 1; + cl->Type = GL_FLOAT; + cl->Ptr = (const void *)ctx->Current.Attrib[i]; cl->BufferObj = ctx->Array.NullBufferObj; } } @@ -118,12 +105,12 @@ static void init_mat_currval(GLcontext *ctx) struct gl_client_array *arrays = vbo->mat_currval; GLuint i; - memset(arrays, 0, sizeof(*arrays) * NR_GENERIC_ATTRIBS); + memset(arrays, 0, sizeof(*arrays) * NR_MAT_ATTRIBS); /* Set up a constant (StrideB == 0) array for each current * attribute: */ - for (i = 0; i < NR_GENERIC_ATTRIBS; i++) { + for (i = 0; i < NR_MAT_ATTRIBS; i++) { struct gl_client_array *cl = &arrays[i]; /* Size is fixed for the material attributes, for others will @@ -156,7 +143,23 @@ static void init_mat_currval(GLcontext *ctx) } } +#if 0 +static void vbo_exec_current_init( struct vbo_exec_context *exec ) +{ + GLcontext *ctx = exec->ctx; + GLint i; + + /* setup the pointers for the typical 16 vertex attributes */ + for (i = 0; i < VBO_ATTRIB_FIRST_MATERIAL; i++) + exec->vtx.current[i] = ctx->Current.Attrib[i]; + + /* setup pointers for the 12 material attributes */ + for (i = 0; i < MAT_ATTRIB_MAX; i++) + exec->vtx.current[VBO_ATTRIB_FIRST_MATERIAL + i] = + ctx->Light.Material.Attrib[i]; +} +#endif GLboolean _vbo_CreateContext( GLcontext *ctx ) { @@ -171,13 +174,11 @@ GLboolean _vbo_CreateContext( GLcontext *ctx ) return GL_FALSE; } - /* Hook our functions into exec and compile dispatch tables. These - * will pretty much be permanently installed, which means that the - * vtxfmt mechanism can be removed now. + /* TODO: remove these pointers. */ - vbo_exec_init( ctx ); - vbo_save_init( ctx ); - + vbo->legacy_currval = &vbo->currval[VBO_ATTRIB_POS]; + vbo->generic_currval = &vbo->currval[VBO_ATTRIB_GENERIC0]; + vbo->mat_currval = &vbo->currval[VBO_ATTRIB_MAT_FRONT_AMBIENT]; init_legacy_currval( ctx ); init_generic_currval( ctx ); @@ -207,6 +208,14 @@ GLboolean _vbo_CreateContext( GLcontext *ctx ) /* By default: */ vbo->draw_prims = _tnl_draw_prims; + + /* Hook our functions into exec and compile dispatch tables. These + * will pretty much be permanently installed, which means that the + * vtxfmt mechanism can be removed now. + */ + vbo_exec_init( ctx ); + vbo_save_init( ctx ); + return GL_TRUE; } diff --git a/src/mesa/vbo/vbo_context.h b/src/mesa/vbo/vbo_context.h index 982da00437..cd02472023 100644 --- a/src/mesa/vbo/vbo_context.h +++ b/src/mesa/vbo/vbo_context.h @@ -57,13 +57,21 @@ struct vbo_context { - struct gl_client_array legacy_currval[16]; - struct gl_client_array generic_currval[16]; - struct gl_client_array mat_currval[16]; + struct gl_client_array currval[VBO_ATTRIB_MAX]; + + /* These point into the above. TODO: remove. + */ + struct gl_client_array *legacy_currval; + struct gl_client_array *generic_currval; + struct gl_client_array *mat_currval; GLuint map_vp_none[32]; GLuint map_vp_arb[32]; + GLfloat *current[VBO_ATTRIB_MAX]; /* points into ctx->Current, ctx->Light.Material */ + GLfloat CurrentFloatEdgeFlag; + + struct vbo_exec_context exec; struct vbo_save_context save; diff --git a/src/mesa/vbo/vbo_exec.h b/src/mesa/vbo/vbo_exec.h index ef158de825..e1fc7b2794 100644 --- a/src/mesa/vbo/vbo_exec.h +++ b/src/mesa/vbo/vbo_exec.h @@ -87,9 +87,6 @@ struct vbo_exec_context GLfloat *vbptr; /* cursor, points into buffer */ GLfloat vertex[VBO_ATTRIB_MAX*4]; /* current vertex */ - GLfloat *current[VBO_ATTRIB_MAX]; /* points into ctx->Current, ctx->Light.Material */ - GLfloat CurrentFloatEdgeFlag; - GLuint vert_count; GLuint max_vert; struct vbo_exec_copied_vtx copied; diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c index c764c4d8b6..71fee8ca16 100644 --- a/src/mesa/vbo/vbo_exec_api.c +++ b/src/mesa/vbo/vbo_exec_api.c @@ -130,17 +130,28 @@ void vbo_exec_vtx_wrap( struct vbo_exec_context *exec ) static void vbo_exec_copy_to_current( struct vbo_exec_context *exec ) { GLcontext *ctx = exec->ctx; + struct vbo_context *vbo = vbo_context(ctx); GLuint i; for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) { if (exec->vtx.attrsz[i]) { + GLfloat *current = (GLfloat *)vbo->currval[i].Ptr; + /* Note: the exec->vtx.current[i] pointers point into the * ctx->Current.Attrib and ctx->Light.Material.Attrib arrays. */ - COPY_CLEAN_4V(exec->vtx.current[i], + COPY_CLEAN_4V(current, exec->vtx.attrsz[i], exec->vtx.attrptr[i]); + + /* Given that we explicitly state size here, there is no need + * for the COPY_CLEAN above, could just copy 16 bytes and be + * done. The only problem is when Mesa accesses ctx->Current + * directly. + */ + vbo->currval[i].Size = exec->vtx.attrsz[i]; + /* This triggers rather too much recalculation of Mesa state * that doesn't get used (eg light positions). */ @@ -150,19 +161,6 @@ static void vbo_exec_copy_to_current( struct vbo_exec_context *exec ) } } - /* color index is special (it's not a float[4] so COPY_CLEAN_4V above - * will trash adjacent memory!) - */ - if (exec->vtx.attrsz[VBO_ATTRIB_INDEX]) { - ctx->Current.Index = exec->vtx.attrptr[VBO_ATTRIB_INDEX][0]; - } - - /* Edgeflag requires additional treatment: - */ - if (exec->vtx.attrsz[VBO_ATTRIB_EDGEFLAG]) { - ctx->Current.EdgeFlag = (exec->vtx.CurrentFloatEdgeFlag == 1.0); - } - /* Colormaterial -- this kindof sucks. */ if (ctx->Light.ColorMaterialEnabled && @@ -178,21 +176,19 @@ static void vbo_exec_copy_to_current( struct vbo_exec_context *exec ) static void vbo_exec_copy_from_current( struct vbo_exec_context *exec ) { GLcontext *ctx = exec->ctx; + struct vbo_context *vbo = vbo_context(ctx); GLint i; - /* Edgeflag requires additional treatment: - */ - exec->vtx.CurrentFloatEdgeFlag = - (GLfloat)ctx->Current.EdgeFlag; - - for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) + for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) { + const GLfloat *current = (GLfloat *)vbo->currval[i].Ptr; switch (exec->vtx.attrsz[i]) { - case 4: exec->vtx.attrptr[i][3] = exec->vtx.current[i][3]; - case 3: exec->vtx.attrptr[i][2] = exec->vtx.current[i][2]; - case 2: exec->vtx.attrptr[i][1] = exec->vtx.current[i][1]; - case 1: exec->vtx.attrptr[i][0] = exec->vtx.current[i][0]; + case 4: exec->vtx.attrptr[i][3] = current[3]; + case 3: exec->vtx.attrptr[i][2] = current[2]; + case 2: exec->vtx.attrptr[i][1] = current[1]; + case 1: exec->vtx.attrptr[i][0] = current[0]; break; } + } ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; } @@ -205,6 +201,7 @@ static void vbo_exec_wrap_upgrade_vertex( struct vbo_exec_context *exec, GLuint newsz ) { GLcontext *ctx = exec->ctx; + struct vbo_context *vbo = vbo_context(ctx); GLint lastcount = exec->vtx.vert_count; GLfloat *tmp; GLuint oldsz; @@ -281,7 +278,8 @@ static void vbo_exec_wrap_upgrade_vertex( struct vbo_exec_context *exec, data += oldsz; dest += newsz; } else { - COPY_SZ_4V( dest, newsz, exec->vtx.current[j] ); + const GLfloat *current = (const GLfloat *)vbo->currval[j].Ptr; + COPY_SZ_4V( dest, newsz, current ); dest += newsz; } } @@ -627,27 +625,10 @@ static void vbo_exec_vtxfmt_init( struct vbo_exec_context *exec ) } -static void vbo_exec_current_init( struct vbo_exec_context *exec ) -{ - GLcontext *ctx = exec->ctx; - GLint i; - - /* setup the pointers for the typical 16 vertex attributes */ - for (i = 0; i < VBO_ATTRIB_FIRST_MATERIAL; i++) - exec->vtx.current[i] = ctx->Current.Attrib[i]; - - /* setup pointers for the 12 material attributes */ - for (i = 0; i < MAT_ATTRIB_MAX; i++) - exec->vtx.current[VBO_ATTRIB_FIRST_MATERIAL + i] = - ctx->Light.Material.Attrib[i]; - - exec->vtx.current[VBO_ATTRIB_INDEX] = &ctx->Current.Index; - exec->vtx.current[VBO_ATTRIB_EDGEFLAG] = &exec->vtx.CurrentFloatEdgeFlag; -} - void vbo_exec_vtx_init( struct vbo_exec_context *exec ) { GLcontext *ctx = exec->ctx; + struct vbo_context *vbo = vbo_context(ctx); GLuint i; /* Allocate a buffer object. Will just reuse this object @@ -656,7 +637,6 @@ void vbo_exec_vtx_init( struct vbo_exec_context *exec ) exec->vtx.bufferobj = ctx->Array.NullBufferObj; exec->vtx.buffer_map = ALIGN_MALLOC(VBO_VERT_BUFFER_SIZE * sizeof(GLfloat), 64); - vbo_exec_current_init( exec ); vbo_exec_vtxfmt_init( exec ); /* Hook our functions into the dispatch table. @@ -668,7 +648,13 @@ void vbo_exec_vtx_init( struct vbo_exec_context *exec ) exec->vtx.active_sz[i] = 0; exec->vtx.inputs[i] = &exec->vtx.arrays[i]; } - + + { + struct gl_client_array *arrays = exec->vtx.arrays; + memcpy(arrays, vbo->legacy_currval, 16 * sizeof(arrays[0])); + memcpy(arrays + 16, vbo->generic_currval, 16 * sizeof(arrays[0])); + } + exec->vtx.vertex_size = 0; } diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c index c1898aea49..846d5dc196 100644 --- a/src/mesa/vbo/vbo_exec_draw.c +++ b/src/mesa/vbo/vbo_exec_draw.c @@ -151,7 +151,7 @@ static void vbo_exec_bind_arrays( GLcontext *ctx ) switch (get_program_mode(exec->ctx)) { case VP_NONE: memcpy(arrays, vbo->legacy_currval, 16 * sizeof(arrays[0])); - memcpy(arrays + 16, vbo->mat_currval, 16 * sizeof(arrays[0])); + memcpy(arrays + 16, vbo->mat_currval, MAT_ATTRIB_MAX * sizeof(arrays[0])); map = vbo->map_vp_none; break; case VP_NV: diff --git a/src/mesa/vbo/vbo_save.c b/src/mesa/vbo/vbo_save.c index 3a97ea66a4..e7f4687963 100644 --- a/src/mesa/vbo/vbo_save.c +++ b/src/mesa/vbo/vbo_save.c @@ -49,13 +49,20 @@ static void vbo_save_callback_init( GLcontext *ctx ) void vbo_save_init( GLcontext *ctx ) { - struct vbo_save_context *save = &vbo_context(ctx)->save; + struct vbo_context *vbo = vbo_context(ctx); + struct vbo_save_context *save = &vbo->save; save->ctx = ctx; vbo_save_api_init( save ); vbo_save_callback_init(ctx); + { + struct gl_client_array *arrays = save->arrays; + memcpy(arrays, vbo->legacy_currval, 16 * sizeof(arrays[0])); + memcpy(arrays + 16, vbo->generic_currval, 16 * sizeof(arrays[0])); + } + ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN; } diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c index 18c770a41c..527e57d6bd 100644 --- a/src/mesa/vbo/vbo_save_draw.c +++ b/src/mesa/vbo/vbo_save_draw.c @@ -41,7 +41,7 @@ static void _playback_copy_to_current( GLcontext *ctx, const struct vbo_save_vertex_list *node ) { - struct vbo_save_context *save = &vbo_context(ctx)->save; + struct vbo_context *vbo = vbo_context(ctx); GLfloat vertex[VBO_ATTRIB_MAX * 4], *data = vertex; GLuint i, offset; @@ -55,7 +55,14 @@ static void _playback_copy_to_current( GLcontext *ctx, for (i = VBO_ATTRIB_POS+1 ; i <= VBO_ATTRIB_INDEX ; i++) { if (node->attrsz[i]) { - COPY_CLEAN_4V(save->current[i], node->attrsz[i], data); + GLfloat *current = (GLfloat *)vbo->currval[i].Ptr; + + COPY_CLEAN_4V(current, + node->attrsz[i], + data); + + vbo->currval[i].Size = node->attrsz[i]; + data += node->attrsz[i]; if (i >= VBO_ATTRIB_MAT_FRONT_AMBIENT && @@ -64,20 +71,11 @@ static void _playback_copy_to_current( GLcontext *ctx, } } - /* Edgeflag requires special treatment: - */ - if (node->attrsz[VBO_ATTRIB_EDGEFLAG]) { - ctx->Current.EdgeFlag = (data[0] == 1.0); - } - - -#if 1 /* Colormaterial -- this kindof sucks. */ if (ctx->Light.ColorMaterialEnabled) { _mesa_update_color_material(ctx, ctx->Current.Attrib[VBO_ATTRIB_COLOR0]); } -#endif /* CurrentExecPrimitive */ @@ -111,7 +109,7 @@ static void vbo_bind_vertex_list( GLcontext *ctx, switch (get_program_mode(ctx)) { case VP_NONE: memcpy(arrays, vbo->legacy_currval, 16 * sizeof(arrays[0])); - memcpy(arrays + 16, vbo->mat_currval, 16 * sizeof(arrays[0])); + memcpy(arrays + 16, vbo->mat_currval, MAT_ATTRIB_MAX * sizeof(arrays[0])); map = vbo->map_vp_none; break; case VP_NV: -- cgit v1.2.3 From a1a8a2c024efdc1df31a4f9f180341f0a77597c3 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 30 Oct 2006 20:29:13 +0000 Subject: oops, get.c is autogenerated --- src/mesa/main/get.c | 6 +++--- src/mesa/main/get_gen.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index 2a24b56974..3dd1aa1873 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -323,7 +323,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) case GL_EDGE_FLAG: { FLUSH_CURRENT(ctx, 0); - params[0] = (ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0] == 1.0F); + params[0] = (ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0] == 1.0); } break; case GL_FEEDBACK_BUFFER_SIZE: @@ -2147,7 +2147,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) case GL_EDGE_FLAG: { FLUSH_CURRENT(ctx, 0); - params[0] = BOOLEAN_TO_FLOAT(ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0] == 1.0F); + params[0] = BOOLEAN_TO_FLOAT((ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0] == 1.0)); } break; case GL_FEEDBACK_BUFFER_SIZE: @@ -3971,7 +3971,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) case GL_EDGE_FLAG: { FLUSH_CURRENT(ctx, 0); - params[0] = BOOLEAN_TO_INT(ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0] == 1.0F); + params[0] = BOOLEAN_TO_INT((ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0] == 1.0)); } break; case GL_FEEDBACK_BUFFER_SIZE: diff --git a/src/mesa/main/get_gen.py b/src/mesa/main/get_gen.py index a9e04863a7..ec8a192b31 100644 --- a/src/mesa/main/get_gen.py +++ b/src/mesa/main/get_gen.py @@ -190,7 +190,7 @@ StateVars = [ ( "GL_DOUBLEBUFFER", GLboolean, ["ctx->DrawBuffer->Visual.doubleBufferMode"], "", None ), ( "GL_DRAW_BUFFER", GLenum, ["ctx->DrawBuffer->ColorDrawBuffer[0]"], "", None ), - ( "GL_EDGE_FLAG", GLboolean, ["ctx->Current.EdgeFlag"], + ( "GL_EDGE_FLAG", GLboolean, ["(ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0] == 1.0)"], "FLUSH_CURRENT(ctx, 0);", None ), ( "GL_FEEDBACK_BUFFER_SIZE", GLint, ["ctx->Feedback.BufferSize"], "", None ), ( "GL_FEEDBACK_BUFFER_TYPE", GLenum, ["ctx->Feedback.Type"], "", None ), -- cgit v1.2.3 From f2eb6434ab1cf72e938956c82d2f530368a6be4a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 31 Oct 2006 11:28:45 +0000 Subject: cleanup code, compiles with vbo changes --- src/mesa/drivers/dri/i965/Makefile | 1 - src/mesa/drivers/dri/i965/brw_clip.h | 2 +- src/mesa/drivers/dri/i965/brw_context.c | 2 - src/mesa/drivers/dri/i965/brw_context.h | 22 +- src/mesa/drivers/dri/i965/brw_draw.c | 72 ++---- src/mesa/drivers/dri/i965/brw_draw.h | 16 +- src/mesa/drivers/dri/i965/brw_draw_current.c | 103 -------- src/mesa/drivers/dri/i965/brw_draw_upload.c | 11 +- src/mesa/drivers/dri/i965/brw_fallback.c | 346 --------------------------- src/mesa/drivers/dri/i965/brw_metaops.c | 69 +++--- src/mesa/drivers/dri/i965/brw_vs.c | 5 +- src/mesa/drivers/dri/i965/brw_vs_constval.c | 7 +- src/mesa/drivers/dri/i965/brw_vs_emit.c | 4 +- src/mesa/drivers/dri/i965/brw_vs_tnl.c | 40 ++-- src/mesa/drivers/dri/i965/brw_vtbl.c | 10 +- 15 files changed, 98 insertions(+), 612 deletions(-) delete mode 100644 src/mesa/drivers/dri/i965/brw_draw_current.c (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile index 8ec422509f..02fb93486e 100644 --- a/src/mesa/drivers/dri/i965/Makefile +++ b/src/mesa/drivers/dri/i965/Makefile @@ -34,7 +34,6 @@ DRIVER_SOURCES = \ brw_context.c \ brw_curbe.c \ brw_draw.c \ - brw_draw_current.c \ brw_draw_upload.c \ brw_eu.c \ brw_eu_debug.c \ diff --git a/src/mesa/drivers/dri/i965/brw_clip.h b/src/mesa/drivers/dri/i965/brw_clip.h index c3967c8c61..49b2770a51 100644 --- a/src/mesa/drivers/dri/i965/brw_clip.h +++ b/src/mesa/drivers/dri/i965/brw_clip.h @@ -116,7 +116,7 @@ struct brw_clip_compile { GLuint last_mrf; GLuint header_position_offset; - GLuint offset[BRW_ATTRIB_MAX]; + GLuint offset[VERT_ATTRIB_MAX]; }; #define ATTR_SIZE (4*4) diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c index b9256d5185..263110bf5e 100644 --- a/src/mesa/drivers/dri/i965/brw_context.c +++ b/src/mesa/drivers/dri/i965/brw_context.c @@ -34,8 +34,6 @@ #include "brw_aub.h" #include "brw_defines.h" #include "brw_draw.h" -#include "brw_exec.h" -#include "brw_save.h" #include "brw_vs.h" #include "imports.h" #include "intel_tex.h" diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index e2279ca276..0a61926ee8 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -214,7 +214,7 @@ struct brw_vs_prog_data { GLuint total_grf; GLuint outputs_written; - GLuint64EXT inputs_read; + GLuint inputs_read; /* Used for calculating urb partitions: */ @@ -381,10 +381,10 @@ struct brw_cached_batch_item { -/* Protect against a future where BRW_ATTRIB_MAX > 32. Wouldn't life +/* Protect against a future where VERT_ATTRIB_MAX > 32. Wouldn't life * be easier if C allowed arrays of packed elements? */ -#define ATTRIB_BIT_DWORDS ((BRW_ATTRIB_MAX+31)/32) +#define ATTRIB_BIT_DWORDS ((VERT_ATTRIB_MAX+31)/32) struct brw_vertex_element { const struct gl_client_array *glarray; @@ -400,8 +400,8 @@ struct brw_vertex_element { struct brw_vertex_info { - GLuint64EXT varying; /* varying:1[BRW_ATTRIB_MAX] */ - GLuint sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[BRW_ATTRIB_MAX] */ + GLuint varying; /* varying:1[VERT_ATTRIB_MAX] */ + GLuint sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[VERT_ATTRIB_MAX] */ }; @@ -448,14 +448,13 @@ struct brw_context struct brw_cached_batch_item *cached_batch_items; struct { - /* Fallback values for inputs not supplied: - */ - struct gl_client_array current_values[BRW_ATTRIB_MAX]; /* Arrays with buffer objects to copy non-bufferobj arrays into * for upload: */ - struct gl_client_array vbo_array[BRW_ATTRIB_MAX]; + struct gl_client_array vbo_array[VERT_ATTRIB_MAX]; + + struct brw_vertex_element inputs[VERT_ATTRIB_MAX]; #define BRW_NR_UPLOAD_BUFS 17 #define BRW_UPLOAD_INIT_SIZE (128*1024) @@ -468,11 +467,6 @@ struct brw_context GLuint wrap; } upload; - /* Currenly bound arrays, including fallbacks to current_values - * above: - */ - struct brw_vertex_element inputs[BRW_ATTRIB_MAX]; - /* Summary of size and varying of active arrays, so we can check * for changes to this state: */ diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index 1bc39762bc..63cb079ec9 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -35,7 +35,6 @@ #include "brw_draw.h" #include "brw_defines.h" -#include "brw_attrib.h" #include "brw_context.h" #include "brw_aub.h" #include "brw_state.h" @@ -45,7 +44,8 @@ #include "intel_batchbuffer.h" #include "intel_buffer_objects.h" - +#include "tnl/tnl.h" +#include "vbo/vbo_context.h" @@ -143,7 +143,7 @@ static void brw_emit_cliprect( struct brw_context *brw, static void brw_emit_prim( struct brw_context *brw, - const struct vbo_prim *prim ) + const struct _mesa_prim *prim ) { struct brw_3d_primitive prim_packet; @@ -170,34 +170,9 @@ static void brw_emit_prim( struct brw_context *brw, } } - - -static void update_current_size( struct gl_client_array *array) -{ - const GLfloat *ptr = (const GLfloat *)array->Ptr; - - assert(array->StrideB == 0); - assert(array->Type == GL_FLOAT || array->Type == GL_UNSIGNED_BYTE); - - if (ptr[3] != 1.0) - array->Size = 4; - else if (ptr[2] != 0.0) - array->Size = 3; - else if (ptr[1] != 0.0) - array->Size = 2; - else - array->Size = 1; -} - - - -/* Fill in any gaps in passed arrays with pointers to current - * attributes: - */ static void brw_merge_inputs( struct brw_context *brw, const struct gl_client_array *arrays[]) { - struct gl_client_array *current_values = brw->vb.current_values; struct brw_vertex_element *inputs = brw->vb.inputs; struct brw_vertex_info old = brw->vb.info; GLuint i; @@ -205,17 +180,11 @@ static void brw_merge_inputs( struct brw_context *brw, memset(inputs, 0, sizeof(*inputs)); memset(&brw->vb.info, 0, sizeof(brw->vb.info)); - for (i = 0; i < BRW_ATTRIB_MAX; i++) { - if (arrays[i] && arrays[i]->Enabled) - { - brw->vb.inputs[i].glarray = arrays[i]; + for (i = 0; i < VERT_ATTRIB_MAX; i++) { + brw->vb.inputs[i].glarray = arrays[i]; + + if (arrays[i]->StrideB != 0) brw->vb.info.varying |= 1 << i; - } - else - { - brw->vb.inputs[i].glarray = ¤t_values[i]; - update_current_size(¤t_values[i]); - } brw->vb.info.sizes[i/16] |= (inputs[i].glarray->Size - 1) << ((i%16) * 2); } @@ -229,8 +198,9 @@ static void brw_merge_inputs( struct brw_context *brw, brw->state.dirty.brw |= BRW_NEW_INPUT_VARYING; } + static GLboolean check_fallbacks( struct brw_context *brw, - const struct vbo_prim *prim, + const struct _mesa_prim *prim, GLuint nr_prims ) { GLuint i; @@ -284,7 +254,7 @@ static GLboolean check_fallbacks( struct brw_context *brw, static GLboolean brw_try_draw_prims( GLcontext *ctx, const struct gl_client_array *arrays[], - const struct vbo_prim *prim, + const struct _mesa_prim *prim, GLuint nr_prims, const struct _mesa_index_buffer *ib, GLuint min_index, @@ -297,11 +267,11 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, if (ctx->NewState) _mesa_update_state( ctx ); - + /* Bind all inputs, derive varying and size information: */ brw_merge_inputs( brw, arrays ); - + /* Have to validate state quite late. Will rebuild tnl_program, * which depends on varying information. * @@ -318,10 +288,6 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, } { - assert(intel->locked); - - - /* Set the first primitive early, ahead of validate_state: */ brw_set_prim(brw, prim[0].mode); @@ -413,7 +379,7 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, void brw_draw_prims( GLcontext *ctx, const struct gl_client_array *arrays[], - const struct vbo_prim *prim, + const struct _mesa_prim *prim, GLuint nr_prims, const struct _mesa_index_buffer *ib, GLuint min_index, @@ -430,7 +396,7 @@ void brw_draw_prims( GLcontext *ctx, * fragmented. Clear out all heaps and start from scratch by * faking a contended lock event: (done elsewhere) */ - if (!retval && bmError(intel)) { + if (!retval && !intel->Fallback && bmError(intel)) { DBG("retrying\n"); /* Then try a second time only to upload textures and draw the * primitives: @@ -443,9 +409,7 @@ void brw_draw_prims( GLcontext *ctx, * swrast to do the drawing. */ if (!retval) { - brw_fallback(); _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index); - brw_unfallback(); } if (intel->aub_file && (INTEL_DEBUG & DEBUG_SYNC)) { @@ -464,8 +428,13 @@ static void brw_invalidate_vbo_cb( struct intel_context *intel, void *ptr ) void brw_draw_init( struct brw_context *brw ) { GLcontext *ctx = &brw->intel.ctx; + struct vbo_context *vbo = vbo_context(ctx); GLuint i; + /* Register our drawing function: + */ + vbo->draw_prims = brw_draw_prims; + brw->vb.upload.size = BRW_UPLOAD_INIT_SIZE; for (i = 0; i < BRW_NR_UPLOAD_BUFS; i++) { @@ -487,9 +456,6 @@ void brw_draw_init( struct brw_context *brw ) NULL, GL_DYNAMIC_DRAW_ARB, brw->vb.upload.vbo[0] ); - - - brw_init_current_values(ctx, brw->vb.current_values); } void brw_draw_destroy( struct brw_context *brw ) diff --git a/src/mesa/drivers/dri/i965/brw_draw.h b/src/mesa/drivers/dri/i965/brw_draw.h index b68cd86115..0f7b738310 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.h +++ b/src/mesa/drivers/dri/i965/brw_draw.h @@ -29,18 +29,18 @@ #define BRW_DRAW_H #include "mtypes.h" /* for GLcontext... */ -#include "brw_attrib.h" +#include "vbo/vbo.h" struct brw_context; -GLboolean brw_draw_prims( GLcontext *ctx, - const struct gl_client_array *arrays[], - const struct vbo_prim *prims, - GLuint nr_prims, - const struct _mesa_index_buffer *ib, - GLuint min_index, - GLuint max_index ); +void brw_draw_prims( GLcontext *ctx, + const struct gl_client_array *arrays[], + const struct _mesa_prim *prims, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLuint min_index, + GLuint max_index ); void brw_draw_init( struct brw_context *brw ); void brw_draw_destroy( struct brw_context *brw ); diff --git a/src/mesa/drivers/dri/i965/brw_draw_current.c b/src/mesa/drivers/dri/i965/brw_draw_current.c deleted file mode 100644 index 98d930738e..0000000000 --- a/src/mesa/drivers/dri/i965/brw_draw_current.c +++ /dev/null @@ -1,103 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 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 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 ITS 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. - * - **************************************************************************/ - -#include - -#include "glheader.h" -#include "context.h" -#include "state.h" -#include "api_validate.h" -#include "enums.h" - -#include "brw_context.h" -#include "brw_draw.h" - -#include "bufmgr.h" -#include "intel_buffer_objects.h" - - -void brw_init_current_values(GLcontext *ctx, - struct gl_client_array *arrays) -{ - GLuint i; - - memset(arrays, 0, sizeof(*arrays) * BRW_ATTRIB_MAX); - - /* Set up a constant (StrideB == 0) array for each current - * attribute: - */ - for (i = 0; i < BRW_ATTRIB_MAX; i++) { - struct gl_client_array *cl = &arrays[i]; - - switch (i) { - case BRW_ATTRIB_MAT_FRONT_SHININESS: - case BRW_ATTRIB_MAT_BACK_SHININESS: - case BRW_ATTRIB_INDEX: - case BRW_ATTRIB_EDGEFLAG: - cl->Size = 1; - break; - case BRW_ATTRIB_MAT_FRONT_INDEXES: - case BRW_ATTRIB_MAT_BACK_INDEXES: - cl->Size = 3; - break; - default: - /* This is fixed for the material attributes, for others will - * be determined at runtime: - */ - if (i >= BRW_ATTRIB_MAT_FRONT_AMBIENT) - cl->Size = 4; - else - cl->Size = 1; - break; - } - - switch (i) { - case BRW_ATTRIB_EDGEFLAG: - cl->Type = GL_UNSIGNED_BYTE; - cl->Ptr = (const void *)&ctx->Current.EdgeFlag; - break; - case BRW_ATTRIB_INDEX: - cl->Type = GL_FLOAT; - cl->Ptr = (const void *)&ctx->Current.Index; - break; - default: - cl->Type = GL_FLOAT; - if (i < BRW_ATTRIB_FIRST_MATERIAL) - cl->Ptr = (const void *)ctx->Current.Attrib[i]; - else - cl->Ptr = (const void *)ctx->Light.Material.Attrib[i - BRW_ATTRIB_FIRST_MATERIAL]; - break; - } - - cl->Stride = 0; - cl->StrideB = 0; - cl->Enabled = 1; - cl->Flags = 0; - cl->BufferObj = ctx->Array.NullBufferObj; - } -} - diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 4d930c6c9e..dfb598acdf 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -35,7 +35,6 @@ #include "brw_draw.h" #include "brw_defines.h" -#include "brw_attrib.h" #include "brw_context.h" #include "brw_aub.h" #include "brw_state.h" @@ -337,7 +336,6 @@ copy_array_to_vbo_array( struct brw_context *brw, vbo_array->Enabled = 1; vbo_array->Normalized = array->Normalized; vbo_array->_MaxElement = array->_MaxElement; /* ? */ - vbo_array->Flags = array->Flags; /* ? */ vbo_array->BufferObj = vbo; { @@ -380,7 +378,6 @@ interleaved_vbo_array( struct brw_context *brw, vbo_array->Enabled = 1; vbo_array->Normalized = array->Normalized; vbo_array->_MaxElement = array->_MaxElement; - vbo_array->Flags = array->Flags; /* ? */ vbo_array->BufferObj = uploaded_array->BufferObj; return vbo_array; @@ -400,10 +397,10 @@ GLboolean brw_upload_vertices( struct brw_context *brw, const void *ptr = NULL; GLuint interleave = 0; - struct brw_vertex_element *enabled[BRW_ATTRIB_MAX]; + struct brw_vertex_element *enabled[VERT_ATTRIB_MAX]; GLuint nr_enabled = 0; - struct brw_vertex_element *upload[BRW_ATTRIB_MAX]; + struct brw_vertex_element *upload[VERT_ATTRIB_MAX]; GLuint nr_uploads = 0; @@ -568,7 +565,7 @@ static GLuint element_size( GLenum type ) static void rebase_indices_to_vbo_indices( struct brw_context *brw, - const struct vbo_index_buffer *index_buffer, + const struct _mesa_index_buffer *index_buffer, struct gl_buffer_object **vbo_return, GLuint *offset_return ) { @@ -642,7 +639,7 @@ static void rebase_indices_to_vbo_indices( struct brw_context *brw, void brw_upload_indices( struct brw_context *brw, - const struct vbo_index_buffer *index_buffer) + const struct _mesa_index_buffer *index_buffer) { struct intel_context *intel = &brw->intel; GLuint ib_size = get_size(index_buffer->type) * index_buffer->count; diff --git a/src/mesa/drivers/dri/i965/brw_fallback.c b/src/mesa/drivers/dri/i965/brw_fallback.c index aab30b6863..86464b2ec5 100644 --- a/src/mesa/drivers/dri/i965/brw_fallback.c +++ b/src/mesa/drivers/dri/i965/brw_fallback.c @@ -30,8 +30,6 @@ #include "tnl/tnl.h" #include "context.h" #include "brw_context.h" -#include "brw_exec.h" -#include "brw_save.h" #include "brw_fallback.h" #include "glheader.h" @@ -40,294 +38,6 @@ #include "imports.h" #include "macros.h" #include "mtypes.h" -#include "dispatch.h" - - -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 -}; - -#if 0 -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 -}; -#endif - - - - - - -static void mat_attr1fv( GLcontext *ctx, GLint target, const GLfloat *v ) -{ - switch (target) { - case BRW_ATTRIB_MAT_FRONT_SHININESS: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_SHININESS, v )); - break; - case BRW_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 BRW_ATTRIB_MAT_FRONT_INDEXES: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_COLOR_INDEXES, v )); - break; - case BRW_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 BRW_ATTRIB_MAT_FRONT_EMISSION: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_EMISSION, v )); - break; - case BRW_ATTRIB_MAT_BACK_EMISSION: - CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_EMISSION, v )); - break; - case BRW_ATTRIB_MAT_FRONT_AMBIENT: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_AMBIENT, v )); - break; - case BRW_ATTRIB_MAT_BACK_AMBIENT: - CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_AMBIENT, v )); - break; - case BRW_ATTRIB_MAT_FRONT_DIFFUSE: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_DIFFUSE, v )); - break; - case BRW_ATTRIB_MAT_BACK_DIFFUSE: - CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_DIFFUSE, v )); - break; - case BRW_ATTRIB_MAT_FRONT_SPECULAR: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_SPECULAR, v )); - break; - case BRW_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 index_attr1fv(GLcontext *ctx, GLint target, const GLfloat *v) -{ - (void) target; - CALL_Indexf(ctx->Exec, (v[0])); -} - -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 GLfloat *buffer, - const struct vbo_prim *prim, - GLuint wrap_count, - GLuint vertex_size, - const struct loopback_attr *la, GLuint nr ) -{ - GLint start = prim->start; - GLint end = start + prim->count; - const GLfloat *data; - GLint j; - GLuint k; - - if (0) - _mesa_printf("loopback prim %s(%s,%s) verts %d..%d\n", - _mesa_lookup_enum_by_nr(prim->mode), - prim->begin ? "begin" : "..", - prim->end ? "end" : "..", - start, - end); - - if (prim->begin) { - CALL_Begin(GET_DISPATCH(), ( prim->mode )); - } - else { - assert(start == 0); - start += wrap_count; - } - - data = buffer + start * vertex_size; - - for (j = start ; j < end ; j++) { - const 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, BRW_ATTRIB_POS, data ); - data = tmp; - } - - if (prim->end) { - CALL_End(GET_DISPATCH(), ()); - } -} - -/* 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 vbo_prim *prim ) -{ - /* 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->begin) - ctx->Driver.CurrentExecPrimitive |= BRW_SAVE_PRIM_WEAK; - if (prim->end) - ctx->Driver.CurrentExecPrimitive &= ~BRW_SAVE_PRIM_WEAK; -} - - -void brw_loopback_vertex_list( GLcontext *ctx, - const GLfloat *buffer, - const GLubyte *attrsz, - const struct vbo_prim *prim, - GLuint prim_count, - GLuint wrap_count, - GLuint vertex_size) -{ - struct loopback_attr la[BRW_ATTRIB_MAX]; - GLuint i, nr = 0; - - for (i = 0 ; i <= BRW_ATTRIB_TEX7 ; i++) { - if (attrsz[i]) { - la[nr].target = i; - la[nr].sz = attrsz[i]; - la[nr].func = vert_attrfunc[attrsz[i]-1]; - nr++; - } - } - - for (i = BRW_ATTRIB_MAT_FRONT_AMBIENT ; - i <= BRW_ATTRIB_MAT_BACK_INDEXES ; - i++) { - if (attrsz[i]) { - la[nr].target = i; - la[nr].sz = attrsz[i]; - la[nr].func = mat_attrfunc[attrsz[i]-1]; - nr++; - } - } - - if (attrsz[BRW_ATTRIB_EDGEFLAG]) { - la[nr].target = BRW_ATTRIB_EDGEFLAG; - la[nr].sz = attrsz[BRW_ATTRIB_EDGEFLAG]; - la[nr].func = edgeflag_attr1fv; - nr++; - } - - if (attrsz[BRW_ATTRIB_INDEX]) { - la[nr].target = BRW_ATTRIB_INDEX; - la[nr].sz = attrsz[BRW_ATTRIB_INDEX]; - la[nr].func = index_attr1fv; - nr++; - } - - /* XXX ARB vertex attribs */ - - for (i = 0 ; i < prim_count ; i++) { - if ((prim[i].mode & BRW_SAVE_PRIM_WEAK) && - (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END)) - { - loopback_weak_prim( ctx, &prim[i] ); - } - else - { - loopback_prim( ctx, buffer, &prim[i], wrap_count, vertex_size, la, nr ); - } - } -} - @@ -402,62 +112,6 @@ const struct brw_tracked_state brw_check_fallback = { -/* If there is a fallback, fallback to software rasterization and - * transformation together. There is never a requirement to have - * software t&l but hardware rasterization. - * - * Further, all fallbacks are based on GL state, not on eg. primitive - * or vertex data. - */ - -static void do_fallback( struct brw_context *brw, - GLboolean fallback ) -{ - GLcontext *ctx = &brw->intel.ctx; - - /* flush: - */ - ctx->Driver.Flush( ctx ); - - if (fallback) { - _swsetup_Wakeup( ctx ); - _tnl_wakeup_exec( ctx ); - - /* Need this because tnl_wakeup_exec does too much: - */ - brw_save_wakeup(ctx); - brw_save_fallback(ctx, GL_TRUE); - } - else { - /* Flush vertices and copy-to-current: - */ - FLUSH_CURRENT(ctx, 0); - - _swrast_flush( ctx ); - - brw_exec_wakeup(ctx); - - /* Need this because tnl_wakeup_exec does too much: - */ - brw_save_wakeup(ctx); - brw_save_fallback(ctx, GL_FALSE); - } -} - - -void brw_fallback( GLcontext *ctx ) -{ - struct brw_context *brw = brw_context(ctx); - do_fallback(brw, 1); -} - - -void brw_unfallback( GLcontext *ctx ) -{ - struct brw_context *brw = brw_context(ctx); - do_fallback(brw, 0); -} - /* Not used: */ void intelFallback( struct intel_context *intel, GLuint bit, GLboolean mode ) diff --git a/src/mesa/drivers/dri/i965/brw_metaops.c b/src/mesa/drivers/dri/i965/brw_metaops.c index d8b6069cfc..2d4c84f612 100644 --- a/src/mesa/drivers/dri/i965/brw_metaops.c +++ b/src/mesa/drivers/dri/i965/brw_metaops.c @@ -46,7 +46,6 @@ #include "brw_context.h" #include "brw_defines.h" #include "brw_draw.h" -#include "brw_attrib.h" #include "brw_fallback.h" #define INIT(brw, STRUCT, ATTRIB) \ @@ -302,8 +301,8 @@ static void meta_draw_quad(struct intel_context *intel, struct brw_context *brw = brw_context(&intel->ctx); struct gl_client_array pos_array; struct gl_client_array color_array; - struct gl_client_array *attribs[BRW_ATTRIB_MAX]; - struct vbo_prim prim[1]; + struct gl_client_array *attribs[VERT_ATTRIB_MAX]; + struct _mesa_prim prim[1]; GLfloat pos[4][3]; GLubyte color[4]; @@ -353,29 +352,29 @@ static void meta_draw_quad(struct intel_context *intel, /* Ignoring texture coords. */ - memset(attribs, 0, BRW_ATTRIB_MAX * sizeof(*attribs)); - - attribs[BRW_ATTRIB_POS] = &pos_array; - attribs[BRW_ATTRIB_POS]->Ptr = 0; - attribs[BRW_ATTRIB_POS]->Type = GL_FLOAT; - attribs[BRW_ATTRIB_POS]->Enabled = 1; - attribs[BRW_ATTRIB_POS]->Size = 3; - attribs[BRW_ATTRIB_POS]->StrideB = 3 * sizeof(GLfloat); - attribs[BRW_ATTRIB_POS]->Stride = 3 * sizeof(GLfloat); - attribs[BRW_ATTRIB_POS]->_MaxElement = 4; - attribs[BRW_ATTRIB_POS]->Normalized = 0; - attribs[BRW_ATTRIB_POS]->BufferObj = brw->metaops.vbo; - - attribs[BRW_ATTRIB_COLOR0] = &color_array; - attribs[BRW_ATTRIB_COLOR0]->Ptr = (const GLubyte *)sizeof(pos); - attribs[BRW_ATTRIB_COLOR0]->Type = GL_UNSIGNED_BYTE; - attribs[BRW_ATTRIB_COLOR0]->Enabled = 1; - attribs[BRW_ATTRIB_COLOR0]->Size = 4; - attribs[BRW_ATTRIB_COLOR0]->StrideB = 0; - attribs[BRW_ATTRIB_COLOR0]->Stride = 0; - attribs[BRW_ATTRIB_COLOR0]->_MaxElement = 1; - attribs[BRW_ATTRIB_COLOR0]->Normalized = 1; - attribs[BRW_ATTRIB_COLOR0]->BufferObj = brw->metaops.vbo; + memset(attribs, 0, VERT_ATTRIB_MAX * sizeof(*attribs)); + + attribs[VERT_ATTRIB_POS] = &pos_array; + attribs[VERT_ATTRIB_POS]->Ptr = 0; + attribs[VERT_ATTRIB_POS]->Type = GL_FLOAT; + attribs[VERT_ATTRIB_POS]->Enabled = 1; + attribs[VERT_ATTRIB_POS]->Size = 3; + attribs[VERT_ATTRIB_POS]->StrideB = 3 * sizeof(GLfloat); + attribs[VERT_ATTRIB_POS]->Stride = 3 * sizeof(GLfloat); + attribs[VERT_ATTRIB_POS]->_MaxElement = 4; + attribs[VERT_ATTRIB_POS]->Normalized = 0; + attribs[VERT_ATTRIB_POS]->BufferObj = brw->metaops.vbo; + + attribs[VERT_ATTRIB_COLOR0] = &color_array; + attribs[VERT_ATTRIB_COLOR0]->Ptr = (const GLubyte *)sizeof(pos); + attribs[VERT_ATTRIB_COLOR0]->Type = GL_UNSIGNED_BYTE; + attribs[VERT_ATTRIB_COLOR0]->Enabled = 1; + attribs[VERT_ATTRIB_COLOR0]->Size = 4; + attribs[VERT_ATTRIB_COLOR0]->StrideB = 0; + attribs[VERT_ATTRIB_COLOR0]->Stride = 0; + attribs[VERT_ATTRIB_COLOR0]->_MaxElement = 1; + attribs[VERT_ATTRIB_COLOR0]->Normalized = 1; + attribs[VERT_ATTRIB_COLOR0]->BufferObj = brw->metaops.vbo; /* Just ignoring texture coordinates for now. */ @@ -390,18 +389,12 @@ static void meta_draw_quad(struct intel_context *intel, prim[0].start = 0; prim[0].count = 4; - if (!brw_draw_prims(&brw->intel.ctx, - (const struct gl_client_array **)attribs, - prim, 1, - NULL, - 0, - 4 )) - { - /* This should not be possible: - */ - _mesa_printf("brw_draw_prims failed in metaops!\n"); - assert(0); - } + brw_draw_prims(&brw->intel.ctx, + (const struct gl_client_array **)attribs, + prim, 1, + NULL, + 0, + 4 ); } diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c index e5a28b96e3..74c9d88e46 100644 --- a/src/mesa/drivers/dri/i965/brw_vs.c +++ b/src/mesa/drivers/dri/i965/brw_vs.c @@ -54,12 +54,11 @@ static void do_vs_prog( struct brw_context *brw, c.vp = vp; c.prog_data.outputs_written = vp->program.Base.OutputsWritten; - c.prog_data.inputs_read = brw_translate_inputs(brw->intel.ctx.VertexProgram._Enabled, - vp->program.Base.InputsRead); + c.prog_data.inputs_read = vp->program.Base.InputsRead; if (c.key.copy_edgeflag) { c.prog_data.outputs_written |= 1<vb.info.sizes[attr/16]; GLuint sizes_bits = (sizes_dword>>((attr%16)*2)) & 0x3; return sizes_bits + 1; +/* return brw->vb.inputs[attr].glarray->Size; */ } /* Calculate sizes of vertex program outputs. Size is the largest @@ -176,8 +177,6 @@ static void calc_wm_input_sizes( struct brw_context *brw ) struct tracker t; GLuint insn; GLuint i; - GLuint64EXT inputs = brw_translate_inputs(brw->intel.ctx.VertexProgram._Enabled, - vp->program.Base.InputsRead); memset(&t, 0, sizeof(t)); @@ -185,8 +184,8 @@ static void calc_wm_input_sizes( struct brw_context *brw ) if (brw->attribs.Light->Model.TwoSide) t.twoside = 1; - for (i = 0; i < BRW_ATTRIB_MAX; i++) - if (inputs & (1<program.Base.InputsRead & (1<nr_inputs = 0; - for (i = 0; i < BRW_ATTRIB_MAX; i++) { + for (i = 0; i < VERT_ATTRIB_MAX; i++) { if (c->prog_data.inputs_read & (1<nr_inputs++; c->regs[PROGRAM_INPUT][i] = brw_vec8_grf(reg, 0); @@ -791,7 +791,7 @@ static void emit_vertex_write( struct brw_vs_compile *c) if (c->key.copy_edgeflag) { brw_MOV(p, get_reg(c, PROGRAM_OUTPUT, VERT_RESULT_EDGE), - get_reg(c, PROGRAM_INPUT, BRW_ATTRIB_EDGEFLAG)); + get_reg(c, PROGRAM_INPUT, VERT_ATTRIB_EDGEFLAG)); } diff --git a/src/mesa/drivers/dri/i965/brw_vs_tnl.c b/src/mesa/drivers/dri/i965/brw_vs_tnl.c index 1df111f645..dc580998e3 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_tnl.c +++ b/src/mesa/drivers/dri/i965/brw_vs_tnl.c @@ -146,9 +146,13 @@ static void make_state_key( GLcontext *ctx, struct state_key *key ) } /* BRW_NEW_INPUT_VARYING */ - for (i = BRW_ATTRIB_MAT_FRONT_AMBIENT ; i < BRW_ATTRIB_INDEX ; i++) - if (brw->vb.info.varying & (1<light_material_mask |= 1<<(i-BRW_ATTRIB_MAT_FRONT_AMBIENT); + + /* For these programs, material values are stuffed into the + * generic slots: + */ + for (i = 0 ; i < MAT_ATTRIB_MAX ; i++) + if (brw->vb.info.varying & (1<<(VERT_ATTRIB_GENERIC0 + i))) + key->light_material_mask |= 1<attribs.Light->Light[i]; @@ -374,12 +378,6 @@ static void release_temps( struct tnl_program *p ) static struct ureg register_input( struct tnl_program *p, GLuint input ) { - /* Cram the material flags into the generic range. We'll translate - * them back later. - */ - if (input >= BRW_ATTRIB_MAT_FRONT_AMBIENT) - input -= BRW_ATTRIB_MAT_FRONT_AMBIENT; - assert(input < 32); p->program->Base.InputsRead |= (1<eye_position)) { - struct ureg pos = register_input( p, BRW_ATTRIB_POS ); + struct ureg pos = register_input( p, VERT_ATTRIB_POS ); struct ureg modelview[4]; p->eye_position = reserve_temp(p); @@ -709,7 +707,7 @@ static struct ureg get_eye_position_normalized( struct tnl_program *p ) static struct ureg get_eye_normal( struct tnl_program *p ) { if (is_undef(p->eye_normal)) { - struct ureg normal = register_input(p, BRW_ATTRIB_NORMAL ); + struct ureg normal = register_input(p, VERT_ATTRIB_NORMAL ); struct ureg mvinv[3]; register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 2, @@ -742,7 +740,7 @@ static struct ureg get_eye_normal( struct tnl_program *p ) static void build_hpos( struct tnl_program *p ) { - struct ureg pos = register_input( p, BRW_ATTRIB_POS ); + struct ureg pos = register_input( p, VERT_ATTRIB_POS ); struct ureg hpos = register_output( p, VERT_RESULT_HPOS ); struct ureg mvp[4]; @@ -786,9 +784,9 @@ static struct ureg get_material( struct tnl_program *p, GLuint side, GLuint attrib = material_attrib(side, property); if (p->color_materials & (1<materials & (1<state->fog_option && @@ -1298,7 +1296,7 @@ static void build_texture_transform( struct tnl_program *p ) for (j = 0; j < 4; j++) { switch (modes[j]) { case TXG_OBJ_LINEAR: { - struct ureg obj = register_input(p, BRW_ATTRIB_POS); + struct ureg obj = register_input(p, VERT_ATTRIB_POS); struct ureg plane = register_param3(p, STATE_TEXGEN, i, STATE_TEXGEN_OBJECT_S + j); @@ -1347,7 +1345,7 @@ static void build_texture_transform( struct tnl_program *p ) } if (copy_mask) { - struct ureg in = register_input(p, BRW_ATTRIB_TEX0+i); + struct ureg in = register_input(p, VERT_ATTRIB_TEX0+i); emit_op1(p, OPCODE_MOV, out_texgen, copy_mask, in ); } } @@ -1356,7 +1354,7 @@ static void build_texture_transform( struct tnl_program *p ) struct ureg texmat[4]; struct ureg in = (!is_undef(out_texgen) ? out_texgen : - register_input(p, BRW_ATTRIB_TEX0+i)); + register_input(p, VERT_ATTRIB_TEX0+i)); if (PREFER_DP4) { register_matrix_param6( p, STATE_MATRIX, STATE_TEXTURE, i, 0, 3, STATE_MATRIX, texmat ); @@ -1372,7 +1370,7 @@ static void build_texture_transform( struct tnl_program *p ) release_temps(p); } else { - emit_passthrough(p, BRW_ATTRIB_TEX0+i, VERT_RESULT_TEX0+i); + emit_passthrough(p, VERT_ATTRIB_TEX0+i, VERT_RESULT_TEX0+i); } } } @@ -1424,10 +1422,10 @@ static void build_tnl_program( struct tnl_program *p ) build_lighting(p); else { if (p->state->fragprog_inputs_read & FRAG_BIT_COL0) - emit_passthrough(p, BRW_ATTRIB_COLOR0, VERT_RESULT_COL0); + emit_passthrough(p, VERT_ATTRIB_COLOR0, VERT_RESULT_COL0); if (p->state->fragprog_inputs_read & FRAG_BIT_COL1) - emit_passthrough(p, BRW_ATTRIB_COLOR1, VERT_RESULT_COL1); + emit_passthrough(p, VERT_ATTRIB_COLOR1, VERT_RESULT_COL1); } } diff --git a/src/mesa/drivers/dri/i965/brw_vtbl.c b/src/mesa/drivers/dri/i965/brw_vtbl.c index 4896882034..a5738e5774 100644 --- a/src/mesa/drivers/dri/i965/brw_vtbl.c +++ b/src/mesa/drivers/dri/i965/brw_vtbl.c @@ -46,8 +46,6 @@ #include "brw_state.h" #include "brw_draw.h" -#include "brw_exec.h" -#include "brw_save.h" #include "brw_state.h" #include "brw_aub.h" #include "brw_fallback.h" @@ -68,9 +66,6 @@ static void brw_destroy_context( struct intel_context *intel ) brw_destroy_state(brw); brw_draw_destroy( brw ); - brw_exec_destroy( ctx ); - brw_save_destroy( ctx ); - brw_ProgramCacheDestroy( ctx ); } @@ -165,10 +160,7 @@ static GLuint brw_flush_cmd( void ) static void brw_invalidate_state( struct intel_context *intel, GLuint new_state ) { - GLcontext *ctx = &intel->ctx; - - brw_exec_invalidate_state(ctx, new_state); - brw_save_invalidate_state(ctx, new_state); + /* nothing */ } -- cgit v1.2.3 From 1f07439fe8c6803f70a27a1cdb9d76360ae40571 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 31 Oct 2006 11:39:57 +0000 Subject: move public structure definitions to vbo.h --- src/mesa/vbo/vbo.h | 28 ++++++++++++++++++++++++++++ src/mesa/vbo/vbo_attrib.h | 25 ------------------------- src/mesa/vbo/vbo_context.h | 1 + src/mesa/vbo/vbo_exec.h | 1 + src/mesa/vbo/vbo_save.h | 1 + 5 files changed, 31 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/mesa/vbo/vbo.h b/src/mesa/vbo/vbo.h index 96b25f18ee..80f7a3322b 100644 --- a/src/mesa/vbo/vbo.h +++ b/src/mesa/vbo/vbo.h @@ -32,6 +32,34 @@ #ifndef _VBO_H #define _VBO_H +#include "mtypes.h" + +struct _mesa_prim { + GLuint mode:8; + GLuint indexed:1; + GLuint begin:1; + GLuint end:1; + GLuint weak:1; + GLuint pad:20; + + GLuint start; + GLuint count; +}; + +/* Would like to call this a "vbo_index_buffer", but this would be + * confusing as the indices are not neccessarily yet in a non-null + * buffer object. + */ +struct _mesa_index_buffer { + GLuint count; + GLenum type; + struct gl_buffer_object *obj; + const void *ptr; + GLuint rebase; +}; + + + GLboolean _vbo_CreateContext( GLcontext *ctx ); void _vbo_DestroyContext( GLcontext *ctx ); void _vbo_InvalidateState( GLcontext *ctx, GLuint new_state ); diff --git a/src/mesa/vbo/vbo_attrib.h b/src/mesa/vbo/vbo_attrib.h index caedbd5ea6..9de4fd0683 100644 --- a/src/mesa/vbo/vbo_attrib.h +++ b/src/mesa/vbo/vbo_attrib.h @@ -103,29 +103,4 @@ enum { #define VBO_MAX_COPIED_VERTS 3 -struct _mesa_prim { - GLuint mode:8; - GLuint indexed:1; - GLuint begin:1; - GLuint end:1; - GLuint weak:1; - GLuint pad:20; - - GLuint start; - GLuint count; -}; - -/* Would like to call this a "vbo_index_buffer", but this would be - * confusing as the indices are not neccessarily yet in a non-null - * buffer object. - */ -struct _mesa_index_buffer { - GLuint count; - GLenum type; - struct gl_buffer_object *obj; - const void *ptr; - GLuint rebase; -}; - - #endif diff --git a/src/mesa/vbo/vbo_context.h b/src/mesa/vbo/vbo_context.h index cd02472023..4c5ed96765 100644 --- a/src/mesa/vbo/vbo_context.h +++ b/src/mesa/vbo/vbo_context.h @@ -51,6 +51,7 @@ #ifndef _VBO_CONTEXT_H #define _VBO_CONTEXT_H +#include "vbo.h" #include "vbo_attrib.h" #include "vbo_save.h" #include "vbo_exec.h" diff --git a/src/mesa/vbo/vbo_exec.h b/src/mesa/vbo/vbo_exec.h index e1fc7b2794..e28913b22a 100644 --- a/src/mesa/vbo/vbo_exec.h +++ b/src/mesa/vbo/vbo_exec.h @@ -35,6 +35,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define __VBO_EXEC_H__ #include "mtypes.h" +#include "vbo.h" #include "vbo_attrib.h" diff --git a/src/mesa/vbo/vbo_save.h b/src/mesa/vbo/vbo_save.h index 5a64429411..3051f5c59a 100644 --- a/src/mesa/vbo/vbo_save.h +++ b/src/mesa/vbo/vbo_save.h @@ -35,6 +35,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define VBO_SAVE_H #include "mtypes.h" +#include "vbo.h" #include "vbo_attrib.h" -- cgit v1.2.3 From 70dd0126bd25f2cc2fedae60281ab5c256cb8664 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 31 Oct 2006 11:40:31 +0000 Subject: pickup structs from vbo.h --- src/mesa/tnl/t_context.c | 2 +- src/mesa/tnl/t_context.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/tnl/t_context.c b/src/mesa/tnl/t_context.c index 851a0672d4..5d6b6dd97d 100644 --- a/src/mesa/tnl/t_context.c +++ b/src/mesa/tnl/t_context.c @@ -38,7 +38,7 @@ #include "t_pipeline.h" #include "t_vp_build.h" -#include "vbo/vbo_attrib.h" +#include "vbo/vbo.h" GLboolean _tnl_CreateContext( GLcontext *ctx ) diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h index 28d1b7faab..a872f26177 100644 --- a/src/mesa/tnl/t_context.h +++ b/src/mesa/tnl/t_context.h @@ -56,7 +56,7 @@ #include "math/m_vector.h" #include "math/m_xform.h" -#include "vbo/vbo_attrib.h" +#include "vbo/vbo.h" #define MAX_PIPELINE_STAGES 30 -- cgit v1.2.3 From 80c88304fc9d09531b2530b74973821e47b46753 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 31 Oct 2006 12:11:10 +0000 Subject: remove vtxfmt code, switch over to vbo --- src/mesa/drivers/dri/r200/Makefile | 6 +- src/mesa/drivers/dri/r200/r200_context.c | 25 +- src/mesa/drivers/dri/r200/r200_state.c | 6 +- src/mesa/drivers/dri/r200/r200_state_init.c | 3 +- src/mesa/drivers/dri/r200/r200_swtcl.c | 8 - src/mesa/drivers/dri/r200/r200_tcl.c | 2 +- src/mesa/drivers/dri/r200/r200_vtxfmt.c | 1234 ----------------------- src/mesa/drivers/dri/r200/r200_vtxfmt.h | 123 --- src/mesa/drivers/dri/r200/r200_vtxfmt_c.c | 1002 ------------------ src/mesa/drivers/dri/r200/r200_vtxfmt_sse.c | 234 ----- src/mesa/drivers/dri/r200/r200_vtxfmt_x86.c | 440 -------- src/mesa/drivers/dri/r200/r200_vtxtmp_x86.S | 499 --------- src/mesa/drivers/dri/radeon/Makefile | 9 +- src/mesa/drivers/dri/radeon/radeon_context.c | 26 +- src/mesa/drivers/dri/radeon/radeon_maos_verts.c | 2 +- src/mesa/drivers/dri/radeon/radeon_state.c | 6 +- src/mesa/drivers/dri/radeon/radeon_state_init.c | 3 +- src/mesa/drivers/dri/radeon/radeon_swtcl.c | 9 - src/mesa/drivers/dri/radeon/radeon_swtcl.h | 1 - src/mesa/drivers/dri/radeon/radeon_tcl.c | 2 +- src/mesa/drivers/dri/radeon/radeon_vtxfmt.c | 1086 -------------------- src/mesa/drivers/dri/radeon/radeon_vtxfmt.h | 120 --- src/mesa/drivers/dri/radeon/radeon_vtxfmt_c.c | 924 ----------------- src/mesa/drivers/dri/radeon/radeon_vtxfmt_sse.c | 236 ----- src/mesa/drivers/dri/radeon/radeon_vtxfmt_x86.c | 440 -------- src/mesa/drivers/dri/radeon/radeon_vtxtmp_x86.S | 498 --------- 26 files changed, 21 insertions(+), 6923 deletions(-) delete mode 100644 src/mesa/drivers/dri/r200/r200_vtxfmt.c delete mode 100644 src/mesa/drivers/dri/r200/r200_vtxfmt.h delete mode 100644 src/mesa/drivers/dri/r200/r200_vtxfmt_c.c delete mode 100644 src/mesa/drivers/dri/r200/r200_vtxfmt_sse.c delete mode 100644 src/mesa/drivers/dri/r200/r200_vtxfmt_x86.c delete mode 100644 src/mesa/drivers/dri/r200/r200_vtxtmp_x86.S delete mode 100644 src/mesa/drivers/dri/radeon/radeon_vtxfmt.c delete mode 100644 src/mesa/drivers/dri/radeon/radeon_vtxfmt.h delete mode 100644 src/mesa/drivers/dri/radeon/radeon_vtxfmt_c.c delete mode 100644 src/mesa/drivers/dri/radeon/radeon_vtxfmt_sse.c delete mode 100644 src/mesa/drivers/dri/radeon/radeon_vtxfmt_x86.c delete mode 100644 src/mesa/drivers/dri/radeon/radeon_vtxtmp_x86.S (limited to 'src') diff --git a/src/mesa/drivers/dri/r200/Makefile b/src/mesa/drivers/dri/r200/Makefile index 75c09ff867..e9144ac75c 100644 --- a/src/mesa/drivers/dri/r200/Makefile +++ b/src/mesa/drivers/dri/r200/Makefile @@ -26,10 +26,6 @@ DRIVER_SOURCES = r200_context.c \ r200_span.c \ r200_maos.c \ r200_sanity.c \ - r200_vtxfmt.c \ - r200_vtxfmt_c.c \ - r200_vtxfmt_sse.c \ - r200_vtxfmt_x86.c \ r200_fragshader.c \ r200_vertprog.c \ radeon_screen.c \ @@ -37,7 +33,7 @@ DRIVER_SOURCES = r200_context.c \ C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES) -X86_SOURCES = r200_vtxtmp_x86.S +X86_SOURCES = DRIVER_DEFINES = -DRADEON_COMMON=1 -DRADEON_COMMON_FOR_R200 diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c index 9cec50147d..02651587a6 100644 --- a/src/mesa/drivers/dri/r200/r200_context.c +++ b/src/mesa/drivers/dri/r200/r200_context.c @@ -45,7 +45,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -60,7 +60,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_tex.h" #include "r200_swtcl.h" #include "r200_tcl.h" -#include "r200_vtxfmt.h" #include "r200_maos.h" #include "r200_vertprog.h" @@ -434,7 +433,7 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); _ae_create_context( ctx ); @@ -447,7 +446,7 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, /* Try and keep materials and vertices separate: */ - _tnl_isolate_materials( ctx, GL_TRUE ); +/* _tnl_isolate_materials( ctx, GL_TRUE ); */ /* Configure swrast and TNL to match hardware characteristics: @@ -552,12 +551,6 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, TCL_FALLBACK(rmesa->glCtx, R200_TCL_FALLBACK_TCL_DISABLE, 1); } - if (rmesa->r200Screen->chip_flags & RADEON_CHIPSET_TCL) { - if (tcl_mode >= DRI_CONF_TCL_VTXFMT) - r200VtxfmtInit( ctx, tcl_mode >= DRI_CONF_TCL_CODEGEN ); - - _tnl_need_dlist_norm_lengths( ctx, GL_FALSE ); - } return GL_TRUE; } @@ -587,7 +580,7 @@ void r200DestroyContext( __DRIcontextPrivate *driContextPriv ) release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1); _swsetup_DestroyContext( rmesa->glCtx ); _tnl_DestroyContext( rmesa->glCtx ); - _ac_DestroyContext( rmesa->glCtx ); + _vbo_DestroyContext( rmesa->glCtx ); _swrast_DestroyContext( rmesa->glCtx ); r200DestroySwtcl( rmesa->glCtx ); @@ -598,12 +591,6 @@ void r200DestroyContext( __DRIcontextPrivate *driContextPriv ) r200FlushCmdBuf( rmesa, __FUNCTION__ ); } - if (!(rmesa->TclFallback & R200_TCL_FALLBACK_TCL_DISABLE)) { - int tcl_mode = driQueryOptioni(&rmesa->optionCache, "tcl_mode"); - if (tcl_mode >= DRI_CONF_TCL_VTXFMT) - r200VtxfmtDestroy( rmesa->glCtx ); - } - if (rmesa->state.scissor.pClipRects) { FREE(rmesa->state.scissor.pClipRects); rmesa->state.scissor.pClipRects = NULL; @@ -713,9 +700,6 @@ r200MakeCurrent( __DRIcontextPrivate *driContextPriv, (GLframebuffer *) driDrawPriv->driverPrivate, (GLframebuffer *) driReadPriv->driverPrivate ); - if (newCtx->vb.enabled) - r200VtxfmtMakeCurrent( newCtx->glCtx ); - _mesa_update_state( newCtx->glCtx ); r200ValidateState( newCtx->glCtx ); @@ -740,6 +724,5 @@ r200UnbindContext( __DRIcontextPrivate *driContextPriv ) if (R200_DEBUG & DEBUG_DRI) fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *)rmesa->glCtx); - r200VtxfmtUnbindContext( rmesa->glCtx ); return GL_TRUE; } diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c index 097fbc868a..e68f1e30f3 100644 --- a/src/mesa/drivers/dri/r200/r200_state.c +++ b/src/mesa/drivers/dri/r200/r200_state.c @@ -42,7 +42,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "light.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" #include "swrast_setup/swrast_setup.h" @@ -53,7 +53,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_tcl.h" #include "r200_tex.h" #include "r200_swtcl.h" -#include "r200_vtxfmt.h" #include "r200_vertprog.h" #include "drirenderbuffer.h" @@ -2517,11 +2516,10 @@ static void r200InvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); _ae_invalidate_state( ctx, new_state ); R200_CONTEXT(ctx)->NewGLState |= new_state; - r200VtxfmtInvalidate( ctx ); } /* A hack. The r200 can actually cope just fine with materials diff --git a/src/mesa/drivers/dri/r200/r200_state_init.c b/src/mesa/drivers/dri/r200/r200_state_init.c index d95a80c7bb..b40d0bdcb7 100644 --- a/src/mesa/drivers/dri/r200/r200_state_init.c +++ b/src/mesa/drivers/dri/r200/r200_state_init.c @@ -39,7 +39,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "api_arrayelt.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" #include "swrast_setup/swrast_setup.h" @@ -50,7 +50,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_tcl.h" #include "r200_tex.h" #include "r200_swtcl.h" -#include "r200_vtxfmt.h" #include "xmlpool.h" diff --git a/src/mesa/drivers/dri/r200/r200_swtcl.c b/src/mesa/drivers/dri/r200/r200_swtcl.c index c14a275f7a..25d229d8ed 100644 --- a/src/mesa/drivers/dri/r200/r200_swtcl.c +++ b/src/mesa/drivers/dri/r200/r200_swtcl.c @@ -48,7 +48,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" -#include "tnl/t_vtx_api.h" #include "r200_context.h" #include "r200_ioctl.h" @@ -936,13 +935,6 @@ r200PointsBitmap( GLcontext *ctx, GLint px, GLint py, } -void r200FlushVertices( GLcontext *ctx, GLuint flags ) -{ - _tnl_FlushVertices( ctx, flags ); - - if (flags & FLUSH_STORED_VERTICES) - R200_NEWPRIM( R200_CONTEXT( ctx ) ); -} /**********************************************************************/ /* Initialization. */ diff --git a/src/mesa/drivers/dri/r200/r200_tcl.c b/src/mesa/drivers/dri/r200/r200_tcl.c index dab478db92..0b3bb281e0 100644 --- a/src/mesa/drivers/dri/r200/r200_tcl.c +++ b/src/mesa/drivers/dri/r200/r200_tcl.c @@ -40,7 +40,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "colormac.h" #include "light.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" diff --git a/src/mesa/drivers/dri/r200/r200_vtxfmt.c b/src/mesa/drivers/dri/r200/r200_vtxfmt.c deleted file mode 100644 index d73fbbafd5..0000000000 --- a/src/mesa/drivers/dri/r200/r200_vtxfmt.c +++ /dev/null @@ -1,1234 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.c,v 1.4 2003/05/06 23:52:08 daenzer Exp $ */ -/* -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -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 (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 NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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 - */ - -#include "glheader.h" -#include "imports.h" -#include "r200_context.h" -#include "r200_state.h" -#include "r200_ioctl.h" -#include "r200_tex.h" -#include "r200_tcl.h" -#include "r200_swtcl.h" -#include "r200_vtxfmt.h" - -#include "api_noop.h" -#include "api_arrayelt.h" -#include "context.h" -#include "mtypes.h" -#include "enums.h" -#include "glapi.h" -#include "colormac.h" -#include "light.h" -#include "state.h" -#include "vtxfmt.h" - -#include "tnl/tnl.h" -#include "tnl/t_context.h" -#include "tnl/t_array_api.h" -#include "tnl/t_save_api.h" - -#include "dispatch.h" - -static void r200VtxFmtFlushVertices( GLcontext *, GLuint ); - -static void count_func( const char *name, struct dynfn *l ) -{ - int i = 0; - struct dynfn *f; - foreach (f, l) i++; - if (i) fprintf(stderr, "%s: %d\n", name, i ); -} - -static void count_funcs( r200ContextPtr rmesa ) -{ - count_func( "Vertex2f", &rmesa->vb.dfn_cache.Vertex2f ); - count_func( "Vertex2fv", &rmesa->vb.dfn_cache.Vertex2fv ); - count_func( "Vertex3f", &rmesa->vb.dfn_cache.Vertex3f ); - count_func( "Vertex3fv", &rmesa->vb.dfn_cache.Vertex3fv ); - count_func( "Color4ub", &rmesa->vb.dfn_cache.Color4ub ); - count_func( "Color4ubv", &rmesa->vb.dfn_cache.Color4ubv ); - count_func( "Color3ub", &rmesa->vb.dfn_cache.Color3ub ); - count_func( "Color3ubv", &rmesa->vb.dfn_cache.Color3ubv ); - count_func( "Color4f", &rmesa->vb.dfn_cache.Color4f ); - count_func( "Color4fv", &rmesa->vb.dfn_cache.Color4fv ); - count_func( "Color3f", &rmesa->vb.dfn_cache.Color3f ); - count_func( "Color3fv", &rmesa->vb.dfn_cache.Color3fv ); - count_func( "SecondaryColor3f", &rmesa->vb.dfn_cache.SecondaryColor3fEXT ); - count_func( "SecondaryColor3fv", &rmesa->vb.dfn_cache.SecondaryColor3fvEXT ); - count_func( "SecondaryColor3ub", &rmesa->vb.dfn_cache.SecondaryColor3ubEXT ); - count_func( "SecondaryColor3ubv", &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT ); - count_func( "Normal3f", &rmesa->vb.dfn_cache.Normal3f ); - count_func( "Normal3fv", &rmesa->vb.dfn_cache.Normal3fv ); - count_func( "TexCoord3f", &rmesa->vb.dfn_cache.TexCoord3f ); - count_func( "TexCoord3fv", &rmesa->vb.dfn_cache.TexCoord3fv ); - count_func( "TexCoord2f", &rmesa->vb.dfn_cache.TexCoord2f ); - count_func( "TexCoord2fv", &rmesa->vb.dfn_cache.TexCoord2fv ); - count_func( "TexCoord1f", &rmesa->vb.dfn_cache.TexCoord1f ); - count_func( "TexCoord1fv", &rmesa->vb.dfn_cache.TexCoord1fv ); - count_func( "MultiTexCoord3fARB", &rmesa->vb.dfn_cache.MultiTexCoord3fARB ); - count_func( "MultiTexCoord3fvARB", &rmesa->vb.dfn_cache.MultiTexCoord3fvARB ); - count_func( "MultiTexCoord2fARB", &rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - count_func( "MultiTexCoord2fvARB", &rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - count_func( "MultiTexCoord1fARB", &rmesa->vb.dfn_cache.MultiTexCoord1fARB ); - count_func( "MultiTexCoord1fvARB", &rmesa->vb.dfn_cache.MultiTexCoord1fvARB ); -/* count_func( "FogCoordfEXT", &rmesa->vb.dfn_cache.FogCoordfEXT ); - count_func( "FogCoordfvEXT", &rmesa->vb.dfn_cache.FogCoordfvEXT );*/ -} - -static void r200NewList( GLcontext *ctx, GLuint list, GLenum mode ) -{ - VFMT_FALLBACK( __FUNCTION__ ); - _tnl_NewList( ctx, list, mode ); - return; -} - -void r200_copy_to_current( GLcontext *ctx ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - unsigned i; - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - assert(ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT); - - if (rmesa->vb.vtxfmt_0 & R200_VTX_N0) { - ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0] = rmesa->vb.normalptr[0]; - ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1] = rmesa->vb.normalptr[1]; - ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2] = rmesa->vb.normalptr[2]; - } - - if (rmesa->vb.vtxfmt_0 & R200_VTX_DISCRETE_FOG) { - ctx->Current.Attrib[VERT_ATTRIB_FOG][0] = rmesa->vb.fogptr[0]; - } - - switch( VTX_COLOR(rmesa->vb.vtxfmt_0, 0) ) { - case R200_VTX_PK_RGBA: - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->red ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->green ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->blue ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->alpha ); - break; - - case R200_VTX_FP_RGB: - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] = rmesa->vb.floatcolorptr[0]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] = rmesa->vb.floatcolorptr[1]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] = rmesa->vb.floatcolorptr[2]; - break; - - case R200_VTX_FP_RGBA: - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] = rmesa->vb.floatcolorptr[0]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] = rmesa->vb.floatcolorptr[1]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] = rmesa->vb.floatcolorptr[2]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = rmesa->vb.floatcolorptr[3]; - break; - - default: - break; - } - - if (VTX_COLOR(rmesa->vb.vtxfmt_0, 1) == R200_VTX_PK_RGBA) { - ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0] = UBYTE_TO_FLOAT( rmesa->vb.specptr->red ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1] = UBYTE_TO_FLOAT( rmesa->vb.specptr->green ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2] = UBYTE_TO_FLOAT( rmesa->vb.specptr->blue ); - } - - for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) { - const unsigned count = VTX_TEXn_COUNT( rmesa->vb.vtxfmt_1, i ); - GLfloat * const src = rmesa->vb.texcoordptr[i]; - - if ( count != 0 ) { - switch( count ) { - case 3: - ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][1] = src[1]; - ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][2] = src[2]; - break; - case 2: - ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][1] = src[1]; - ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][2] = 0.0F; - break; - case 1: - ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][1] = 0.0F; - ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][2] = 0.0F; - break; - } - - ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][0] = src[0]; - ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][3] = 1.0F; - } - } - - ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT; -} - -static GLboolean discreet_gl_prim[GL_POLYGON+1] = { - 1, /* 0 points */ - 1, /* 1 lines */ - 0, /* 2 line_strip */ - 0, /* 3 line_loop */ - 1, /* 4 tris */ - 0, /* 5 tri_fan */ - 0, /* 6 tri_strip */ - 1, /* 7 quads */ - 0, /* 8 quadstrip */ - 0, /* 9 poly */ -}; - -static void flush_prims( r200ContextPtr rmesa ) -{ - int i,j; - struct r200_dma_region tmp = rmesa->dma.current; - - tmp.buf->refcount++; - tmp.aos_size = rmesa->vb.vertex_size; - tmp.aos_stride = rmesa->vb.vertex_size; - tmp.aos_start = GET_START(&tmp); - - rmesa->dma.current.ptr = rmesa->dma.current.start += - (rmesa->vb.initial_counter - rmesa->vb.counter) * - rmesa->vb.vertex_size * 4; - - rmesa->tcl.vertex_format = rmesa->vb.vtxfmt_0; - rmesa->tcl.aos_components[0] = &tmp; - rmesa->tcl.nr_aos_components = 1; - rmesa->dma.flush = NULL; - - /* Optimize the primitive list: - */ - if (rmesa->vb.nrprims > 1) { - for (j = 0, i = 1 ; i < rmesa->vb.nrprims; i++) { - int pj = rmesa->vb.primlist[j].prim & 0xf; - int pi = rmesa->vb.primlist[i].prim & 0xf; - - if (pj == pi && discreet_gl_prim[pj] && - rmesa->vb.primlist[i].start == rmesa->vb.primlist[j].end) { - rmesa->vb.primlist[j].end = rmesa->vb.primlist[i].end; - } - else { - j++; - if (j != i) rmesa->vb.primlist[j] = rmesa->vb.primlist[i]; - } - } - rmesa->vb.nrprims = j+1; - } - - if (rmesa->vb.vtxfmt_0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] || - rmesa->vb.vtxfmt_1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) { - R200_STATECHANGE( rmesa, vtx ); - rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = rmesa->vb.vtxfmt_0; - rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = rmesa->vb.vtxfmt_1; - } - - - for (i = 0 ; i < rmesa->vb.nrprims; i++) { - if (R200_DEBUG & DEBUG_PRIMS) - fprintf(stderr, "vtxfmt prim %d: %s %d..%d\n", i, - _mesa_lookup_enum_by_nr( rmesa->vb.primlist[i].prim & - PRIM_MODE_MASK ), - rmesa->vb.primlist[i].start, - rmesa->vb.primlist[i].end); - - if (rmesa->vb.primlist[i].start < rmesa->vb.primlist[i].end) - r200EmitPrimitive( rmesa->glCtx, - rmesa->vb.primlist[i].start, - rmesa->vb.primlist[i].end, - rmesa->vb.primlist[i].prim ); - } - - rmesa->vb.nrprims = 0; - r200ReleaseDmaRegion( rmesa, &tmp, __FUNCTION__ ); -} - - -static void start_prim( r200ContextPtr rmesa, GLuint mode ) -{ - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s %d\n", __FUNCTION__, - rmesa->vb.initial_counter - rmesa->vb.counter); - - rmesa->vb.primlist[rmesa->vb.nrprims].start = - rmesa->vb.initial_counter - rmesa->vb.counter; - rmesa->vb.primlist[rmesa->vb.nrprims].prim = mode; -} - -static void note_last_prim( r200ContextPtr rmesa, GLuint flags ) -{ - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s %d\n", __FUNCTION__, - rmesa->vb.initial_counter - rmesa->vb.counter); - - if (rmesa->vb.prim[0] != GL_POLYGON+1) { - rmesa->vb.primlist[rmesa->vb.nrprims].prim |= flags; - rmesa->vb.primlist[rmesa->vb.nrprims].end = - rmesa->vb.initial_counter - rmesa->vb.counter; - - if (++(rmesa->vb.nrprims) == R200_MAX_PRIMS) - flush_prims( rmesa ); - } -} - - -static void copy_vertex( r200ContextPtr rmesa, GLuint n, GLfloat *dst ) -{ - GLuint i; - GLfloat *src = (GLfloat *)(rmesa->dma.current.address + - rmesa->dma.current.ptr + - (rmesa->vb.primlist[rmesa->vb.nrprims].start + n) * - rmesa->vb.vertex_size * 4); - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "copy_vertex %d\n", rmesa->vb.primlist[rmesa->vb.nrprims].start + n); - - for (i = 0 ; i < rmesa->vb.vertex_size; i++) { - dst[i] = src[i]; - } -} - -/* NOTE: This actually reads the copied vertices back from uncached - * memory. Could also use the counter/notify mechanism to populate - * tmp on the fly as vertices are generated. - */ -static GLuint copy_dma_verts( r200ContextPtr rmesa, GLfloat (*tmp)[R200_MAX_VERTEX_SIZE] ) -{ - GLuint ovf, i; - GLuint nr = (rmesa->vb.initial_counter - rmesa->vb.counter) - - rmesa->vb.primlist[rmesa->vb.nrprims].start; - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s %d verts\n", __FUNCTION__, nr); - - switch( rmesa->vb.prim[0] ) - { - case GL_POINTS: - return 0; - case GL_LINES: - ovf = nr&1; - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - case GL_TRIANGLES: - ovf = nr%3; - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - case GL_QUADS: - ovf = nr&3; - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - case GL_LINE_STRIP: - if (nr == 0) - return 0; - copy_vertex( rmesa, nr-1, tmp[0] ); - return 1; - case GL_LINE_LOOP: - case GL_TRIANGLE_FAN: - case GL_POLYGON: - if (nr == 0) - return 0; - else if (nr == 1) { - copy_vertex( rmesa, 0, tmp[0] ); - return 1; - } else { - copy_vertex( rmesa, 0, tmp[0] ); - copy_vertex( rmesa, nr-1, tmp[1] ); - return 2; - } - case GL_TRIANGLE_STRIP: - ovf = MIN2( nr, 2 ); - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - 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++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - default: - assert(0); - return 0; - } -} - -static void VFMT_FALLBACK_OUTSIDE_BEGIN_END( const char *caller ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - if (R200_DEBUG & (DEBUG_VFMT|DEBUG_FALLBACKS)) - fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); - - if (ctx->Driver.NeedFlush) - r200VtxFmtFlushVertices( ctx, ctx->Driver.NeedFlush ); - - if (ctx->NewState) - _mesa_update_state( ctx ); /* clear state so fell_back sticks */ - - _tnl_wakeup_exec( ctx ); - ctx->Driver.FlushVertices = r200FlushVertices; - ctx->Driver.NewList = _tnl_NewList; - - assert( rmesa->dma.flush == 0 ); - rmesa->vb.fell_back = GL_TRUE; - rmesa->vb.installed = GL_FALSE; -} - - -/** - * \todo - * An interesting optimization of this function would be to have 3 element - * table with the dispatch offsets of the TexCoord?fv functions, use count - * to look-up the table, and a specialized version of GL_CALL that used the - * offset number instead of the name. - */ -static void dispatch_multitexcoord( GLuint count, GLuint unit, GLfloat * f ) -{ - switch( count ) { - case 3: - CALL_MultiTexCoord3fvARB(GET_DISPATCH(), (GL_TEXTURE0+unit, f)); - break; - case 2: - CALL_MultiTexCoord2fvARB(GET_DISPATCH(), (GL_TEXTURE0+unit, f)); - break; - case 1: - CALL_MultiTexCoord1fvARB(GET_DISPATCH(), (GL_TEXTURE0+unit, f)); - break; - default: - assert( count == 0 ); - break; - } -} - -void VFMT_FALLBACK( const char *caller ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat tmp[3][R200_MAX_VERTEX_SIZE]; - GLuint i, prim; - GLuint ind0 = rmesa->vb.vtxfmt_0; - GLuint ind1 = rmesa->vb.vtxfmt_1; - GLuint nrverts; - GLfloat alpha = 1.0; - GLuint count; - GLuint unit; - - if (R200_DEBUG & (DEBUG_FALLBACKS|DEBUG_VFMT)) - fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); - - if (rmesa->vb.prim[0] == GL_POLYGON+1) { - VFMT_FALLBACK_OUTSIDE_BEGIN_END( __FUNCTION__ ); - return; - } - - /* Copy vertices out of dma: - */ - nrverts = copy_dma_verts( rmesa, tmp ); - - /* Finish the prim at this point: - */ - note_last_prim( rmesa, 0 ); - flush_prims( rmesa ); - - /* Update ctx->Driver.CurrentExecPrimitive and swap in swtnl. - */ - prim = rmesa->vb.prim[0]; - ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1; - _tnl_wakeup_exec( ctx ); - ctx->Driver.FlushVertices = r200FlushVertices; - - assert(rmesa->dma.flush == 0); - rmesa->vb.fell_back = GL_TRUE; - rmesa->vb.installed = GL_FALSE; - CALL_Begin(GET_DISPATCH(), (prim)); - - if (rmesa->vb.installed_color_3f_sz == 4) - alpha = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3]; - - /* Replay saved vertices - */ - for (i = 0 ; i < nrverts; i++) { - GLuint offset = 3; - - if (ind0 & R200_VTX_N0) { - CALL_Normal3fv(GET_DISPATCH(), (&tmp[i][offset])); - offset += 3; - } - - if (ind0 & R200_VTX_DISCRETE_FOG) { - CALL_FogCoordfvEXT(GET_DISPATCH(), (&tmp[i][offset])); - offset++; - } - - if (VTX_COLOR(ind0, 0) == R200_VTX_PK_RGBA) { - CALL_Color4ubv(GET_DISPATCH(), ((GLubyte *)&tmp[i][offset])); - offset++; - } - else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGBA) { - CALL_Color4fv(GET_DISPATCH(), (&tmp[i][offset])); - offset+=4; - } - else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGB) { - CALL_Color3fv(GET_DISPATCH(), (&tmp[i][offset])); - offset+=3; - } - - if (VTX_COLOR(ind0, 1) == R200_VTX_PK_RGBA) { - CALL_SecondaryColor3ubvEXT(GET_DISPATCH(), ((GLubyte *)&tmp[i][offset])); - offset++; - } - - for ( unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++ ) { - count = VTX_TEXn_COUNT( ind1, unit ); - dispatch_multitexcoord( count, unit, &tmp[i][offset] ); - offset += count; - } - - CALL_Vertex3fv(GET_DISPATCH(), (&tmp[i][0])); - } - - /* Replay current vertex - */ - if (ind0 & R200_VTX_N0) - CALL_Normal3fv(GET_DISPATCH(), (rmesa->vb.normalptr)); - if (ind0 & R200_VTX_DISCRETE_FOG) { - CALL_FogCoordfvEXT(GET_DISPATCH(), (rmesa->vb.fogptr)); - } - - if (VTX_COLOR(ind0, 0) == R200_VTX_PK_RGBA) { - CALL_Color4ub(GET_DISPATCH(), (rmesa->vb.colorptr->red, - rmesa->vb.colorptr->green, - rmesa->vb.colorptr->blue, - rmesa->vb.colorptr->alpha)); - } - else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGBA) { - CALL_Color4fv(GET_DISPATCH(), (rmesa->vb.floatcolorptr)); - } - else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGB) { - if (rmesa->vb.installed_color_3f_sz == 4 && alpha != 1.0) { - CALL_Color4f(GET_DISPATCH(), (rmesa->vb.floatcolorptr[0], - rmesa->vb.floatcolorptr[1], - rmesa->vb.floatcolorptr[2], - alpha)); - } - else { - CALL_Color3fv(GET_DISPATCH(), (rmesa->vb.floatcolorptr)); - } - } - - if (VTX_COLOR(ind0, 1) == R200_VTX_PK_RGBA) - CALL_SecondaryColor3ubEXT(GET_DISPATCH(), (rmesa->vb.specptr->red, - rmesa->vb.specptr->green, - rmesa->vb.specptr->blue)); - - for ( unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++ ) { - count = VTX_TEXn_COUNT( ind1, unit ); - dispatch_multitexcoord( count, unit, rmesa->vb.texcoordptr[unit] ); - } -} - - - -static void wrap_buffer( void ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat tmp[3][R200_MAX_VERTEX_SIZE]; - GLuint i, nrverts; - - if (R200_DEBUG & (DEBUG_VFMT|DEBUG_PRIMS)) - fprintf(stderr, "%s %d\n", __FUNCTION__, - rmesa->vb.initial_counter - rmesa->vb.counter); - - /* Don't deal with parity. - */ - if ((((rmesa->vb.initial_counter - rmesa->vb.counter) - - rmesa->vb.primlist[rmesa->vb.nrprims].start) & 1)) { - rmesa->vb.counter++; - rmesa->vb.initial_counter++; - return; - } - - /* Copy vertices out of dma: - */ - if (rmesa->vb.prim[0] == GL_POLYGON+1) - nrverts = 0; - else { - nrverts = copy_dma_verts( rmesa, tmp ); - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%d vertices to copy\n", nrverts); - - /* Finish the prim at this point: - */ - note_last_prim( rmesa, 0 ); - } - - /* Fire any buffered primitives - */ - flush_prims( rmesa ); - - /* Get new buffer - */ - r200RefillCurrentDmaRegion( rmesa ); - - /* Reset counter, dmaptr - */ - rmesa->vb.dmaptr = (int *)(rmesa->dma.current.ptr + rmesa->dma.current.address); - rmesa->vb.counter = (rmesa->dma.current.end - rmesa->dma.current.ptr) / - (rmesa->vb.vertex_size * 4); - rmesa->vb.counter--; - rmesa->vb.initial_counter = rmesa->vb.counter; - rmesa->vb.notify = wrap_buffer; - - rmesa->dma.flush = flush_prims; - - /* Restart wrapped primitive: - */ - if (rmesa->vb.prim[0] != GL_POLYGON+1) - start_prim( rmesa, rmesa->vb.prim[0] ); - - - /* Reemit saved vertices - */ - for (i = 0 ; i < nrverts; i++) { - if (R200_DEBUG & DEBUG_VERTS) { - int j; - fprintf(stderr, "re-emit vertex %d to %p\n", i, - (void *)rmesa->vb.dmaptr); - if (R200_DEBUG & DEBUG_VERBOSE) - for (j = 0 ; j < rmesa->vb.vertex_size; j++) - fprintf(stderr, "\t%08x/%f\n", *(int*)&tmp[i][j], tmp[i][j]); - } - - memcpy( rmesa->vb.dmaptr, tmp[i], rmesa->vb.vertex_size * 4 ); - rmesa->vb.dmaptr += rmesa->vb.vertex_size; - rmesa->vb.counter--; - } -} - - -/** - * Determines the hardware vertex format based on the current state vector. - * - * \returns - * If the hardware TCL unit is capable of handling the current state vector, - * \c GL_TRUE is returned. Otherwise, \c GL_FALSE is returned. - * - * \todo - * Make this color format selection data driven. If we receive only ubytes, - * send color as ubytes. Also check if converting (with free checking for - * overflow) is cheaper than sending floats directly. - * - * \todo - * When intializing texture coordinates, it might be faster to just copy the - * entire \c VERT_ATTRIB_TEX0 vector into the vertex buffer. It may mean that - * some of the data (i.e., the last texture coordinate components) get copied - * over, but that still may be faster than the conditional branching. If - * nothing else, the code will be smaller and easier to follow. - */ -static GLboolean check_vtx_fmt( GLcontext *ctx ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLuint ind0 = R200_VTX_Z0; - GLuint ind1 = 0; - GLuint i; - GLuint count[R200_MAX_TEXTURE_UNITS]; - - if (rmesa->TclFallback || rmesa->vb.fell_back || ctx->CompileFlag || - (ctx->Fog.Enabled && (ctx->Fog.FogCoordinateSource == GL_FOG_COORD)) || - /* TODO: set tcl out fmt/compsel and reenable vtxfmt code */ - ctx->VertexProgram._Enabled) - return GL_FALSE; - - if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) - ctx->Driver.FlushVertices( ctx, FLUSH_UPDATE_CURRENT ); - - /* Make all this event-driven: - */ - if (ctx->Light.Enabled) { - ind0 |= R200_VTX_N0; - - if (ctx->Light.ColorMaterialEnabled) - ind0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT; - else - ind0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT; - } - else { - /* TODO: make this data driven? - */ - ind0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT; - - if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { - ind0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT; - } - } - - if ( ctx->Fog.FogCoordinateSource == GL_FOG_COORD ) { - ind0 |= R200_VTX_DISCRETE_FOG; - } - - for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) { - count[i] = 0; - - if (ctx->Texture.Unit[i]._ReallyEnabled) { - if (rmesa->TexGenNeedNormals[i]) { - ind0 |= R200_VTX_N0; - } - else { - switch( ctx->Texture.Unit[i]._ReallyEnabled ) { - case TEXTURE_CUBE_BIT: - case TEXTURE_3D_BIT: - count[i] = 3; - break; - case TEXTURE_2D_BIT: - case TEXTURE_RECT_BIT: - count[i] = 2; - break; - case TEXTURE_1D_BIT: - count[i] = 1; - break; - } - - ind1 |= count[i] << (3 * i); - } - } - } - - if (R200_DEBUG & (DEBUG_VFMT|DEBUG_STATE)) - fprintf(stderr, "%s: format: 0x%x, 0x%x\n", __FUNCTION__, ind0, ind1 ); - - R200_NEWPRIM(rmesa); - rmesa->vb.vtxfmt_0 = ind0; - rmesa->vb.vtxfmt_1 = ind1; - rmesa->vb.prim = &ctx->Driver.CurrentExecPrimitive; - - rmesa->vb.vertex_size = 3; - rmesa->vb.normalptr = ctx->Current.Attrib[VERT_ATTRIB_NORMAL]; - rmesa->vb.colorptr = NULL; - rmesa->vb.floatcolorptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; - rmesa->vb.fogptr = ctx->Current.Attrib[VERT_ATTRIB_FOG]; - rmesa->vb.specptr = NULL; - rmesa->vb.floatspecptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR1]; - rmesa->vb.texcoordptr[0] = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; - rmesa->vb.texcoordptr[1] = ctx->Current.Attrib[VERT_ATTRIB_TEX1]; - rmesa->vb.texcoordptr[2] = ctx->Current.Attrib[VERT_ATTRIB_TEX2]; - rmesa->vb.texcoordptr[3] = ctx->Current.Attrib[VERT_ATTRIB_TEX3]; - rmesa->vb.texcoordptr[4] = ctx->Current.Attrib[VERT_ATTRIB_TEX4]; - rmesa->vb.texcoordptr[5] = ctx->Current.Attrib[VERT_ATTRIB_TEX5]; - rmesa->vb.texcoordptr[6] = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; /* dummy */ - rmesa->vb.texcoordptr[7] = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; /* dummy */ - - /* Run through and initialize the vertex components in the order - * the hardware understands: - */ - if (ind0 & R200_VTX_N0) { - rmesa->vb.normalptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; - rmesa->vb.vertex_size += 3; - rmesa->vb.normalptr[0] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0]; - rmesa->vb.normalptr[1] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1]; - rmesa->vb.normalptr[2] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2]; - } - - if (ind0 & R200_VTX_DISCRETE_FOG) { - rmesa->vb.fogptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; - rmesa->vb.vertex_size += 1; - rmesa->vb.fogptr[0] = ctx->Current.Attrib[VERT_ATTRIB_FOG][0]; - } - - if (VTX_COLOR(ind0, 0) == R200_VTX_PK_RGBA) { - rmesa->vb.colorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].color; - rmesa->vb.vertex_size += 1; - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->red, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->green, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->blue, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->alpha, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] ); - } - else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGBA) { - rmesa->vb.floatcolorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; - rmesa->vb.vertex_size += 4; - rmesa->vb.floatcolorptr[0] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0]; - rmesa->vb.floatcolorptr[1] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1]; - rmesa->vb.floatcolorptr[2] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2]; - rmesa->vb.floatcolorptr[3] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3]; - } - else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGB) { - rmesa->vb.floatcolorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; - rmesa->vb.vertex_size += 3; - rmesa->vb.floatcolorptr[0] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0]; - rmesa->vb.floatcolorptr[1] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1]; - rmesa->vb.floatcolorptr[2] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2]; - } - - if (VTX_COLOR(ind0, 1) == R200_VTX_PK_RGBA) { - rmesa->vb.specptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].color; - rmesa->vb.vertex_size += 1; - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->red, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->green, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->blue, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2] ); - } - - - for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) { - if ( count[i] != 0 ) { - float * const attr = ctx->Current.Attrib[VERT_ATTRIB_TEX0+i]; - unsigned j; - - rmesa->vb.texcoordptr[i] = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; - - for ( j = 0 ; j < count[i] ; j++ ) { - rmesa->vb.texcoordptr[i][j] = attr[j]; - } - - rmesa->vb.vertex_size += count[i]; - } - } - - if (rmesa->vb.installed_vertex_format != rmesa->vb.vtxfmt_0) { - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "reinstall on vertex_format change\n"); - _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); - rmesa->vb.installed_vertex_format = rmesa->vb.vtxfmt_0; - } - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s -- success\n", __FUNCTION__); - - return GL_TRUE; -} - - -void r200VtxfmtInvalidate( GLcontext *ctx ) -{ - r200ContextPtr rmesa = R200_CONTEXT( ctx ); - - rmesa->vb.recheck = GL_TRUE; - rmesa->vb.fell_back = GL_FALSE; -} - - -static void r200VtxfmtValidate( GLcontext *ctx ) -{ - r200ContextPtr rmesa = R200_CONTEXT( ctx ); - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (ctx->Driver.NeedFlush) - ctx->Driver.FlushVertices( ctx, ctx->Driver.NeedFlush ); - - rmesa->vb.recheck = GL_FALSE; - - if (check_vtx_fmt( ctx )) { - if (!rmesa->vb.installed) { - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "reinstall (new install)\n"); - - _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); - ctx->Driver.FlushVertices = r200VtxFmtFlushVertices; - ctx->Driver.NewList = r200NewList; - rmesa->vb.installed = GL_TRUE; - } - else if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s: already installed", __FUNCTION__); - } - else { - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s: failed\n", __FUNCTION__); - - if (rmesa->vb.installed) { - if (rmesa->dma.flush) - rmesa->dma.flush( rmesa ); - _tnl_wakeup_exec( ctx ); - ctx->Driver.FlushVertices = r200FlushVertices; - ctx->Driver.NewList =_tnl_NewList; - rmesa->vb.installed = GL_FALSE; - } - } -} - - - -/* Materials: - */ -static void r200_Materialfv( GLenum face, GLenum pname, - const GLfloat *params ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT( ctx ); - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (rmesa->vb.prim[0] != GL_POLYGON+1) { - VFMT_FALLBACK( __FUNCTION__ ); - CALL_Materialfv(GET_DISPATCH(), (face, pname, params)); - return; - } - _mesa_noop_Materialfv( face, pname, params ); - r200UpdateMaterial( ctx ); -} - - -/* Begin/End - */ -static void r200_Begin( GLenum mode ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s( %s )\n", __FUNCTION__, - _mesa_lookup_enum_by_nr( mode )); - - if (mode > GL_POLYGON) { - _mesa_error( ctx, GL_INVALID_ENUM, "glBegin" ); - return; - } - - if (rmesa->vb.prim[0] != GL_POLYGON+1) { - _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" ); - return; - } - - if (ctx->NewState) - _mesa_update_state( ctx ); - - if (rmesa->NewGLState) - r200ValidateState( ctx ); - - if (rmesa->vb.recheck) - r200VtxfmtValidate( ctx ); - - if (!rmesa->vb.installed) { - CALL_Begin(GET_DISPATCH(), (mode)); - return; - } - - - if (rmesa->dma.flush && rmesa->vb.counter < 12) { - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s: flush almost-empty buffers\n", __FUNCTION__); - flush_prims( rmesa ); - } - - /* Need to arrange to save vertices here? Or always copy from dma (yuk)? - */ - if (!rmesa->dma.flush) { - if (rmesa->dma.current.ptr + 12*rmesa->vb.vertex_size*4 > - rmesa->dma.current.end) { - R200_NEWPRIM( rmesa ); - r200RefillCurrentDmaRegion( rmesa ); - } - - rmesa->vb.dmaptr = (int *)(rmesa->dma.current.address + rmesa->dma.current.ptr); - rmesa->vb.counter = (rmesa->dma.current.end - rmesa->dma.current.ptr) / - (rmesa->vb.vertex_size * 4); - rmesa->vb.counter--; - rmesa->vb.initial_counter = rmesa->vb.counter; - rmesa->vb.notify = wrap_buffer; - rmesa->dma.flush = flush_prims; - ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; - } - - - rmesa->vb.prim[0] = mode; - start_prim( rmesa, mode | PRIM_BEGIN ); -} - - - -static void r200_End( void ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (rmesa->vb.prim[0] == GL_POLYGON+1) { - _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" ); - return; - } - - note_last_prim( rmesa, PRIM_END ); - rmesa->vb.prim[0] = GL_POLYGON+1; -} - - -/* Fallback on difficult entrypoints: - */ -#define PRE_LOOPBACK( FUNC ) \ -do { \ - if (R200_DEBUG & DEBUG_VFMT) \ - fprintf(stderr, "%s\n", __FUNCTION__); \ - VFMT_FALLBACK( __FUNCTION__ ); \ -} while (0) -#define TAG(x) r200_fallback_##x -#include "vtxfmt_tmp.h" - - - -static GLboolean r200NotifyBegin( GLcontext *ctx, GLenum p ) -{ - r200ContextPtr rmesa = R200_CONTEXT( ctx ); - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - assert(!rmesa->vb.installed); - - if (ctx->NewState) - _mesa_update_state( ctx ); - - if (rmesa->NewGLState) - r200ValidateState( ctx ); - - if (ctx->Driver.NeedFlush) - ctx->Driver.FlushVertices( ctx, ctx->Driver.NeedFlush ); - - if (rmesa->vb.recheck) - r200VtxfmtValidate( ctx ); - - if (!rmesa->vb.installed) { - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s -- failed\n", __FUNCTION__); - return GL_FALSE; - } - - r200_Begin( p ); - return GL_TRUE; -} - -static void r200VtxFmtFlushVertices( GLcontext *ctx, GLuint flags ) -{ - r200ContextPtr rmesa = R200_CONTEXT( ctx ); - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - assert(rmesa->vb.installed); - - if (flags & FLUSH_UPDATE_CURRENT) { - r200_copy_to_current( ctx ); - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "reinstall on update_current\n"); - _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); - ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT; - } - - if (flags & FLUSH_STORED_VERTICES) { - assert (rmesa->dma.flush == 0 || - rmesa->dma.flush == flush_prims); - if (rmesa->dma.flush == flush_prims) - flush_prims( rmesa ); - ctx->Driver.NeedFlush &= ~FLUSH_STORED_VERTICES; - } -} - - - -/* At this point, don't expect very many versions of each function to - * be generated, so not concerned about freeing them? - */ - - -/** - * Called once during context creation. - */ -void r200VtxfmtInit( GLcontext *ctx, GLboolean useCodegen ) -{ - r200ContextPtr rmesa = R200_CONTEXT( ctx ); - GLvertexformat *vfmt = &(rmesa->vb.vtxfmt); - - /* start by initializing to no-op functions */ - _mesa_noop_vtxfmt_init(vfmt); - - /* Hook in chooser functions for codegen, etc: - */ - r200VtxfmtInitChoosers( vfmt ); - - /* Handled fully in supported states, but no codegen: - */ - vfmt->Materialfv = r200_Materialfv; - vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ - vfmt->Begin = r200_Begin; - vfmt->End = r200_End; - - /* Fallback for performance reasons: (Fix with cva/elt path here and - * dmatmp2.h style primitive-merging) - * - * These should call NotifyBegin(), as should _tnl_EvalMesh, to allow - * a driver-hook. - */ - vfmt->DrawArrays = r200_fallback_DrawArrays; - vfmt->DrawElements = r200_fallback_DrawElements; - vfmt->DrawRangeElements = r200_fallback_DrawRangeElements; - - /* Active but unsupported -- fallback if we receive these: - */ - vfmt->CallList = r200_fallback_CallList; - vfmt->CallLists = r200_fallback_CallLists; - vfmt->EvalCoord1f = r200_fallback_EvalCoord1f; - vfmt->EvalCoord1fv = r200_fallback_EvalCoord1fv; - vfmt->EvalCoord2f = r200_fallback_EvalCoord2f; - vfmt->EvalCoord2fv = r200_fallback_EvalCoord2fv; - vfmt->EvalMesh1 = r200_fallback_EvalMesh1; - vfmt->EvalMesh2 = r200_fallback_EvalMesh2; - vfmt->EvalPoint1 = r200_fallback_EvalPoint1; - vfmt->EvalPoint2 = r200_fallback_EvalPoint2; - vfmt->TexCoord4f = r200_fallback_TexCoord4f; - vfmt->TexCoord4fv = r200_fallback_TexCoord4fv; - vfmt->MultiTexCoord4fARB = r200_fallback_MultiTexCoord4fARB; - vfmt->MultiTexCoord4fvARB = r200_fallback_MultiTexCoord4fvARB; - vfmt->Vertex4f = r200_fallback_Vertex4f; - vfmt->Vertex4fv = r200_fallback_Vertex4fv; - vfmt->VertexAttrib1fNV = r200_fallback_VertexAttrib1fNV; - vfmt->VertexAttrib1fvNV = r200_fallback_VertexAttrib1fvNV; - vfmt->VertexAttrib2fNV = r200_fallback_VertexAttrib2fNV; - vfmt->VertexAttrib2fvNV = r200_fallback_VertexAttrib2fvNV; - vfmt->VertexAttrib3fNV = r200_fallback_VertexAttrib3fNV; - vfmt->VertexAttrib3fvNV = r200_fallback_VertexAttrib3fvNV; - vfmt->VertexAttrib4fNV = r200_fallback_VertexAttrib4fNV; - vfmt->VertexAttrib4fvNV = r200_fallback_VertexAttrib4fvNV; - vfmt->FogCoordfEXT = r200_fallback_FogCoordfEXT; - vfmt->FogCoordfvEXT = r200_fallback_FogCoordfvEXT; - - (void)r200_fallback_vtxfmt; - - TNL_CONTEXT(ctx)->Driver.NotifyBegin = r200NotifyBegin; - - rmesa->vb.enabled = 1; - rmesa->vb.prim = &ctx->Driver.CurrentExecPrimitive; - rmesa->vb.primflags = 0; - - make_empty_list( &rmesa->vb.dfn_cache.Vertex2f ); - make_empty_list( &rmesa->vb.dfn_cache.Vertex2fv ); - make_empty_list( &rmesa->vb.dfn_cache.Vertex3f ); - make_empty_list( &rmesa->vb.dfn_cache.Vertex3fv ); - make_empty_list( &rmesa->vb.dfn_cache.Color4ub ); - make_empty_list( &rmesa->vb.dfn_cache.Color4ubv ); - make_empty_list( &rmesa->vb.dfn_cache.Color3ub ); - make_empty_list( &rmesa->vb.dfn_cache.Color3ubv ); - make_empty_list( &rmesa->vb.dfn_cache.Color4f ); - make_empty_list( &rmesa->vb.dfn_cache.Color4fv ); - make_empty_list( &rmesa->vb.dfn_cache.Color3f ); - make_empty_list( &rmesa->vb.dfn_cache.Color3fv ); - make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3fEXT ); - make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3fvEXT ); - make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3ubEXT ); - make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT ); - make_empty_list( &rmesa->vb.dfn_cache.Normal3f ); - make_empty_list( &rmesa->vb.dfn_cache.Normal3fv ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord3f ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord3fv ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord2f ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord2fv ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord1f ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord1fv ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord3fARB ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord3fvARB ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord1fARB ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord1fvARB ); -/* make_empty_list( &rmesa->vb.dfn_cache.FogCoordfEXT ); - make_empty_list( &rmesa->vb.dfn_cache.FogCoordfvEXT );*/ - - r200InitCodegen( &rmesa->vb.codegen, useCodegen ); -} - -static void free_funcs( struct dynfn *l ) -{ - struct dynfn *f, *tmp; - foreach_s (f, tmp, l) { - remove_from_list( f ); - _mesa_exec_free( f->code ); - _mesa_free( f ); - } -} - -void r200VtxfmtUnbindContext( GLcontext *ctx ) -{ -} - - -void r200VtxfmtMakeCurrent( GLcontext *ctx ) -{ -} - - -void r200VtxfmtDestroy( GLcontext *ctx ) -{ - r200ContextPtr rmesa = R200_CONTEXT( ctx ); - - count_funcs( rmesa ); - free_funcs( &rmesa->vb.dfn_cache.Vertex2f ); - free_funcs( &rmesa->vb.dfn_cache.Vertex2fv ); - free_funcs( &rmesa->vb.dfn_cache.Vertex3f ); - free_funcs( &rmesa->vb.dfn_cache.Vertex3fv ); - free_funcs( &rmesa->vb.dfn_cache.Color4ub ); - free_funcs( &rmesa->vb.dfn_cache.Color4ubv ); - free_funcs( &rmesa->vb.dfn_cache.Color3ub ); - free_funcs( &rmesa->vb.dfn_cache.Color3ubv ); - free_funcs( &rmesa->vb.dfn_cache.Color4f ); - free_funcs( &rmesa->vb.dfn_cache.Color4fv ); - free_funcs( &rmesa->vb.dfn_cache.Color3f ); - free_funcs( &rmesa->vb.dfn_cache.Color3fv ); - free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3ubEXT ); - free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT ); - free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3fEXT ); - free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3fvEXT ); - free_funcs( &rmesa->vb.dfn_cache.Normal3f ); - free_funcs( &rmesa->vb.dfn_cache.Normal3fv ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord3f ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord3fv ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord2f ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord2fv ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord1f ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord1fv ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord3fARB ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord3fvARB ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord1fARB ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord1fvARB ); -/* free_funcs( &rmesa->vb.dfn_cache.FogCoordfEXT ); - free_funcs( &rmesa->vb.dfn_cache.FogCoordfvEXT );*/ -} - diff --git a/src/mesa/drivers/dri/r200/r200_vtxfmt.h b/src/mesa/drivers/dri/r200/r200_vtxfmt.h deleted file mode 100644 index 46999191e0..0000000000 --- a/src/mesa/drivers/dri/r200/r200_vtxfmt.h +++ /dev/null @@ -1,123 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.h,v 1.1 2002/10/30 12:51:53 alanh Exp $ */ -/* -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -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 (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 NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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 - */ - -#ifndef __R200_VTXFMT_H__ -#define __R200_VTXFMT_H__ - -#include "r200_context.h" - - - -extern void r200VtxfmtUpdate( GLcontext *ctx ); -extern void r200VtxfmtInit( GLcontext *ctx, GLboolean useCodegen ); -extern void r200VtxfmtInvalidate( GLcontext *ctx ); -extern void r200VtxfmtDestroy( GLcontext *ctx ); -extern void r200VtxfmtInitChoosers( GLvertexformat *vfmt ); - -extern void r200VtxfmtMakeCurrent( GLcontext *ctx ); -extern void r200VtxfmtUnbindContext( GLcontext *ctx ); - -extern void r200_copy_to_current( GLcontext *ctx ); -extern void VFMT_FALLBACK( const char *caller ); - -#define DFN( FUNC, CACHE) \ -do { \ - char *start = (char *)&FUNC; \ - char *end = (char *)&FUNC##_end; \ - insert_at_head( &CACHE, dfn ); \ - dfn->key[0] = key[0]; \ - dfn->key[1] = key[1]; \ - dfn->code = _mesa_exec_malloc( end - start ); \ - _mesa_memcpy(dfn->code, start, end - start); \ -} \ -while ( 0 ) - -#define FIXUP( CODE, OFFSET, CHECKVAL, NEWVAL ) \ -do { \ - int *icode = (int *)(CODE+OFFSET); \ - assert (*icode == CHECKVAL); \ - *icode = (int)NEWVAL; \ -} while (0) - - -/* Useful for figuring out the offsets: - */ -#define FIXUP2( CODE, OFFSET, CHECKVAL, NEWVAL ) \ -do { \ - while (*(int *)(CODE+OFFSET) != CHECKVAL) OFFSET++; \ - /*fprintf(stderr, "%s/%d CVAL %x OFFSET %d VAL %x\n", __FUNCTION__,*/ \ - /* __LINE__, CHECKVAL, OFFSET, (int)(NEWVAL));*/ \ - *(int *)(CODE+OFFSET) = (int)(NEWVAL); \ - OFFSET += 4; \ -} while (0) - -/* - */ -void r200InitCodegen( struct dfn_generators *gen, GLboolean useCodegen ); -void r200InitX86Codegen( struct dfn_generators *gen ); -void r200InitSSECodegen( struct dfn_generators *gen ); - - - -/* Defined in r200_vtxfmt_x86.c - */ -struct dynfn *r200_makeX86Vertex2f( GLcontext *, const int * ); -struct dynfn *r200_makeX86Vertex2fv( GLcontext *, const int * ); -struct dynfn *r200_makeX86Vertex3f( GLcontext *, const int * ); -struct dynfn *r200_makeX86Vertex3fv( GLcontext *, const int * ); -struct dynfn *r200_makeX86Color4ub( GLcontext *, const int * ); -struct dynfn *r200_makeX86Color4ubv( GLcontext *, const int * ); -struct dynfn *r200_makeX86Color3ub( GLcontext *, const int * ); -struct dynfn *r200_makeX86Color3ubv( GLcontext *, const int * ); -struct dynfn *r200_makeX86Color4f( GLcontext *, const int * ); -struct dynfn *r200_makeX86Color4fv( GLcontext *, const int * ); -struct dynfn *r200_makeX86Color3f( GLcontext *, const int * ); -struct dynfn *r200_makeX86Color3fv( GLcontext *, const int * ); -struct dynfn *r200_makeX86SecondaryColor3ubEXT( GLcontext *, const int * ); -struct dynfn *r200_makeX86SecondaryColor3ubvEXT( GLcontext *, const int * ); -struct dynfn *r200_makeX86SecondaryColor3fEXT( GLcontext *, const int * ); -struct dynfn *r200_makeX86SecondaryColor3fvEXT( GLcontext *, const int * ); -struct dynfn *r200_makeX86Normal3f( GLcontext *, const int * ); -struct dynfn *r200_makeX86Normal3fv( GLcontext *, const int * ); -struct dynfn *r200_makeX86TexCoord2f( GLcontext *, const int * ); -struct dynfn *r200_makeX86TexCoord2fv( GLcontext *, const int * ); -struct dynfn *r200_makeX86TexCoord1f( GLcontext *, const int * ); -struct dynfn *r200_makeX86TexCoord1fv( GLcontext *, const int * ); -struct dynfn *r200_makeX86MultiTexCoord2fARB( GLcontext *, const int * ); -struct dynfn *r200_makeX86MultiTexCoord2fvARB( GLcontext *, const int * ); -struct dynfn *r200_makeX86MultiTexCoord1fARB( GLcontext *, const int * ); -struct dynfn *r200_makeX86MultiTexCoord1fvARB( GLcontext *, const int * ); - -#endif diff --git a/src/mesa/drivers/dri/r200/r200_vtxfmt_c.c b/src/mesa/drivers/dri/r200/r200_vtxfmt_c.c deleted file mode 100644 index 1db5950c8f..0000000000 --- a/src/mesa/drivers/dri/r200/r200_vtxfmt_c.c +++ /dev/null @@ -1,1002 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_c.c,v 1.2 2002/12/16 16:18:56 dawes Exp $ */ -/* -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -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 (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 NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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 - */ - -#include "glheader.h" -#include "imports.h" -#include "mtypes.h" -#include "colormac.h" -#include "simple_list.h" -#include "api_noop.h" -#include "vtxfmt.h" - -#include "r200_vtxfmt.h" -#include "r200_tcl.h" - -#include "dispatch.h" - -/* Fallback versions of all the entrypoints for situations where - * codegen isn't available. This is still a lot faster than the - * vb/pipeline implementation in Mesa. - */ -static void r200_Vertex3f( GLfloat x, GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - int i; - - *rmesa->vb.dmaptr++ = *(int *)&x; - *rmesa->vb.dmaptr++ = *(int *)&y; - *rmesa->vb.dmaptr++ = *(int *)&z; - - for (i = 3; i < rmesa->vb.vertex_size; i++) - *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i; - - if (--rmesa->vb.counter == 0) - rmesa->vb.notify(); -} - - -static void r200_Vertex3fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - int i; - - *rmesa->vb.dmaptr++ = *(int *)&v[0]; - *rmesa->vb.dmaptr++ = *(int *)&v[1]; - *rmesa->vb.dmaptr++ = *(int *)&v[2]; - - for (i = 3; i < rmesa->vb.vertex_size; i++) - *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i; - - if (--rmesa->vb.counter == 0) - rmesa->vb.notify(); -} - - -static void r200_Vertex2f( GLfloat x, GLfloat y ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - int i; - - *rmesa->vb.dmaptr++ = *(int *)&x; - *rmesa->vb.dmaptr++ = *(int *)&y; - *rmesa->vb.dmaptr++ = 0; - - for (i = 3; i < rmesa->vb.vertex_size; i++) - *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i; - - if (--rmesa->vb.counter == 0) - rmesa->vb.notify(); -} - - -static void r200_Vertex2fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - int i; - - *rmesa->vb.dmaptr++ = *(int *)&v[0]; - *rmesa->vb.dmaptr++ = *(int *)&v[1]; - *rmesa->vb.dmaptr++ = 0; - - for (i = 3; i < rmesa->vb.vertex_size; i++) - *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i; - - if (--rmesa->vb.counter == 0) - rmesa->vb.notify(); -} - - - -/* Color for ubyte (packed) color formats: - */ -#if 0 -static void r200_Color3ub_ub( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.colorptr; - dest->red = r; - dest->green = g; - dest->blue = b; - dest->alpha = 0xff; -} - -static void r200_Color3ubv_ub( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.colorptr; - dest->red = v[0]; - dest->green = v[1]; - dest->blue = v[2]; - dest->alpha = 0xff; -} - -static void r200_Color4ub_ub( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.colorptr; - dest->red = r; - dest->green = g; - dest->blue = b; - dest->alpha = a; -} - -static void r200_Color4ubv_ub( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - *(GLuint *)rmesa->vb.colorptr = LE32_TO_CPU(*(GLuint *)v); -} -#endif /* 0 */ - -static void r200_Color3f_ub( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.colorptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); - dest->alpha = 255; -} - -static void r200_Color3fv_ub( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.colorptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); - dest->alpha = 255; -} - -static void r200_Color4f_ub( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.colorptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, a ); -} - -static void r200_Color4fv_ub( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.colorptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, v[3] ); -} - - -/* Color for float color+alpha formats: - */ -#if 0 -static void r200_Color3ub_4f( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); - dest[3] = 1.0; -} - -static void r200_Color3ubv_4f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); - dest[3] = 1.0; -} - -static void r200_Color4ub_4f( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); - dest[3] = UBYTE_TO_FLOAT(a); -} - -static void r200_Color4ubv_4f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); - dest[3] = UBYTE_TO_FLOAT(v[3]); -} -#endif /* 0 */ - - -static void r200_Color3f_4f( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; - dest[3] = 1.0; -} - -static void r200_Color3fv_4f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - dest[3] = 1.0; -} - -static void r200_Color4f_4f( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; - dest[3] = a; -} - -static void r200_Color4fv_4f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - dest[3] = v[3]; -} - - -/* Color for float color formats: - */ -#if 0 -static void r200_Color3ub_3f( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); -} - -static void r200_Color3ubv_3f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); -} - -static void r200_Color4ub_3f( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT(a); -} - -static void r200_Color4ubv_3f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT(v[3]); -} -#endif /* 0 */ - - -static void r200_Color3f_3f( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; -} - -static void r200_Color3fv_3f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; -} - -static void r200_Color4f_3f( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = a; -} - -static void r200_Color4fv_3f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = v[3]; -} - - -/* Secondary Color: - */ -#if 0 -static void r200_SecondaryColor3ubEXT_ub( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.specptr; - dest->red = r; - dest->green = g; - dest->blue = b; - dest->alpha = 0xff; -} - -static void r200_SecondaryColor3ubvEXT_ub( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.specptr; - dest->red = v[0]; - dest->green = v[1]; - dest->blue = v[2]; - dest->alpha = 0xff; -} -#endif /* 0 */ - -static void r200_SecondaryColor3fEXT_ub( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.specptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); - dest->alpha = 255; -} - -static void r200_SecondaryColor3fvEXT_ub( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.specptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); - dest->alpha = 255; -} - -#if 0 -static void r200_SecondaryColor3ubEXT_3f( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatspecptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); - dest[3] = 1.0; -} - -static void r200_SecondaryColor3ubvEXT_3f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatspecptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); - dest[3] = 1.0; -} -#endif /* 0 */ - -static void r200_SecondaryColor3fEXT_3f( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatspecptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; - dest[3] = 1.0; -} - -static void r200_SecondaryColor3fvEXT_3f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatspecptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - dest[3] = 1.0; -} - - - -/* Normal - */ -static void r200_Normal3f( GLfloat n0, GLfloat n1, GLfloat n2 ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.normalptr; - dest[0] = n0; - dest[1] = n1; - dest[2] = n2; -} - -static void r200_Normal3fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.normalptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; -} - - -/* FogCoord - */ -static void r200_FogCoordfEXT( GLfloat f ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.fogptr; - dest[0] = r200ComputeFogBlendFactor( ctx, f ); -/* ctx->Current.Attrib[VERT_ATTRIB_FOG][0] = f;*/ -} - -static void r200_FogCoordfvEXT( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.fogptr; - dest[0] = r200ComputeFogBlendFactor( ctx, v[0] ); -/* ctx->Current.Attrib[VERT_ATTRIB_FOG][0] = v[0];*/ -} - - -/* TexCoord - */ - -/* \todo maybe (target & 4 ? target & 5 : target & 3) is more save than (target & 7) */ -static void r200_MultiTexCoord1fARB(GLenum target, GLfloat s) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLint unit = (target & 7); - GLfloat * const dest = rmesa->vb.texcoordptr[unit]; - - switch( ctx->Texture.Unit[unit]._ReallyEnabled ) { - case TEXTURE_CUBE_BIT: - case TEXTURE_3D_BIT: - dest[2] = 0.0; - /* FALLTHROUGH */ - case TEXTURE_2D_BIT: - case TEXTURE_RECT_BIT: - dest[1] = 0.0; - /* FALLTHROUGH */ - case TEXTURE_1D_BIT: - dest[0] = s; - } -} - -static void r200_MultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLint unit = (target & 7); - GLfloat * const dest = rmesa->vb.texcoordptr[unit]; - - switch( ctx->Texture.Unit[unit]._ReallyEnabled ) { - case TEXTURE_CUBE_BIT: - case TEXTURE_3D_BIT: - dest[2] = 0.0; - /* FALLTHROUGH */ - case TEXTURE_2D_BIT: - case TEXTURE_RECT_BIT: - dest[1] = t; - dest[0] = s; - break; - default: - VFMT_FALLBACK(__FUNCTION__); - CALL_MultiTexCoord2fARB(GET_DISPATCH(), (target, s, t)); - return; - } -} - -static void r200_MultiTexCoord3fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLint unit = (target & 7); - GLfloat * const dest = rmesa->vb.texcoordptr[unit]; - - switch( ctx->Texture.Unit[unit]._ReallyEnabled ) { - case TEXTURE_CUBE_BIT: - case TEXTURE_3D_BIT: - dest[2] = r; - dest[1] = t; - dest[0] = s; - break; - default: - VFMT_FALLBACK(__FUNCTION__); - CALL_MultiTexCoord3fARB(GET_DISPATCH(), (target, s, t, r)); - return; - } -} - -static void r200_TexCoord1f(GLfloat s) -{ - r200_MultiTexCoord1fARB(GL_TEXTURE0, s); -} - -static void r200_TexCoord2f(GLfloat s, GLfloat t) -{ - r200_MultiTexCoord2fARB(GL_TEXTURE0, s, t); -} - -static void r200_TexCoord3f(GLfloat s, GLfloat t, GLfloat r) -{ - r200_MultiTexCoord3fARB(GL_TEXTURE0, s, t, r); -} - -static void r200_TexCoord1fv(const GLfloat *v) -{ - r200_MultiTexCoord1fARB(GL_TEXTURE0, v[0]); -} - -static void r200_TexCoord2fv(const GLfloat *v) -{ - r200_MultiTexCoord2fARB(GL_TEXTURE0, v[0], v[1]); -} - -static void r200_TexCoord3fv(const GLfloat *v) -{ - r200_MultiTexCoord3fARB(GL_TEXTURE0, v[0], v[1], v[2]); -} - -static void r200_MultiTexCoord1fvARB(GLenum target, const GLfloat *v) -{ - r200_MultiTexCoord1fARB(target, v[0]); -} - -static void r200_MultiTexCoord2fvARB(GLenum target, const GLfloat *v) -{ - r200_MultiTexCoord2fARB(target, v[0], v[1]); -} - -static void r200_MultiTexCoord3fvARB(GLenum target, const GLfloat *v) -{ - r200_MultiTexCoord3fARB(target, v[0], v[1], v[2]); -} - - -static struct dynfn *lookup( struct dynfn *l, const int *key ) -{ - struct dynfn *f; - - foreach( f, l ) { - if (f->key[0] == key[0] && f->key[1] == key[1]) - return f; - } - - return NULL; -} - -/* Can't use the loopback template for this: - */ - -#define CHOOSE(FN, FNTYPE, MASK0, MASK1, ARGS1, ARGS2 ) \ -static void choose_##FN ARGS1 \ -{ \ - GET_CURRENT_CONTEXT(ctx); \ - r200ContextPtr rmesa = R200_CONTEXT(ctx); \ - int key[2]; \ - struct dynfn *dfn; \ - \ - key[0] = rmesa->vb.vtxfmt_0 & MASK0; \ - key[1] = rmesa->vb.vtxfmt_1 & MASK1; \ - \ - dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \ - if (dfn == 0) \ - dfn = rmesa->vb.codegen.FN( ctx, key ); \ - else if (R200_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- cached codegen\n", __FUNCTION__ ); \ - \ - if (dfn) \ - SET_ ## FN (ctx->Exec, (FNTYPE)(dfn->code)); \ - else { \ - if (R200_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \ - SET_ ## FN (ctx->Exec, r200_##FN); \ - } \ - \ - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \ - CALL_ ## FN (ctx->Exec, ARGS2); \ -} - - - -/* For the _3f case, only allow one color function to be hooked in at - * a time. Eventually, use a similar mechanism to allow selecting the - * color component of the vertex format based on client behaviour. - * - * Note: Perform these actions even if there is a codegen or cached - * codegen version of the chosen function. - */ -#define CHOOSE_COLOR(FN, FNTYPE, NR, MASK0, MASK1, ARGS1, ARGS2 ) \ -static void choose_##FN ARGS1 \ -{ \ - GET_CURRENT_CONTEXT(ctx); \ - r200ContextPtr rmesa = R200_CONTEXT(ctx); \ - int key[2]; \ - struct dynfn *dfn; \ - \ - key[0] = rmesa->vb.vtxfmt_0 & MASK0; \ - key[1] = rmesa->vb.vtxfmt_1 & MASK1; \ - \ - if (VTX_COLOR(rmesa->vb.vtxfmt_0,0) == R200_VTX_PK_RGBA) { \ - SET_ ## FN (ctx->Exec, r200_##FN##_ub); \ - } \ - else if (VTX_COLOR(rmesa->vb.vtxfmt_0,0) == R200_VTX_FP_RGB) { \ - \ - if (rmesa->vb.installed_color_3f_sz != NR) { \ - rmesa->vb.installed_color_3f_sz = NR; \ - if (NR == 3) ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = 1.0; \ - if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) { \ - r200_copy_to_current( ctx ); \ - _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); \ - CALL_ ## FN (ctx->Exec, ARGS2); \ - return; \ - } \ - } \ - \ - SET_ ## FN (ctx->Exec, r200_##FN##_3f); \ - } \ - else { \ - SET_ ## FN (ctx->Exec, r200_##FN##_4f); \ - } \ - \ - \ - dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \ - if (!dfn) dfn = rmesa->vb.codegen.FN( ctx, key ); \ - \ - if (dfn) { \ - if (R200_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- codegen version\n", __FUNCTION__ ); \ - SET_ ## FN (ctx->Exec, (FNTYPE)dfn->code); \ - } \ - else if (R200_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- 'c' version\n", __FUNCTION__ ); \ - \ - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \ - CALL_ ## FN (ctx->Exec, ARGS2); \ -} - - - -/* Right now there are both _ub and _3f versions of the secondary color - * functions. Currently, we only set-up the hardware to use the _ub versions. - * The _3f versions are needed for the cases where secondary color isn't used - * in the vertex format, but it still needs to be stored in the context - * state vector. - */ -#define CHOOSE_SECONDARY_COLOR(FN, FNTYPE, MASK0, MASK1, ARGS1, ARGS2 ) \ -static void choose_##FN ARGS1 \ -{ \ - GET_CURRENT_CONTEXT(ctx); \ - r200ContextPtr rmesa = R200_CONTEXT(ctx); \ - int key[2]; \ - struct dynfn *dfn; \ - \ - key[0] = rmesa->vb.vtxfmt_0 & MASK0; \ - key[1] = rmesa->vb.vtxfmt_1 & MASK1; \ - \ - dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \ - if (dfn == 0) \ - dfn = rmesa->vb.codegen.FN( ctx, key ); \ - else if (R200_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- cached version\n", __FUNCTION__ ); \ - \ - if (dfn) \ - SET_ ## FN (ctx->Exec, (FNTYPE)(dfn->code)); \ - else { \ - if (R200_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \ - SET_ ## FN (ctx->Exec, (VTX_COLOR(rmesa->vb.vtxfmt_0,1) == R200_VTX_PK_RGBA) \ - ? r200_##FN##_ub : r200_##FN##_3f); \ - } \ - \ - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \ - CALL_ ## FN (ctx->Exec, ARGS2); \ -} - - - - - - - -/* VTXFMT_0 - */ -#define MASK_XYZW (R200_VTX_W0|R200_VTX_Z0) -#define MASK_NORM (MASK_XYZW|R200_VTX_N0) -#define MASK_FOG (MASK_NORM |R200_VTX_DISCRETE_FOG) -#define MASK_COLOR (MASK_FOG |(R200_VTX_COLOR_MASK<Color3f = choose_Color3f; - vfmt->Color3fv = choose_Color3fv; - vfmt->Color4f = choose_Color4f; - vfmt->Color4fv = choose_Color4fv; - vfmt->SecondaryColor3fEXT = choose_SecondaryColor3fEXT; - vfmt->SecondaryColor3fvEXT = choose_SecondaryColor3fvEXT; - vfmt->MultiTexCoord1fARB = choose_MultiTexCoord1fARB; - vfmt->MultiTexCoord1fvARB = choose_MultiTexCoord1fvARB; - vfmt->MultiTexCoord2fARB = choose_MultiTexCoord2fARB; - vfmt->MultiTexCoord2fvARB = choose_MultiTexCoord2fvARB; - vfmt->MultiTexCoord3fARB = choose_MultiTexCoord3fARB; - vfmt->MultiTexCoord3fvARB = choose_MultiTexCoord3fvARB; - vfmt->Normal3f = choose_Normal3f; - vfmt->Normal3fv = choose_Normal3fv; - vfmt->TexCoord1f = choose_TexCoord1f; - vfmt->TexCoord1fv = choose_TexCoord1fv; - vfmt->TexCoord2f = choose_TexCoord2f; - vfmt->TexCoord2fv = choose_TexCoord2fv; - vfmt->TexCoord3f = choose_TexCoord3f; - vfmt->TexCoord3fv = choose_TexCoord3fv; - vfmt->Vertex2f = choose_Vertex2f; - vfmt->Vertex2fv = choose_Vertex2fv; - vfmt->Vertex3f = choose_Vertex3f; - vfmt->Vertex3fv = choose_Vertex3fv; -/* vfmt->FogCoordfEXT = choose_FogCoordfEXT; - vfmt->FogCoordfvEXT = choose_FogCoordfvEXT;*/ - - /* TODO: restore ubyte colors to vtxfmt. - */ -#if 0 - vfmt->Color3ub = choose_Color3ub; - vfmt->Color3ubv = choose_Color3ubv; - vfmt->Color4ub = choose_Color4ub; - vfmt->Color4ubv = choose_Color4ubv; - vfmt->SecondaryColor3ubEXT = choose_SecondaryColor3ubEXT; - vfmt->SecondaryColor3ubvEXT = choose_SecondaryColor3ubvEXT; -#endif -} - - -static struct dynfn *codegen_noop( GLcontext *ctx, const int *key ) -{ - (void) ctx; (void) key; - return NULL; -} - -void r200InitCodegen( struct dfn_generators *gen, GLboolean useCodegen ) -{ - gen->Vertex3f = codegen_noop; - gen->Vertex3fv = codegen_noop; - gen->Color4ub = codegen_noop; - gen->Color4ubv = codegen_noop; - gen->Normal3f = codegen_noop; - gen->Normal3fv = codegen_noop; - - gen->TexCoord3f = codegen_noop; - gen->TexCoord3fv = codegen_noop; - gen->TexCoord2f = codegen_noop; - gen->TexCoord2fv = codegen_noop; - gen->TexCoord1f = codegen_noop; - gen->TexCoord1fv = codegen_noop; - - gen->MultiTexCoord3fARB = codegen_noop; - gen->MultiTexCoord3fvARB = codegen_noop; - gen->MultiTexCoord2fARB = codegen_noop; - gen->MultiTexCoord2fvARB = codegen_noop; - gen->MultiTexCoord1fARB = codegen_noop; - gen->MultiTexCoord1fvARB = codegen_noop; -/* gen->FogCoordfEXT = codegen_noop; - gen->FogCoordfvEXT = codegen_noop;*/ - - gen->Vertex2f = codegen_noop; - gen->Vertex2fv = codegen_noop; - gen->Color3ub = codegen_noop; - gen->Color3ubv = codegen_noop; - gen->Color4f = codegen_noop; - gen->Color4fv = codegen_noop; - gen->Color3f = codegen_noop; - gen->Color3fv = codegen_noop; - gen->SecondaryColor3fEXT = codegen_noop; - gen->SecondaryColor3fvEXT = codegen_noop; - gen->SecondaryColor3ubEXT = codegen_noop; - gen->SecondaryColor3ubvEXT = codegen_noop; - - if (useCodegen) { -#if defined(USE_X86_ASM) - r200InitX86Codegen( gen ); -#endif - -#if defined(USE_SSE_ASM) - r200InitSSECodegen( gen ); -#endif - } -} diff --git a/src/mesa/drivers/dri/r200/r200_vtxfmt_sse.c b/src/mesa/drivers/dri/r200/r200_vtxfmt_sse.c deleted file mode 100644 index 5901730494..0000000000 --- a/src/mesa/drivers/dri/r200/r200_vtxfmt_sse.c +++ /dev/null @@ -1,234 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_sse.c,v 1.1 2002/10/30 12:51:53 alanh Exp $ */ -/* -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -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 (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 NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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 - */ - -#include "glheader.h" -#include "imports.h" -#include "simple_list.h" -#include "r200_vtxfmt.h" - -#if defined(USE_SSE_ASM) -#include "x86/common_x86_asm.h" - -#define EXTERN( FUNC ) \ -extern const char *FUNC; \ -extern const char *FUNC##_end - -EXTERN( _sse_Attribute2fv ); -EXTERN( _sse_Attribute2f ); -EXTERN( _sse_Attribute3fv ); -EXTERN( _sse_Attribute3f ); -EXTERN( _sse_MultiTexCoord2fv ); -EXTERN( _sse_MultiTexCoord2f ); -EXTERN( _sse_MultiTexCoord2fv_2 ); -EXTERN( _sse_MultiTexCoord2f_2 ); - -/* Build specialized versions of the immediate calls on the fly for - * the current state. - */ - -static struct dynfn *r200_makeSSEAttribute2fv( struct dynfn * cache, const int * key, - const char * name, void * dest) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key[0] ); - - DFN ( _sse_Attribute2fv, (*cache) ); - FIXUP(dfn->code, 10, 0x0, (int)dest); - return dfn; -} - -static struct dynfn *r200_makeSSEAttribute2f( struct dynfn * cache, const int * key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key[0] ); - - DFN ( _sse_Attribute2f, (*cache) ); - FIXUP(dfn->code, 8, 0x0, (int)dest); - return dfn; -} - -static struct dynfn *r200_makeSSEAttribute3fv( struct dynfn * cache, const int * key, - const char * name, void * dest) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key[0] ); - - DFN ( _sse_Attribute3fv, (*cache) ); - FIXUP(dfn->code, 13, 0x0, (int)dest); - FIXUP(dfn->code, 18, 0x8, 8+(int)dest); - return dfn; -} - -static struct dynfn *r200_makeSSEAttribute3f( struct dynfn * cache, const int * key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key[0] ); - - DFN ( _sse_Attribute3f, (*cache) ); - FIXUP(dfn->code, 12, 0x0, (int)dest); - FIXUP(dfn->code, 17, 0x8, 8+(int)dest); - return dfn; -} - -static struct dynfn *r200_makeSSENormal3fv( GLcontext *ctx, const int *key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeSSEAttribute3fv( & rmesa->vb.dfn_cache.Normal3fv, key, - __FUNCTION__, rmesa->vb.normalptr ); -} - -static struct dynfn *r200_makeSSENormal3f( GLcontext *ctx, const int * key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeSSEAttribute3f( & rmesa->vb.dfn_cache.Normal3f, key, - __FUNCTION__, rmesa->vb.normalptr ); -} - -static struct dynfn *r200_makeSSEColor3fv( GLcontext *ctx, const int * key ) -{ - if (VTX_COLOR(key[0],0) != R200_VTX_FP_RGB) - return NULL; - else - { - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeSSEAttribute3fv( & rmesa->vb.dfn_cache.Color3fv, key, - __FUNCTION__, rmesa->vb.floatcolorptr ); - } -} - -static struct dynfn *r200_makeSSEColor3f( GLcontext *ctx, const int * key ) -{ - if (VTX_COLOR(key[0],0) != R200_VTX_FP_RGB) - return NULL; - else - { - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeSSEAttribute3f( & rmesa->vb.dfn_cache.Color3f, key, - __FUNCTION__, rmesa->vb.floatcolorptr ); - } -} - -#if 0 /* Temporarily disabled as it is broken w/the new cubemap code. - idr */ -static struct dynfn *r200_makeSSETexCoord2fv( GLcontext *ctx, const int * key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeSSEAttribute2fv( & rmesa->vb.dfn_cache.TexCoord2fv, key, - __FUNCTION__, rmesa->vb.texcoordptr[0] ); -} - -static struct dynfn *r200_makeSSETexCoord2f( GLcontext *ctx, const int * key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeSSEAttribute2f( & rmesa->vb.dfn_cache.TexCoord2f, key, - __FUNCTION__, rmesa->vb.texcoordptr[0] ); -} - -static struct dynfn *r200_makeSSEMultiTexCoord2fv( GLcontext *ctx, const int * key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); - - if (rmesa->vb.texcoordptr[1] == rmesa->vb.texcoordptr[0]+4) { - DFN ( _sse_MultiTexCoord2fv, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - FIXUP(dfn->code, 18, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); - } else { - DFN ( _sse_MultiTexCoord2fv_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - FIXUP(dfn->code, 14, 0x0, (int)rmesa->vb.texcoordptr); - } - return dfn; -} - -static struct dynfn *r200_makeSSEMultiTexCoord2f( GLcontext *ctx, const int * key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); - - if (rmesa->vb.texcoordptr[1] == rmesa->vb.texcoordptr[0]+4) { - DFN ( _sse_MultiTexCoord2f, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - FIXUP(dfn->code, 16, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); - } else { - DFN ( _sse_MultiTexCoord2f_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - FIXUP(dfn->code, 15, 0x0, (int)rmesa->vb.texcoordptr); - } - return dfn; -} -#endif - -void r200InitSSECodegen( struct dfn_generators *gen ) -{ - if ( cpu_has_xmm ) { - gen->Normal3fv = (void *) r200_makeSSENormal3fv; - gen->Normal3f = (void *) r200_makeSSENormal3f; - gen->Color3fv = (void *) r200_makeSSEColor3fv; - gen->Color3f = (void *) r200_makeSSEColor3f; -#if 0 /* Temporarily disabled as it is broken w/the new cubemap code. - idr */ - gen->TexCoord2fv = (void *) r200_makeSSETexCoord2fv; - gen->TexCoord2f = (void *) r200_makeSSETexCoord2f; - gen->MultiTexCoord2fvARB = (void *) r200_makeSSEMultiTexCoord2fv; - gen->MultiTexCoord2fARB = (void *) r200_makeSSEMultiTexCoord2f; -#endif - } -} - -#else - -void r200InitSSECodegen( struct dfn_generators *gen ) -{ - (void) gen; -} - -#endif diff --git a/src/mesa/drivers/dri/r200/r200_vtxfmt_x86.c b/src/mesa/drivers/dri/r200/r200_vtxfmt_x86.c deleted file mode 100644 index b78a55c31f..0000000000 --- a/src/mesa/drivers/dri/r200/r200_vtxfmt_x86.c +++ /dev/null @@ -1,440 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_x86.c,v 1.2 2002/12/16 16:18:56 dawes Exp $ */ -/* -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -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 (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 NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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 - */ - -#include "glheader.h" -#include "imports.h" -#include "simple_list.h" -#include "r200_vtxfmt.h" - -#if defined(USE_X86_ASM) - -#define EXTERN( FUNC ) \ -extern const char *FUNC; \ -extern const char *FUNC##_end - -EXTERN ( _x86_Attribute2fv ); -EXTERN ( _x86_Attribute2f ); -EXTERN ( _x86_Attribute3fv ); -EXTERN ( _x86_Attribute3f ); -EXTERN ( _x86_Vertex3fv_6 ); -EXTERN ( _x86_Vertex3fv_8 ); -EXTERN ( _x86_Vertex3fv ); -EXTERN ( _x86_Vertex3f_4 ); -EXTERN ( _x86_Vertex3f_6 ); -EXTERN ( _x86_Vertex3f ); -EXTERN ( _x86_Color4ubv_ub ); -EXTERN ( _x86_Color4ubv_4f ); -EXTERN ( _x86_Color4ub_ub ); -EXTERN ( _x86_MultiTexCoord2fv ); -EXTERN ( _x86_MultiTexCoord2fv_2 ); -EXTERN ( _x86_MultiTexCoord2f ); -EXTERN ( _x86_MultiTexCoord2f_2 ); - - -/* Build specialized versions of the immediate calls on the fly for - * the current state. Generic x86 versions. - */ - -struct dynfn *r200_makeX86Vertex3f( GLcontext *ctx, const int *key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x 0x%08x %d\n", __FUNCTION__, - key[0], key[1], rmesa->vb.vertex_size ); - - switch (rmesa->vb.vertex_size) { - case 4: { - - DFN ( _x86_Vertex3f_4, rmesa->vb.dfn_cache.Vertex3f ); - FIXUP(dfn->code, 2, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 25, 0x0, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 36, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 46, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 51, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 60, 0x0, (int)&rmesa->vb.notify); - break; - } - case 6: { - - DFN ( _x86_Vertex3f_6, rmesa->vb.dfn_cache.Vertex3f ); - FIXUP(dfn->code, 3, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 28, 0x0, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 34, 0x0, (int)&rmesa->vb.vertex[4]); - FIXUP(dfn->code, 40, 0x0, (int)&rmesa->vb.vertex[5]); - FIXUP(dfn->code, 57, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 63, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 70, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 79, 0x0, (int)&rmesa->vb.notify); - break; - } - default: { - - DFN ( _x86_Vertex3f, rmesa->vb.dfn_cache.Vertex3f ); - FIXUP(dfn->code, 3, 0x0, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 9, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 37, 0x0, rmesa->vb.vertex_size-3); - FIXUP(dfn->code, 44, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 50, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 56, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 67, 0x0, (int)&rmesa->vb.notify); - break; - } - } - - return dfn; -} - - - -struct dynfn *r200_makeX86Vertex3fv( GLcontext *ctx, const int *key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x 0x%08x %d\n", __FUNCTION__, - key[0], key[1], rmesa->vb.vertex_size ); - - switch (rmesa->vb.vertex_size) { - case 6: { - - DFN ( _x86_Vertex3fv_6, rmesa->vb.dfn_cache.Vertex3fv ); - FIXUP(dfn->code, 1, 0x00000000, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 27, 0x0000001c, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 33, 0x00000020, (int)&rmesa->vb.vertex[4]); - FIXUP(dfn->code, 45, 0x00000024, (int)&rmesa->vb.vertex[5]); - FIXUP(dfn->code, 56, 0x00000000, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 61, 0x00000004, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 67, 0x00000004, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 76, 0x00000008, (int)&rmesa->vb.notify); - break; - } - - - case 8: { - - DFN ( _x86_Vertex3fv_8, rmesa->vb.dfn_cache.Vertex3fv ); - FIXUP(dfn->code, 1, 0x00000000, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 27, 0x0000001c, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 33, 0x00000020, (int)&rmesa->vb.vertex[4]); - FIXUP(dfn->code, 45, 0x0000001c, (int)&rmesa->vb.vertex[5]); - FIXUP(dfn->code, 51, 0x00000020, (int)&rmesa->vb.vertex[6]); - FIXUP(dfn->code, 63, 0x00000024, (int)&rmesa->vb.vertex[7]); - FIXUP(dfn->code, 74, 0x00000000, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 79, 0x00000004, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 85, 0x00000004, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 94, 0x00000008, (int)&rmesa->vb.notify); - break; - } - - - - default: { - - DFN ( _x86_Vertex3fv, rmesa->vb.dfn_cache.Vertex3fv ); - FIXUP(dfn->code, 8, 0x01010101, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 32, 0x00000006, rmesa->vb.vertex_size-3); - FIXUP(dfn->code, 37, 0x00000058, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 45, 0x01010101, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 50, 0x02020202, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 58, 0x02020202, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 67, 0x0, (int)&rmesa->vb.notify); - break; - } - } - - return dfn; -} - -static struct dynfn * -r200_makeX86Attribute2fv( struct dynfn * cache, const int *key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key[0] ); - - DFN ( _x86_Attribute2fv, (*cache) ); - FIXUP(dfn->code, 11, 0x0, (int)dest); - FIXUP(dfn->code, 16, 0x4, 4+(int)dest); - - return dfn; -} - -static struct dynfn * -r200_makeX86Attribute2f( struct dynfn * cache, const int *key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key[0] ); - - DFN ( _x86_Attribute2f, (*cache) ); - FIXUP(dfn->code, 1, 0x0, (int)dest); - - return dfn; -} - - -static struct dynfn * -r200_makeX86Attribute3fv( struct dynfn * cache, const int *key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key[0] ); - - DFN ( _x86_Attribute3fv, (*cache) ); - FIXUP(dfn->code, 14, 0x0, (int)dest); - FIXUP(dfn->code, 20, 0x4, 4+(int)dest); - FIXUP(dfn->code, 25, 0x8, 8+(int)dest); - - return dfn; -} - -static struct dynfn * -r200_makeX86Attribute3f( struct dynfn * cache, const int *key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key[0] ); - - DFN ( _x86_Attribute3f, (*cache) ); - FIXUP(dfn->code, 14, 0x0, (int)dest); - FIXUP(dfn->code, 20, 0x4, 4+(int)dest); - FIXUP(dfn->code, 25, 0x8, 8+(int)dest); - - return dfn; -} - -struct dynfn *r200_makeX86Normal3fv( GLcontext *ctx, const int *key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeX86Attribute3fv( & rmesa->vb.dfn_cache.Normal3fv, key, - __FUNCTION__, rmesa->vb.normalptr ); -} - -struct dynfn *r200_makeX86Normal3f( GLcontext *ctx, const int *key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeX86Attribute3f( & rmesa->vb.dfn_cache.Normal3f, key, - __FUNCTION__, rmesa->vb.normalptr ); -} - -struct dynfn *r200_makeX86Color4ubv( GLcontext *ctx, const int *key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); - - if (VTX_COLOR(key[0],0) == R200_VTX_PK_RGBA) { - DFN ( _x86_Color4ubv_ub, rmesa->vb.dfn_cache.Color4ubv); - FIXUP(dfn->code, 5, 0x12345678, (int)rmesa->vb.colorptr); - return dfn; - } - else { - - DFN ( _x86_Color4ubv_4f, rmesa->vb.dfn_cache.Color4ubv); - FIXUP(dfn->code, 2, 0x00000000, (int)_mesa_ubyte_to_float_color_tab); - FIXUP(dfn->code, 27, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr); - FIXUP(dfn->code, 33, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr+4); - FIXUP(dfn->code, 55, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr+8); - FIXUP(dfn->code, 61, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr+12); - return dfn; - } -} - -struct dynfn *r200_makeX86Color4ub( GLcontext *ctx, const int *key ) -{ - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); - - if (VTX_COLOR(key[0],0) == R200_VTX_PK_RGBA) { - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - DFN ( _x86_Color4ub_ub, rmesa->vb.dfn_cache.Color4ub ); - FIXUP(dfn->code, 18, 0x0, (int)rmesa->vb.colorptr); - FIXUP(dfn->code, 24, 0x0, (int)rmesa->vb.colorptr+1); - FIXUP(dfn->code, 30, 0x0, (int)rmesa->vb.colorptr+2); - FIXUP(dfn->code, 36, 0x0, (int)rmesa->vb.colorptr+3); - return dfn; - } - else - return NULL; -} - - -struct dynfn *r200_makeX86Color3fv( GLcontext *ctx, const int *key ) -{ - if (VTX_COLOR(key[0],0) != R200_VTX_FP_RGB) - return NULL; - else - { - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeX86Attribute3fv( & rmesa->vb.dfn_cache.Color3fv, key, - __FUNCTION__, rmesa->vb.floatcolorptr ); - } -} - -struct dynfn *r200_makeX86Color3f( GLcontext *ctx, const int *key ) -{ - if (VTX_COLOR(key[0],0) != R200_VTX_FP_RGB) - return NULL; - else - { - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeX86Attribute3f( & rmesa->vb.dfn_cache.Color3f, key, - __FUNCTION__, rmesa->vb.floatcolorptr ); - } -} - - - -#if 0 /* Temporarily disabled as it is broken w/the new cubemap code. - idr */ -struct dynfn *r200_makeX86TexCoord2fv( GLcontext *ctx, const int *key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeX86Attribute2fv( & rmesa->vb.dfn_cache.TexCoord2fv, key, - __FUNCTION__, rmesa->vb.texcoordptr[0] ); -} - -struct dynfn *r200_makeX86TexCoord2f( GLcontext *ctx, const int *key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeX86Attribute2f( & rmesa->vb.dfn_cache.TexCoord2f, key, - __FUNCTION__, rmesa->vb.texcoordptr[0] ); -} - -struct dynfn *r200_makeX86MultiTexCoord2fvARB( GLcontext *ctx, const int *key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x 0x%08x\n", __FUNCTION__, key[0], key[1] ); - - if (rmesa->vb.texcoordptr[1] == rmesa->vb.texcoordptr[0]+4) { - DFN ( _x86_MultiTexCoord2fv, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - FIXUP(dfn->code, 21, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); - FIXUP(dfn->code, 27, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]+4); - } else { - DFN ( _x86_MultiTexCoord2fv_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - FIXUP(dfn->code, 14, 0x0, (int)rmesa->vb.texcoordptr); - } - return dfn; -} - -struct dynfn *r200_makeX86MultiTexCoord2fARB( GLcontext *ctx, - const int *key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x 0x%08x\n", __FUNCTION__, key[0], key[1] ); - - if (rmesa->vb.texcoordptr[1] == rmesa->vb.texcoordptr[0]+4) { - DFN ( _x86_MultiTexCoord2f, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - FIXUP(dfn->code, 20, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); - FIXUP(dfn->code, 26, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]+4); - } - else { - /* Note: this might get generated multiple times, even though the - * actual emitted code is the same. - */ - DFN ( _x86_MultiTexCoord2f_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - FIXUP(dfn->code, 18, 0x0, (int)rmesa->vb.texcoordptr); - } - return dfn; -} -#endif - -void r200InitX86Codegen( struct dfn_generators *gen ) -{ - gen->Vertex3f = r200_makeX86Vertex3f; - gen->Vertex3fv = r200_makeX86Vertex3fv; - gen->Color4ub = r200_makeX86Color4ub; /* PKCOLOR only */ - gen->Color4ubv = r200_makeX86Color4ubv; /* PKCOLOR only */ - gen->Normal3f = r200_makeX86Normal3f; - gen->Normal3fv = r200_makeX86Normal3fv; -#if 0 /* Temporarily disabled as it is broken w/the new cubemap code. - idr */ - gen->TexCoord2f = r200_makeX86TexCoord2f; - gen->TexCoord2fv = r200_makeX86TexCoord2fv; - gen->MultiTexCoord2fARB = r200_makeX86MultiTexCoord2fARB; - gen->MultiTexCoord2fvARB = r200_makeX86MultiTexCoord2fvARB; -#endif - gen->Color3f = r200_makeX86Color3f; - gen->Color3fv = r200_makeX86Color3fv; - - /* Not done: - */ -/* gen->Vertex2f = r200_makeX86Vertex2f; */ -/* gen->Vertex2fv = r200_makeX86Vertex2fv; */ -/* gen->Color3ub = r200_makeX86Color3ub; */ -/* gen->Color3ubv = r200_makeX86Color3ubv; */ -/* gen->Color4f = r200_makeX86Color4f; */ -/* gen->Color4fv = r200_makeX86Color4fv; */ -/* gen->TexCoord1f = r200_makeX86TexCoord1f; */ -/* gen->TexCoord1fv = r200_makeX86TexCoord1fv; */ -/* gen->MultiTexCoord1fARB = r200_makeX86MultiTexCoord1fARB; */ -/* gen->MultiTexCoord1fvARB = r200_makeX86MultiTexCoord1fvARB; */ -} - - -#else - -void r200InitX86Codegen( struct dfn_generators *gen ) -{ - (void) gen; -} - -#endif diff --git a/src/mesa/drivers/dri/r200/r200_vtxtmp_x86.S b/src/mesa/drivers/dri/r200/r200_vtxtmp_x86.S deleted file mode 100644 index 5e33c7bdee..0000000000 --- a/src/mesa/drivers/dri/r200/r200_vtxtmp_x86.S +++ /dev/null @@ -1,499 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxtmp_x86.S,v 1.2 2002/11/07 18:31:59 tsi Exp $ */ -/************************************************************************** - -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 -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. - -**************************************************************************/ - -#define GLOBL( x ) \ -.globl x; \ -x: - -.data -.align 4 - -/* - vertex 3f vertex size 4 -*/ - -GLOBL ( _x86_Vertex3f_4 ) - movl (0), %ecx - movl 4(%esp), %eax - movl 8(%esp), %edx - movl %eax, (%ecx) - movl %edx, 4(%ecx) - movl 12(%esp), %eax - movl (0), %edx - movl %eax, 8(%ecx) - movl %edx, 12(%ecx) - movl (0), %eax - addl $16, %ecx - dec %eax - movl %ecx, (0) - movl %eax, (0) - je .1 - ret -.1: jmp *0 - -GLOBL ( _x86_Vertex3f_4_end ) - -/* - vertex 3f vertex size 6 -*/ -GLOBL ( _x86_Vertex3f_6 ) - push %edi - movl (0), %edi - movl 8(%esp), %eax - movl 12(%esp), %edx - movl 16(%esp), %ecx - movl %eax, (%edi) - movl %edx, 4(%edi) - movl %ecx, 8(%edi) - movl (0), %eax - movl (0), %edx - movl (0), %ecx - movl %eax, 12(%edi) - movl %edx, 16(%edi) - movl %ecx, 20(%edi) - addl $24, %edi - movl (0), %eax - movl %edi, (0) - dec %eax - pop %edi - movl %eax, (0) - je .2 - ret -.2: jmp *0 -GLOBL ( _x86_Vertex3f_6_end ) -/* - vertex 3f generic size -*/ -GLOBL ( _x86_Vertex3f ) - push %edi - push %esi - movl $0, %esi - movl (0), %edi - movl 12(%esp), %eax - movl 16(%esp), %edx - movl 20(%esp), %ecx - movl %eax, (%edi) - movl %edx, 4(%edi) - movl %ecx, 8(%edi) - addl $12, %edi - movl $0, %ecx - repz - movsl %ds:(%esi), %es:(%edi) - movl (0), %eax - movl %edi, (0) - dec %eax - movl %eax, (0) - pop %esi - pop %edi - je .3 - ret -.3: jmp *0 - -GLOBL ( _x86_Vertex3f_end ) - -/* - Vertex 3fv vertex size 6 -*/ -GLOBL ( _x86_Vertex3fv_6 ) - movl (0), %eax - movl 4(%esp), %ecx - movl (%ecx), %edx - movl %edx, (%eax) - movl 4(%ecx), %edx - movl 8(%ecx), %ecx - movl %edx, 4(%eax) - movl %ecx, 8(%eax) - movl (28), %edx - movl (32), %ecx - movl %edx, 12(%eax) - movl %ecx, 16(%eax) - movl (36), %edx - movl %edx, 20(%eax) - addl $24, %eax - movl %eax, 0 - movl 4, %eax - dec %eax - movl %eax, 4 - je .4 - ret -.4: jmp *8 - -GLOBL ( _x86_Vertex3fv_6_end ) - -/* - Vertex 3fv vertex size 8 -*/ -GLOBL ( _x86_Vertex3fv_8 ) - movl (0), %eax - movl 4(%esp), %ecx - movl (%ecx), %edx - movl %edx ,(%eax) - movl 4(%ecx) ,%edx - movl 8(%ecx) ,%ecx - movl %edx, 4(%eax) - movl %ecx, 8(%eax) - movl (28), %edx - movl (32), %ecx - movl %edx, 12(%eax) - movl %ecx, 16(%eax) - movl (28), %edx - movl (32), %ecx - movl %edx, 20(%eax) - movl %ecx, 24(%eax) - movl (36), %edx - movl %edx, 28(%eax) - addl $32, %eax - movl %eax, (0) - movl 4, %eax - dec %eax - movl %eax, (4) - je .5 - ret -.5: jmp *8 - -GLOBL ( _x86_Vertex3fv_8_end ) - -/* - Vertex 3fv generic vertex size -*/ -GLOBL ( _x86_Vertex3fv ) - movl 4(%esp), %edx - push %edi - push %esi - movl (0x1010101), %edi - movl (%edx), %eax - movl 4(%edx), %ecx - movl 8(%edx), %esi - movl %eax, (%edi) - movl %ecx, 4(%edi) - movl %esi, 8(%edi) - addl $12, %edi - movl $6, %ecx - movl $0x58, %esi - repz - movsl %ds:(%esi), %es:(%edi) - movl %edi, (0x1010101) - movl (0x2020202), %eax - pop %esi - pop %edi - dec %eax - movl %eax, (0x2020202) - je .6 - ret -.6: jmp *0 -GLOBL ( _x86_Vertex3fv_end ) - - -/** - * Generic handler for 2 float format data. This can be used for - * TexCoord2f and possibly other functions. - */ - -GLOBL ( _x86_Attribute2f ) - movl $0x0, %edx - movl 4(%esp), %eax - movl 8(%esp), %ecx - movl %eax, (%edx) - movl %ecx, 4(%edx) - ret -GLOBL ( _x86_Attribute2f_end ) - - -/** - * Generic handler for 2 float vector format data. This can be used for - * TexCoord2fv and possibly other functions. - */ - -GLOBL( _x86_Attribute2fv) - movl 4(%esp), %eax /* load 'v' off stack */ - movl (%eax), %ecx /* load v[0] */ - movl 4(%eax), %eax /* load v[1] */ - movl %ecx, 0 /* store v[0] to current vertex */ - movl %eax, 4 /* store v[1] to current vertex */ - ret -GLOBL ( _x86_Attribute2fv_end ) - - -/** - * Generic handler for 3 float format data. This can be used for - * Normal3f, Color3f (when the color target is also float), or - * TexCoord3f. - */ - -GLOBL ( _x86_Attribute3f ) - movl 4(%esp), %ecx - movl 8(%esp), %edx - movl 12(%esp), %eax - movl %ecx, 0 - movl %edx, 4 - movl %eax, 8 - ret -GLOBL ( _x86_Attribute3f_end ) - -/** - * Generic handler for 3 float vector format data. This can be used for - * Normal3f, Color3f (when the color target is also float), or - * TexCoord3f. - */ - -GLOBL( _x86_Attribute3fv) - movl 4(%esp), %eax /* load 'v' off stack */ - movl (%eax), %ecx /* load v[0] */ - movl 4(%eax), %edx /* load v[1] */ - movl 8(%eax), %eax /* load v[2] */ - movl %ecx, 0 /* store v[0] to current vertex */ - movl %edx, 4 /* store v[1] to current vertex */ - movl %eax, 8 /* store v[2] to current vertex */ - ret -GLOBL ( _x86_Attribute3fv_end ) - - -/* - Color 4ubv_ub -*/ -GLOBL ( _x86_Color4ubv_ub ) - movl 4(%esp), %eax - movl $0x12345678, %edx - movl (%eax), %eax - movl %eax, (%edx) - ret -GLOBL ( _x86_Color4ubv_ub_end ) - -/* - Color 4ubv 4f -*/ -GLOBL ( _x86_Color4ubv_4f ) - push %ebx - movl $0, %edx - xor %eax, %eax - xor %ecx, %ecx - movl 8(%esp), %ebx - movl (%ebx), %ebx - mov %bl, %al - mov %bh, %cl - movl (%edx,%eax,4),%eax - movl (%edx,%ecx,4),%ecx - movl %eax, (0xdeadbeaf) - movl %ecx, (0xdeadbeaf) - xor %eax, %eax - xor %ecx, %ecx - shr $16, %ebx - mov %bl, %al - mov %bh, %cl - movl (%edx,%eax,4), %eax - movl (%edx,%ecx,4), %ecx - movl %eax, (0xdeadbeaf) - movl %ecx, (0xdeadbeaf) - pop %ebx - ret -GLOBL ( _x86_Color4ubv_4f_end ) - -/* - - Color4ub_ub -*/ -GLOBL( _x86_Color4ub_ub ) - push %ebx - movl 8(%esp), %eax - movl 12(%esp), %edx - movl 16(%esp), %ecx - movl 20(%esp), %ebx - mov %al, (0) - mov %dl, (0) - mov %cl, (0) - mov %bl, (0) - pop %ebx - ret -GLOBL( _x86_Color4ub_ub_end ) - - -/* \todo: change the "and $7, %eax" to something like "target & 4 ? target & 5 : target & 3)" */ -/* - MultiTexCoord2fv st0/st1 -*/ -GLOBL( _x86_MultiTexCoord2fv ) - movl 4(%esp), %eax - movl 8(%esp), %ecx - and $7, %eax - movl (%ecx), %edx - shl $3, %eax - movl 4(%ecx), %ecx - movl %edx, 0xdeadbeef(%eax) - movl %ecx, 0xdeadbeef(%eax) - ret -GLOBL( _x86_MultiTexCoord2fv_end ) - -/* - MultiTexCoord2fv -*/ - -GLOBL( _x86_MultiTexCoord2fv_2 ) - movl 4(%esp,1), %eax - movl 8(%esp,1), %ecx - and $0x7, %eax - movl 0(,%eax,4), %edx - movl (%ecx), %eax - movl %eax, (%edx) - movl 4(%ecx), %eax - movl %eax, 4(%edx) - ret -GLOBL( _x86_MultiTexCoord2fv_2_end ) - -/* - MultiTexCoord2f st0/st1 -*/ -GLOBL( _x86_MultiTexCoord2f ) - movl 4(%esp), %eax - movl 8(%esp), %edx - movl 12(%esp), %ecx - and $7, %eax - shl $3, %eax - movl %edx, 0xdeadbeef(%eax) - movl %ecx, 0xdeadbeef(%eax) - ret -GLOBL( _x86_MultiTexCoord2f_end ) - -/* - MultiTexCoord2f -*/ -GLOBL( _x86_MultiTexCoord2f_2 ) - movl 4(%esp), %eax - movl 8(%esp), %edx - movl 12(%esp,1), %ecx - and $7,%eax - movl 0(,%eax,4), %eax - movl %edx, (%eax) - movl %ecx, 4(%eax) - ret -GLOBL( _x86_MultiTexCoord2f_2_end ) - -#if defined(USE_SSE_ASM) -/** - * This can be used as a template for either Color3fv (when the color - * target is also a 3f) or Normal3fv. - */ - -GLOBL( _sse_Attribute3fv ) - movl 4(%esp), %eax - movlps (%eax), %xmm0 - movl 8(%eax), %eax - movlps %xmm0, 0 - movl %eax, 8 - ret -GLOBL( _sse_Attribute3fv_end ) - -/** - * This can be used as a template for either Color3f (when the color - * target is also a 3f) or Normal3f. - */ - -GLOBL( _sse_Attribute3f ) - movlps 4(%esp), %xmm0 - movl 12(%esp), %eax - movlps %xmm0, 0 - movl %eax, 8 - ret -GLOBL( _sse_Attribute3f_end ) - - -/** - * Generic handler for 2 float vector format data. This can be used for - * TexCoord2fv and possibly other functions. - */ - -GLOBL( _sse_Attribute2fv ) - movl 4(%esp), %eax - movlps (%eax), %xmm0 - movlps %xmm0, 0 - ret -GLOBL( _sse_Attribute2fv_end ) - - -/** - * Generic handler for 2 float format data. This can be used for - * TexCoord2f and possibly other functions. - */ - -GLOBL( _sse_Attribute2f ) - movlps 4(%esp), %xmm0 - movlps %xmm0, 0 - ret -GLOBL( _sse_Attribute2f_end ) - -/* - MultiTexCoord2fv st0/st1 -*/ -GLOBL( _sse_MultiTexCoord2fv ) - movl 4(%esp), %eax - movl 8(%esp), %ecx - and $7, %eax - movlps (%ecx), %xmm0 - movlps %xmm0, 0xdeadbeef(,%eax,8) - ret -GLOBL( _sse_MultiTexCoord2fv_end ) - -/* - MultiTexCoord2fv -*/ -GLOBL( _sse_MultiTexCoord2fv_2 ) - movl 4(%esp), %eax - movl 8(%esp), %ecx - and $0x7, %eax - movl 0(,%eax,4), %edx - movlps (%ecx), %xmm0 - movlps %xmm0, (%edx) - ret -GLOBL( _sse_MultiTexCoord2fv_2_end ) - -/* - MultiTexCoord2f st0/st1 -*/ -GLOBL( _sse_MultiTexCoord2f ) - movl 4(%esp), %eax - and $7, %eax - movlps 8(%esp), %xmm0 - movlps %xmm0, 0xdeadbeef(,%eax,8) - ret -GLOBL( _sse_MultiTexCoord2f_end ) - -/* - MultiTexCoord2f -*/ -GLOBL( _sse_MultiTexCoord2f_2 ) - movl 4(%esp), %eax - movlps 8(%esp), %xmm0 - and $7,%eax - movl 0(,%eax,4), %eax - movlps %xmm0, (%eax) - ret -GLOBL( _sse_MultiTexCoord2f_2_end ) -#endif - -#if defined (__ELF__) && defined (__linux__) - .section .note.GNU-stack,"",%progbits -#endif diff --git a/src/mesa/drivers/dri/radeon/Makefile b/src/mesa/drivers/dri/radeon/Makefile index 6e46620b39..f223b2d922 100644 --- a/src/mesa/drivers/dri/radeon/Makefile +++ b/src/mesa/drivers/dri/radeon/Makefile @@ -22,11 +22,7 @@ DRIVER_SOURCES = \ radeon_swtcl.c \ radeon_span.c \ radeon_maos.c \ - radeon_sanity.c \ - radeon_vtxfmt.c \ - radeon_vtxfmt_c.c \ - radeon_vtxfmt_sse.c \ - radeon_vtxfmt_x86.c + radeon_sanity.c C_SOURCES = \ $(COMMON_SOURCES) \ @@ -34,8 +30,7 @@ C_SOURCES = \ DRIVER_DEFINES = -DRADEON_COMMON=0 -X86_SOURCES = \ - radeon_vtxtmp_x86.S +X86_SOURCES = include ../Makefile.template diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index e4dcc96466..8845881e3f 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -46,7 +46,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -60,7 +60,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_tex.h" #include "radeon_swtcl.h" #include "radeon_tcl.h" -#include "radeon_vtxfmt.h" #include "radeon_maos.h" #define need_GL_ARB_multisample @@ -362,7 +361,7 @@ radeonCreateContext( const __GLcontextModes *glVisual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); _ae_create_context( ctx ); @@ -371,13 +370,10 @@ radeonCreateContext( const __GLcontextModes *glVisual, */ _tnl_destroy_pipeline( ctx ); _tnl_install_pipeline( ctx, radeon_pipeline ); - ctx->Driver.FlushVertices = radeonFlushVertices; /* Try and keep materials and vertices separate: */ - _tnl_isolate_materials( ctx, GL_TRUE ); - -/* _mesa_allow_light_in_model( ctx, GL_FALSE ); */ +/* _tnl_isolate_materials( ctx, GL_TRUE ); */ /* Configure swrast and T&L to match hardware characteristics: */ @@ -451,10 +447,7 @@ radeonCreateContext( const __GLcontextModes *glVisual, } if (rmesa->radeonScreen->chip_flags & RADEON_CHIPSET_TCL) { - if (tcl_mode >= DRI_CONF_TCL_VTXFMT) - radeonVtxfmtInit( ctx, tcl_mode >= DRI_CONF_TCL_CODEGEN ); - - _tnl_need_dlist_norm_lengths( ctx, GL_FALSE ); +/* _tnl_need_dlist_norm_lengths( ctx, GL_FALSE ); */ } return GL_TRUE; } @@ -485,7 +478,7 @@ void radeonDestroyContext( __DRIcontextPrivate *driContextPriv ) release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1); _swsetup_DestroyContext( rmesa->glCtx ); _tnl_DestroyContext( rmesa->glCtx ); - _ac_DestroyContext( rmesa->glCtx ); + _vbo_DestroyContext( rmesa->glCtx ); _swrast_DestroyContext( rmesa->glCtx ); radeonDestroySwtcl( rmesa->glCtx ); @@ -495,12 +488,6 @@ void radeonDestroyContext( __DRIcontextPrivate *driContextPriv ) radeonFlushCmdBuf( rmesa, __FUNCTION__ ); } - if (!(rmesa->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE)) { - int tcl_mode = driQueryOptioni(&rmesa->optionCache, "tcl_mode"); - if (tcl_mode >= DRI_CONF_TCL_VTXFMT) - radeonVtxfmtDestroy( rmesa->glCtx ); - } - _mesa_vector4f_free( &rmesa->tcl.ObjClean ); if (rmesa->state.scissor.pClipRects) { @@ -622,9 +609,6 @@ radeonMakeCurrent( __DRIcontextPrivate *driContextPriv, (GLframebuffer *) driDrawPriv->driverPrivate, (GLframebuffer *) driReadPriv->driverPrivate ); - if (newCtx->vb.enabled) - radeonVtxfmtMakeCurrent( newCtx->glCtx ); - } else { if (RADEON_DEBUG & DEBUG_DRI) fprintf(stderr, "%s ctx is null\n", __FUNCTION__); diff --git a/src/mesa/drivers/dri/radeon/radeon_maos_verts.c b/src/mesa/drivers/dri/radeon/radeon_maos_verts.c index 91a60bb9f1..65dbecf7a6 100644 --- a/src/mesa/drivers/dri/radeon/radeon_maos_verts.c +++ b/src/mesa/drivers/dri/radeon/radeon_maos_verts.c @@ -37,7 +37,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "imports.h" #include "mtypes.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "math/m_translate.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c index 86d8c4d963..f1a1728eaa 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.c +++ b/src/mesa/drivers/dri/radeon/radeon_state.c @@ -41,7 +41,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "state.h" #include "context.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" #include "swrast_setup/swrast_setup.h" @@ -52,7 +52,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_tcl.h" #include "radeon_tex.h" #include "radeon_swtcl.h" -#include "radeon_vtxfmt.h" #include "drirenderbuffer.h" static void radeonUpdateSpecular( GLcontext *ctx ); @@ -2302,11 +2301,10 @@ static void radeonInvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); _ae_invalidate_state( ctx, new_state ); RADEON_CONTEXT(ctx)->NewGLState |= new_state; - radeonVtxfmtInvalidate( ctx ); } diff --git a/src/mesa/drivers/dri/radeon/radeon_state_init.c b/src/mesa/drivers/dri/radeon/radeon_state_init.c index 5682d95ae1..5fc34f0933 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state_init.c +++ b/src/mesa/drivers/dri/radeon/radeon_state_init.c @@ -33,7 +33,7 @@ #include "api_arrayelt.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" #include "swrast_setup/swrast_setup.h" @@ -44,7 +44,6 @@ #include "radeon_tcl.h" #include "radeon_tex.h" #include "radeon_swtcl.h" -#include "radeon_vtxfmt.h" #include "xmlpool.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_swtcl.c b/src/mesa/drivers/dri/radeon/radeon_swtcl.c index e36a710d33..7ce1fa67cf 100644 --- a/src/mesa/drivers/dri/radeon/radeon_swtcl.c +++ b/src/mesa/drivers/dri/radeon/radeon_swtcl.c @@ -45,7 +45,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" -#include "tnl/t_vtx_api.h" /* for _tnl_FlushVertices */ #include "radeon_context.h" #include "radeon_ioctl.h" @@ -848,14 +847,6 @@ void radeonFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) } -void radeonFlushVertices( GLcontext *ctx, GLuint flags ) -{ - _tnl_FlushVertices( ctx, flags ); - - if (flags & FLUSH_STORED_VERTICES) - RADEON_NEWPRIM( RADEON_CONTEXT( ctx ) ); -} - /**********************************************************************/ /* Initialization. */ /**********************************************************************/ diff --git a/src/mesa/drivers/dri/radeon/radeon_swtcl.h b/src/mesa/drivers/dri/radeon/radeon_swtcl.h index f95a52c0b8..64f9019513 100644 --- a/src/mesa/drivers/dri/radeon/radeon_swtcl.h +++ b/src/mesa/drivers/dri/radeon/radeon_swtcl.h @@ -43,7 +43,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. extern void radeonInitSwtcl( GLcontext *ctx ); extern void radeonDestroySwtcl( GLcontext *ctx ); -extern void radeonFlushVertices( GLcontext *ctx, GLuint flags ); extern void radeonChooseRenderState( GLcontext *ctx ); extern void radeonChooseVertexState( GLcontext *ctx ); diff --git a/src/mesa/drivers/dri/radeon/radeon_tcl.c b/src/mesa/drivers/dri/radeon/radeon_tcl.c index ffd49b525b..5ad044c262 100644 --- a/src/mesa/drivers/dri/radeon/radeon_tcl.c +++ b/src/mesa/drivers/dri/radeon/radeon_tcl.c @@ -39,7 +39,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "mtypes.h" #include "enums.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_vtxfmt.c b/src/mesa/drivers/dri/radeon/radeon_vtxfmt.c deleted file mode 100644 index a5a9eb144b..0000000000 --- a/src/mesa/drivers/dri/radeon/radeon_vtxfmt.c +++ /dev/null @@ -1,1086 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c,v 1.6 2003/05/06 23:52:08 daenzer Exp $ */ -/************************************************************************** - -Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and - 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 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 (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 NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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 - */ -#include "glheader.h" -#include "imports.h" -#include "api_noop.h" -#include "api_arrayelt.h" -#include "context.h" -#include "mtypes.h" -#include "enums.h" -#include "glapi.h" -#include "colormac.h" -#include "light.h" -#include "state.h" -#include "vtxfmt.h" - -#include "tnl/tnl.h" -#include "tnl/t_context.h" -#include "tnl/t_array_api.h" -#include "tnl/t_save_api.h" - -#include "radeon_context.h" -#include "radeon_state.h" -#include "radeon_ioctl.h" -#include "radeon_tex.h" -#include "radeon_tcl.h" -#include "radeon_swtcl.h" -#include "radeon_vtxfmt.h" - -#define VERT_ATTRIB_TEX(u) (VERT_ATTRIB_TEX0 + (u)) - -#include "dispatch.h" - -static void radeonVtxfmtFlushVertices( GLcontext *, GLuint ); - -static void count_func( const char *name, struct dynfn *l ) -{ - int i = 0; - struct dynfn *f; - foreach (f, l) i++; - if (i) fprintf(stderr, "%s: %d\n", name, i ); -} - -static void count_funcs( radeonContextPtr rmesa ) -{ - count_func( "Vertex2f", &rmesa->vb.dfn_cache.Vertex2f ); - count_func( "Vertex2fv", &rmesa->vb.dfn_cache.Vertex2fv ); - count_func( "Vertex3f", &rmesa->vb.dfn_cache.Vertex3f ); - count_func( "Vertex3fv", &rmesa->vb.dfn_cache.Vertex3fv ); - count_func( "Color4ub", &rmesa->vb.dfn_cache.Color4ub ); - count_func( "Color4ubv", &rmesa->vb.dfn_cache.Color4ubv ); - count_func( "Color3ub", &rmesa->vb.dfn_cache.Color3ub ); - count_func( "Color3ubv", &rmesa->vb.dfn_cache.Color3ubv ); - count_func( "Color4f", &rmesa->vb.dfn_cache.Color4f ); - count_func( "Color4fv", &rmesa->vb.dfn_cache.Color4fv ); - count_func( "Color3f", &rmesa->vb.dfn_cache.Color3f ); - count_func( "Color3fv", &rmesa->vb.dfn_cache.Color3fv ); - count_func( "SecondaryColor3f", &rmesa->vb.dfn_cache.SecondaryColor3fEXT ); - count_func( "SecondaryColor3fv", &rmesa->vb.dfn_cache.SecondaryColor3fvEXT ); - count_func( "SecondaryColor3ub", &rmesa->vb.dfn_cache.SecondaryColor3ubEXT ); - count_func( "SecondaryColor3ubv", &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT ); - count_func( "Normal3f", &rmesa->vb.dfn_cache.Normal3f ); - count_func( "Normal3fv", &rmesa->vb.dfn_cache.Normal3fv ); - count_func( "TexCoord2f", &rmesa->vb.dfn_cache.TexCoord2f ); - count_func( "TexCoord2fv", &rmesa->vb.dfn_cache.TexCoord2fv ); - count_func( "TexCoord1f", &rmesa->vb.dfn_cache.TexCoord1f ); - count_func( "TexCoord1fv", &rmesa->vb.dfn_cache.TexCoord1fv ); - count_func( "MultiTexCoord2fARB", &rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - count_func( "MultiTexCoord2fvARB", &rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - count_func( "MultiTexCoord1fARB", &rmesa->vb.dfn_cache.MultiTexCoord1fARB ); - count_func( "MultiTexCoord1fvARB", &rmesa->vb.dfn_cache.MultiTexCoord1fvARB ); -} - - -void radeon_copy_to_current( GLcontext *ctx ) -{ - GLuint unit; - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - assert(ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT); - - if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_N0) { - ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0] = rmesa->vb.normalptr[0]; - ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1] = rmesa->vb.normalptr[1]; - ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2] = rmesa->vb.normalptr[2]; - } - - if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_PKCOLOR) { - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->red ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->green ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->blue ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->alpha ); - } - - if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_FPCOLOR) { - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] = rmesa->vb.floatcolorptr[0]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] = rmesa->vb.floatcolorptr[1]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] = rmesa->vb.floatcolorptr[2]; - } - - if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_FPALPHA) - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = rmesa->vb.floatcolorptr[3]; - - if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_PKSPEC) { - ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0] = UBYTE_TO_FLOAT( rmesa->vb.specptr->red ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1] = UBYTE_TO_FLOAT( rmesa->vb.specptr->green ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2] = UBYTE_TO_FLOAT( rmesa->vb.specptr->blue ); - } - - for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) { - if (rmesa->vb.vertex_format & RADEON_ST_BIT(unit)) { - ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][0] = rmesa->vb.texcoordptr[unit][0]; - ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][1] = rmesa->vb.texcoordptr[unit][1]; - ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][2] = 0.0F; - ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][3] = 1.0F; - } - } - - ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT; -} - -static GLboolean discreet_gl_prim[GL_POLYGON+1] = { - 1, /* 0 points */ - 1, /* 1 lines */ - 0, /* 2 line_strip */ - 0, /* 3 line_loop */ - 1, /* 4 tris */ - 0, /* 5 tri_fan */ - 0, /* 6 tri_strip */ - 1, /* 7 quads */ - 0, /* 8 quadstrip */ - 0, /* 9 poly */ -}; - -static void flush_prims( radeonContextPtr rmesa ) -{ - int i,j; - struct radeon_dma_region tmp = rmesa->dma.current; - - tmp.buf->refcount++; - tmp.aos_size = rmesa->vb.vertex_size; - tmp.aos_stride = rmesa->vb.vertex_size; - tmp.aos_start = GET_START(&tmp); - - rmesa->dma.current.ptr = rmesa->dma.current.start += - (rmesa->vb.initial_counter - rmesa->vb.counter) * rmesa->vb.vertex_size * 4; - - rmesa->tcl.vertex_format = rmesa->vb.vertex_format; - rmesa->tcl.aos_components[0] = &tmp; - rmesa->tcl.nr_aos_components = 1; - rmesa->dma.flush = NULL; - - /* Optimize the primitive list: - */ - if (rmesa->vb.nrprims > 1) { - for (j = 0, i = 1 ; i < rmesa->vb.nrprims; i++) { - int pj = rmesa->vb.primlist[j].prim & 0xf; - int pi = rmesa->vb.primlist[i].prim & 0xf; - - if (pj == pi && discreet_gl_prim[pj] && - rmesa->vb.primlist[i].start == rmesa->vb.primlist[j].end) { - rmesa->vb.primlist[j].end = rmesa->vb.primlist[i].end; - } - else { - j++; - if (j != i) rmesa->vb.primlist[j] = rmesa->vb.primlist[i]; - } - } - rmesa->vb.nrprims = j+1; - } - - for (i = 0 ; i < rmesa->vb.nrprims; i++) { - if (RADEON_DEBUG & DEBUG_PRIMS) - fprintf(stderr, "vtxfmt prim %d: %s %d..%d\n", i, - _mesa_lookup_enum_by_nr( rmesa->vb.primlist[i].prim & - PRIM_MODE_MASK ), - rmesa->vb.primlist[i].start, - rmesa->vb.primlist[i].end); - - radeonEmitPrimitive( rmesa->glCtx, - rmesa->vb.primlist[i].start, - rmesa->vb.primlist[i].end, - rmesa->vb.primlist[i].prim ); - } - - rmesa->vb.nrprims = 0; - radeonReleaseDmaRegion( rmesa, &tmp, __FUNCTION__ ); -} - - -static void start_prim( radeonContextPtr rmesa, GLuint mode ) -{ - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s %d\n", __FUNCTION__, rmesa->vb.initial_counter - rmesa->vb.counter); - - rmesa->vb.primlist[rmesa->vb.nrprims].start = rmesa->vb.initial_counter - rmesa->vb.counter; - rmesa->vb.primlist[rmesa->vb.nrprims].prim = mode; -} - -static void note_last_prim( radeonContextPtr rmesa, GLuint flags ) -{ - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s %d\n", __FUNCTION__, rmesa->vb.initial_counter - rmesa->vb.counter); - - if (rmesa->vb.prim[0] != GL_POLYGON+1) { - rmesa->vb.primlist[rmesa->vb.nrprims].prim |= flags; - rmesa->vb.primlist[rmesa->vb.nrprims].end = rmesa->vb.initial_counter - rmesa->vb.counter; - - if (++(rmesa->vb.nrprims) == RADEON_MAX_PRIMS) - flush_prims( rmesa ); - } -} - - -static void copy_vertex( radeonContextPtr rmesa, GLuint n, GLfloat *dst ) -{ - GLuint i; - GLfloat *src = (GLfloat *)(rmesa->dma.current.address + - rmesa->dma.current.ptr + - (rmesa->vb.primlist[rmesa->vb.nrprims].start + n) * - rmesa->vb.vertex_size * 4); - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "copy_vertex %d\n", rmesa->vb.primlist[rmesa->vb.nrprims].start + n); - - for (i = 0 ; i < rmesa->vb.vertex_size; i++) { - dst[i] = src[i]; - } -} - -/* NOTE: This actually reads the copied vertices back from uncached - * memory. Could also use the counter/notify mechanism to populate - * tmp on the fly as vertices are generated. - */ -static GLuint copy_dma_verts( radeonContextPtr rmesa, GLfloat (*tmp)[RADEON_MAX_VERTEX_SIZE] ) -{ - GLuint ovf, i; - GLuint nr = (rmesa->vb.initial_counter - rmesa->vb.counter) - rmesa->vb.primlist[rmesa->vb.nrprims].start; - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s %d verts\n", __FUNCTION__, nr); - - switch( rmesa->vb.prim[0] ) - { - case GL_POINTS: - return 0; - case GL_LINES: - ovf = nr&1; - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - case GL_TRIANGLES: - ovf = nr%3; - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - case GL_QUADS: - ovf = nr&3; - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - case GL_LINE_STRIP: - if (nr == 0) - return 0; - copy_vertex( rmesa, nr-1, tmp[0] ); - return 1; - case GL_LINE_LOOP: - case GL_TRIANGLE_FAN: - case GL_POLYGON: - if (nr == 0) - return 0; - else if (nr == 1) { - copy_vertex( rmesa, 0, tmp[0] ); - return 1; - } else { - copy_vertex( rmesa, 0, tmp[0] ); - copy_vertex( rmesa, nr-1, tmp[1] ); - return 2; - } - case GL_TRIANGLE_STRIP: - ovf = MIN2(nr, 2); - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - 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++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - default: - assert(0); - return 0; - } -} - -static void VFMT_FALLBACK_OUTSIDE_BEGIN_END( const char *caller ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_FALLBACKS)) - fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); - - if (ctx->Driver.NeedFlush) - radeonVtxfmtFlushVertices( ctx, ctx->Driver.NeedFlush ); - - if (ctx->NewState) - _mesa_update_state( ctx ); /* clear state so fell_back sticks */ - - _tnl_wakeup_exec( ctx ); - ctx->Driver.FlushVertices = radeonFlushVertices; - ctx->Driver.NewList =_tnl_NewList; - - assert( rmesa->dma.flush == 0 ); - rmesa->vb.fell_back = GL_TRUE; - rmesa->vb.installed = GL_FALSE; -} - - -static void VFMT_FALLBACK( const char *caller ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat tmp[3][RADEON_MAX_VERTEX_SIZE]; - GLuint i, prim; - GLuint ind = rmesa->vb.vertex_format; - GLuint nrverts; - GLfloat alpha = 1.0; - GLuint unit; - - if (RADEON_DEBUG & (DEBUG_FALLBACKS|DEBUG_VFMT)) - fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); - - if (rmesa->vb.prim[0] == GL_POLYGON+1) { - VFMT_FALLBACK_OUTSIDE_BEGIN_END( __FUNCTION__ ); - return; - } - - /* Copy vertices out of dma: - */ - nrverts = copy_dma_verts( rmesa, tmp ); - - /* Finish the prim at this point: - */ - note_last_prim( rmesa, 0 ); - flush_prims( rmesa ); - - /* Update ctx->Driver.CurrentExecPrimitive and swap in swtnl. - */ - prim = rmesa->vb.prim[0]; - ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1; - _tnl_wakeup_exec( ctx ); - ctx->Driver.FlushVertices = radeonFlushVertices; - - assert(rmesa->dma.flush == 0); - rmesa->vb.fell_back = GL_TRUE; - rmesa->vb.installed = GL_FALSE; - CALL_Begin(GET_DISPATCH(), (prim)); - - if (rmesa->vb.installed_color_3f_sz == 4) - alpha = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3]; - - /* Replay saved vertices - */ - for (i = 0 ; i < nrverts; i++) { - GLuint offset = 3; - if (ind & RADEON_CP_VC_FRMT_N0) { - CALL_Normal3fv(GET_DISPATCH(), (&tmp[i][offset])); - offset += 3; - } - - if (ind & RADEON_CP_VC_FRMT_PKCOLOR) { - radeon_color_t *col = (radeon_color_t *)&tmp[i][offset]; - CALL_Color4ub(GET_DISPATCH(), (col->red, col->green, col->blue, col->alpha)); - offset++; - } - else if (ind & RADEON_CP_VC_FRMT_FPALPHA) { - CALL_Color4fv(GET_DISPATCH(), (&tmp[i][offset])); - offset+=4; - } - else if (ind & RADEON_CP_VC_FRMT_FPCOLOR) { - CALL_Color3fv(GET_DISPATCH(), (&tmp[i][offset])); - offset+=3; - } - - if (ind & RADEON_CP_VC_FRMT_PKSPEC) { - radeon_color_t *spec = (radeon_color_t *)&tmp[i][offset]; - CALL_SecondaryColor3ubEXT(GET_DISPATCH(), (spec->red, spec->green, spec->blue)); - offset++; - } - - for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) { - if (ind & RADEON_ST_BIT(unit)) { - CALL_MultiTexCoord2fvARB(GET_DISPATCH(), ((GL_TEXTURE0 + unit), &tmp[i][offset])); - offset += 2; - } - } - CALL_Vertex3fv(GET_DISPATCH(), (&tmp[i][0])); - } - - /* Replay current vertex - */ - if (ind & RADEON_CP_VC_FRMT_N0) - CALL_Normal3fv(GET_DISPATCH(), (rmesa->vb.normalptr)); - - if (ind & RADEON_CP_VC_FRMT_PKCOLOR) - CALL_Color4ub(GET_DISPATCH(), (rmesa->vb.colorptr->red, rmesa->vb.colorptr->green, - rmesa->vb.colorptr->blue, rmesa->vb.colorptr->alpha)); - else if (ind & RADEON_CP_VC_FRMT_FPALPHA) - CALL_Color4fv(GET_DISPATCH(), (rmesa->vb.floatcolorptr)); - else if (ind & RADEON_CP_VC_FRMT_FPCOLOR) { - if (rmesa->vb.installed_color_3f_sz == 4 && alpha != 1.0) - CALL_Color4f(GET_DISPATCH(), (rmesa->vb.floatcolorptr[0], - rmesa->vb.floatcolorptr[1], - rmesa->vb.floatcolorptr[2], - alpha)); - else - CALL_Color3fv(GET_DISPATCH(), (rmesa->vb.floatcolorptr)); - } - - if (ind & RADEON_CP_VC_FRMT_PKSPEC) - CALL_SecondaryColor3ubEXT(GET_DISPATCH(), (rmesa->vb.specptr->red, - rmesa->vb.specptr->green, - rmesa->vb.specptr->blue)); - - for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) { - if (ind & RADEON_ST_BIT(unit)) { - CALL_MultiTexCoord2fvARB(GET_DISPATCH(), ((GL_TEXTURE0 + unit), - rmesa->vb.texcoordptr[unit])); - } - } -} - -static void radeonNewList( GLcontext *ctx, GLuint list, GLenum mode ) -{ - VFMT_FALLBACK( __FUNCTION__ ); - _tnl_NewList( ctx, list, mode ); - return; -} - - -static void wrap_buffer( void ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat tmp[3][RADEON_MAX_VERTEX_SIZE]; - GLuint i, nrverts; - - if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_PRIMS)) - fprintf(stderr, "%s %d\n", __FUNCTION__, rmesa->vb.initial_counter - rmesa->vb.counter); - - /* Don't deal with parity. - */ - if ((((rmesa->vb.initial_counter - rmesa->vb.counter) - - rmesa->vb.primlist[rmesa->vb.nrprims].start) & 1)) { - rmesa->vb.counter++; - rmesa->vb.initial_counter++; - return; - } - - /* Copy vertices out of dma: - */ - if (rmesa->vb.prim[0] == GL_POLYGON+1) - nrverts = 0; - else { - nrverts = copy_dma_verts( rmesa, tmp ); - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%d vertices to copy\n", nrverts); - - /* Finish the prim at this point: - */ - note_last_prim( rmesa, 0 ); - } - - /* Fire any buffered primitives - */ - flush_prims( rmesa ); - - /* Get new buffer - */ - radeonRefillCurrentDmaRegion( rmesa ); - - /* Reset counter, dmaptr - */ - rmesa->vb.dmaptr = (int *)(rmesa->dma.current.ptr + rmesa->dma.current.address); - rmesa->vb.counter = (rmesa->dma.current.end - rmesa->dma.current.ptr) / - (rmesa->vb.vertex_size * 4); - rmesa->vb.counter--; - rmesa->vb.initial_counter = rmesa->vb.counter; - rmesa->vb.notify = wrap_buffer; - - rmesa->dma.flush = flush_prims; - - /* Restart wrapped primitive: - */ - if (rmesa->vb.prim[0] != GL_POLYGON+1) - start_prim( rmesa, rmesa->vb.prim[0] ); - - /* Reemit saved vertices - */ - for (i = 0 ; i < nrverts; i++) { - if (RADEON_DEBUG & DEBUG_VERTS) { - int j; - fprintf(stderr, "re-emit vertex %d to %p\n", i, (void *)rmesa->vb.dmaptr); - if (RADEON_DEBUG & DEBUG_VERBOSE) - for (j = 0 ; j < rmesa->vb.vertex_size; j++) - fprintf(stderr, "\t%08x/%f\n", *(int*)&tmp[i][j], tmp[i][j]); - } - - memcpy( rmesa->vb.dmaptr, tmp[i], rmesa->vb.vertex_size * 4 ); - rmesa->vb.dmaptr += rmesa->vb.vertex_size; - rmesa->vb.counter--; - } -} - - - -static GLboolean check_vtx_fmt( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLuint ind = RADEON_CP_VC_FRMT_Z; - GLuint unit; - - if (rmesa->TclFallback || rmesa->vb.fell_back || ctx->CompileFlag || - (ctx->Fog.Enabled && (ctx->Fog.FogCoordinateSource == GL_FOG_COORD))) - return GL_FALSE; - - if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) - ctx->Driver.FlushVertices( ctx, FLUSH_UPDATE_CURRENT ); - - /* Make all this event-driven: - */ - if (ctx->Light.Enabled) { - ind |= RADEON_CP_VC_FRMT_N0; - - /* TODO: make this data driven: If we receive only ubytes, send - * color as ubytes. Also check if converting (with free - * checking for overflow) is cheaper than sending floats - * directly. - */ - if (ctx->Light.ColorMaterialEnabled) { - ind |= (RADEON_CP_VC_FRMT_FPCOLOR | - RADEON_CP_VC_FRMT_FPALPHA); - } - else - ind |= RADEON_CP_VC_FRMT_PKCOLOR; /* for alpha? */ - } - else { - /* TODO: make this data driven? - */ - ind |= RADEON_CP_VC_FRMT_PKCOLOR; - - if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { - ind |= RADEON_CP_VC_FRMT_PKSPEC; - } - } - - if ( ctx->Fog.FogCoordinateSource == GL_FOG_COORD ) { - ind |= RADEON_CP_VC_FRMT_PKSPEC; - } - - for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) { - if (ctx->Texture.Unit[unit]._ReallyEnabled) { - if (ctx->Texture.Unit[unit].TexGenEnabled) { - if (rmesa->TexGenNeedNormals[unit]) { - ind |= RADEON_CP_VC_FRMT_N0; - } - } else { - if (ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][3] != 1.0) { - if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_FALLBACKS)) - fprintf(stderr, "%s: q%u\n", __FUNCTION__, unit); - return GL_FALSE; - } - ind |= RADEON_ST_BIT(unit); - } - } - } - - if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_STATE)) - fprintf(stderr, "%s: format: 0x%x\n", __FUNCTION__, ind ); - - RADEON_NEWPRIM(rmesa); - rmesa->vb.vertex_format = ind; - rmesa->vb.vertex_size = 3; - rmesa->vb.prim = &ctx->Driver.CurrentExecPrimitive; - - rmesa->vb.normalptr = ctx->Current.Attrib[VERT_ATTRIB_NORMAL]; - rmesa->vb.colorptr = NULL; - rmesa->vb.floatcolorptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; - rmesa->vb.specptr = NULL; - rmesa->vb.floatspecptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR1]; - rmesa->vb.texcoordptr[0] = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; - rmesa->vb.texcoordptr[1] = ctx->Current.Attrib[VERT_ATTRIB_TEX1]; - rmesa->vb.texcoordptr[2] = ctx->Current.Attrib[VERT_ATTRIB_TEX2]; - rmesa->vb.texcoordptr[3] = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; /* dummy */ - - /* Run through and initialize the vertex components in the order - * the hardware understands: - */ - if (ind & RADEON_CP_VC_FRMT_N0) { - rmesa->vb.normalptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; - rmesa->vb.vertex_size += 3; - rmesa->vb.normalptr[0] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0]; - rmesa->vb.normalptr[1] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1]; - rmesa->vb.normalptr[2] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2]; - } - - if (ind & RADEON_CP_VC_FRMT_PKCOLOR) { - rmesa->vb.colorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].color; - rmesa->vb.vertex_size += 1; - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->red, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->green, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->blue, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->alpha, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] ); - } - - if (ind & RADEON_CP_VC_FRMT_FPCOLOR) { - assert(!(ind & RADEON_CP_VC_FRMT_PKCOLOR)); - rmesa->vb.floatcolorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; - rmesa->vb.vertex_size += 3; - rmesa->vb.floatcolorptr[0] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0]; - rmesa->vb.floatcolorptr[1] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1]; - rmesa->vb.floatcolorptr[2] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2]; - - if (ind & RADEON_CP_VC_FRMT_FPALPHA) { - rmesa->vb.vertex_size += 1; - rmesa->vb.floatcolorptr[3] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3]; - } - } - - if (ind & RADEON_CP_VC_FRMT_PKSPEC) { - rmesa->vb.specptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].color; - rmesa->vb.vertex_size += 1; - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->red, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->green, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->blue, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2] ); - /* fog ??? */ -/* UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->alpha, - radeonComputeFogFactor(ctx->Current.Attrib[VERT_ATTRIB_FOG][0]) ); */ - } - - for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) { - if (ind & RADEON_ST_BIT(unit)) { - rmesa->vb.texcoordptr[unit] = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; - rmesa->vb.vertex_size += 2; - rmesa->vb.texcoordptr[unit][0] = ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][0]; - rmesa->vb.texcoordptr[unit][1] = ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][1]; - } - } - - if (rmesa->vb.installed_vertex_format != rmesa->vb.vertex_format) { - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "reinstall on vertex_format change\n"); - _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); - rmesa->vb.installed_vertex_format = rmesa->vb.vertex_format; - } - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s -- success\n", __FUNCTION__); - - return GL_TRUE; -} - -void radeonVtxfmtInvalidate( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); - - rmesa->vb.recheck = GL_TRUE; - rmesa->vb.fell_back = GL_FALSE; -} - - -static void radeonVtxfmtValidate( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (ctx->Driver.NeedFlush) - ctx->Driver.FlushVertices( ctx, ctx->Driver.NeedFlush ); - - rmesa->vb.recheck = GL_FALSE; - - if (check_vtx_fmt( ctx )) { - if (!rmesa->vb.installed) { - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "reinstall (new install)\n"); - - _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); - ctx->Driver.FlushVertices = radeonVtxfmtFlushVertices; - ctx->Driver.NewList = radeonNewList; - rmesa->vb.installed = GL_TRUE; - } - else if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s: already installed", __FUNCTION__); - } - else { - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s: failed\n", __FUNCTION__); - - if (rmesa->vb.installed) { - if (rmesa->dma.flush) - rmesa->dma.flush( rmesa ); - _tnl_wakeup_exec( ctx ); - ctx->Driver.FlushVertices = radeonFlushVertices; - ctx->Driver.NewList =_tnl_NewList; - rmesa->vb.installed = GL_FALSE; - } - } -} - - - -/* Materials: - */ -static void radeon_Materialfv( GLenum face, GLenum pname, - const GLfloat *params ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (rmesa->vb.prim[0] != GL_POLYGON+1) { - VFMT_FALLBACK( __FUNCTION__ ); - CALL_Materialfv(GET_DISPATCH(), (face, pname, params)); - return; - } - _mesa_noop_Materialfv( face, pname, params ); - radeonUpdateMaterial( ctx ); -} - - -/* Begin/End - */ -static void radeon_Begin( GLenum mode ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s( %s )\n", __FUNCTION__, - _mesa_lookup_enum_by_nr( mode )); - - if (mode > GL_POLYGON) { - _mesa_error( ctx, GL_INVALID_ENUM, "glBegin" ); - return; - } - - if (rmesa->vb.prim[0] != GL_POLYGON+1) { - _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" ); - return; - } - - if (ctx->NewState) - _mesa_update_state( ctx ); - - if (rmesa->NewGLState) - radeonValidateState( ctx ); - - if (rmesa->vb.recheck) - radeonVtxfmtValidate( ctx ); - - if (!rmesa->vb.installed) { - CALL_Begin(GET_DISPATCH(), (mode)); - return; - } - - - if (rmesa->dma.flush && rmesa->vb.counter < 12) { - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s: flush almost-empty buffers\n", __FUNCTION__); - flush_prims( rmesa ); - } - - /* Need to arrange to save vertices here? Or always copy from dma (yuk)? - */ - if (!rmesa->dma.flush) { -/* FIXME: what are these constants? */ - if (rmesa->dma.current.ptr + 12*rmesa->vb.vertex_size*4 > - rmesa->dma.current.end) { - RADEON_NEWPRIM( rmesa ); - radeonRefillCurrentDmaRegion( rmesa ); - } - - rmesa->vb.dmaptr = (int *)(rmesa->dma.current.address + rmesa->dma.current.ptr); - rmesa->vb.counter = (rmesa->dma.current.end - rmesa->dma.current.ptr) / - (rmesa->vb.vertex_size * 4); - rmesa->vb.counter--; - rmesa->vb.initial_counter = rmesa->vb.counter; - rmesa->vb.notify = wrap_buffer; - rmesa->dma.flush = flush_prims; - ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; - } - - - rmesa->vb.prim[0] = mode; - start_prim( rmesa, mode | PRIM_BEGIN ); -} - - - -static void radeon_End( void ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (rmesa->vb.prim[0] == GL_POLYGON+1) { - _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" ); - return; - } - - note_last_prim( rmesa, PRIM_END ); - rmesa->vb.prim[0] = GL_POLYGON+1; -} - - -/* Fallback on difficult entrypoints: - */ -#define PRE_LOOPBACK( FUNC ) \ -do { \ - if (RADEON_DEBUG & DEBUG_VFMT) \ - fprintf(stderr, "%s\n", __FUNCTION__); \ - VFMT_FALLBACK( __FUNCTION__ ); \ -} while (0) -#define TAG(x) radeon_fallback_##x -#include "vtxfmt_tmp.h" - - - -static GLboolean radeonNotifyBegin( GLcontext *ctx, GLenum p ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - assert(!rmesa->vb.installed); - - if (ctx->NewState) - _mesa_update_state( ctx ); - - if (rmesa->NewGLState) - radeonValidateState( ctx ); - - if (ctx->Driver.NeedFlush) - ctx->Driver.FlushVertices( ctx, ctx->Driver.NeedFlush ); - - if (rmesa->vb.recheck) - radeonVtxfmtValidate( ctx ); - - if (!rmesa->vb.installed) { - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s -- failed\n", __FUNCTION__); - return GL_FALSE; - } - - radeon_Begin( p ); - return GL_TRUE; -} - -static void radeonVtxfmtFlushVertices( GLcontext *ctx, GLuint flags ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - assert(rmesa->vb.installed); - - if (flags & FLUSH_UPDATE_CURRENT) { - radeon_copy_to_current( ctx ); - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "reinstall on update_current\n"); - _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); - ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT; - } - - if (flags & FLUSH_STORED_VERTICES) { - radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); - assert (rmesa->dma.flush == 0 || - rmesa->dma.flush == flush_prims); - if (rmesa->dma.flush == flush_prims) - flush_prims( RADEON_CONTEXT( ctx ) ); - ctx->Driver.NeedFlush &= ~FLUSH_STORED_VERTICES; - } -} - - - -/* At this point, don't expect very many versions of each function to - * be generated, so not concerned about freeing them? - */ - - -void radeonVtxfmtInit( GLcontext *ctx, GLboolean useCodegen ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); - GLvertexformat *vfmt = &(rmesa->vb.vtxfmt); - - /* start by initializing to no-op functions */ - _mesa_noop_vtxfmt_init(vfmt); - - /* Hook in chooser functions for codegen, etc: - */ - radeonVtxfmtInitChoosers( vfmt ); - - /* Handled fully in supported states, but no codegen: - */ - vfmt->Materialfv = radeon_Materialfv; - vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ - vfmt->Begin = radeon_Begin; - vfmt->End = radeon_End; - - /* Fallback for performance reasons: (Fix with cva/elt path here and - * dmatmp2.h style primitive-merging) - * - * These should call NotifyBegin(), as should _tnl_EvalMesh, to allow - * a driver-hook. - */ - vfmt->DrawArrays = radeon_fallback_DrawArrays; - vfmt->DrawElements = radeon_fallback_DrawElements; - vfmt->DrawRangeElements = radeon_fallback_DrawRangeElements; - - /* Active but unsupported -- fallback if we receive these: - */ - vfmt->CallList = radeon_fallback_CallList; - vfmt->CallLists = radeon_fallback_CallLists; - vfmt->EvalCoord1f = radeon_fallback_EvalCoord1f; - vfmt->EvalCoord1fv = radeon_fallback_EvalCoord1fv; - vfmt->EvalCoord2f = radeon_fallback_EvalCoord2f; - vfmt->EvalCoord2fv = radeon_fallback_EvalCoord2fv; - vfmt->EvalMesh1 = radeon_fallback_EvalMesh1; - vfmt->EvalMesh2 = radeon_fallback_EvalMesh2; - vfmt->EvalPoint1 = radeon_fallback_EvalPoint1; - vfmt->EvalPoint2 = radeon_fallback_EvalPoint2; - vfmt->TexCoord3f = radeon_fallback_TexCoord3f; - vfmt->TexCoord3fv = radeon_fallback_TexCoord3fv; - vfmt->TexCoord4f = radeon_fallback_TexCoord4f; - vfmt->TexCoord4fv = radeon_fallback_TexCoord4fv; - vfmt->MultiTexCoord3fARB = radeon_fallback_MultiTexCoord3fARB; - vfmt->MultiTexCoord3fvARB = radeon_fallback_MultiTexCoord3fvARB; - vfmt->MultiTexCoord4fARB = radeon_fallback_MultiTexCoord4fARB; - vfmt->MultiTexCoord4fvARB = radeon_fallback_MultiTexCoord4fvARB; - vfmt->Vertex4f = radeon_fallback_Vertex4f; - vfmt->Vertex4fv = radeon_fallback_Vertex4fv; - vfmt->VertexAttrib1fNV = radeon_fallback_VertexAttrib1fNV; - vfmt->VertexAttrib1fvNV = radeon_fallback_VertexAttrib1fvNV; - vfmt->VertexAttrib2fNV = radeon_fallback_VertexAttrib2fNV; - vfmt->VertexAttrib2fvNV = radeon_fallback_VertexAttrib2fvNV; - vfmt->VertexAttrib3fNV = radeon_fallback_VertexAttrib3fNV; - vfmt->VertexAttrib3fvNV = radeon_fallback_VertexAttrib3fvNV; - vfmt->VertexAttrib4fNV = radeon_fallback_VertexAttrib4fNV; - vfmt->VertexAttrib4fvNV = radeon_fallback_VertexAttrib4fvNV; - vfmt->FogCoordfEXT = radeon_fallback_FogCoordfEXT; - vfmt->FogCoordfvEXT = radeon_fallback_FogCoordfvEXT; - - (void)radeon_fallback_vtxfmt; - - TNL_CONTEXT(ctx)->Driver.NotifyBegin = radeonNotifyBegin; - - rmesa->vb.enabled = 1; - rmesa->vb.prim = &ctx->Driver.CurrentExecPrimitive; - rmesa->vb.primflags = 0; - - make_empty_list( &rmesa->vb.dfn_cache.Vertex2f ); - make_empty_list( &rmesa->vb.dfn_cache.Vertex2fv ); - make_empty_list( &rmesa->vb.dfn_cache.Vertex3f ); - make_empty_list( &rmesa->vb.dfn_cache.Vertex3fv ); - make_empty_list( &rmesa->vb.dfn_cache.Color4ub ); - make_empty_list( &rmesa->vb.dfn_cache.Color4ubv ); - make_empty_list( &rmesa->vb.dfn_cache.Color3ub ); - make_empty_list( &rmesa->vb.dfn_cache.Color3ubv ); - make_empty_list( &rmesa->vb.dfn_cache.Color4f ); - make_empty_list( &rmesa->vb.dfn_cache.Color4fv ); - make_empty_list( &rmesa->vb.dfn_cache.Color3f ); - make_empty_list( &rmesa->vb.dfn_cache.Color3fv ); - make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3fEXT ); - make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3fvEXT ); - make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3ubEXT ); - make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT ); - make_empty_list( &rmesa->vb.dfn_cache.Normal3f ); - make_empty_list( &rmesa->vb.dfn_cache.Normal3fv ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord2f ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord2fv ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord1f ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord1fv ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord1fARB ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord1fvARB ); - - radeonInitCodegen( &rmesa->vb.codegen, useCodegen ); -} - -static void free_funcs( struct dynfn *l ) -{ - struct dynfn *f, *tmp; - foreach_s (f, tmp, l) { - remove_from_list( f ); - _mesa_exec_free( f->code ); - _mesa_free( f ); - } -} - - - -void radeonVtxfmtMakeCurrent( GLcontext *ctx ) -{ -} - - -void radeonVtxfmtDestroy( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); - - count_funcs( rmesa ); - free_funcs( &rmesa->vb.dfn_cache.Vertex2f ); - free_funcs( &rmesa->vb.dfn_cache.Vertex2fv ); - free_funcs( &rmesa->vb.dfn_cache.Vertex3f ); - free_funcs( &rmesa->vb.dfn_cache.Vertex3fv ); - free_funcs( &rmesa->vb.dfn_cache.Color4ub ); - free_funcs( &rmesa->vb.dfn_cache.Color4ubv ); - free_funcs( &rmesa->vb.dfn_cache.Color3ub ); - free_funcs( &rmesa->vb.dfn_cache.Color3ubv ); - free_funcs( &rmesa->vb.dfn_cache.Color4f ); - free_funcs( &rmesa->vb.dfn_cache.Color4fv ); - free_funcs( &rmesa->vb.dfn_cache.Color3f ); - free_funcs( &rmesa->vb.dfn_cache.Color3fv ); - free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3ubEXT ); - free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT ); - free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3fEXT ); - free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3fvEXT ); - free_funcs( &rmesa->vb.dfn_cache.Normal3f ); - free_funcs( &rmesa->vb.dfn_cache.Normal3fv ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord2f ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord2fv ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord1f ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord1fv ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord1fARB ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord1fvARB ); -} - diff --git a/src/mesa/drivers/dri/radeon/radeon_vtxfmt.h b/src/mesa/drivers/dri/radeon/radeon_vtxfmt.h deleted file mode 100644 index a656e49e44..0000000000 --- a/src/mesa/drivers/dri/radeon/radeon_vtxfmt.h +++ /dev/null @@ -1,120 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.h,v 1.3 2002/12/21 17:02:16 dawes Exp $ */ -/************************************************************************** - -Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and - 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 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 (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 NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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 - */ - -#ifndef __RADEON_VTXFMT_H__ -#define __RADEON_VTXFMT_H__ - -#include "radeon_context.h" - - -extern void radeonVtxfmtUpdate( GLcontext *ctx ); -extern void radeonVtxfmtInit( GLcontext *ctx, GLboolean useCodegen ); -extern void radeonVtxfmtInvalidate( GLcontext *ctx ); -extern void radeonVtxfmtDestroy( GLcontext *ctx ); -extern void radeonVtxfmtInitChoosers( GLvertexformat *vfmt ); - -extern void radeonVtxfmtMakeCurrent( GLcontext *ctx ); -extern void radeonVtxfmtUnbindContext( GLcontext *ctx ); - -extern void radeon_copy_to_current( GLcontext *ctx ); - -#define DFN( FUNC, CACHE) \ -do { \ - char *start = (char *)&FUNC; \ - char *end = (char *)&FUNC##_end; \ - insert_at_head( &CACHE, dfn ); \ - dfn->key = key; \ - dfn->code = _mesa_exec_malloc( end - start ); \ - _mesa_memcpy(dfn->code, start, end - start); \ -} \ -while ( 0 ) - -#define FIXUP( CODE, OFFSET, CHECKVAL, NEWVAL ) \ -do { \ - int *icode = (int *)(CODE+OFFSET); \ - assert (*icode == CHECKVAL); \ - *icode = (int)NEWVAL; \ -} while (0) - - -/* Useful for figuring out the offsets: - */ -#define FIXUP2( CODE, OFFSET, CHECKVAL, NEWVAL ) \ -do { \ - while (*(int *)(CODE+OFFSET) != CHECKVAL) OFFSET++; \ - fprintf(stderr, "%s/%d CVAL %x OFFSET %d VAL %x\n", __FUNCTION__, \ - __LINE__, CHECKVAL, OFFSET, (int)(NEWVAL)); \ - *(int *)(CODE+OFFSET) = (int)(NEWVAL); \ - OFFSET += 4; \ -} while (0) - -/* - */ -void radeonInitCodegen( struct dfn_generators *gen, GLboolean useCodegen ); -void radeonInitX86Codegen( struct dfn_generators *gen ); -void radeonInitSSECodegen( struct dfn_generators *gen ); - - - -/* Defined in radeon_vtxfmt_x86.c - */ -struct dynfn *radeon_makeX86Vertex2f( GLcontext *, int ); -struct dynfn *radeon_makeX86Vertex2fv( GLcontext *, int ); -struct dynfn *radeon_makeX86Vertex3f( GLcontext *, int ); -struct dynfn *radeon_makeX86Vertex3fv( GLcontext *, int ); -struct dynfn *radeon_makeX86Color4ub( GLcontext *, int ); -struct dynfn *radeon_makeX86Color4ubv( GLcontext *, int ); -struct dynfn *radeon_makeX86Color3ub( GLcontext *, int ); -struct dynfn *radeon_makeX86Color3ubv( GLcontext *, int ); -struct dynfn *radeon_makeX86Color4f( GLcontext *, int ); -struct dynfn *radeon_makeX86Color4fv( GLcontext *, int ); -struct dynfn *radeon_makeX86Color3f( GLcontext *, int ); -struct dynfn *radeon_makeX86Color3fv( GLcontext *, int ); -struct dynfn *radeon_makeX86SecondaryColor3ubEXT( GLcontext *, int ); -struct dynfn *radeon_makeX86SecondaryColor3ubvEXT( GLcontext *, int ); -struct dynfn *radeon_makeX86SecondaryColor3fEXT( GLcontext *, int ); -struct dynfn *radeon_makeX86SecondaryColor3fvEXT( GLcontext *, int ); -struct dynfn *radeon_makeX86Normal3f( GLcontext *, int ); -struct dynfn *radeon_makeX86Normal3fv( GLcontext *, int ); -struct dynfn *radeon_makeX86TexCoord2f( GLcontext *, int ); -struct dynfn *radeon_makeX86TexCoord2fv( GLcontext *, int ); -struct dynfn *radeon_makeX86TexCoord1f( GLcontext *, int ); -struct dynfn *radeon_makeX86TexCoord1fv( GLcontext *, int ); -struct dynfn *radeon_makeX86MultiTexCoord2fARB( GLcontext *, int ); -struct dynfn *radeon_makeX86MultiTexCoord2fvARB( GLcontext *, int ); -struct dynfn *radeon_makeX86MultiTexCoord1fARB( GLcontext *, int ); -struct dynfn *radeon_makeX86MultiTexCoord1fvARB( GLcontext *, int ); - -#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_vtxfmt_c.c b/src/mesa/drivers/dri/radeon/radeon_vtxfmt_c.c deleted file mode 100644 index aac029aa0e..0000000000 --- a/src/mesa/drivers/dri/radeon/radeon_vtxfmt_c.c +++ /dev/null @@ -1,924 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_c.c,v 1.2 2002/12/16 16:18:59 dawes Exp $ */ -/************************************************************************** - -Copyright 2002 ATI Technologies Inc., Ontario, Canada, and - 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 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 (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 NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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 - */ -#include "glheader.h" -#include "mtypes.h" -#include "colormac.h" -#include "simple_list.h" -#include "api_noop.h" -#include "vtxfmt.h" - -#include "radeon_vtxfmt.h" - -#include "dispatch.h" - -/* Fallback versions of all the entrypoints for situations where - * codegen isn't available. This is still a lot faster than the - * vb/pipeline implementation in Mesa. - */ -static void radeon_Vertex3f( GLfloat x, GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - int i; - - *rmesa->vb.dmaptr++ = *(int *)&x; - *rmesa->vb.dmaptr++ = *(int *)&y; - *rmesa->vb.dmaptr++ = *(int *)&z; - - for (i = 3; i < rmesa->vb.vertex_size; i++) - *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i; - - if (--rmesa->vb.counter == 0) - rmesa->vb.notify(); -} - - -static void radeon_Vertex3fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - int i; - - *rmesa->vb.dmaptr++ = *(int *)&v[0]; - *rmesa->vb.dmaptr++ = *(int *)&v[1]; - *rmesa->vb.dmaptr++ = *(int *)&v[2]; - - for (i = 3; i < rmesa->vb.vertex_size; i++) - *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i; - - if (--rmesa->vb.counter == 0) - rmesa->vb.notify(); -} - - -static void radeon_Vertex2f( GLfloat x, GLfloat y ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - int i; - - *rmesa->vb.dmaptr++ = *(int *)&x; - *rmesa->vb.dmaptr++ = *(int *)&y; - *rmesa->vb.dmaptr++ = 0; - - for (i = 3; i < rmesa->vb.vertex_size; i++) - *rmesa->vb.dmaptr++ = *(int *)&rmesa->vb.vertex[i]; - - if (--rmesa->vb.counter == 0) - rmesa->vb.notify(); -} - - -static void radeon_Vertex2fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - int i; - - *rmesa->vb.dmaptr++ = *(int *)&v[0]; - *rmesa->vb.dmaptr++ = *(int *)&v[1]; - *rmesa->vb.dmaptr++ = 0; - - for (i = 3; i < rmesa->vb.vertex_size; i++) - *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i; - - if (--rmesa->vb.counter == 0) - rmesa->vb.notify(); -} - - -#if 0 -/* Color for ubyte (packed) color formats: - */ -static void radeon_Color3ub_ub( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.colorptr; - dest->red = r; - dest->green = g; - dest->blue = b; - dest->alpha = 0xff; -} - -static void radeon_Color3ubv_ub( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.colorptr; - dest->red = v[0]; - dest->green = v[1]; - dest->blue = v[2]; - dest->alpha = 0xff; -} - -static void radeon_Color4ub_ub( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.colorptr; - dest->red = r; - dest->green = g; - dest->blue = b; - dest->alpha = a; -} - -static void radeon_Color4ubv_ub( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - *(GLuint *)rmesa->vb.colorptr = LE32_TO_CPU(*(GLuint *)v); -} -#endif /* 0 */ - -static void radeon_Color3f_ub( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.colorptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); - dest->alpha = 255; -} - -static void radeon_Color3fv_ub( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.colorptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); - dest->alpha = 255; -} - -static void radeon_Color4f_ub( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.colorptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, a ); -} - -static void radeon_Color4fv_ub( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.colorptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, v[3] ); -} - - -/* Color for float color+alpha formats: - */ -#if 0 -static void radeon_Color3ub_4f( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); - dest[3] = 1.0; -} - -static void radeon_Color3ubv_4f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); - dest[3] = 1.0; -} - -static void radeon_Color4ub_4f( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); - dest[3] = UBYTE_TO_FLOAT(a); -} - -static void radeon_Color4ubv_4f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); - dest[3] = UBYTE_TO_FLOAT(v[3]); -} -#endif /* 0 */ - - -static void radeon_Color3f_4f( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; - dest[3] = 1.0; -} - -static void radeon_Color3fv_4f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - dest[3] = 1.0; -} - -static void radeon_Color4f_4f( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; - dest[3] = a; -} - -static void radeon_Color4fv_4f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - dest[3] = v[3]; -} - - -/* Color for float color formats: - */ -#if 0 -static void radeon_Color3ub_3f( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); -} - -static void radeon_Color3ubv_3f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); -} - -static void radeon_Color4ub_3f( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT(a); -} - -static void radeon_Color4ubv_3f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT(v[3]); -} -#endif /* 0 */ - - -static void radeon_Color3f_3f( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; -} - -static void radeon_Color3fv_3f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; -} - -static void radeon_Color4f_3f( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = a; -} - -static void radeon_Color4fv_3f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = v[3]; -} - - -/* Secondary Color: - */ -#if 0 -static void radeon_SecondaryColor3ubEXT_ub( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.specptr; - dest->red = r; - dest->green = g; - dest->blue = b; - dest->alpha = 0xff; -} - -static void radeon_SecondaryColor3ubvEXT_ub( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.specptr; - dest->red = v[0]; - dest->green = v[1]; - dest->blue = v[2]; - dest->alpha = 0xff; -} -#endif /* 0 */ - -static void radeon_SecondaryColor3fEXT_ub( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.specptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); - dest->alpha = 255; -} - -static void radeon_SecondaryColor3fvEXT_ub( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.specptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); - dest->alpha = 255; -} - -#if 0 -static void radeon_SecondaryColor3ubEXT_3f( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatspecptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); - dest[3] = 1.0; -} - -static void radeon_SecondaryColor3ubvEXT_3f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatspecptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); - dest[3] = 1.0; -} -#endif /* 0 */ - -static void radeon_SecondaryColor3fEXT_3f( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatspecptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; - dest[3] = 1.0; -} - -static void radeon_SecondaryColor3fvEXT_3f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatspecptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - dest[3] = 1.0; -} - - -/* Normal - */ -static void radeon_Normal3f( GLfloat n0, GLfloat n1, GLfloat n2 ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.normalptr; - dest[0] = n0; - dest[1] = n1; - dest[2] = n2; -} - -static void radeon_Normal3fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.normalptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; -} - - -/* TexCoord - */ -static void radeon_TexCoord1f( GLfloat s ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[0]; - dest[0] = s; - dest[1] = 0; -} - -static void radeon_TexCoord1fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[0]; - dest[0] = v[0]; - dest[1] = 0; -} - -static void radeon_TexCoord2f( GLfloat s, GLfloat t ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[0]; - dest[0] = s; - dest[1] = t; -} - -static void radeon_TexCoord2fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[0]; - dest[0] = v[0]; - dest[1] = v[1]; -} - - -/* MultiTexcoord - * - * Technically speaking, these functions should subtract GL_TEXTURE0 from - * \c target before masking and using it. The value of GL_TEXTURE0 is 0x84C0, - * which has the low-order 5 bits 0. For all possible valid values of - * \c target. Subtracting GL_TEXTURE0 has the net effect of masking \c target - * with 0x1F. Masking with 0x1F and then masking with 0x01 is redundant, so - * the subtraction has been omitted. - */ - -static void radeon_MultiTexCoord1fARB( GLenum target, GLfloat s ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[target & 3]; - dest[0] = s; - dest[1] = 0; -} - -static void radeon_MultiTexCoord1fvARB( GLenum target, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[target & 3]; - dest[0] = v[0]; - dest[1] = 0; -} - -static void radeon_MultiTexCoord2fARB( GLenum target, GLfloat s, GLfloat t ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[target & 3]; - dest[0] = s; - dest[1] = t; -} - -static void radeon_MultiTexCoord2fvARB( GLenum target, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[target & 3]; - dest[0] = v[0]; - dest[1] = v[1]; -} - -static struct dynfn *lookup( struct dynfn *l, int key ) -{ - struct dynfn *f; - - foreach( f, l ) { - if (f->key == key) - return f; - } - - return NULL; -} - -/* Can't use the loopback template for this: - */ - -#define CHOOSE(FN, FNTYPE, MASK, ACTIVE, ARGS1, ARGS2 ) \ -static void choose_##FN ARGS1 \ -{ \ - GET_CURRENT_CONTEXT(ctx); \ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ - int key = rmesa->vb.vertex_format & (MASK|ACTIVE); \ - struct dynfn *dfn; \ - \ - dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \ - if (dfn == 0) \ - dfn = rmesa->vb.codegen.FN( ctx, key ); \ - else if (RADEON_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- cached codegen\n", __FUNCTION__ ); \ - \ - if (dfn) \ - SET_ ## FN (ctx->Exec, (FNTYPE)(dfn->code)); \ - else { \ - if (RADEON_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \ - SET_ ## FN (ctx->Exec, radeon_##FN); \ - } \ - \ - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \ - CALL_ ## FN (ctx->Exec, ARGS2); \ -} - - - -/* For the _3f case, only allow one color function to be hooked in at - * a time. Eventually, use a similar mechanism to allow selecting the - * color component of the vertex format based on client behaviour. - * - * Note: Perform these actions even if there is a codegen or cached - * codegen version of the chosen function. - */ -#define CHOOSE_COLOR(FN, FNTYPE, NR, MASK, ACTIVE, ARGS1, ARGS2 ) \ -static void choose_##FN ARGS1 \ -{ \ - GET_CURRENT_CONTEXT(ctx); \ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ - int key = rmesa->vb.vertex_format & (MASK|ACTIVE); \ - struct dynfn *dfn; \ - \ - if (rmesa->vb.vertex_format & ACTIVE_PKCOLOR) { \ - SET_ ## FN (ctx->Exec, radeon_##FN##_ub); \ - } \ - else if ((rmesa->vb.vertex_format & \ - (ACTIVE_FPCOLOR|ACTIVE_FPALPHA)) == ACTIVE_FPCOLOR) { \ - \ - if (rmesa->vb.installed_color_3f_sz != NR) { \ - rmesa->vb.installed_color_3f_sz = NR; \ - if (NR == 3) ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = 1.0; \ - if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) { \ - radeon_copy_to_current( ctx ); \ - _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); \ - CALL_ ## FN (ctx->Exec, ARGS2); \ - return; \ - } \ - } \ - \ - SET_ ## FN (ctx->Exec, radeon_##FN##_3f); \ - } \ - else { \ - SET_ ## FN (ctx->Exec, radeon_##FN##_4f); \ - } \ - \ - \ - dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \ - if (!dfn) dfn = rmesa->vb.codegen.FN( ctx, key ); \ - \ - if (dfn) { \ - if (RADEON_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- codegen version\n", __FUNCTION__ ); \ - SET_ ## FN (ctx->Exec, (FNTYPE)dfn->code); \ - } \ - else if (RADEON_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- 'c' version\n", __FUNCTION__ ); \ - \ - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \ - CALL_ ## FN (ctx->Exec, ARGS2); \ -} - - - -/* Right now there are both _ub and _3f versions of the secondary color - * functions. Currently, we only set-up the hardware to use the _ub versions. - * The _3f versions are needed for the cases where secondary color isn't used - * in the vertex format, but it still needs to be stored in the context - * state vector. - */ -#define CHOOSE_SECONDARY_COLOR(FN, FNTYPE, MASK, ACTIVE, ARGS1, ARGS2 ) \ -static void choose_##FN ARGS1 \ -{ \ - GET_CURRENT_CONTEXT(ctx); \ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ - int key = rmesa->vb.vertex_format & (MASK|ACTIVE); \ - struct dynfn *dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \ - \ - if (dfn == 0) \ - dfn = rmesa->vb.codegen.FN( ctx, key ); \ - else if (RADEON_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- cached version\n", __FUNCTION__ ); \ - \ - if (dfn) \ - SET_ ## FN (ctx->Exec, (FNTYPE)(dfn->code)); \ - else { \ - if (RADEON_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \ - SET_ ## FN (ctx->Exec, ((rmesa->vb.vertex_format & ACTIVE_PKSPEC) != 0) \ - ? radeon_##FN##_ub : radeon_##FN##_3f); \ - } \ - \ - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \ - CALL_ ## FN (ctx->Exec, ARGS2); \ -} - - - - - -/* Shorthands - */ -#define ACTIVE_XYZW (RADEON_CP_VC_FRMT_W0|RADEON_CP_VC_FRMT_Z) -#define ACTIVE_NORM RADEON_CP_VC_FRMT_N0 - -#define ACTIVE_PKCOLOR RADEON_CP_VC_FRMT_PKCOLOR -#define ACTIVE_FPCOLOR RADEON_CP_VC_FRMT_FPCOLOR -#define ACTIVE_FPALPHA RADEON_CP_VC_FRMT_FPALPHA -#define ACTIVE_COLOR (ACTIVE_FPCOLOR|ACTIVE_PKCOLOR) - -#define ACTIVE_PKSPEC RADEON_CP_VC_FRMT_PKSPEC -#define ACTIVE_FPSPEC RADEON_CP_VC_FRMT_FPSPEC -#define ACTIVE_SPEC (ACTIVE_FPSPEC|ACTIVE_PKSPEC) - -#define ACTIVE_ST0 RADEON_CP_VC_FRMT_ST0 -#define ACTIVE_ST1 RADEON_CP_VC_FRMT_ST1 -#define ACTIVE_ST2 RADEON_CP_VC_FRMT_ST2 -#define ACTIVE_ST_ALL (RADEON_CP_VC_FRMT_ST1|RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST2) - -/* Each codegen function should be able to be fully specified by a - * subsetted version of rmesa->vb.vertex_format. - */ -#define MASK_NORM (ACTIVE_XYZW) -#define MASK_COLOR (MASK_NORM|ACTIVE_NORM) -#define MASK_SPEC (MASK_COLOR|ACTIVE_COLOR) -#define MASK_ST0 (MASK_SPEC|ACTIVE_SPEC) -#define MASK_ST1 (MASK_ST0|ACTIVE_ST0) -#define MASK_ST2 (MASK_ST1|ACTIVE_ST1) -#define MASK_ST_ALL (MASK_ST2|ACTIVE_ST2) -#define MASK_VERTEX (MASK_ST_ALL|ACTIVE_FPALPHA) - - -typedef void (*p4f)( GLfloat, GLfloat, GLfloat, GLfloat ); -typedef void (*p3f)( GLfloat, GLfloat, GLfloat ); -typedef void (*p2f)( GLfloat, GLfloat ); -typedef void (*p1f)( GLfloat ); -typedef void (*pe2f)( GLenum, GLfloat, GLfloat ); -typedef void (*pe1f)( GLenum, GLfloat ); -typedef void (*p4ub)( GLubyte, GLubyte, GLubyte, GLubyte ); -typedef void (*p3ub)( GLubyte, GLubyte, GLubyte ); -typedef void (*pfv)( const GLfloat * ); -typedef void (*pefv)( GLenum, const GLfloat * ); -typedef void (*pubv)( const GLubyte * ); - - -CHOOSE(Normal3f, p3f, MASK_NORM, ACTIVE_NORM, - (GLfloat a,GLfloat b,GLfloat c), (a,b,c)) -CHOOSE(Normal3fv, pfv, MASK_NORM, ACTIVE_NORM, - (const GLfloat *v), (v)) - -#if 0 -CHOOSE_COLOR(Color4ub, p4ub, 4, MASK_COLOR, ACTIVE_COLOR, - (GLubyte a,GLubyte b, GLubyte c, GLubyte d), (a,b,c,d)) -CHOOSE_COLOR(Color4ubv, pubv, 4, MASK_COLOR, ACTIVE_COLOR, - (const GLubyte *v), (v)) -CHOOSE_COLOR(Color3ub, p3ub, 3, MASK_COLOR, ACTIVE_COLOR, - (GLubyte a,GLubyte b, GLubyte c), (a,b,c)) -CHOOSE_COLOR(Color3ubv, pubv, 3, MASK_COLOR, ACTIVE_COLOR, - (const GLubyte *v), (v)) -#endif - -CHOOSE_COLOR(Color4f, p4f, 4, MASK_COLOR, ACTIVE_COLOR, - (GLfloat a,GLfloat b, GLfloat c, GLfloat d), (a,b,c,d)) -CHOOSE_COLOR(Color4fv, pfv, 4, MASK_COLOR, ACTIVE_COLOR, - (const GLfloat *v), (v)) -CHOOSE_COLOR(Color3f, p3f, 3, MASK_COLOR, ACTIVE_COLOR, - (GLfloat a,GLfloat b, GLfloat c), (a,b,c)) -CHOOSE_COLOR(Color3fv, pfv, 3, MASK_COLOR, ACTIVE_COLOR, - (const GLfloat *v), (v)) - - -#if 0 -CHOOSE_SECONDARY_COLOR(SecondaryColor3ubEXT, p3ub, MASK_SPEC, ACTIVE_SPEC, - (GLubyte a,GLubyte b, GLubyte c), (a,b,c)) -CHOOSE_SECONDARY_COLOR(SecondaryColor3ubvEXT, pubv, MASK_SPEC, ACTIVE_SPEC, - (const GLubyte *v), (v)) -#endif -CHOOSE_SECONDARY_COLOR(SecondaryColor3fEXT, p3f, MASK_SPEC, ACTIVE_SPEC, - (GLfloat a,GLfloat b, GLfloat c), (a,b,c)) -CHOOSE_SECONDARY_COLOR(SecondaryColor3fvEXT, pfv, MASK_SPEC, ACTIVE_SPEC, - (const GLfloat *v), (v)) - -CHOOSE(TexCoord2f, p2f, MASK_ST0, ACTIVE_ST0, - (GLfloat a,GLfloat b), (a,b)) -CHOOSE(TexCoord2fv, pfv, MASK_ST0, ACTIVE_ST0, - (const GLfloat *v), (v)) -CHOOSE(TexCoord1f, p1f, MASK_ST0, ACTIVE_ST0, - (GLfloat a), (a)) -CHOOSE(TexCoord1fv, pfv, MASK_ST0, ACTIVE_ST0, - (const GLfloat *v), (v)) - -CHOOSE(MultiTexCoord2fARB, pe2f, MASK_ST_ALL, ACTIVE_ST_ALL, - (GLenum u,GLfloat a,GLfloat b), (u,a,b)) -CHOOSE(MultiTexCoord2fvARB, pefv, MASK_ST_ALL, ACTIVE_ST_ALL, - (GLenum u,const GLfloat *v), (u,v)) -CHOOSE(MultiTexCoord1fARB, pe1f, MASK_ST_ALL, ACTIVE_ST_ALL, - (GLenum u,GLfloat a), (u,a)) -CHOOSE(MultiTexCoord1fvARB, pefv, MASK_ST_ALL, ACTIVE_ST_ALL, - (GLenum u,const GLfloat *v), (u,v)) - -CHOOSE(Vertex3f, p3f, MASK_VERTEX, MASK_VERTEX, - (GLfloat a,GLfloat b,GLfloat c), (a,b,c)) -CHOOSE(Vertex3fv, pfv, MASK_VERTEX, MASK_VERTEX, - (const GLfloat *v), (v)) -CHOOSE(Vertex2f, p2f, MASK_VERTEX, MASK_VERTEX, - (GLfloat a,GLfloat b), (a,b)) -CHOOSE(Vertex2fv, pfv, MASK_VERTEX, MASK_VERTEX, - (const GLfloat *v), (v)) - - - - - -void radeonVtxfmtInitChoosers( GLvertexformat *vfmt ) -{ - vfmt->Color3f = choose_Color3f; - vfmt->Color3fv = choose_Color3fv; - vfmt->Color4f = choose_Color4f; - vfmt->Color4fv = choose_Color4fv; - vfmt->SecondaryColor3fEXT = choose_SecondaryColor3fEXT; - vfmt->SecondaryColor3fvEXT = choose_SecondaryColor3fvEXT; - vfmt->MultiTexCoord1fARB = choose_MultiTexCoord1fARB; - vfmt->MultiTexCoord1fvARB = choose_MultiTexCoord1fvARB; - vfmt->MultiTexCoord2fARB = choose_MultiTexCoord2fARB; - vfmt->MultiTexCoord2fvARB = choose_MultiTexCoord2fvARB; - vfmt->Normal3f = choose_Normal3f; - vfmt->Normal3fv = choose_Normal3fv; - vfmt->TexCoord1f = choose_TexCoord1f; - vfmt->TexCoord1fv = choose_TexCoord1fv; - vfmt->TexCoord2f = choose_TexCoord2f; - vfmt->TexCoord2fv = choose_TexCoord2fv; - vfmt->Vertex2f = choose_Vertex2f; - vfmt->Vertex2fv = choose_Vertex2fv; - vfmt->Vertex3f = choose_Vertex3f; - vfmt->Vertex3fv = choose_Vertex3fv; - -#if 0 - vfmt->Color3ub = choose_Color3ub; - vfmt->Color3ubv = choose_Color3ubv; - vfmt->Color4ub = choose_Color4ub; - vfmt->Color4ubv = choose_Color4ubv; - vfmt->SecondaryColor3ubEXT = choose_SecondaryColor3ubEXT; - vfmt->SecondaryColor3ubvEXT = choose_SecondaryColor3ubvEXT; -#endif -} - - -static struct dynfn *codegen_noop( GLcontext *ctx, int key ) -{ - (void) ctx; (void) key; - return NULL; -} - -void radeonInitCodegen( struct dfn_generators *gen, GLboolean useCodegen ) -{ - gen->Vertex3f = codegen_noop; - gen->Vertex3fv = codegen_noop; - gen->Color4ub = codegen_noop; - gen->Color4ubv = codegen_noop; - gen->Normal3f = codegen_noop; - gen->Normal3fv = codegen_noop; - gen->TexCoord2f = codegen_noop; - gen->TexCoord2fv = codegen_noop; - gen->MultiTexCoord2fARB = codegen_noop; - gen->MultiTexCoord2fvARB = codegen_noop; - gen->Vertex2f = codegen_noop; - gen->Vertex2fv = codegen_noop; - gen->Color3ub = codegen_noop; - gen->Color3ubv = codegen_noop; - gen->Color4f = codegen_noop; - gen->Color4fv = codegen_noop; - gen->Color3f = codegen_noop; - gen->Color3fv = codegen_noop; - gen->SecondaryColor3fEXT = codegen_noop; - gen->SecondaryColor3fvEXT = codegen_noop; - gen->SecondaryColor3ubEXT = codegen_noop; - gen->SecondaryColor3ubvEXT = codegen_noop; - gen->TexCoord1f = codegen_noop; - gen->TexCoord1fv = codegen_noop; - gen->MultiTexCoord1fARB = codegen_noop; - gen->MultiTexCoord1fvARB = codegen_noop; - - if (useCodegen) { -#if defined(USE_X86_ASM) - radeonInitX86Codegen( gen ); -#endif - -#if defined(USE_SSE_ASM) - radeonInitSSECodegen( gen ); -#endif - } -} diff --git a/src/mesa/drivers/dri/radeon/radeon_vtxfmt_sse.c b/src/mesa/drivers/dri/radeon/radeon_vtxfmt_sse.c deleted file mode 100644 index 0f0fc9e065..0000000000 --- a/src/mesa/drivers/dri/radeon/radeon_vtxfmt_sse.c +++ /dev/null @@ -1,236 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_sse.c,v 1.1 2002/10/30 12:51:58 alanh Exp $ */ -/************************************************************************** - -Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and - 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 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 (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 NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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 - */ - -#include "glheader.h" -#include "imports.h" -#include "simple_list.h" -#include "radeon_vtxfmt.h" - -#if defined(USE_SSE_ASM) -#include "x86/common_x86_asm.h" - -#define EXTERN( FUNC ) \ -extern const char *FUNC; \ -extern const char *FUNC##_end - -EXTERN( _sse_Attribute2fv ); -EXTERN( _sse_Attribute2f ); -EXTERN( _sse_Attribute3fv ); -EXTERN( _sse_Attribute3f ); -EXTERN( _sse_MultiTexCoord2fv ); -EXTERN( _sse_MultiTexCoord2f ); -EXTERN( _sse_MultiTexCoord2fv_2 ); -EXTERN( _sse_MultiTexCoord2f_2 ); - -/* Build specialized versions of the immediate calls on the fly for - * the current state. - */ - -static struct dynfn *radeon_makeSSEAttribute2fv( struct dynfn * cache, int key, - const char * name, void * dest) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key ); - - DFN ( _sse_Attribute2fv, (*cache) ); - FIXUP(dfn->code, 10, 0x0, (int)dest); - return dfn; -} - -static struct dynfn *radeon_makeSSEAttribute2f( struct dynfn * cache, int key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key ); - - DFN ( _sse_Attribute2f, (*cache) ); - FIXUP(dfn->code, 8, 0x0, (int)dest); - return dfn; -} - -static struct dynfn *radeon_makeSSEAttribute3fv( struct dynfn * cache, int key, - const char * name, void * dest) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key ); - - DFN ( _sse_Attribute3fv, (*cache) ); - FIXUP(dfn->code, 13, 0x0, (int)dest); - FIXUP(dfn->code, 18, 0x8, 8+(int)dest); - return dfn; -} - -static struct dynfn *radeon_makeSSEAttribute3f( struct dynfn * cache, int key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key ); - - DFN ( _sse_Attribute3f, (*cache) ); - FIXUP(dfn->code, 12, 0x0, (int)dest); - FIXUP(dfn->code, 17, 0x8, 8+(int)dest); - return dfn; -} - -static struct dynfn * radeon_makeSSENormal3fv( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeSSEAttribute3fv( & rmesa->vb.dfn_cache.Normal3fv, key, - __FUNCTION__, rmesa->vb.normalptr ); -} - -static struct dynfn *radeon_makeSSENormal3f( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeSSEAttribute3f( & rmesa->vb.dfn_cache.Normal3f, key, - __FUNCTION__, rmesa->vb.normalptr ); -} - -static struct dynfn *radeon_makeSSEColor3fv( GLcontext *ctx, int key ) -{ - if (key & (RADEON_CP_VC_FRMT_PKCOLOR|RADEON_CP_VC_FRMT_FPALPHA)) - return NULL; - else - { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeSSEAttribute3fv( & rmesa->vb.dfn_cache.Color3fv, key, - __FUNCTION__, rmesa->vb.floatcolorptr ); - } -} - -static struct dynfn *radeon_makeSSEColor3f( GLcontext *ctx, int key ) -{ - if (key & (RADEON_CP_VC_FRMT_PKCOLOR|RADEON_CP_VC_FRMT_FPALPHA)) - return NULL; - else - { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeSSEAttribute3f( & rmesa->vb.dfn_cache.Color3f, key, - __FUNCTION__, rmesa->vb.floatcolorptr ); - } -} - -static struct dynfn *radeon_makeSSETexCoord2fv( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeSSEAttribute2fv( & rmesa->vb.dfn_cache.TexCoord2fv, key, - __FUNCTION__, rmesa->vb.texcoordptr[0] ); -} - -static struct dynfn *radeon_makeSSETexCoord2f( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeSSEAttribute2f( & rmesa->vb.dfn_cache.TexCoord2f, key, - __FUNCTION__, rmesa->vb.texcoordptr[0] ); -} - -#if 0 /* Temporarily disabled - probably needs adjustments for more than 2 tex units -rs */ -static struct dynfn *radeon_makeSSEMultiTexCoord2fv( GLcontext *ctx, int key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); - - if ((key & (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) == - (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) { - DFN ( _sse_MultiTexCoord2fv, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - FIXUP(dfn->code, 18, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); - } else { - DFN ( _sse_MultiTexCoord2fv_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - FIXUP(dfn->code, 14, 0x0, (int)rmesa->vb.texcoordptr); - } - return dfn; -} - -static struct dynfn *radeon_makeSSEMultiTexCoord2f( GLcontext *ctx, int key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); - - if ((key & (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) == - (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) { - DFN ( _sse_MultiTexCoord2f, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - FIXUP(dfn->code, 16, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); - } else { - DFN ( _sse_MultiTexCoord2f_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - FIXUP(dfn->code, 15, 0x0, (int)rmesa->vb.texcoordptr); - } - return dfn; -} -#endif - -void radeonInitSSECodegen( struct dfn_generators *gen ) -{ - if ( cpu_has_xmm ) { - gen->Normal3fv = (void *) radeon_makeSSENormal3fv; - gen->Normal3f = (void *) radeon_makeSSENormal3f; - gen->Color3fv = (void *) radeon_makeSSEColor3fv; - gen->Color3f = (void *) radeon_makeSSEColor3f; - gen->TexCoord2fv = (void *) radeon_makeSSETexCoord2fv; - gen->TexCoord2f = (void *) radeon_makeSSETexCoord2f; -#if 0 /* Temporarily disabled - probably needs adjustments for more than 2 tex units -rs */ - gen->MultiTexCoord2fvARB = (void *) radeon_makeSSEMultiTexCoord2fv; - gen->MultiTexCoord2fARB = (void *) radeon_makeSSEMultiTexCoord2f; -#endif - } -} - -#else - -void radeonInitSSECodegen( struct dfn_generators *gen ) -{ - (void) gen; -} - -#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_vtxfmt_x86.c b/src/mesa/drivers/dri/radeon/radeon_vtxfmt_x86.c deleted file mode 100644 index 529e79065e..0000000000 --- a/src/mesa/drivers/dri/radeon/radeon_vtxfmt_x86.c +++ /dev/null @@ -1,440 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_x86.c,v 1.2 2002/12/21 17:02:16 dawes Exp $ */ -/************************************************************************** - -Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and - 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 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 (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 NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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 - */ - -#include "glheader.h" -#include "imports.h" -#include "simple_list.h" -#include "radeon_vtxfmt.h" - -#if defined(USE_X86_ASM) - -#define EXTERN( FUNC ) \ -extern const char *FUNC; \ -extern const char *FUNC##_end - -EXTERN ( _x86_Attribute2fv ); -EXTERN ( _x86_Attribute2f ); -EXTERN ( _x86_Attribute3fv ); -EXTERN ( _x86_Attribute3f ); -EXTERN ( _x86_Vertex3fv_6 ); -EXTERN ( _x86_Vertex3fv_8 ); -EXTERN ( _x86_Vertex3fv ); -EXTERN ( _x86_Vertex3f_4 ); -EXTERN ( _x86_Vertex3f_6 ); -EXTERN ( _x86_Vertex3f ); -EXTERN ( _x86_Color4ubv_ub ); -EXTERN ( _x86_Color4ubv_4f ); -EXTERN ( _x86_Color4ub_ub ); -EXTERN ( _x86_MultiTexCoord2fv ); -EXTERN ( _x86_MultiTexCoord2fv_2 ); -EXTERN ( _x86_MultiTexCoord2f ); -EXTERN ( _x86_MultiTexCoord2f_2 ); - - -/* Build specialized versions of the immediate calls on the fly for - * the current state. Generic x86 versions. - */ - -struct dynfn *radeon_makeX86Vertex3f( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x %d\n", __FUNCTION__, key, rmesa->vb.vertex_size ); - - switch (rmesa->vb.vertex_size) { - case 4: { - - DFN ( _x86_Vertex3f_4, rmesa->vb.dfn_cache.Vertex3f ); - FIXUP(dfn->code, 2, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 25, 0x0, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 36, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 46, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 51, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 60, 0x0, (int)&rmesa->vb.notify); - break; - } - case 6: { - - DFN ( _x86_Vertex3f_6, rmesa->vb.dfn_cache.Vertex3f ); - FIXUP(dfn->code, 3, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 28, 0x0, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 34, 0x0, (int)&rmesa->vb.vertex[4]); - FIXUP(dfn->code, 40, 0x0, (int)&rmesa->vb.vertex[5]); - FIXUP(dfn->code, 57, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 63, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 70, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 79, 0x0, (int)&rmesa->vb.notify); - break; - } - default: { - - DFN ( _x86_Vertex3f, rmesa->vb.dfn_cache.Vertex3f ); - FIXUP(dfn->code, 3, 0x0, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 9, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 37, 0x0, rmesa->vb.vertex_size-3); - FIXUP(dfn->code, 44, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 50, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 56, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 67, 0x0, (int)&rmesa->vb.notify); - break; - } - } - - return dfn; -} - - - -struct dynfn *radeon_makeX86Vertex3fv( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x %d\n", __FUNCTION__, key, rmesa->vb.vertex_size ); - - switch (rmesa->vb.vertex_size) { - case 6: { - - DFN ( _x86_Vertex3fv_6, rmesa->vb.dfn_cache.Vertex3fv ); - FIXUP(dfn->code, 1, 0x00000000, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 27, 0x0000001c, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 33, 0x00000020, (int)&rmesa->vb.vertex[4]); - FIXUP(dfn->code, 45, 0x00000024, (int)&rmesa->vb.vertex[5]); - FIXUP(dfn->code, 56, 0x00000000, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 61, 0x00000004, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 67, 0x00000004, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 76, 0x00000008, (int)&rmesa->vb.notify); - break; - } - - - case 8: { - - DFN ( _x86_Vertex3fv_8, rmesa->vb.dfn_cache.Vertex3fv ); - FIXUP(dfn->code, 1, 0x00000000, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 27, 0x0000001c, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 33, 0x00000020, (int)&rmesa->vb.vertex[4]); - FIXUP(dfn->code, 45, 0x0000001c, (int)&rmesa->vb.vertex[5]); - FIXUP(dfn->code, 51, 0x00000020, (int)&rmesa->vb.vertex[6]); - FIXUP(dfn->code, 63, 0x00000024, (int)&rmesa->vb.vertex[7]); - FIXUP(dfn->code, 74, 0x00000000, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 79, 0x00000004, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 85, 0x00000004, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 94, 0x00000008, (int)&rmesa->vb.notify); - break; - } - - - - default: { - - DFN ( _x86_Vertex3fv, rmesa->vb.dfn_cache.Vertex3fv ); - FIXUP(dfn->code, 8, 0x01010101, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 32, 0x00000006, rmesa->vb.vertex_size-3); - FIXUP(dfn->code, 37, 0x00000058, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 45, 0x01010101, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 50, 0x02020202, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 58, 0x02020202, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 67, 0x0, (int)&rmesa->vb.notify); - break; - } - } - - return dfn; -} - -static struct dynfn * -radeon_makeX86Attribute2fv( struct dynfn * cache, int key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key ); - - DFN ( _x86_Attribute2fv, (*cache) ); - FIXUP(dfn->code, 11, 0x0, (int)dest); - FIXUP(dfn->code, 16, 0x4, 4+(int)dest); - - return dfn; -} - -static struct dynfn * -radeon_makeX86Attribute2f( struct dynfn * cache, int key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key ); - - DFN ( _x86_Attribute2f, (*cache) ); - FIXUP(dfn->code, 1, 0x0, (int)dest); - - return dfn; -} - - -static struct dynfn * -radeon_makeX86Attribute3fv( struct dynfn * cache, int key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key ); - - DFN ( _x86_Attribute3fv, (*cache) ); - FIXUP(dfn->code, 14, 0x0, (int)dest); - FIXUP(dfn->code, 20, 0x4, 4+(int)dest); - FIXUP(dfn->code, 25, 0x8, 8+(int)dest); - - return dfn; -} - -static struct dynfn * -radeon_makeX86Attribute3f( struct dynfn * cache, int key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key ); - - DFN ( _x86_Attribute3f, (*cache) ); - FIXUP(dfn->code, 14, 0x0, (int)dest); - FIXUP(dfn->code, 20, 0x4, 4+(int)dest); - FIXUP(dfn->code, 25, 0x8, 8+(int)dest); - - return dfn; -} - -struct dynfn *radeon_makeX86Normal3fv( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeX86Attribute3fv( & rmesa->vb.dfn_cache.Normal3fv, key, - __FUNCTION__, rmesa->vb.normalptr ); -} - -struct dynfn *radeon_makeX86Normal3f( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeX86Attribute3f( & rmesa->vb.dfn_cache.Normal3f, key, - __FUNCTION__, rmesa->vb.normalptr ); -} - -struct dynfn *radeon_makeX86Color4ubv( GLcontext *ctx, int key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); - - if (key & RADEON_CP_VC_FRMT_PKCOLOR) { - DFN ( _x86_Color4ubv_ub, rmesa->vb.dfn_cache.Color4ubv); - FIXUP(dfn->code, 5, 0x12345678, (int)rmesa->vb.colorptr); - return dfn; - } - else { - - DFN ( _x86_Color4ubv_4f, rmesa->vb.dfn_cache.Color4ubv); - FIXUP(dfn->code, 2, 0x00000000, (int)_mesa_ubyte_to_float_color_tab); - FIXUP(dfn->code, 27, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr); - FIXUP(dfn->code, 33, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr+4); - FIXUP(dfn->code, 55, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr+8); - FIXUP(dfn->code, 61, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr+12); - return dfn; - } -} - -struct dynfn *radeon_makeX86Color4ub( GLcontext *ctx, int key ) -{ - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); - - if (key & RADEON_CP_VC_FRMT_PKCOLOR) { - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - DFN ( _x86_Color4ub_ub, rmesa->vb.dfn_cache.Color4ub ); - FIXUP(dfn->code, 18, 0x0, (int)rmesa->vb.colorptr); - FIXUP(dfn->code, 24, 0x0, (int)rmesa->vb.colorptr+1); - FIXUP(dfn->code, 30, 0x0, (int)rmesa->vb.colorptr+2); - FIXUP(dfn->code, 36, 0x0, (int)rmesa->vb.colorptr+3); - return dfn; - } - else - return NULL; -} - - -struct dynfn *radeon_makeX86Color3fv( GLcontext *ctx, int key ) -{ - if (key & (RADEON_CP_VC_FRMT_PKCOLOR|RADEON_CP_VC_FRMT_FPALPHA)) - return NULL; - else - { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeX86Attribute3fv( & rmesa->vb.dfn_cache.Color3fv, key, - __FUNCTION__, rmesa->vb.floatcolorptr ); - } -} - -struct dynfn *radeon_makeX86Color3f( GLcontext *ctx, int key ) -{ - if (key & (RADEON_CP_VC_FRMT_PKCOLOR|RADEON_CP_VC_FRMT_FPALPHA)) - return NULL; - else - { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeX86Attribute3f( & rmesa->vb.dfn_cache.Color3f, key, - __FUNCTION__, rmesa->vb.floatcolorptr ); - } -} - - - -struct dynfn *radeon_makeX86TexCoord2fv( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeX86Attribute2fv( & rmesa->vb.dfn_cache.TexCoord2fv, key, - __FUNCTION__, rmesa->vb.texcoordptr[0] ); -} - -struct dynfn *radeon_makeX86TexCoord2f( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeX86Attribute2f( & rmesa->vb.dfn_cache.TexCoord2f, key, - __FUNCTION__, rmesa->vb.texcoordptr[0] ); -} - -#if 0 /* Temporarily disabled - probably needs adjustments for more than 2 tex units -rs */ -struct dynfn *radeon_makeX86MultiTexCoord2fvARB( GLcontext *ctx, int key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); - - if ((key & (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) == - (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) { - DFN ( _x86_MultiTexCoord2fv, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - FIXUP(dfn->code, 21, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); - FIXUP(dfn->code, 27, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]+4); - } else { - DFN ( _x86_MultiTexCoord2fv_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - FIXUP(dfn->code, 14, 0x0, (int)rmesa->vb.texcoordptr); - } - return dfn; -} - -struct dynfn *radeon_makeX86MultiTexCoord2fARB( GLcontext *ctx, - int key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); - - if ((key & (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) == - (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) { - DFN ( _x86_MultiTexCoord2f, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - FIXUP(dfn->code, 20, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); - FIXUP(dfn->code, 26, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]+4); - } - else { - /* Note: this might get generated multiple times, even though the - * actual emitted code is the same. - */ - DFN ( _x86_MultiTexCoord2f_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - FIXUP(dfn->code, 18, 0x0, (int)rmesa->vb.texcoordptr); - } - return dfn; -} -#endif - -void radeonInitX86Codegen( struct dfn_generators *gen ) -{ - gen->Vertex3f = radeon_makeX86Vertex3f; - gen->Vertex3fv = radeon_makeX86Vertex3fv; - gen->Color4ub = radeon_makeX86Color4ub; /* PKCOLOR only */ - gen->Color4ubv = radeon_makeX86Color4ubv; /* PKCOLOR only */ - gen->Normal3f = radeon_makeX86Normal3f; - gen->Normal3fv = radeon_makeX86Normal3fv; - gen->TexCoord2f = radeon_makeX86TexCoord2f; - gen->TexCoord2fv = radeon_makeX86TexCoord2fv; -#if 0 /* Temporarily disabled - probably needs adjustments for more than 2 tex units -rs */ - gen->MultiTexCoord2fARB = radeon_makeX86MultiTexCoord2fARB; - gen->MultiTexCoord2fvARB = radeon_makeX86MultiTexCoord2fvARB; -#endif - gen->Color3f = radeon_makeX86Color3f; - gen->Color3fv = radeon_makeX86Color3fv; - - /* Not done: - */ -/* gen->Vertex2f = radeon_makeX86Vertex2f; */ -/* gen->Vertex2fv = radeon_makeX86Vertex2fv; */ -/* gen->Color3ub = radeon_makeX86Color3ub; */ -/* gen->Color3ubv = radeon_makeX86Color3ubv; */ -/* gen->Color4f = radeon_makeX86Color4f; */ -/* gen->Color4fv = radeon_makeX86Color4fv; */ -/* gen->TexCoord1f = radeon_makeX86TexCoord1f; */ -/* gen->TexCoord1fv = radeon_makeX86TexCoord1fv; */ -/* gen->MultiTexCoord1fARB = radeon_makeX86MultiTexCoord1fARB; */ -/* gen->MultiTexCoord1fvARB = radeon_makeX86MultiTexCoord1fvARB; */ -} - - -#else - -void radeonInitX86Codegen( struct dfn_generators *gen ) -{ - (void) gen; -} - -#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_vtxtmp_x86.S b/src/mesa/drivers/dri/radeon/radeon_vtxtmp_x86.S deleted file mode 100644 index 1b433491aa..0000000000 --- a/src/mesa/drivers/dri/radeon/radeon_vtxtmp_x86.S +++ /dev/null @@ -1,498 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxtmp_x86.S,v 1.1 2002/10/30 12:51:58 alanh Exp $ */ -/************************************************************************** - -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 -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. - -**************************************************************************/ - -#define GLOBL( x ) \ -.globl x; \ -x: - -.data -.align 4 - -/* - vertex 3f vertex size 4 -*/ - -GLOBL ( _x86_Vertex3f_4 ) - movl (0), %ecx - movl 4(%esp), %eax - movl 8(%esp), %edx - movl %eax, (%ecx) - movl %edx, 4(%ecx) - movl 12(%esp), %eax - movl (0), %edx - movl %eax, 8(%ecx) - movl %edx, 12(%ecx) - movl (0), %eax - addl $16, %ecx - dec %eax - movl %ecx, (0) - movl %eax, (0) - je .1 - ret -.1: jmp *0 - -GLOBL ( _x86_Vertex3f_4_end ) - -/* - vertex 3f vertex size 6 -*/ -GLOBL ( _x86_Vertex3f_6 ) - push %edi - movl (0), %edi - movl 8(%esp), %eax - movl 12(%esp), %edx - movl 16(%esp), %ecx - movl %eax, (%edi) - movl %edx, 4(%edi) - movl %ecx, 8(%edi) - movl (0), %eax - movl (0), %edx - movl (0), %ecx - movl %eax, 12(%edi) - movl %edx, 16(%edi) - movl %ecx, 20(%edi) - addl $24, %edi - movl (0), %eax - movl %edi, (0) - dec %eax - pop %edi - movl %eax, (0) - je .2 - ret -.2: jmp *0 -GLOBL ( _x86_Vertex3f_6_end ) -/* - vertex 3f generic size -*/ -GLOBL ( _x86_Vertex3f ) - push %edi - push %esi - movl $0, %esi - movl (0), %edi - movl 12(%esp), %eax - movl 16(%esp), %edx - movl 20(%esp), %ecx - movl %eax, (%edi) - movl %edx, 4(%edi) - movl %ecx, 8(%edi) - addl $12, %edi - movl $0, %ecx - repz - movsl %ds:(%esi), %es:(%edi) - movl (0), %eax - movl %edi, (0) - dec %eax - movl %eax, (0) - pop %esi - pop %edi - je .3 - ret -.3: jmp *0 - -GLOBL ( _x86_Vertex3f_end ) - -/* - Vertex 3fv vertex size 6 -*/ -GLOBL ( _x86_Vertex3fv_6 ) - movl (0), %eax - movl 4(%esp), %ecx - movl (%ecx), %edx - movl %edx, (%eax) - movl 4(%ecx), %edx - movl 8(%ecx), %ecx - movl %edx, 4(%eax) - movl %ecx, 8(%eax) - movl (28), %edx - movl (32), %ecx - movl %edx, 12(%eax) - movl %ecx, 16(%eax) - movl (36), %edx - movl %edx, 20(%eax) - addl $24, %eax - movl %eax, 0 - movl 4, %eax - dec %eax - movl %eax, 4 - je .4 - ret -.4: jmp *8 - -GLOBL ( _x86_Vertex3fv_6_end ) - -/* - Vertex 3fv vertex size 8 -*/ -GLOBL ( _x86_Vertex3fv_8 ) - movl (0), %eax - movl 4(%esp), %ecx - movl (%ecx), %edx - movl %edx ,(%eax) - movl 4(%ecx) ,%edx - movl 8(%ecx) ,%ecx - movl %edx, 4(%eax) - movl %ecx, 8(%eax) - movl (28), %edx - movl (32), %ecx - movl %edx, 12(%eax) - movl %ecx, 16(%eax) - movl (28), %edx - movl (32), %ecx - movl %edx, 20(%eax) - movl %ecx, 24(%eax) - movl (36), %edx - movl %edx, 28(%eax) - addl $32, %eax - movl %eax, (0) - movl 4, %eax - dec %eax - movl %eax, (4) - je .5 - ret -.5: jmp *8 - -GLOBL ( _x86_Vertex3fv_8_end ) - -/* - Vertex 3fv generic vertex size -*/ -GLOBL ( _x86_Vertex3fv ) - movl 4(%esp), %edx - push %edi - push %esi - movl (0x1010101), %edi - movl (%edx), %eax - movl 4(%edx), %ecx - movl 8(%edx), %esi - movl %eax, (%edi) - movl %ecx, 4(%edi) - movl %esi, 8(%edi) - addl $12, %edi - movl $6, %ecx - movl $0x58, %esi - repz - movsl %ds:(%esi), %es:(%edi) - movl %edi, (0x1010101) - movl (0x2020202), %eax - pop %esi - pop %edi - dec %eax - movl %eax, (0x2020202) - je .6 - ret -.6: jmp *0 -GLOBL ( _x86_Vertex3fv_end ) - - -/** - * Generic handler for 2 float format data. This can be used for - * TexCoord2f and possibly other functions. - */ - -GLOBL ( _x86_Attribute2f ) - movl $0x0, %edx - movl 4(%esp), %eax - movl 8(%esp), %ecx - movl %eax, (%edx) - movl %ecx, 4(%edx) - ret -GLOBL ( _x86_Attribute2f_end ) - - -/** - * Generic handler for 2 float vector format data. This can be used for - * TexCoord2fv and possibly other functions. - */ - -GLOBL( _x86_Attribute2fv) - movl 4(%esp), %eax /* load 'v' off stack */ - movl (%eax), %ecx /* load v[0] */ - movl 4(%eax), %eax /* load v[1] */ - movl %ecx, 0 /* store v[0] to current vertex */ - movl %eax, 4 /* store v[1] to current vertex */ - ret -GLOBL ( _x86_Attribute2fv_end ) - - -/** - * Generic handler for 3 float format data. This can be used for - * Normal3f, Color3f (when the color target is also float), or - * TexCoord3f. - */ - -GLOBL ( _x86_Attribute3f ) - movl 4(%esp), %ecx - movl 8(%esp), %edx - movl 12(%esp), %eax - movl %ecx, 0 - movl %edx, 4 - movl %eax, 8 - ret -GLOBL ( _x86_Attribute3f_end ) - -/** - * Generic handler for 3 float vector format data. This can be used for - * Normal3f, Color3f (when the color target is also float), or - * TexCoord3f. - */ - -GLOBL( _x86_Attribute3fv) - movl 4(%esp), %eax /* load 'v' off stack */ - movl (%eax), %ecx /* load v[0] */ - movl 4(%eax), %edx /* load v[1] */ - movl 8(%eax), %eax /* load v[2] */ - movl %ecx, 0 /* store v[0] to current vertex */ - movl %edx, 4 /* store v[1] to current vertex */ - movl %eax, 8 /* store v[2] to current vertex */ - ret -GLOBL ( _x86_Attribute3fv_end ) - - -/* - Color 4ubv_ub -*/ -GLOBL ( _x86_Color4ubv_ub ) - movl 4(%esp), %eax - movl $0x12345678, %edx - movl (%eax), %eax - movl %eax, (%edx) - ret -GLOBL ( _x86_Color4ubv_ub_end ) - -/* - Color 4ubv 4f -*/ -GLOBL ( _x86_Color4ubv_4f ) - push %ebx - movl $0, %edx - xor %eax, %eax - xor %ecx, %ecx - movl 8(%esp), %ebx - movl (%ebx), %ebx - mov %bl, %al - mov %bh, %cl - movl (%edx,%eax,4),%eax - movl (%edx,%ecx,4),%ecx - movl %eax, (0xdeadbeaf) - movl %ecx, (0xdeadbeaf) - xor %eax, %eax - xor %ecx, %ecx - shr $16, %ebx - mov %bl, %al - mov %bh, %cl - movl (%edx,%eax,4), %eax - movl (%edx,%ecx,4), %ecx - movl %eax, (0xdeadbeaf) - movl %ecx, (0xdeadbeaf) - pop %ebx - ret -GLOBL ( _x86_Color4ubv_4f_end ) - -/* - - Color4ub_ub -*/ -GLOBL( _x86_Color4ub_ub ) - push %ebx - movl 8(%esp), %eax - movl 12(%esp), %edx - movl 16(%esp), %ecx - movl 20(%esp), %ebx - mov %al, (0) - mov %dl, (0) - mov %cl, (0) - mov %bl, (0) - pop %ebx - ret -GLOBL( _x86_Color4ub_ub_end ) - - -/* - MultiTexCoord2fv st0/st1 -*/ -GLOBL( _x86_MultiTexCoord2fv ) - movl 4(%esp), %eax - movl 8(%esp), %ecx - and $3, %eax - movl (%ecx), %edx - shl $3, %eax - movl 4(%ecx), %ecx - movl %edx, 0xdeadbeef(%eax) - movl %ecx, 0xdeadbeef(%eax) - ret -GLOBL( _x86_MultiTexCoord2fv_end ) - -/* - MultiTexCoord2fv -*/ - -GLOBL( _x86_MultiTexCoord2fv_2 ) - movl 4(%esp,1), %eax - movl 8(%esp,1), %ecx - and $3, %eax - movl 0(,%eax,4), %edx - movl (%ecx), %eax - movl %eax, (%edx) - movl 4(%ecx), %eax - movl %eax, 4(%edx) - ret -GLOBL( _x86_MultiTexCoord2fv_2_end ) - -/* - MultiTexCoord2f st0/st1 -*/ -GLOBL( _x86_MultiTexCoord2f ) - movl 4(%esp), %eax - movl 8(%esp), %edx - movl 12(%esp), %ecx - and $3, %eax - shl $3, %eax - movl %edx, 0xdeadbeef(%eax) - movl %ecx, 0xdeadbeef(%eax) - ret -GLOBL( _x86_MultiTexCoord2f_end ) - -/* - MultiTexCoord2f -*/ -GLOBL( _x86_MultiTexCoord2f_2 ) - movl 4(%esp), %eax - movl 8(%esp), %edx - movl 12(%esp,1), %ecx - and $3,%eax - movl 0(,%eax,4), %eax - movl %edx, (%eax) - movl %ecx, 4(%eax) - ret -GLOBL( _x86_MultiTexCoord2f_2_end ) - -#if defined(USE_SSE_ASM) -/** - * This can be used as a template for either Color3fv (when the color - * target is also a 3f) or Normal3fv. - */ - -GLOBL( _sse_Attribute3fv ) - movl 4(%esp), %eax - movlps (%eax), %xmm0 - movl 8(%eax), %eax - movlps %xmm0, 0 - movl %eax, 8 - ret -GLOBL( _sse_Attribute3fv_end ) - -/** - * This can be used as a template for either Color3f (when the color - * target is also a 3f) or Normal3f. - */ - -GLOBL( _sse_Attribute3f ) - movlps 4(%esp), %xmm0 - movl 12(%esp), %eax - movlps %xmm0, 0 - movl %eax, 8 - ret -GLOBL( _sse_Attribute3f_end ) - - -/** - * Generic handler for 2 float vector format data. This can be used for - * TexCoord2fv and possibly other functions. - */ - -GLOBL( _sse_Attribute2fv ) - movl 4(%esp), %eax - movlps (%eax), %xmm0 - movlps %xmm0, 0 - ret -GLOBL( _sse_Attribute2fv_end ) - - -/** - * Generic handler for 2 float format data. This can be used for - * TexCoord2f and possibly other functions. - */ - -GLOBL( _sse_Attribute2f ) - movlps 4(%esp), %xmm0 - movlps %xmm0, 0 - ret -GLOBL( _sse_Attribute2f_end ) - -/* - MultiTexCoord2fv st0/st1 -*/ -GLOBL( _sse_MultiTexCoord2fv ) - movl 4(%esp), %eax - movl 8(%esp), %ecx - and $3, %eax - movlps (%ecx), %xmm0 - movlps %xmm0, 0xdeadbeef(,%eax,8) - ret -GLOBL( _sse_MultiTexCoord2fv_end ) - -/* - MultiTexCoord2fv -*/ -GLOBL( _sse_MultiTexCoord2fv_2 ) - movl 4(%esp), %eax - movl 8(%esp), %ecx - and $3, %eax - movl 0(,%eax,4), %edx - movlps (%ecx), %xmm0 - movlps %xmm0, (%edx) - ret -GLOBL( _sse_MultiTexCoord2fv_2_end ) - -/* - MultiTexCoord2f st0/st1 -*/ -GLOBL( _sse_MultiTexCoord2f ) - movl 4(%esp), %eax - and $3, %eax - movlps 8(%esp), %xmm0 - movlps %xmm0, 0xdeadbeef(,%eax,8) - ret -GLOBL( _sse_MultiTexCoord2f_end ) - -/* - MultiTexCoord2f -*/ -GLOBL( _sse_MultiTexCoord2f_2 ) - movl 4(%esp), %eax - movlps 8(%esp), %xmm0 - and $3,%eax - movl 0(,%eax,4), %eax - movlps %xmm0, (%eax) - ret -GLOBL( _sse_MultiTexCoord2f_2_end ) -#endif - -#if defined (__ELF__) && defined (__linux__) - .section .note.GNU-stack,"",%progbits -#endif -- cgit v1.2.3 From 851d15ef3ae8e7f78f1d0ef1cf8a3ff6765354b0 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 31 Oct 2006 12:11:56 +0000 Subject: disable vtxfmt_a code, switch over to vbo --- src/mesa/drivers/dri/r300/r300_context.c | 8 ++++---- src/mesa/drivers/dri/r300/r300_context.h | 7 +++++-- src/mesa/drivers/dri/r300/r300_render.c | 4 ++-- src/mesa/drivers/dri/r300/r300_state.c | 4 ++-- src/mesa/drivers/dri/r300/radeon_state.c | 4 +--- 5 files changed, 14 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index 54eb081d05..b58c6075c7 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -44,7 +44,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -287,7 +287,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext(ctx); - _ac_CreateContext(ctx); + _vbo_CreateContext(ctx); _tnl_CreateContext(ctx); _swsetup_CreateContext(ctx); _swsetup_Wakeup(ctx); @@ -300,7 +300,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, /* Try and keep materials and vertices separate: */ - _tnl_isolate_materials(ctx, GL_TRUE); +/* _tnl_isolate_materials(ctx, GL_TRUE); */ /* Configure swrast and TNL to match hardware characteristics: */ @@ -478,7 +478,7 @@ void r300DestroyContext(__DRIcontextPrivate * driContextPriv) _swsetup_DestroyContext(r300->radeon.glCtx); _tnl_ProgramCacheDestroy(r300->radeon.glCtx); _tnl_DestroyContext(r300->radeon.glCtx); - _ac_DestroyContext(r300->radeon.glCtx); + _vbo_DestroyContext(r300->radeon.glCtx); _swrast_DestroyContext(r300->radeon.glCtx); if (r300->dma.current.buf) { diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index df73cdedc1..02ffbfcbef 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -48,7 +48,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_context.h" #define USER_BUFFERS -#define RADEON_VTXFMT_A +/* KW: Disable this code. Driver should hook into vbo module + * directly, see i965 driver for example. + */ +/* #define RADEON_VTXFMT_A */ #define HW_VBOS /* We don't handle 16 bits elts swapping yet */ @@ -739,7 +742,7 @@ struct radeon_vertex_buffer { struct dt AttribPtr[VERT_ATTRIB_MAX]; - struct tnl_prim *Primitive; + const struct _mesa_prim *Primitive; GLuint PrimitiveCount; GLint LockFirst; GLsizei LockCount; diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index 03f168365d..8c259d345c 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -42,7 +42,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "api_arrayelt.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_vp_build.h" @@ -352,7 +352,7 @@ GLboolean r300_run_vb_render(GLcontext *ctx, r300EmitState(rmesa); 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; diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 29ffa7a017..5a98226300 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -46,7 +46,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "api_arrayelt.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "texformat.h" @@ -1806,7 +1806,7 @@ static void r300InvalidateState(GLcontext * ctx, GLuint new_state) _swrast_InvalidateState(ctx, new_state); _swsetup_InvalidateState(ctx, new_state); - _ac_InvalidateState(ctx, new_state); + _vbo_InvalidateState(ctx, new_state); _tnl_InvalidateState(ctx, new_state); _ae_invalidate_state(ctx, new_state); diff --git a/src/mesa/drivers/dri/r300/radeon_state.c b/src/mesa/drivers/dri/r300/radeon_state.c index 917acb7243..7726c22f42 100644 --- a/src/mesa/drivers/dri/r300/radeon_state.c +++ b/src/mesa/drivers/dri/r300/radeon_state.c @@ -41,7 +41,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "light.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" #include "swrast_setup/swrast_setup.h" @@ -134,8 +134,6 @@ void radeonUpdateScissor(GLcontext* ctx) static void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h) { - radeonContextPtr radeon = RADEON_CONTEXT(ctx); - if (ctx->Scissor.Enabled) { /* We don't pipeline cliprect changes */ r300Flush(ctx); -- cgit v1.2.3 From 35ee4affc5bd2c7be3005725ce74a016a3da8b59 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 31 Oct 2006 12:12:15 +0000 Subject: switch remaining drivers over to vbo --- src/mesa/drivers/directfb/idirectfbgl_mesa.c | 2 +- src/mesa/drivers/dri/fb/fb_dri.c | 8 ++++---- src/mesa/drivers/dri/fb/fb_egl.c | 6 +++--- src/mesa/drivers/dri/ffb/ffb_state.c | 4 ++-- src/mesa/drivers/dri/ffb/ffb_xmesa.c | 6 +++--- src/mesa/drivers/dri/gamma/gamma_context.c | 4 ++-- src/mesa/drivers/dri/gamma/gamma_state.c | 4 ++-- src/mesa/drivers/dri/gamma/gamma_xmesa.c | 4 ++-- src/mesa/drivers/dri/mach64/mach64_context.c | 6 +++--- src/mesa/drivers/dri/mach64/mach64_state.c | 4 ++-- src/mesa/drivers/dri/mga/mga_xmesa.c | 6 +++--- src/mesa/drivers/dri/mga/mgastate.c | 4 ++-- src/mesa/drivers/dri/r128/r128_context.c | 6 +++--- src/mesa/drivers/dri/r128/r128_state.c | 4 ++-- src/mesa/drivers/dri/s3v/s3v_context.c | 4 ++-- src/mesa/drivers/dri/s3v/s3v_state.c | 4 ++-- src/mesa/drivers/dri/s3v/s3v_xmesa.c | 4 ++-- src/mesa/drivers/dri/savage/savage_xmesa.c | 6 +++--- src/mesa/drivers/dri/savage/savagestate.c | 4 ++-- src/mesa/drivers/dri/sis/sis6326_state.c | 4 ++-- src/mesa/drivers/dri/sis/sis_context.c | 6 +++--- src/mesa/drivers/dri/sis/sis_state.c | 4 ++-- src/mesa/drivers/dri/tdfx/tdfx_context.c | 6 +++--- src/mesa/drivers/dri/tdfx/tdfx_state.c | 4 ++-- src/mesa/drivers/dri/trident/trident_context.c | 6 +++--- src/mesa/drivers/dri/trident/trident_state.c | 4 ++-- src/mesa/drivers/dri/unichrome/via_context.c | 6 +++--- src/mesa/drivers/dri/unichrome/via_state.c | 4 ++-- src/mesa/drivers/glide/fxdd.c | 2 +- 29 files changed, 68 insertions(+), 68 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/directfb/idirectfbgl_mesa.c b/src/mesa/drivers/directfb/idirectfbgl_mesa.c index 3c2a77b5bc..524249e8a5 100644 --- a/src/mesa/drivers/directfb/idirectfbgl_mesa.c +++ b/src/mesa/drivers/directfb/idirectfbgl_mesa.c @@ -53,7 +53,7 @@ #include "texformat.h" #include "teximage.h" #include "texstore.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" diff --git a/src/mesa/drivers/dri/fb/fb_dri.c b/src/mesa/drivers/dri/fb/fb_dri.c index d6ba23bc6e..08b52b4d8f 100644 --- a/src/mesa/drivers/dri/fb/fb_dri.c +++ b/src/mesa/drivers/dri/fb/fb_dri.c @@ -50,7 +50,7 @@ #include "extensions.h" #include "framebuffer.h" #include "renderbuffer.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" @@ -93,7 +93,7 @@ update_state( GLcontext *ctx, GLuint new_state ) /* not much to do here - pass it on */ _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); } @@ -365,7 +365,7 @@ fbCreateContext( const __GLcontextModes *glVisual, /* Create module contexts */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); _swsetup_Wakeup( ctx ); @@ -399,7 +399,7 @@ fbDestroyContext( __DRIcontextPrivate *driContextPriv ) if ( fbmesa ) { _swsetup_DestroyContext( fbmesa->glCtx ); _tnl_DestroyContext( fbmesa->glCtx ); - _ac_DestroyContext( fbmesa->glCtx ); + _vbo_DestroyContext( fbmesa->glCtx ); _swrast_DestroyContext( fbmesa->glCtx ); /* free the Mesa context */ diff --git a/src/mesa/drivers/dri/fb/fb_egl.c b/src/mesa/drivers/dri/fb/fb_egl.c index 5c74b0b0f4..517e71f888 100644 --- a/src/mesa/drivers/dri/fb/fb_egl.c +++ b/src/mesa/drivers/dri/fb/fb_egl.c @@ -17,7 +17,7 @@ #include "extensions.h" #include "framebuffer.h" #include "renderbuffer.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" @@ -388,7 +388,7 @@ update_state( GLcontext *ctx, GLuint new_state ) /* not much to do here - pass it on */ _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); } @@ -491,7 +491,7 @@ fbCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext sh /* Create module contexts */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); _swsetup_Wakeup( ctx ); diff --git a/src/mesa/drivers/dri/ffb/ffb_state.c b/src/mesa/drivers/dri/ffb/ffb_state.c index b81d94de25..eb13478166 100644 --- a/src/mesa/drivers/dri/ffb/ffb_state.c +++ b/src/mesa/drivers/dri/ffb/ffb_state.c @@ -40,7 +40,7 @@ #include "enums.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" @@ -1034,7 +1034,7 @@ static void ffbDDUpdateState(GLcontext *ctx, GLuint newstate) _swrast_InvalidateState( ctx, newstate ); _swsetup_InvalidateState( ctx, newstate ); - _ac_InvalidateState( ctx, newstate ); + _vbo_InvalidateState( ctx, newstate ); _tnl_InvalidateState( ctx, newstate ); if (newstate & _NEW_TEXTURE) diff --git a/src/mesa/drivers/dri/ffb/ffb_xmesa.c b/src/mesa/drivers/dri/ffb/ffb_xmesa.c index ab2a6688ba..7c1e439364 100644 --- a/src/mesa/drivers/dri/ffb/ffb_xmesa.c +++ b/src/mesa/drivers/dri/ffb/ffb_xmesa.c @@ -38,7 +38,7 @@ #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "drivers/common/driverfuncs.h" #include "ffb_context.h" @@ -277,7 +277,7 @@ ffbCreateContext(const __GLcontextModes *mesaVis, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -313,7 +313,7 @@ ffbDestroyContext(__DRIcontextPrivate *driContextPriv) _swsetup_DestroyContext( fmesa->glCtx ); _tnl_DestroyContext( fmesa->glCtx ); - _ac_DestroyContext( fmesa->glCtx ); + _vbo_DestroyContext( fmesa->glCtx ); _swrast_DestroyContext( fmesa->glCtx ); /* free the Mesa context */ diff --git a/src/mesa/drivers/dri/gamma/gamma_context.c b/src/mesa/drivers/dri/gamma/gamma_context.c index ffaf45459b..b1dcbfcdcf 100644 --- a/src/mesa/drivers/dri/gamma/gamma_context.c +++ b/src/mesa/drivers/dri/gamma/gamma_context.c @@ -28,7 +28,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -147,7 +147,7 @@ GLboolean gammaCreateContext( const __GLcontextModes *glVisual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); diff --git a/src/mesa/drivers/dri/gamma/gamma_state.c b/src/mesa/drivers/dri/gamma/gamma_state.c index 026ff5efbf..1d5ce20995 100644 --- a/src/mesa/drivers/dri/gamma/gamma_state.c +++ b/src/mesa/drivers/dri/gamma/gamma_state.c @@ -33,7 +33,7 @@ #include "colormac.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #define ENABLELIGHTING 0 @@ -1664,7 +1664,7 @@ static void gammaDDUpdateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); GAMMA_CONTEXT(ctx)->new_gl_state |= new_state; } diff --git a/src/mesa/drivers/dri/gamma/gamma_xmesa.c b/src/mesa/drivers/dri/gamma/gamma_xmesa.c index 00f6aa32ae..e8922b1503 100644 --- a/src/mesa/drivers/dri/gamma/gamma_xmesa.c +++ b/src/mesa/drivers/dri/gamma/gamma_xmesa.c @@ -34,7 +34,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" static GLboolean gammaInitDriver(__DRIscreenPrivate *sPriv) @@ -57,7 +57,7 @@ gammaDestroyContext(__DRIcontextPrivate *driContextPriv) if (gmesa) { _swsetup_DestroyContext( gmesa->glCtx ); _tnl_DestroyContext( gmesa->glCtx ); - _ac_DestroyContext( gmesa->glCtx ); + _vbo_DestroyContext( gmesa->glCtx ); _swrast_DestroyContext( gmesa->glCtx ); gammaFreeVB( gmesa->glCtx ); diff --git a/src/mesa/drivers/dri/mach64/mach64_context.c b/src/mesa/drivers/dri/mach64/mach64_context.c index 03ec96a222..eeb4cbcf71 100644 --- a/src/mesa/drivers/dri/mach64/mach64_context.c +++ b/src/mesa/drivers/dri/mach64/mach64_context.c @@ -38,7 +38,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -203,7 +203,7 @@ GLboolean mach64CreateContext( const __GLcontextModes *glVisual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -272,7 +272,7 @@ void mach64DestroyContext( __DRIcontextPrivate *driContextPriv ) _swsetup_DestroyContext( mmesa->glCtx ); _tnl_DestroyContext( mmesa->glCtx ); - _ac_DestroyContext( mmesa->glCtx ); + _vbo_DestroyContext( mmesa->glCtx ); _swrast_DestroyContext( mmesa->glCtx ); mach64FreeVB( mmesa->glCtx ); diff --git a/src/mesa/drivers/dri/mach64/mach64_state.c b/src/mesa/drivers/dri/mach64/mach64_state.c index d4804a2c55..667a394520 100644 --- a/src/mesa/drivers/dri/mach64/mach64_state.c +++ b/src/mesa/drivers/dri/mach64/mach64_state.c @@ -40,7 +40,7 @@ #include "enums.h" #include "colormac.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" @@ -1023,7 +1023,7 @@ static void mach64DDInvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); MACH64_CONTEXT(ctx)->NewGLState |= new_state; } diff --git a/src/mesa/drivers/dri/mga/mga_xmesa.c b/src/mesa/drivers/dri/mga/mga_xmesa.c index 73bcfcce73..32cfbc6a1c 100644 --- a/src/mesa/drivers/dri/mga/mga_xmesa.c +++ b/src/mesa/drivers/dri/mga/mga_xmesa.c @@ -45,7 +45,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/t_pipeline.h" @@ -593,7 +593,7 @@ mgaCreateContext( const __GLcontextModes *mesaVis, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -676,7 +676,7 @@ mgaDestroyContext(__DRIcontextPrivate *driContextPriv) release_texture_heaps = (mmesa->glCtx->Shared->RefCount == 1); _swsetup_DestroyContext( mmesa->glCtx ); _tnl_DestroyContext( mmesa->glCtx ); - _ac_DestroyContext( mmesa->glCtx ); + _vbo_DestroyContext( mmesa->glCtx ); _swrast_DestroyContext( mmesa->glCtx ); mgaFreeVB( mmesa->glCtx ); diff --git a/src/mesa/drivers/dri/mga/mgastate.c b/src/mesa/drivers/dri/mga/mgastate.c index 783de53197..69f85d62a5 100644 --- a/src/mesa/drivers/dri/mga/mgastate.c +++ b/src/mesa/drivers/dri/mga/mgastate.c @@ -42,7 +42,7 @@ #include "mgaregs.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" @@ -1062,7 +1062,7 @@ static void mgaDDInvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); MGA_CONTEXT(ctx)->NewGLState |= new_state; } diff --git a/src/mesa/drivers/dri/r128/r128_context.c b/src/mesa/drivers/dri/r128/r128_context.c index 8ec027542a..89ddafa02a 100644 --- a/src/mesa/drivers/dri/r128/r128_context.c +++ b/src/mesa/drivers/dri/r128/r128_context.c @@ -42,7 +42,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -235,7 +235,7 @@ GLboolean r128CreateContext( const __GLcontextModes *glVisual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -293,7 +293,7 @@ void r128DestroyContext( __DRIcontextPrivate *driContextPriv ) _swsetup_DestroyContext( rmesa->glCtx ); _tnl_DestroyContext( rmesa->glCtx ); - _ac_DestroyContext( rmesa->glCtx ); + _vbo_DestroyContext( rmesa->glCtx ); _swrast_DestroyContext( rmesa->glCtx ); if ( release_texture_heaps ) { diff --git a/src/mesa/drivers/dri/r128/r128_state.c b/src/mesa/drivers/dri/r128/r128_state.c index 1bfd370937..e476afa5d8 100644 --- a/src/mesa/drivers/dri/r128/r128_state.c +++ b/src/mesa/drivers/dri/r128/r128_state.c @@ -44,7 +44,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "enums.h" #include "colormac.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" @@ -1250,7 +1250,7 @@ static void r128DDInvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); R128_CONTEXT(ctx)->NewGLState |= new_state; } diff --git a/src/mesa/drivers/dri/s3v/s3v_context.c b/src/mesa/drivers/dri/s3v/s3v_context.c index 7b0aa0daee..2d2f704ad7 100644 --- a/src/mesa/drivers/dri/s3v/s3v_context.c +++ b/src/mesa/drivers/dri/s3v/s3v_context.c @@ -6,7 +6,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -139,7 +139,7 @@ GLboolean s3vCreateContext(const __GLcontextModes *glVisual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); diff --git a/src/mesa/drivers/dri/s3v/s3v_state.c b/src/mesa/drivers/dri/s3v/s3v_state.c index 4f412edf09..08ce0f565c 100644 --- a/src/mesa/drivers/dri/s3v/s3v_state.c +++ b/src/mesa/drivers/dri/s3v/s3v_state.c @@ -10,7 +10,7 @@ #include "colormac.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" /* #define DEBUG(str) printf str */ @@ -826,7 +826,7 @@ static void s3vDDUpdateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); S3V_CONTEXT(ctx)->new_gl_state |= new_state; } diff --git a/src/mesa/drivers/dri/s3v/s3v_xmesa.c b/src/mesa/drivers/dri/s3v/s3v_xmesa.c index 533424cdea..c451f7452b 100644 --- a/src/mesa/drivers/dri/s3v/s3v_xmesa.c +++ b/src/mesa/drivers/dri/s3v/s3v_xmesa.c @@ -13,7 +13,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" /* #define DEBUG(str) printf str */ @@ -38,7 +38,7 @@ s3vDestroyContext(__DRIcontextPrivate *driContextPriv) if (vmesa) { _swsetup_DestroyContext( vmesa->glCtx ); _tnl_DestroyContext( vmesa->glCtx ); - _ac_DestroyContext( vmesa->glCtx ); + _vbo_DestroyContext( vmesa->glCtx ); _swrast_DestroyContext( vmesa->glCtx ); s3vFreeVB( vmesa->glCtx ); diff --git a/src/mesa/drivers/dri/savage/savage_xmesa.c b/src/mesa/drivers/dri/savage/savage_xmesa.c index aaba58ed33..3557ce0118 100644 --- a/src/mesa/drivers/dri/savage/savage_xmesa.c +++ b/src/mesa/drivers/dri/savage/savage_xmesa.c @@ -40,7 +40,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/t_pipeline.h" @@ -501,7 +501,7 @@ savageCreateContext( const __GLcontextModes *mesaVis, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -591,7 +591,7 @@ savageDestroyContext(__DRIcontextPrivate *driContextPriv) _swsetup_DestroyContext(imesa->glCtx ); _tnl_DestroyContext( imesa->glCtx ); - _ac_DestroyContext( imesa->glCtx ); + _vbo_DestroyContext( imesa->glCtx ); _swrast_DestroyContext( imesa->glCtx ); /* free the Mesa context */ diff --git a/src/mesa/drivers/dri/savage/savagestate.c b/src/mesa/drivers/dri/savage/savagestate.c index e554afdbb7..5c2b397bde 100644 --- a/src/mesa/drivers/dri/savage/savagestate.c +++ b/src/mesa/drivers/dri/savage/savagestate.c @@ -41,7 +41,7 @@ #include "savage_bci.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" @@ -1676,7 +1676,7 @@ static void savageDDInvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); SAVAGE_CONTEXT(ctx)->new_gl_state |= new_state; } diff --git a/src/mesa/drivers/dri/sis/sis6326_state.c b/src/mesa/drivers/dri/sis/sis6326_state.c index 6bc2c6de3b..08402fb3e2 100644 --- a/src/mesa/drivers/dri/sis/sis6326_state.c +++ b/src/mesa/drivers/dri/sis/sis6326_state.c @@ -37,7 +37,7 @@ #include "enums.h" #include "colormac.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" @@ -645,7 +645,7 @@ sis6326DDInvalidateState( GLcontext *ctx, GLuint new_state ) _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); smesa->NewGLState |= new_state; } diff --git a/src/mesa/drivers/dri/sis/sis_context.c b/src/mesa/drivers/dri/sis/sis_context.c index a300a080ec..89b81da347 100644 --- a/src/mesa/drivers/dri/sis/sis_context.c +++ b/src/mesa/drivers/dri/sis/sis_context.c @@ -53,7 +53,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -306,7 +306,7 @@ sisCreateContext( const __GLcontextModes *glVisual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -353,7 +353,7 @@ sisDestroyContext ( __DRIcontextPrivate *driContextPriv ) if ( smesa != NULL ) { _swsetup_DestroyContext( smesa->glCtx ); _tnl_DestroyContext( smesa->glCtx ); - _ac_DestroyContext( smesa->glCtx ); + _vbo_DestroyContext( smesa->glCtx ); _swrast_DestroyContext( smesa->glCtx ); if (smesa->using_agp) diff --git a/src/mesa/drivers/dri/sis/sis_state.c b/src/mesa/drivers/dri/sis/sis_state.c index 2a10a5fbf6..33a2f089b8 100644 --- a/src/mesa/drivers/dri/sis/sis_state.c +++ b/src/mesa/drivers/dri/sis/sis_state.c @@ -42,7 +42,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "enums.h" #include "colormac.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" @@ -707,7 +707,7 @@ sisDDInvalidateState( GLcontext *ctx, GLuint new_state ) _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); smesa->NewGLState |= new_state; } diff --git a/src/mesa/drivers/dri/tdfx/tdfx_context.c b/src/mesa/drivers/dri/tdfx/tdfx_context.c index dd40544d49..07d2cb1db5 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_context.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_context.c @@ -54,7 +54,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -331,7 +331,7 @@ GLboolean tdfxCreateContext( const __GLcontextModes *mesaVis, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -612,7 +612,7 @@ tdfxDestroyContext( __DRIcontextPrivate *driContextPriv ) _swsetup_DestroyContext( fxMesa->glCtx ); _tnl_DestroyContext( fxMesa->glCtx ); - _ac_DestroyContext( fxMesa->glCtx ); + _vbo_DestroyContext( fxMesa->glCtx ); _swrast_DestroyContext( fxMesa->glCtx ); tdfxFreeVB( fxMesa->glCtx ); diff --git a/src/mesa/drivers/dri/tdfx/tdfx_state.c b/src/mesa/drivers/dri/tdfx/tdfx_state.c index 59e6549e5e..42cb5dfaa3 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_state.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_state.c @@ -46,7 +46,7 @@ #include "teximage.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" #include "swrast_setup/swrast_setup.h" @@ -1234,7 +1234,7 @@ static void tdfxDDInvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); TDFX_CONTEXT(ctx)->new_gl_state |= new_state; } diff --git a/src/mesa/drivers/dri/trident/trident_context.c b/src/mesa/drivers/dri/trident/trident_context.c index 9c8f7ef01f..a07b40fd5d 100644 --- a/src/mesa/drivers/dri/trident/trident_context.c +++ b/src/mesa/drivers/dri/trident/trident_context.c @@ -30,7 +30,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -142,7 +142,7 @@ tridentCreateContext( const __GLcontextModes *glVisual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -182,7 +182,7 @@ tridentDestroyContext(__DRIcontextPrivate *driContextPriv) if (tmesa) { _swsetup_DestroyContext( tmesa->glCtx ); _tnl_DestroyContext( tmesa->glCtx ); - _ac_DestroyContext( tmesa->glCtx ); + _vbo_DestroyContext( tmesa->glCtx ); _swrast_DestroyContext( tmesa->glCtx ); /* free the Mesa context */ diff --git a/src/mesa/drivers/dri/trident/trident_state.c b/src/mesa/drivers/dri/trident/trident_state.c index a9be50688b..6cdf23092a 100644 --- a/src/mesa/drivers/dri/trident/trident_state.c +++ b/src/mesa/drivers/dri/trident/trident_state.c @@ -26,7 +26,7 @@ */ #include "trident_context.h" #include "trident_lock.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" @@ -469,7 +469,7 @@ tridentDDUpdateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); TRIDENT_CONTEXT(ctx)->new_gl_state |= new_state; } diff --git a/src/mesa/drivers/dri/unichrome/via_context.c b/src/mesa/drivers/dri/unichrome/via_context.c index fa143186c1..38dcf458db 100644 --- a/src/mesa/drivers/dri/unichrome/via_context.c +++ b/src/mesa/drivers/dri/unichrome/via_context.c @@ -42,7 +42,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/t_pipeline.h" @@ -588,7 +588,7 @@ viaCreateContext(const __GLcontextModes *visual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext(ctx); - _ac_CreateContext(ctx); + _vbo_CreateContext(ctx); _tnl_CreateContext(ctx); _swsetup_CreateContext(ctx); @@ -713,7 +713,7 @@ viaDestroyContext(__DRIcontextPrivate *driContextPriv) _swsetup_DestroyContext(vmesa->glCtx); _tnl_DestroyContext(vmesa->glCtx); - _ac_DestroyContext(vmesa->glCtx); + _vbo_DestroyContext(vmesa->glCtx); _swrast_DestroyContext(vmesa->glCtx); /* free the Mesa context */ _mesa_destroy_context(vmesa->glCtx); diff --git a/src/mesa/drivers/dri/unichrome/via_state.c b/src/mesa/drivers/dri/unichrome/via_state.c index c001661d0b..102a333068 100644 --- a/src/mesa/drivers/dri/unichrome/via_state.c +++ b/src/mesa/drivers/dri/unichrome/via_state.c @@ -40,7 +40,7 @@ #include "via_3d_reg.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" @@ -1501,7 +1501,7 @@ static void viaInvalidateState(GLcontext *ctx, GLuint newState) _swrast_InvalidateState(ctx, newState); _swsetup_InvalidateState(ctx, newState); - _ac_InvalidateState(ctx, newState); + _vbo_InvalidateState(ctx, newState); _tnl_InvalidateState(ctx, newState); } diff --git a/src/mesa/drivers/glide/fxdd.c b/src/mesa/drivers/glide/fxdd.c index 0ee0e0cae0..e218a316aa 100644 --- a/src/mesa/drivers/glide/fxdd.c +++ b/src/mesa/drivers/glide/fxdd.c @@ -55,7 +55,7 @@ #include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" -- cgit v1.2.3 From c22f8a7787bd5260135a20a0c2ae8b743228497b Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 2 Nov 2006 08:37:17 +0000 Subject: missing file --- src/mesa/tnl/t_draw.c | 305 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 305 insertions(+) create mode 100644 src/mesa/tnl/t_draw.c (limited to 'src') diff --git a/src/mesa/tnl/t_draw.c b/src/mesa/tnl/t_draw.c new file mode 100644 index 0000000000..be811ef628 --- /dev/null +++ b/src/mesa/tnl/t_draw.c @@ -0,0 +1,305 @@ + +/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * 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 + */ + +#include "glheader.h" +#include "context.h" +#include "imports.h" +#include "state.h" +#include "mtypes.h" +#include "macros.h" + +#include "t_context.h" +#include "t_pipeline.h" +#include "t_vp_build.h" +#include "t_vertex.h" +#include "tnl.h" + +#define CONVERT( TYPE, MACRO ) do { \ + GLuint i, j; \ + for (i = 0; i < count; i++) { \ + const TYPE *in = (TYPE *)ptr; \ + for (j = 0; j < sz; j++) { \ + *fptr++ = MACRO(*in); \ + in++; \ + } \ + ptr += input->StrideB; \ + } \ +} while (0) + + +static GLfloat *get_space(GLcontext *ctx, GLuint bytes) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLubyte *space = _mesa_malloc(bytes); + + tnl->block[tnl->nr_blocks++] = space; + return (GLfloat *)space; +} + + +static void free_space(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint i; + for (i = 0; i < tnl->nr_blocks; i++) + _mesa_free(tnl->block[i]); + tnl->nr_blocks = 0; +} + + +/* Adjust pointer to point at first requested element, convert to + * floating point, populate VB->AttribPtr[]. + */ +static void _tnl_import_array( GLcontext *ctx, + GLuint attrib, + GLuint start, + GLuint end, + const struct gl_client_array *input, + const char *ptr ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + const GLuint count = end - start; + GLuint stride = input->StrideB; + + ptr += start * stride; + + if (input->Type != GL_FLOAT) { + const GLuint sz = input->Size; + GLfloat *fptr = get_space(ctx, count * sz * sizeof(GLfloat)); + + switch (input->Type) { + case GL_BYTE: + CONVERT(GLbyte, BYTE_TO_FLOAT); + break; + case GL_UNSIGNED_BYTE: + CONVERT(GLubyte, UBYTE_TO_FLOAT); + break; + case GL_SHORT: + CONVERT(GLshort, SHORT_TO_FLOAT); + break; + case GL_UNSIGNED_SHORT: + CONVERT(GLushort, USHORT_TO_FLOAT); + break; + case GL_INT: + CONVERT(GLint, INT_TO_FLOAT); + break; + case GL_UNSIGNED_INT: + CONVERT(GLuint, UINT_TO_FLOAT); + break; + case GL_DOUBLE: + CONVERT(GLdouble, (GLfloat)); + break; + default: + assert(0); + break; + } + + ptr = (const char *)fptr; + stride = sz * sizeof(GLfloat); + } + + VB->AttribPtr[attrib] = &tnl->tmp_inputs[attrib]; + VB->AttribPtr[attrib]->data = (GLfloat (*)[4])ptr; + VB->AttribPtr[attrib]->start = (GLfloat *)ptr; + VB->AttribPtr[attrib]->count = count; + VB->AttribPtr[attrib]->stride = stride; + VB->AttribPtr[attrib]->size = input->Size; + + /* This should die, but so should the whole GLvector4f concept: + */ + VB->AttribPtr[attrib]->flags = (((1<Size)-1) | + VEC_NOT_WRITEABLE | + (stride == 4*sizeof(GLfloat) ? 0 : VEC_BAD_STRIDE)); + + VB->AttribPtr[attrib]->storage = NULL; +} + + +static void bind_inputs( GLcontext *ctx, + const struct gl_client_array *inputs[], + GLint start, GLint end, + struct gl_buffer_object **bo, + GLuint *nr_bo ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint i; + + /* Map all the VBOs + */ + for (i = 0; i < VERT_ATTRIB_MAX; i++) { + const void *ptr; + + if (inputs[i]->BufferObj->Name) { + if (!inputs[i]->BufferObj->Pointer) { + bo[*nr_bo] = inputs[i]->BufferObj; + *nr_bo++; + ctx->Driver.MapBuffer(ctx, + GL_ARRAY_BUFFER, + GL_READ_ONLY_ARB, + inputs[i]->BufferObj); + + assert(inputs[i]->BufferObj->Pointer); + } + + ptr = ADD_POINTERS(inputs[i]->BufferObj->Pointer, + inputs[i]->Ptr); + } + else + ptr = inputs[i]->Ptr; + + /* Just make sure the array is floating point, otherwise convert to + * temporary storage. Rebase arrays so that 'start' becomes + * element zero. + * + * XXX: remove the GLvector4f type at some stage and just use + * client arrays. + */ + _tnl_import_array(ctx, i, start, end, inputs[i], ptr); + } + + /* 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]; + } + +#if 0 + /* odd-ball vertex attribute + */ + if (ctx->Polygon.FrontMode != GL_FILL || + ctx->Polygon.BackMode != GL_FILL) + { + VB->EdgeFlag = _tnl_import_edgeflag( ctx, VB->AttribPtr[_TNL_ATTRIB_EDGEFLAG]); + } +#endif + +} + + +/* Translate indices to GLuints and store in VB->Elts. + */ +static void bind_indicies( GLcontext *ctx, + const struct _mesa_index_buffer *ib, + struct gl_buffer_object **bo, + GLuint *nr_bo) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + + if (!ib) + return; + + if (ib->obj->Name && !ib->obj->Pointer) { + bo[*nr_bo] = ib->obj; + *nr_bo++; + ctx->Driver.MapBuffer(ctx, + GL_ELEMENT_ARRAY_BUFFER, + GL_READ_ONLY_ARB, + ib->obj); + + assert(ib->obj->Pointer); + } + + VB->Elts = (GLuint *)ADD_POINTERS(ib->obj->Pointer, + ib->ptr); + + VB->Elts += ib->rebase; + + switch (ib->type) { + case GL_UNSIGNED_INT: + return; + case GL_UNSIGNED_SHORT: + break; + case GL_UNSIGNED_BYTE: + break; + } +} + +static void unmap_vbos( GLcontext *ctx, + struct gl_buffer_object **bo, + GLuint nr_bo ) +{ + GLuint i; + for (i = 0; i < nr_bo; i++) { + ctx->Driver.UnmapBuffer(ctx, + 0, /* target -- I don't see why this would be needed */ + bo[i]); + } +} + + + +/* This is the main entrypoint into the slimmed-down software tnl + * module. In a regular swtnl driver, this can be plugged straight + * into the vbo->Driver.DrawPrims() callback. + */ +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) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + + /* May need to map a vertex buffer object for every attribute plus + * one for the index buffer. + */ + struct gl_buffer_object *bo[VERT_ATTRIB_MAX + 1]; + GLuint nr_bo = 0; + + /* Binding inputs may imply mapping some vertex buffer objects. + * They will need to be unmapped below. + */ + bind_inputs(ctx, arrays, min_index, max_index, bo, &nr_bo); + bind_indicies(ctx, ib, bo, &nr_bo); + + VB->Primitive = prim; + VB->PrimitiveCount = nr_prims; + VB->Count = max_index - min_index; + + TNL_CONTEXT(ctx)->Driver.RunPipeline(ctx); + + unmap_vbos(ctx, bo, nr_bo); + free_space(ctx); +} + -- cgit v1.2.3 From 9827dc8bea422b940f1efcfbd1c0d76f8bbca844 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 2 Nov 2006 09:48:30 +0000 Subject: Respect array->Normalized flag. Import edgeflag attribute to array of GLbooleans as expected by downstream code. --- src/mesa/tnl/t_draw.c | 70 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/mesa/tnl/t_draw.c b/src/mesa/tnl/t_draw.c index be811ef628..c84a10856e 100644 --- a/src/mesa/tnl/t_draw.c +++ b/src/mesa/tnl/t_draw.c @@ -39,17 +39,6 @@ #include "t_vertex.h" #include "tnl.h" -#define CONVERT( TYPE, MACRO ) do { \ - GLuint i, j; \ - for (i = 0; i < count; i++) { \ - const TYPE *in = (TYPE *)ptr; \ - for (j = 0; j < sz; j++) { \ - *fptr++ = MACRO(*in); \ - in++; \ - } \ - ptr += input->StrideB; \ - } \ -} while (0) static GLfloat *get_space(GLcontext *ctx, GLuint bytes) @@ -72,6 +61,34 @@ static void free_space(GLcontext *ctx) } +/* Convert the incoming array to GLfloats. Understands the + * array->Normalized flag and selects the correct conversion method. + */ +#define CONVERT( TYPE, MACRO ) do { \ + GLuint i, j; \ + if (input->Normalized) { \ + for (i = 0; i < count; i++) { \ + const TYPE *in = (TYPE *)ptr; \ + for (j = 0; j < sz; j++) { \ + *fptr++ = MACRO(*in); \ + in++; \ + } \ + ptr += input->StrideB; \ + } \ + } else { \ + for (i = 0; i < count; i++) { \ + const TYPE *in = (TYPE *)ptr; \ + for (j = 0; j < sz; j++) { \ + *fptr++ = (GLfloat)(*in); \ + in++; \ + } \ + ptr += input->StrideB; \ + } \ + } \ +} while (0) + + + /* Adjust pointer to point at first requested element, convert to * floating point, populate VB->AttribPtr[]. */ @@ -140,6 +157,27 @@ static void _tnl_import_array( GLcontext *ctx, VB->AttribPtr[attrib]->storage = NULL; } +#define CLIPVERTS ((6 + MAX_CLIP_PLANES) * 2) + + +static GLboolean *_tnl_import_edgeflag( GLcontext *ctx, + const GLvector4f *input, + GLuint count) +{ + const GLubyte *ptr = (const GLubyte *)input->data; + const GLuint stride = input->stride; + GLboolean *space = (GLboolean *)get_space(ctx, count + CLIPVERTS); + GLboolean *bptr = space; + GLuint i; + + for (i = 0; i < count; i++) { + *bptr++ = ((GLfloat *)ptr)[0] == 1.0; + ptr += stride; + } + + return space; +} + static void bind_inputs( GLcontext *ctx, const struct gl_client_array *inputs[], @@ -200,15 +238,17 @@ static void bind_inputs( GLcontext *ctx, VB->TexCoordPtr[i] = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]; } -#if 0 - /* odd-ball vertex attribute + /* Clipping and drawing code still requires this to be a packed + * array of ubytes which can be written into. TODO: Fix and + * remove. */ if (ctx->Polygon.FrontMode != GL_FILL || ctx->Polygon.BackMode != GL_FILL) { - VB->EdgeFlag = _tnl_import_edgeflag( ctx, VB->AttribPtr[_TNL_ATTRIB_EDGEFLAG]); + VB->EdgeFlag = _tnl_import_edgeflag( ctx, + VB->AttribPtr[_TNL_ATTRIB_EDGEFLAG], + VB->Count ); } -#endif } -- cgit v1.2.3 From 18d52f96bb1f20b1887b67e87506835bca05d73a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 2 Nov 2006 11:40:56 +0000 Subject: Fix typo in display list attrib binding. --- src/mesa/vbo/vbo_save_draw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c index 527e57d6bd..ab3275ec94 100644 --- a/src/mesa/vbo/vbo_save_draw.c +++ b/src/mesa/vbo/vbo_save_draw.c @@ -124,7 +124,7 @@ static void vbo_bind_vertex_list( GLcontext *ctx, break; } - for (attr = 0; attr <= VBO_ATTRIB_INDEX; attr++) { + for (attr = 0; attr < VBO_ATTRIB_MAX; attr++) { if (node->attrsz[attr]) { arrays[attr].Ptr = (const GLubyte *)data; arrays[attr].Size = node->attrsz[attr]; -- cgit v1.2.3 From 6d104cb932080c5c0d951fbc0ec6d30fb7ebef45 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Thu, 2 Nov 2006 12:02:13 +0000 Subject: merge current trunk into vbo branch --- configs/linux-dri | 2 +- docs/relnotes-6.5.2.html | 3 + progs/demos/Makefile | 1 + progs/demos/streaming_rect.c | 322 +++++ progs/demos/texdown.c | 133 +- progs/trivial/Makefile | 2 + progs/trivial/quad-tex-pbo.c | 181 +++ src/glx/x11/glxext.c | 70 +- src/mesa/drivers/directfb/idirectfbgl_mesa.c | 10 +- src/mesa/drivers/dri/Makefile.template | 7 +- src/mesa/drivers/dri/common/dri_bufmgr.c | 493 ++++++++ src/mesa/drivers/dri/common/dri_bufmgr.h | 99 ++ src/mesa/drivers/dri/common/dri_bufpool.h | 86 ++ src/mesa/drivers/dri/common/dri_drmpool.c | 227 ++++ src/mesa/drivers/dri/common/dri_util.c | 2 +- src/mesa/drivers/dri/common/dri_util.h | 8 +- src/mesa/drivers/dri/ffb/ffb_clear.c | 5 +- src/mesa/drivers/dri/ffb/ffb_clear.h | 5 +- src/mesa/drivers/dri/ffb/ffb_xmesa.c | 3 +- src/mesa/drivers/dri/gamma/gamma_state.c | 5 +- src/mesa/drivers/dri/i810/i810ioctl.c | 5 +- src/mesa/drivers/dri/i915/i830_metaops.c | 14 +- src/mesa/drivers/dri/i915/i915_fragprog.c | 3 + src/mesa/drivers/dri/i915/i915_metaops.c | 22 +- src/mesa/drivers/dri/i915/intel_batchbuffer.c | 41 +- src/mesa/drivers/dri/i915/intel_ioctl.c | 9 +- src/mesa/drivers/dri/i915/intel_ioctl.h | 3 +- src/mesa/drivers/dri/i915tex/Makefile | 66 + src/mesa/drivers/dri/i915tex/i830_context.c | 104 ++ src/mesa/drivers/dri/i915tex/i830_context.h | 208 ++++ src/mesa/drivers/dri/i915tex/i830_metaops.c | 485 ++++++++ src/mesa/drivers/dri/i915tex/i830_reg.h | 641 ++++++++++ src/mesa/drivers/dri/i915tex/i830_state.c | 1113 +++++++++++++++++ src/mesa/drivers/dri/i915tex/i830_tex.c | 100 ++ src/mesa/drivers/dri/i915tex/i830_texblend.c | 463 +++++++ src/mesa/drivers/dri/i915tex/i830_texstate.c | 316 +++++ src/mesa/drivers/dri/i915tex/i830_vtbl.c | 606 +++++++++ src/mesa/drivers/dri/i915tex/i915_context.c | 175 +++ src/mesa/drivers/dri/i915tex/i915_context.h | 367 ++++++ src/mesa/drivers/dri/i915tex/i915_debug.c | 334 +++++ src/mesa/drivers/dri/i915tex/i915_fragprog.c | 1072 ++++++++++++++++ src/mesa/drivers/dri/i915tex/i915_metaops.c | 509 ++++++++ src/mesa/drivers/dri/i915tex/i915_program.c | 518 ++++++++ src/mesa/drivers/dri/i915tex/i915_program.h | 160 +++ src/mesa/drivers/dri/i915tex/i915_reg.h | 841 +++++++++++++ src/mesa/drivers/dri/i915tex/i915_state.c | 1019 ++++++++++++++++ src/mesa/drivers/dri/i915tex/i915_tex.c | 113 ++ src/mesa/drivers/dri/i915tex/i915_tex_layout.c | 380 ++++++ src/mesa/drivers/dri/i915tex/i915_texstate.c | 338 ++++++ src/mesa/drivers/dri/i915tex/i915_vtbl.c | 549 +++++++++ src/mesa/drivers/dri/i915tex/intel_batchbuffer.c | 342 ++++++ src/mesa/drivers/dri/i915tex/intel_batchbuffer.h | 124 ++ src/mesa/drivers/dri/i915tex/intel_batchpool.c | 418 +++++++ src/mesa/drivers/dri/i915tex/intel_blit.c | 552 +++++++++ src/mesa/drivers/dri/i915tex/intel_blit.h | 61 + .../drivers/dri/i915tex/intel_buffer_objects.c | 250 ++++ .../drivers/dri/i915tex/intel_buffer_objects.h | 86 ++ src/mesa/drivers/dri/i915tex/intel_buffers.c | 956 +++++++++++++++ src/mesa/drivers/dri/i915tex/intel_buffers.h | 56 + src/mesa/drivers/dri/i915tex/intel_context.c | 707 +++++++++++ src/mesa/drivers/dri/i915tex/intel_context.h | 502 ++++++++ src/mesa/drivers/dri/i915tex/intel_depthstencil.c | 282 +++++ src/mesa/drivers/dri/i915tex/intel_depthstencil.h | 14 + src/mesa/drivers/dri/i915tex/intel_fbo.c | 622 ++++++++++ src/mesa/drivers/dri/i915tex/intel_fbo.h | 80 ++ src/mesa/drivers/dri/i915tex/intel_ioctl.c | 138 +++ src/mesa/drivers/dri/i915tex/intel_ioctl.h | 40 + src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c | 341 ++++++ src/mesa/drivers/dri/i915tex/intel_mipmap_tree.h | 198 +++ src/mesa/drivers/dri/i915tex/intel_pixel.c | 119 ++ src/mesa/drivers/dri/i915tex/intel_pixel.h | 63 + src/mesa/drivers/dri/i915tex/intel_pixel_bitmap.c | 350 ++++++ src/mesa/drivers/dri/i915tex/intel_pixel_copy.c | 380 ++++++ src/mesa/drivers/dri/i915tex/intel_pixel_draw.c | 365 ++++++ src/mesa/drivers/dri/i915tex/intel_pixel_read.c | 317 +++++ src/mesa/drivers/dri/i915tex/intel_reg.h | 84 ++ src/mesa/drivers/dri/i915tex/intel_regions.c | 466 +++++++ src/mesa/drivers/dri/i915tex/intel_regions.h | 141 +++ src/mesa/drivers/dri/i915tex/intel_render.c | 242 ++++ src/mesa/drivers/dri/i915tex/intel_rotate.c | 237 ++++ src/mesa/drivers/dri/i915tex/intel_rotate.h | 39 + src/mesa/drivers/dri/i915tex/intel_screen.c | 864 +++++++++++++ src/mesa/drivers/dri/i915tex/intel_screen.h | 132 ++ src/mesa/drivers/dri/i915tex/intel_span.c | 409 +++++++ src/mesa/drivers/dri/i915tex/intel_span.h | 38 + src/mesa/drivers/dri/i915tex/intel_state.c | 363 ++++++ src/mesa/drivers/dri/i915tex/intel_structs.h | 132 ++ src/mesa/drivers/dri/i915tex/intel_tex.c | 182 +++ src/mesa/drivers/dri/i915tex/intel_tex.h | 134 ++ src/mesa/drivers/dri/i915tex/intel_tex_copy.c | 301 +++++ src/mesa/drivers/dri/i915tex/intel_tex_format.c | 146 +++ src/mesa/drivers/dri/i915tex/intel_tex_image.c | 626 ++++++++++ src/mesa/drivers/dri/i915tex/intel_tex_subimage.c | 183 +++ src/mesa/drivers/dri/i915tex/intel_tex_validate.c | 252 ++++ src/mesa/drivers/dri/i915tex/intel_tris.c | 1149 ++++++++++++++++++ src/mesa/drivers/dri/i915tex/intel_tris.h | 69 ++ src/mesa/drivers/dri/i915tex/server/i830_common.h | 212 ++++ src/mesa/drivers/dri/i915tex/server/i830_dri.h | 73 ++ src/mesa/drivers/dri/i915tex/server/intel.h | 328 +++++ src/mesa/drivers/dri/i915tex/server/intel_dri.c | 1282 ++++++++++++++++++++ src/mesa/drivers/dri/i965/intel_blit.c | 27 +- src/mesa/drivers/dri/i965/intel_blit.h | 3 +- src/mesa/drivers/dri/i965/intel_buffers.c | 39 +- src/mesa/drivers/dri/mach64/mach64_ioctl.c | 5 +- src/mesa/drivers/dri/mga/mga_xmesa.c | 1 - src/mesa/drivers/dri/mga/mgacontext.h | 7 - src/mesa/drivers/dri/mga/mgadd.c | 19 +- src/mesa/drivers/dri/mga/mgaioctl.c | 5 +- src/mesa/drivers/dri/mga/mgaspan.c | 4 +- src/mesa/drivers/dri/mga/mgastate.c | 52 +- src/mesa/drivers/dri/r128/r128_ioctl.c | 5 +- src/mesa/drivers/dri/r200/r200_ioctl.c | 5 +- src/mesa/drivers/dri/r300/r300_fragprog.c | 102 +- src/mesa/drivers/dri/r300/r300_fragprog.h | 3 +- src/mesa/drivers/dri/r300/r300_ioctl.c | 5 +- src/mesa/drivers/dri/r300/r300_reg.h | 2 + src/mesa/drivers/dri/r300/r300_state.c | 1 - src/mesa/drivers/dri/r300/r300_texstate.c | 1 - src/mesa/drivers/dri/r300/radeon_context.c | 28 +- src/mesa/drivers/dri/r300/radeon_context.h | 10 +- src/mesa/drivers/dri/r300/radeon_lock.c | 44 +- src/mesa/drivers/dri/r300/radeon_state.c | 62 +- src/mesa/drivers/dri/r300/radeon_state.h | 2 +- src/mesa/drivers/dri/radeon/radeon_ioctl.c | 5 +- src/mesa/drivers/dri/radeon/radeon_state.c | 5 +- src/mesa/drivers/dri/s3v/s3v_state.c | 5 +- src/mesa/drivers/dri/savage/savageioctl.c | 5 +- src/mesa/drivers/dri/sis/sis6326_clear.c | 5 +- src/mesa/drivers/dri/sis/sis_clear.c | 9 +- src/mesa/drivers/dri/sis/sis_screen.c | 2 +- src/mesa/drivers/dri/sis/sis_state.h | 6 +- src/mesa/drivers/dri/tdfx/tdfx_render.c | 6 +- src/mesa/drivers/dri/tdfx/tdfx_tex.c | 6 +- src/mesa/drivers/dri/trident/trident_state.c | 5 +- src/mesa/drivers/dri/unichrome/via_ioctl.c | 7 +- src/mesa/drivers/ggi/ggimesa.c | 10 +- src/mesa/drivers/glide/fxdd.c | 9 +- src/mesa/drivers/svga/svgamesa15.c | 12 +- src/mesa/drivers/svga/svgamesa16.c | 12 +- src/mesa/drivers/svga/svgamesa24.c | 12 +- src/mesa/drivers/svga/svgamesa32.c | 12 +- src/mesa/drivers/svga/svgamesa8.c | 12 +- src/mesa/drivers/windows/gdi/wmesa.c | 13 +- src/mesa/drivers/x11/xm_dd.c | 16 +- src/mesa/main/attrib.c | 5 + src/mesa/main/buffers.c | 7 +- src/mesa/main/context.c | 11 + src/mesa/main/dd.h | 34 +- src/mesa/main/extensions.c | 7 +- src/mesa/main/fbobject.c | 6 +- src/mesa/main/get.c | 24 +- src/mesa/main/get_gen.py | 10 +- src/mesa/main/getstring.c | 4 +- src/mesa/main/mipmap.c | 4 +- src/mesa/main/mtypes.h | 37 +- src/mesa/main/state.c | 15 +- src/mesa/main/state.h | 6 + src/mesa/main/stencil.c | 101 +- src/mesa/main/texcompress_s3tc.c | 6 +- src/mesa/main/texenvprogram.c | 55 +- src/mesa/main/teximage.c | 1080 ++++++++++------- src/mesa/main/teximage.h | 21 +- src/mesa/main/texobj.c | 39 +- src/mesa/main/texobj.h | 4 + src/mesa/main/texstate.c | 125 +- src/mesa/shader/arbprogparse.c | 14 +- src/mesa/shader/nvfragparse.c | 2 +- src/mesa/shader/nvprogram.c | 7 +- src/mesa/shader/nvvertexec.c | 349 +++--- src/mesa/shader/nvvertexec.h | 34 +- src/mesa/shader/nvvertparse.c | 2 +- src/mesa/shader/program.c | 98 +- src/mesa/shader/program_instruction.h | 2 +- src/mesa/shader/programopt.c | 7 +- src/mesa/swrast/s_arbshader.c | 11 +- src/mesa/swrast/s_buffers.c | 21 +- src/mesa/swrast/s_context.c | 19 +- src/mesa/swrast/s_nvfragprog.c | 232 ++-- src/mesa/swrast/s_span.c | 52 +- src/mesa/swrast/s_texstore.c | 10 +- src/mesa/swrast/swrast.h | 3 +- src/mesa/tnl/t_context.c | 5 +- src/mesa/tnl/t_vb_program.c | 14 +- 183 files changed, 29322 insertions(+), 1452 deletions(-) create mode 100644 progs/demos/streaming_rect.c create mode 100644 progs/trivial/quad-tex-pbo.c create mode 100644 src/mesa/drivers/dri/common/dri_bufmgr.c create mode 100644 src/mesa/drivers/dri/common/dri_bufmgr.h create mode 100644 src/mesa/drivers/dri/common/dri_bufpool.h create mode 100644 src/mesa/drivers/dri/common/dri_drmpool.c create mode 100644 src/mesa/drivers/dri/i915tex/Makefile create mode 100644 src/mesa/drivers/dri/i915tex/i830_context.c create mode 100644 src/mesa/drivers/dri/i915tex/i830_context.h create mode 100644 src/mesa/drivers/dri/i915tex/i830_metaops.c create mode 100644 src/mesa/drivers/dri/i915tex/i830_reg.h create mode 100644 src/mesa/drivers/dri/i915tex/i830_state.c create mode 100644 src/mesa/drivers/dri/i915tex/i830_tex.c create mode 100644 src/mesa/drivers/dri/i915tex/i830_texblend.c create mode 100644 src/mesa/drivers/dri/i915tex/i830_texstate.c create mode 100644 src/mesa/drivers/dri/i915tex/i830_vtbl.c create mode 100644 src/mesa/drivers/dri/i915tex/i915_context.c create mode 100644 src/mesa/drivers/dri/i915tex/i915_context.h create mode 100644 src/mesa/drivers/dri/i915tex/i915_debug.c create mode 100644 src/mesa/drivers/dri/i915tex/i915_fragprog.c create mode 100644 src/mesa/drivers/dri/i915tex/i915_metaops.c create mode 100644 src/mesa/drivers/dri/i915tex/i915_program.c create mode 100644 src/mesa/drivers/dri/i915tex/i915_program.h create mode 100644 src/mesa/drivers/dri/i915tex/i915_reg.h create mode 100644 src/mesa/drivers/dri/i915tex/i915_state.c create mode 100644 src/mesa/drivers/dri/i915tex/i915_tex.c create mode 100644 src/mesa/drivers/dri/i915tex/i915_tex_layout.c create mode 100644 src/mesa/drivers/dri/i915tex/i915_texstate.c create mode 100644 src/mesa/drivers/dri/i915tex/i915_vtbl.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_batchbuffer.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_batchbuffer.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_batchpool.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_blit.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_blit.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_buffer_objects.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_buffer_objects.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_buffers.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_buffers.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_context.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_context.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_depthstencil.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_depthstencil.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_fbo.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_fbo.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_ioctl.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_ioctl.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_mipmap_tree.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_pixel.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_pixel.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_pixel_bitmap.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_pixel_copy.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_pixel_draw.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_pixel_read.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_reg.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_regions.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_regions.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_render.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_rotate.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_rotate.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_screen.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_screen.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_span.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_span.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_state.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_structs.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_tex.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_tex.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_tex_copy.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_tex_format.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_tex_image.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_tex_subimage.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_tex_validate.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_tris.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_tris.h create mode 100644 src/mesa/drivers/dri/i915tex/server/i830_common.h create mode 100644 src/mesa/drivers/dri/i915tex/server/i830_dri.h create mode 100644 src/mesa/drivers/dri/i915tex/server/intel.h create mode 100644 src/mesa/drivers/dri/i915tex/server/intel_dri.c (limited to 'src') diff --git a/configs/linux-dri b/configs/linux-dri index 8504297d0e..7e822e2eb6 100644 --- a/configs/linux-dri +++ b/configs/linux-dri @@ -65,5 +65,5 @@ WINDOW_SYSTEM=dri # gamma are missing because they have not been converted to use the new # interface. -DRI_DIRS = i810 i915 i965 mach64 mga r128 r200 r300 radeon s3v \ +DRI_DIRS = i810 i915tex i915 i965 mach64 mga r128 r200 r300 radeon s3v \ savage sis tdfx trident unichrome ffb diff --git a/docs/relnotes-6.5.2.html b/docs/relnotes-6.5.2.html index 5b69daf0c5..06a4763c67 100644 --- a/docs/relnotes-6.5.2.html +++ b/docs/relnotes-6.5.2.html @@ -23,6 +23,8 @@ Mesa 6.5.2 is a 6.5 follow-on development release mostly consisting of

New Features

    +
  • New minstall script to replace normal install program +
  • Faster fragment program execution in software

Changes

@@ -36,6 +38,7 @@ Mesa 6.5.2 is a 6.5 follow-on development release mostly consisting of
  • OPTION NV_position_invariant didn't work in NV vertex programs
  • glDrawPixels into a user-created framebuffer object could crash Xlib driver
  • Line clipping was broken in some circumstances +
  • fragment.fogcoord register didn't always contain the correct value diff --git a/progs/demos/Makefile b/progs/demos/Makefile index 43d0f17c85..feb2abd6cf 100644 --- a/progs/demos/Makefile +++ b/progs/demos/Makefile @@ -47,6 +47,7 @@ PROGS = \ renormal \ shadowtex \ singlebuffer \ + streaming_rect \ spectex \ spriteblast \ stex3d \ diff --git a/progs/demos/streaming_rect.c b/progs/demos/streaming_rect.c new file mode 100644 index 0000000000..86e00803c0 --- /dev/null +++ b/progs/demos/streaming_rect.c @@ -0,0 +1,322 @@ + +/* + * GL_ARB_multitexture demo + * + * Command line options: + * -info print GL implementation information + * + * + * Brian Paul November 1998 This program is in the public domain. + * Modified on 12 Feb 2002 for > 2 texture units. + */ + +#define GL_GLEXT_PROTOTYPES + +#include +#include +#include +#include +#include + +#include "readtex.h" + + +#define ANIMATE 10 +#define PBO 11 +#define QUIT 100 + +static GLboolean Animate = GL_TRUE; +static GLboolean use_pbo = 1; +static GLboolean whole_rect = 1; + +static GLfloat Drift = 0.0; +static GLfloat drift_increment = 1/255.0; +static GLfloat Xrot = 20.0, Yrot = 30.0; + +static GLuint Width = 1024; +static GLuint Height = 512; + + +static void Idle( void ) +{ + if (Animate) { + + Drift += drift_increment; + if (Drift >= 1.0) + Drift = 0.0; + + glutPostRedisplay(); + } +} + +static int max( int a, int b ) { return a > b ? a : b; } +static int min( int a, int b ) { return a < b ? a : b; } + +static void DrawObject() +{ + GLint size = Width * Height * 4; + + if (use_pbo) { + /* XXX: This is extremely important - semantically makes the buffer + * contents undefined, but in practice means that the driver can + * release the old copy of the texture and allocate a new one + * without waiting for outstanding rendering to complete. + */ + glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, size, NULL, GL_STREAM_DRAW_ARB); + + { + char *image = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, GL_WRITE_ONLY_ARB); + + printf("char %d\n", (unsigned char)(Drift * 255)); + + memset(image, size, (unsigned char)(Drift * 255)); + + glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT); + } + + + /* BGRA is required for most hardware paths: + */ + glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, Width, Height, 0, + GL_BGRA, GL_UNSIGNED_BYTE, NULL); + } + else { + static char *image = NULL; + + if (image == NULL) + image = malloc(size); + + memset(image, size, (unsigned char)(Drift * 255)); + + /* BGRA should be the fast path for regular uploads as well. + */ + glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, Width, Height, 0, + GL_BGRA, GL_UNSIGNED_BYTE, image); + } + + { + int x,y,w,h; + + if (whole_rect) { + x = y = 0; + w = Width; + h = Height; + } + else { + x = y = 0; + w = min(10, Width); + h = min(10, Height); + } + + glBegin(GL_QUADS); + + glTexCoord2f( x, y); + glVertex2f( x, y ); + + glTexCoord2f( x, y + h); + glVertex2f( x, y + h); + + glTexCoord2f( x + w + .5, y + h); + glVertex2f( x + w, y + h ); + + glTexCoord2f( x + w, y + .5); + glVertex2f( x + w, y ); + + glEnd(); + } +} + + + +static void Display( void ) +{ + static GLint T0 = 0; + static GLint Frames = 0; + GLint t; + + glClear( GL_COLOR_BUFFER_BIT ); + + glPushMatrix(); + DrawObject(); + glPopMatrix(); + + glutSwapBuffers(); + + Frames++; + + t = glutGet(GLUT_ELAPSED_TIME); + if (t - T0 >= 1000) { + GLfloat seconds = (t - T0) / 1000.0; + + GLfloat fps = Frames / seconds; + printf("%d frames in %6.3f seconds = %6.3f FPS\n", Frames, seconds, fps); + + drift_increment = 2.2 * seconds / Frames; + T0 = t; + Frames = 0; + } +} + + +static void Reshape( int width, int height ) +{ + glViewport( 0, 0, width, height ); + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); +/* glFrustum( -1.0, 1.0, -1.0, 1.0, 10.0, 100.0 ); */ + gluOrtho2D( 0, width, height, 0 ); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + glTranslatef(0.375, 0.375, 0); +} + + +static void ModeMenu(int entry) +{ + if (entry==ANIMATE) { + Animate = !Animate; + } + else if (entry==PBO) { + use_pbo = !use_pbo; + } + else if (entry==QUIT) { + exit(0); + } + + glutPostRedisplay(); +} + + +static void Key( unsigned char key, int x, int y ) +{ + (void) x; + (void) y; + switch (key) { + case 27: + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void SpecialKey( int key, int x, int y ) +{ + float step = 3.0; + (void) x; + (void) y; + + switch (key) { + case GLUT_KEY_UP: + Xrot += step; + break; + case GLUT_KEY_DOWN: + Xrot -= step; + break; + case GLUT_KEY_LEFT: + Yrot += step; + break; + case GLUT_KEY_RIGHT: + Yrot -= step; + break; + } + glutPostRedisplay(); +} + + +static void Init( int argc, char *argv[] ) +{ + const char *exten = (const char *) glGetString(GL_EXTENSIONS); + GLuint texObj, DrawPBO; + GLint size; + + + if (!strstr(exten, "GL_ARB_multitexture")) { + printf("Sorry, GL_ARB_multitexture not supported by this renderer.\n"); + exit(1); + } + + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size); + printf("%d x %d max texture size\n", size, size); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + /* allocate two texture objects */ + glGenTextures(1, &texObj); + + /* setup the texture objects */ + glActiveTextureARB(GL_TEXTURE0_ARB); + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texObj); + + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glGenBuffersARB(1, &DrawPBO); + + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, DrawPBO); + glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, + Width * Height * 4, NULL, GL_STREAM_DRAW); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + glEnable(GL_TEXTURE_RECTANGLE_ARB); + + glShadeModel(GL_SMOOTH); + glClearColor(0.3, 0.3, 0.4, 1.0); + + if (argc > 1 && strcmp(argv[1], "-info")==0) { + printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); + printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); + printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS)); + } +} + + +int main( int argc, char *argv[] ) +{ + GLint i; + + glutInit( &argc, argv ); + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-w") == 0) { + Width = atoi(argv[i+1]); + if (Width <= 0) { + printf("Error, bad width\n"); + exit(1); + } + i++; + } + else if (strcmp(argv[i], "-h") == 0) { + Height = atoi(argv[i+1]); + if (Height <= 0) { + printf("Error, bad height\n"); + exit(1); + } + i++; + } + } + + glutInitWindowSize( Width, Height ); + glutInitWindowPosition( 0, 0 ); + glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); + glutCreateWindow(argv[0] ); + + Init( argc, argv ); + + glutReshapeFunc( Reshape ); + glutKeyboardFunc( Key ); + glutSpecialFunc( SpecialKey ); + glutDisplayFunc( Display ); + glutIdleFunc( Idle ); + + glutCreateMenu(ModeMenu); + glutAddMenuEntry("Toggle Animation", ANIMATE); + glutAddMenuEntry("Toggle PBO", PBO); + glutAddMenuEntry("Quit", QUIT); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + glutMainLoop(); + return 0; +} diff --git a/progs/demos/texdown.c b/progs/demos/texdown.c index 79525a0395..fc98fddb31 100644 --- a/progs/demos/texdown.c +++ b/progs/demos/texdown.c @@ -38,8 +38,8 @@ #include -static GLsizei MaxSize = 1024; -static GLsizei TexWidth = 256, TexHeight = 256, TexBorder = 0; +static GLsizei MaxSize = 2048; +static GLsizei TexWidth = 1024, TexHeight = 1024, TexBorder = 0; static GLboolean ScaleAndBias = GL_FALSE; static GLboolean SubImage = GL_FALSE; static GLdouble DownloadRate = 0.0; /* texels/sec */ @@ -47,6 +47,32 @@ static GLdouble DownloadRate = 0.0; /* texels/sec */ static GLuint Mode = 0; +/* Try and avoid L2 cache effects by cycling through a small number of + * textures. + * + * At the initial size of 1024x1024x4 == 4mbyte, say 8 textures will + * keep us out of most caches at 32mb total. + * + * This turns into a fairly interesting question of what exactly you + * expect to be in cache in normal usage, and what you think should be + * outside. There's no rules for this, no reason to favour one usage + * over another except what the application you care about happens to + * resemble most closely. + * + * - Should the client texture image be in L2 cache? Has it just been + * generated or read from disk? + * - Does the application really use >1 texture, or is it constantly + * updating one image in-place? + * + * Different answers will favour different texture upload mechanisms. + * To upload an image that is purely outside of cache, a DMA-based + * upload will probably win, whereas for small, in-cache textures, + * copying looks good. + */ +#define NR_TEXOBJ 4 +static GLuint TexObj[NR_TEXOBJ]; + + struct FormatRec { GLenum Format; GLenum Type; @@ -116,25 +142,57 @@ TypeStr(GLenum type) } } +/* On x86, there is a performance cliff for memcpy to texture memory + * for sources below 64 byte alignment. We do our best with this in + * the driver, but it is better if the images are correctly aligned to + * start with: + */ +#define ALIGN (1<<12) + +static unsigned align(unsigned value, unsigned a) +{ + return (value + a - 1) & ~(a-1); +} + +static int MIN2(int a, int b) +{ + return a < b ? a : b; +} static void MeasureDownloadRate(void) { const int w = TexWidth + 2 * TexBorder; const int h = TexHeight + 2 * TexBorder; - const int bytes = w * h * BytesPerTexel(Format); + const int image_bytes = align(w * h * BytesPerTexel(Format), ALIGN); + const int bytes = image_bytes * NR_TEXOBJ; + GLubyte *orig_texImage, *orig_getImage; GLubyte *texImage, *getImage; GLdouble t0, t1, time; int count; int i; + int offset = 0; + GLdouble total = 0; /* ints will tend to overflow */ + + printf("allocating %d bytes for %d %dx%d images\n", + bytes, NR_TEXOBJ, w, h); - texImage = (GLubyte *) malloc(bytes); - getImage = (GLubyte *) malloc(bytes); - if (!texImage || !getImage) { + orig_texImage = (GLubyte *) malloc(bytes + ALIGN); + orig_getImage = (GLubyte *) malloc(image_bytes + ALIGN); + if (!orig_texImage || !orig_getImage) { DownloadRate = 0.0; return; } + printf("alloc %p %p\n", orig_texImage, orig_getImage); + + texImage = (GLubyte *)align((unsigned)orig_texImage, ALIGN); + getImage = (GLubyte *)align((unsigned)orig_getImage, ALIGN); + + for (i = 1; !(((unsigned)texImage) & i); i<<=1) + ; + printf("texture image alignment: %d bytes (%p)\n", i, texImage); + for (i = 0; i < bytes; i++) { texImage[i] = i & 0xff; } @@ -166,16 +224,50 @@ MeasureDownloadRate(void) count = 0; t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001; do { + int img = count%NR_TEXOBJ; + GLubyte *img_ptr = texImage + img * image_bytes; + + glBindTexture(GL_TEXTURE_2D, TexObj[img]); + if (SubImage && count > 0) { - glTexSubImage2D(GL_TEXTURE_2D, 0, -TexBorder, -TexBorder, w, h, + /* Only update a portion of the image each iteration. This + * is presumably why you'd want to use texsubimage, otherwise + * you may as well just call teximage again. + * + * A bigger question is whether to use a pointer that moves + * with each call, ie does the incoming data come from L2 + * cache under normal circumstances, or is it pulled from + * uncached memory? + * + * There's a good argument to say L2 cache, ie you'd expect + * the data to have been recently generated. It's possible + * that it could have come from a file read, which may or may + * not have gone through the cpu. + */ + glTexSubImage2D(GL_TEXTURE_2D, 0, + -TexBorder, + -TexBorder + offset * h/8, + w, + h/8, FormatTable[Format].Format, - FormatTable[Format].Type, texImage); + FormatTable[Format].Type, +#if 1 + texImage /* likely in L2$ */ +#else + img_ptr + offset * bytes/8 /* unlikely in L2$ */ +#endif + ); + offset += 1; + offset %= 8; + total += w * h / 8; } else { glTexImage2D(GL_TEXTURE_2D, 0, FormatTable[Format].IntFormat, w, h, TexBorder, FormatTable[Format].Format, - FormatTable[Format].Type, texImage); + FormatTable[Format].Type, + img_ptr); + total += w*h; } /* draw a tiny polygon to force texture into texram */ @@ -192,25 +284,12 @@ MeasureDownloadRate(void) glDisable(GL_TEXTURE_2D); - printf("w*h=%d count=%d time=%f\n", w*h, count, time); - DownloadRate = w * h * count / time; - -#if 0 - if (!ScaleAndBias) { - /* verify texture readback */ - glGetTexImage(GL_TEXTURE_2D, 0, - FormatTable[Format].Format, - FormatTable[Format].Type, getImage); - for (i = 0; i < w * h; i++) { - if (texImage[i] != getImage[i]) { - printf("[%d] %d != %d\n", i, texImage[i], getImage[i]); - } - } - } -#endif + printf("total texels=%f time=%f\n", total, time); + DownloadRate = total / time; + - free(texImage); - free(getImage); + free(orig_texImage); + free(orig_getImage); { GLint err = glGetError(); diff --git a/progs/trivial/Makefile b/progs/trivial/Makefile index cdc6328353..b9ed5c70dc 100644 --- a/progs/trivial/Makefile +++ b/progs/trivial/Makefile @@ -38,7 +38,9 @@ SOURCES = \ quad-offset-unfilled.c \ quad-unfilled.c \ quad-tex-2d.c \ + quad-tex-pbo.c \ quad-tex-3d.c \ + quad-tex-dep.c \ quad.c \ quads.c \ quadstrip.c \ diff --git a/progs/trivial/quad-tex-pbo.c b/progs/trivial/quad-tex-pbo.c new file mode 100644 index 0000000000..5b63c698a7 --- /dev/null +++ b/progs/trivial/quad-tex-pbo.c @@ -0,0 +1,181 @@ +/* + * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the name of + * Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF + * ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#define GL_GLEXT_PROTOTYPES + +#include +#include +#include +#include + + +#define CI_OFFSET_1 16 +#define CI_OFFSET_2 32 + +GLenum doubleBuffer; + +static GLuint DrawPBO; + +static void Init(void) +{ + fprintf(stderr, "GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + fprintf(stderr, "GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); + fprintf(stderr, "GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); + + glClearColor(0.0, 0.0, 1.0, 0.0); + +#define SIZE 16 + { + GLubyte tex2d[SIZE][SIZE][4]; + GLint s, t; + + for (s = 0; s < SIZE; s++) { + for (t = 0; t < SIZE; t++) { + /* bgra: + */ + tex2d[t][s][0] = 0x30; + tex2d[t][s][1] = t*255/(SIZE-1); + tex2d[t][s][2] = s*255/(SIZE-1); + tex2d[t][s][3] = 0xff; + } + } + + + /* put image into DrawPBO */ + glGenBuffersARB(1, &DrawPBO); + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, DrawPBO); + glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT, + SIZE * SIZE * 4, tex2d, GL_STATIC_DRAW); + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0); + + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, DrawPBO); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SIZE, SIZE, 0, + GL_BGRA, GL_UNSIGNED_BYTE, NULL); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + glEnable(GL_TEXTURE_2D); + } + +} + +static void Reshape(int width, int height) +{ + + glViewport(0, 0, (GLint)width, (GLint)height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0); + glMatrixMode(GL_MODELVIEW); +} + +static void Key(unsigned char key, int x, int y) +{ + + switch (key) { + case 27: + exit(1); + default: + return; + } + + glutPostRedisplay(); +} + +static void Draw(void) +{ + glClear(GL_COLOR_BUFFER_BIT); + + glBegin(GL_QUADS); + glTexCoord2f(1,0); + glVertex3f( 0.9, -0.9, -30.0); + glTexCoord2f(1,1); + glVertex3f( 0.9, 0.9, -30.0); + glTexCoord2f(0,1); + glVertex3f(-0.9, 0.9, -30.0); + glTexCoord2f(0,0); + glVertex3f(-0.9, -0.9, -30.0); + glEnd(); + + glFlush(); + + if (doubleBuffer) { + glutSwapBuffers(); + } +} + +static GLenum Args(int argc, char **argv) +{ + GLint i; + + doubleBuffer = GL_FALSE; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-sb") == 0) { + doubleBuffer = GL_FALSE; + } else if (strcmp(argv[i], "-db") == 0) { + doubleBuffer = GL_TRUE; + } else { + fprintf(stderr, "%s (Bad option).\n", argv[i]); + return GL_FALSE; + } + } + return GL_TRUE; +} + +int main(int argc, char **argv) +{ + GLenum type; + + glutInit(&argc, argv); + + if (Args(argc, argv) == GL_FALSE) { + exit(1); + } + + glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250); + + type = GLUT_RGB; + type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE; + glutInitDisplayMode(type); + + if (glutCreateWindow("First Tri") == GL_FALSE) { + exit(1); + } + + Init(); + + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutDisplayFunc(Draw); + glutMainLoop(); + return 0; +} diff --git a/src/glx/x11/glxext.c b/src/glx/x11/glxext.c index d386436396..bad09ce4cc 100644 --- a/src/glx/x11/glxext.c +++ b/src/glx/x11/glxext.c @@ -722,6 +722,69 @@ static const __DRIinterfaceMethods interface_methods = { __glXGetMscRateOML, }; +#define DRM_MAX_FDS 16 +static struct { + char *BusID; + int fd; + int refcount; +} connection[DRM_MAX_FDS]; + +static int nr_fds = 0; + +int drmOpenOnce(void *unused, + const char *BusID, + int *newlyopened) +{ + int i; + int fd; + + for (i = 0; i < nr_fds; i++) + if (strcmp(BusID, connection[i].BusID) == 0) { + connection[i].refcount++; + *newlyopened = 0; + return connection[i].fd; + } + + fd = drmOpen(unused, BusID); + if (fd <= 0 || nr_fds == DRM_MAX_FDS) + return fd; + + connection[nr_fds].BusID = strdup(BusID); + connection[nr_fds].fd = fd; + connection[nr_fds].refcount = 1; + *newlyopened = 1; + + if (0) + fprintf(stderr, "saved connection %d for %s %d\n", + nr_fds, connection[nr_fds].BusID, + strcmp(BusID, connection[nr_fds].BusID)); + + nr_fds++; + + return fd; +} + +void drmCloseOnce(int fd) +{ + int i; + + + + for (i = 0; i < nr_fds; i++) { + if (fd == connection[i].fd) { + if (--connection[i].refcount == 0) { + drmClose(connection[i].fd); + free(connection[i].BusID); + + if (i < --nr_fds) + connection[i] = connection[nr_fds]; + + return; + } + } + } +} + /** * Perform the required libGL-side initialization and call the client-side @@ -773,7 +836,8 @@ CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc, framebuffer.dev_priv = NULL; if (XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) { - fd = drmOpen(NULL,BusID); + int newlyopened; + fd = drmOpenOnce(NULL,BusID, &newlyopened); Xfree(BusID); /* No longer needed */ err_msg = "open DRM"; @@ -800,7 +864,7 @@ CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc, } err_msg = "XF86DRIAuthConnection"; - if (XF86DRIAuthConnection(dpy, scrn, magic)) { + if (!newlyopened || XF86DRIAuthConnection(dpy, scrn, magic)) { char *driverName; /* @@ -904,7 +968,7 @@ CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc, } if ( fd >= 0 ) { - (void)drmClose(fd); + (void)drmCloseOnce(fd); } (void)XF86DRICloseConnection(dpy, scrn); diff --git a/src/mesa/drivers/directfb/idirectfbgl_mesa.c b/src/mesa/drivers/directfb/idirectfbgl_mesa.c index 524249e8a5..2a20bddb1b 100644 --- a/src/mesa/drivers/directfb/idirectfbgl_mesa.c +++ b/src/mesa/drivers/directfb/idirectfbgl_mesa.c @@ -372,10 +372,14 @@ dfbSetViewport( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h ) } static void -dfbClear( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint x, GLint y, GLint width, GLint height ) +dfbClear( GLcontext *ctx, GLbitfield mask ) { IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx; + int x = ctx->DrawBuffer->_Xmin; + int y = ctx->DrawBuffer->_Ymin; + int width = ctx->DrawBuffer->_Xmax - x; + int height = ctx->DrawBuffer->_Ymax - y; + GLboolean all = (width == ctx->DrawBuffer->Width && height == ctx->DrawBuffer->height) if (mask & BUFFER_BIT_FRONT_LEFT && ctx->Color.ColorMask[0] && @@ -420,7 +424,7 @@ dfbClear( GLcontext *ctx, GLbitfield mask, GLboolean all, } if (mask) - _swrast_Clear( ctx, mask, all, x, y, width, height ); + _swrast_Clear( ctx, mask ); } diff --git a/src/mesa/drivers/dri/Makefile.template b/src/mesa/drivers/dri/Makefile.template index 1040194d0d..5261a4b55d 100644 --- a/src/mesa/drivers/dri/Makefile.template +++ b/src/mesa/drivers/dri/Makefile.template @@ -9,7 +9,12 @@ COMMON_SOURCES = \ ../common/vblank.c \ ../common/dri_util.c \ ../common/xmlconfig.c \ - ../common/drirenderbuffer.c + ../common/drirenderbuffer.c + +COMMON_BM_SOURCES = \ + ../common/dri_bufmgr.c \ + ../common/dri_drmpool.c + ifeq ($(WINDOW_SYSTEM),dri) WINOBJ= diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.c b/src/mesa/drivers/dri/common/dri_bufmgr.c new file mode 100644 index 0000000000..370b56c3a3 --- /dev/null +++ b/src/mesa/drivers/dri/common/dri_bufmgr.c @@ -0,0 +1,493 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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, 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 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 + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + * Keith Whitwell + */ + +#include +#include +#include "glthread.h" +#include "errno.h" +#include "dri_bufmgr.h" +#include "string.h" +#include "imports.h" +#include "dri_bufpool.h" + +_glthread_DECLARE_STATIC_MUTEX(bmMutex); + +/* + * TODO: Introduce fence pools in the same way as + * buffer object pools. + */ + + + +typedef struct _DriFenceObject +{ + int fd; + _glthread_Mutex mutex; + int refCount; + const char *name; + drmFence fence; +} DriFenceObject; + +typedef struct _DriBufferObject +{ + DriBufferPool *pool; + _glthread_Mutex mutex; + int refCount; + const char *name; + unsigned flags; + unsigned hint; + unsigned alignment; + void *private; +} DriBufferObject; + + +void +bmError(int val, const char *file, const char *function, int line) +{ + _mesa_printf("Fatal video memory manager error \"%s\".\n" + "Check kernel logs or set the LIBGL_DEBUG\n" + "environment variable to \"verbose\" for more info.\n" + "Detected in file %s, line %d, function %s.\n", + strerror(-val), file, line, function); +#ifndef NDEBUG + abort(); +#else + abort(); +#endif +} + +DriFenceObject * +driFenceBuffers(int fd, char *name, unsigned flags) +{ + DriFenceObject *fence = (DriFenceObject *) malloc(sizeof(*fence)); + int ret; + + if (!fence) + BM_CKFATAL(-EINVAL); + + _glthread_LOCK_MUTEX(bmMutex); + fence->refCount = 1; + fence->name = name; + fence->fd = fd; + _glthread_INIT_MUTEX(fence->mutex); + ret = drmFenceBuffers(fd, flags, &fence->fence); + _glthread_UNLOCK_MUTEX(bmMutex); + if (ret) { + free(fence); + BM_CKFATAL(ret); + } + return fence; +} + + +unsigned +driFenceType(DriFenceObject * fence) +{ + unsigned ret; + + _glthread_LOCK_MUTEX(bmMutex); + ret = fence->fence.flags; + _glthread_UNLOCK_MUTEX(bmMutex); + + return ret; +} + + +DriFenceObject * +driFenceReference(DriFenceObject * fence) +{ + _glthread_LOCK_MUTEX(bmMutex); + ++fence->refCount; + _glthread_UNLOCK_MUTEX(bmMutex); + return fence; +} + +void +driFenceUnReference(DriFenceObject * fence) +{ + if (!fence) + return; + + _glthread_LOCK_MUTEX(bmMutex); + if (--fence->refCount == 0) { + drmFenceDestroy(fence->fd, &fence->fence); + free(fence); + } + _glthread_UNLOCK_MUTEX(bmMutex); +} + +void +driFenceFinish(DriFenceObject * fence, unsigned type, int lazy) +{ + int ret; + unsigned flags = (lazy) ? DRM_FENCE_FLAG_WAIT_LAZY : 0; + + _glthread_LOCK_MUTEX(fence->mutex); + ret = drmFenceWait(fence->fd, flags, &fence->fence, type); + _glthread_UNLOCK_MUTEX(fence->mutex); + BM_CKFATAL(ret); +} + +int +driFenceSignaled(DriFenceObject * fence, unsigned type) +{ + int signaled; + int ret; + + if (fence == NULL) + return GL_TRUE; + + _glthread_LOCK_MUTEX(fence->mutex); + ret = drmFenceSignaled(fence->fd, &fence->fence, type, &signaled); + _glthread_UNLOCK_MUTEX(fence->mutex); + BM_CKFATAL(ret); + return signaled; +} + + +extern drmBO * +driBOKernel(struct _DriBufferObject *buf) +{ + drmBO *ret; + + assert(buf->private != NULL); + ret = buf->pool->kernel(buf->pool, buf->private); + if (!ret) + BM_CKFATAL(-EINVAL); + + return ret; +} + +void +driBOWaitIdle(struct _DriBufferObject *buf, int lazy) +{ + assert(buf->private != NULL); + + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(buf->pool->waitIdle(buf->pool, buf->private, lazy)); + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void * +driBOMap(struct _DriBufferObject *buf, unsigned flags, unsigned hint) +{ + void *virtual; + + assert(buf->private != NULL); + + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(buf->pool->map(buf->pool, buf->private, flags, hint, &virtual)); + _glthread_UNLOCK_MUTEX(buf->mutex); + return virtual; +} + +void +driBOUnmap(struct _DriBufferObject *buf) +{ + assert(buf->private != NULL); + + buf->pool->unmap(buf->pool, buf->private); +} + +unsigned long +driBOOffset(struct _DriBufferObject *buf) +{ + unsigned long ret; + + assert(buf->private != NULL); + + _glthread_LOCK_MUTEX(buf->mutex); + ret = buf->pool->offset(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + return ret; +} + +unsigned +driBOFlags(struct _DriBufferObject *buf) +{ + unsigned ret; + + assert(buf->private != NULL); + + _glthread_LOCK_MUTEX(buf->mutex); + ret = buf->pool->flags(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + return ret; +} + +struct _DriBufferObject * +driBOReference(struct _DriBufferObject *buf) +{ + _glthread_LOCK_MUTEX(bmMutex); + if (++buf->refCount == 1) { + BM_CKFATAL(-EINVAL); + } + _glthread_UNLOCK_MUTEX(bmMutex); + return buf; +} + +void +driBOUnReference(struct _DriBufferObject *buf) +{ + int tmp; + + if (!buf) + return; + + _glthread_LOCK_MUTEX(bmMutex); + tmp = --buf->refCount; + _glthread_UNLOCK_MUTEX(bmMutex); + if (!tmp) { + buf->pool->destroy(buf->pool, buf->private); + free(buf); + } +} + +void +driBOData(struct _DriBufferObject *buf, + unsigned size, const void *data, unsigned flags) +{ + void *virtual; + int newBuffer; + struct _DriBufferPool *pool; + + _glthread_LOCK_MUTEX(buf->mutex); + pool = buf->pool; + if (!pool->create) { + _mesa_error(NULL, GL_INVALID_OPERATION, + "driBOData called on invalid buffer\n"); + BM_CKFATAL(-EINVAL); + } + newBuffer = !buf->private || (pool->size(pool, buf->private) < size) || + pool->map(pool, buf->private, DRM_BO_FLAG_WRITE, + DRM_BO_HINT_DONT_BLOCK, &virtual); + + if (newBuffer) { + if (buf->private) + pool->destroy(pool, buf->private); + if (!flags) + flags = buf->flags; + buf->private = pool->create(pool, size, flags, 0, buf->alignment); + if (!buf->private) + BM_CKFATAL(-ENOMEM); + BM_CKFATAL(pool->map(pool, buf->private, + DRM_BO_FLAG_WRITE, + DRM_BO_HINT_DONT_BLOCK, &virtual)); + } + + if (data != NULL) + memcpy(virtual, data, size); + + BM_CKFATAL(pool->unmap(pool, buf->private)); + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void +driBOSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, const void *data) +{ + void *virtual; + + _glthread_LOCK_MUTEX(buf->mutex); + if (size && data) { + BM_CKFATAL(buf->pool->map(buf->pool, buf->private, + DRM_BO_FLAG_WRITE, 0, &virtual)); + memcpy((unsigned char *) virtual + offset, data, size); + BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); + } + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void +driBOGetSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, void *data) +{ + void *virtual; + + _glthread_LOCK_MUTEX(buf->mutex); + if (size && data) { + BM_CKFATAL(buf->pool->map(buf->pool, buf->private, + DRM_BO_FLAG_READ, 0, &virtual)); + memcpy(data, (unsigned char *) virtual + offset, size); + BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); + } + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void +driBOSetStatic(struct _DriBufferObject *buf, + unsigned long offset, + unsigned long size, void *virtual, unsigned flags) +{ + _glthread_LOCK_MUTEX(buf->mutex); + if (buf->private != NULL) { + _mesa_error(NULL, GL_INVALID_OPERATION, + "Invalid buffer for setStatic\n"); + BM_CKFATAL(-EINVAL); + } + if (buf->pool->setstatic == NULL) { + _mesa_error(NULL, GL_INVALID_OPERATION, + "Invalid buffer pool for setStatic\n"); + BM_CKFATAL(-EINVAL); + } + + if (!flags) + flags = buf->flags; + + buf->private = buf->pool->setstatic(buf->pool, offset, size, + virtual, flags); + if (!buf->private) { + _mesa_error(NULL, GL_OUT_OF_MEMORY, + "Invalid buffer pool for setStatic\n"); + BM_CKFATAL(-ENOMEM); + } + _glthread_UNLOCK_MUTEX(buf->mutex); +} + + + +void +driGenBuffers(struct _DriBufferPool *pool, + const char *name, + unsigned n, + struct _DriBufferObject *buffers[], + unsigned alignment, unsigned flags, unsigned hint) +{ + struct _DriBufferObject *buf; + int i; + + flags = (flags) ? flags : DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_VRAM | + DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; + + + for (i = 0; i < n; ++i) { + buf = (struct _DriBufferObject *) calloc(1, sizeof(*buf)); + if (!buf) + BM_CKFATAL(-ENOMEM); + + _glthread_INIT_MUTEX(buf->mutex); + _glthread_LOCK_MUTEX(buf->mutex); + _glthread_LOCK_MUTEX(bmMutex); + buf->refCount = 1; + _glthread_UNLOCK_MUTEX(bmMutex); + buf->flags = flags; + buf->hint = hint; + buf->name = name; + buf->alignment = alignment; + buf->pool = pool; + _glthread_UNLOCK_MUTEX(buf->mutex); + buffers[i] = buf; + } +} + +void +driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]) +{ + int i; + + for (i = 0; i < n; ++i) { + driBOUnReference(buffers[i]); + } +} + + +void +driInitBufMgr(int fd) +{ + ; +} + + +void +driBOCreateList(int target, drmBOList * list) +{ + _glthread_LOCK_MUTEX(bmMutex); + BM_CKFATAL(drmBOCreateList(20, list)); + _glthread_UNLOCK_MUTEX(bmMutex); +} + +void +driBOResetList(drmBOList * list) +{ + _glthread_LOCK_MUTEX(bmMutex); + BM_CKFATAL(drmBOResetList(list)); + _glthread_UNLOCK_MUTEX(bmMutex); +} + +void +driBOAddListItem(drmBOList * list, struct _DriBufferObject *buf, + unsigned flags, unsigned mask) +{ + int newItem; + + _glthread_LOCK_MUTEX(buf->mutex); + _glthread_LOCK_MUTEX(bmMutex); + BM_CKFATAL(drmAddValidateItem(list, driBOKernel(buf), + flags, mask, &newItem)); + _glthread_UNLOCK_MUTEX(bmMutex); + + /* + * Tell userspace pools to validate the buffer. This should be a + * noop if the pool is already validated. + * FIXME: We should have a list for this as well. + */ + + if (buf->pool->validate) { + BM_CKFATAL(buf->pool->validate(buf->pool, buf->private)); + } + + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void +driBOFence(struct _DriBufferObject *buf, struct _DriFenceObject *fence) +{ + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(buf->pool->fence(buf->pool, buf->private, fence)); + _glthread_UNLOCK_MUTEX(buf->mutex); + +} + +void +driBOValidateList(int fd, drmBOList * list) +{ + _glthread_LOCK_MUTEX(bmMutex); + BM_CKFATAL(drmBOValidateList(fd, list)); + _glthread_UNLOCK_MUTEX(bmMutex); +} + +void +driPoolTakeDown(struct _DriBufferPool *pool) +{ + pool->takeDown(pool); + +} diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.h b/src/mesa/drivers/dri/common/dri_bufmgr.h new file mode 100644 index 0000000000..01f149ae4e --- /dev/null +++ b/src/mesa/drivers/dri/common/dri_bufmgr.h @@ -0,0 +1,99 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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, 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 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 + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + * Keith Whitwell + */ + +#ifndef _DRI_BUFMGR_H_ +#define _DRI_BUFMGR_H_ +#include + + +struct _DriFenceObject; +struct _DriBufferObject; +struct _DriBufferPool; + +extern struct _DriFenceObject *driFenceBuffers(int fd, char *name, + unsigned flags); + +extern struct _DriFenceObject *driFenceReference(struct _DriFenceObject *fence); + +extern void driFenceUnReference(struct _DriFenceObject *fence); + +extern void +driFenceFinish(struct _DriFenceObject *fence, unsigned type, int lazy); + +extern int driFenceSignaled(struct _DriFenceObject *fence, unsigned type); +extern unsigned driFenceType(struct _DriFenceObject *fence); + +/* + * Return a pointer to the libdrm buffer object this DriBufferObject + * uses. + */ + +extern drmBO *driBOKernel(struct _DriBufferObject *buf); +extern void *driBOMap(struct _DriBufferObject *buf, unsigned flags, + unsigned hint); +extern void driBOUnmap(struct _DriBufferObject *buf); +extern unsigned long driBOOffset(struct _DriBufferObject *buf); +extern unsigned driBOFlags(struct _DriBufferObject *buf); +extern struct _DriBufferObject *driBOReference(struct _DriBufferObject *buf); +extern void driBOUnReference(struct _DriBufferObject *buf); +extern void driBOData(struct _DriBufferObject *r_buf, + unsigned size, const void *data, unsigned flags); +extern void driBOSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, + const void *data); +extern void driBOGetSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, + void *data); +extern void driGenBuffers(struct _DriBufferPool *pool, + const char *name, + unsigned n, + struct _DriBufferObject *buffers[], + unsigned alignment, unsigned flags, unsigned hint); +extern void driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]); +extern void driInitBufMgr(int fd); +extern void driBOCreateList(int target, drmBOList * list); +extern void driBOResetList(drmBOList * list); +extern void driBOAddListItem(drmBOList * list, struct _DriBufferObject *buf, + unsigned flags, unsigned mask); +extern void driBOValidateList(int fd, drmBOList * list); + +extern void driBOFence(struct _DriBufferObject *buf, + struct _DriFenceObject *fence); + +extern void driPoolTakeDown(struct _DriBufferPool *pool); +extern void driBOSetStatic(struct _DriBufferObject *buf, + unsigned long offset, + unsigned long size, void *virtual, unsigned flags); +extern void driBOWaitIdle(struct _DriBufferObject *buf, int lazy); +extern void driPoolTakeDown(struct _DriBufferPool *pool); + +#endif diff --git a/src/mesa/drivers/dri/common/dri_bufpool.h b/src/mesa/drivers/dri/common/dri_bufpool.h new file mode 100644 index 0000000000..c6fb2c3ce0 --- /dev/null +++ b/src/mesa/drivers/dri/common/dri_bufpool.h @@ -0,0 +1,86 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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, 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 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 + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + */ + +#ifndef _DRI_BUFPOOL_H_ +#define _DRI_BUFPOOL_H_ + +#include +struct _DriFenceObject; + +typedef struct _DriBufferPool +{ + int fd; + int (*map) (struct _DriBufferPool * pool, void *private, + unsigned flags, int hint, void **virtual); + int (*unmap) (struct _DriBufferPool * pool, void *private); + int (*destroy) (struct _DriBufferPool * pool, void *private); + unsigned long (*offset) (struct _DriBufferPool * pool, void *private); + unsigned (*flags) (struct _DriBufferPool * pool, void *private); + unsigned long (*size) (struct _DriBufferPool * pool, void *private); + void *(*create) (struct _DriBufferPool * pool, unsigned long size, + unsigned flags, unsigned hint, unsigned alignment); + int (*fence) (struct _DriBufferPool * pool, void *private, + struct _DriFenceObject * fence); + drmBO *(*kernel) (struct _DriBufferPool * pool, void *private); + int (*validate) (struct _DriBufferPool * pool, void *private); + void *(*setstatic) (struct _DriBufferPool * pool, unsigned long offset, + unsigned long size, void *virtual, unsigned flags); + int (*waitIdle) (struct _DriBufferPool *pool, void *private, + int lazy); + void (*takeDown) (struct _DriBufferPool * pool); + void *data; +} DriBufferPool; + +extern void bmError(int val, const char *file, const char *function, + int line); +#define BM_CKFATAL(val) \ + do{ \ + int tstVal = (val); \ + if (tstVal) \ + bmError(tstVal, __FILE__, __FUNCTION__, __LINE__); \ + } while(0); + + + + + +/* + * Builtin pools. + */ + +/* + * Kernel buffer objects. Size in multiples of page size. Page size aligned. + */ + +extern struct _DriBufferPool *driDRMPoolInit(int fd); +extern struct _DriBufferPool *driDRMStaticPoolInit(int fd); + +#endif diff --git a/src/mesa/drivers/dri/common/dri_drmpool.c b/src/mesa/drivers/dri/common/dri_drmpool.c new file mode 100644 index 0000000000..b5b324be50 --- /dev/null +++ b/src/mesa/drivers/dri/common/dri_drmpool.c @@ -0,0 +1,227 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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, 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 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 + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + */ + +#include +#include +#include +#include "dri_bufpool.h" + +/* + * Buffer pool implementation using DRM buffer objects as DRI buffer objects. + */ + +static void * +pool_create(struct _DriBufferPool *pool, + unsigned long size, unsigned flags, unsigned hint, + unsigned alignment) +{ + drmBO *buf = (drmBO *) malloc(sizeof(*buf)); + int ret; + unsigned pageSize = getpagesize(); + + if (!buf) + return NULL; + + if ((alignment > pageSize) && (alignment % pageSize)) { + return NULL; + } + + ret = drmBOCreate(pool->fd, 0, size, alignment / pageSize, + NULL, drm_bo_type_dc, + flags, hint, buf); + if (ret) { + free(buf); + return NULL; + } + + return (void *) buf; +} + +static int +pool_destroy(struct _DriBufferPool *pool, void *private) +{ + int ret; + drmBO *buf = (drmBO *) private; + ret = drmBODestroy(pool->fd, buf); + free(buf); + return ret; +} + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, void **virtual) +{ + drmBO *buf = (drmBO *) private; + + return drmBOMap(pool->fd, buf, flags, hint, virtual); +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + return drmBOUnmap(pool->fd, buf); +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + return buf->offset; +} + +static unsigned +pool_flags(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + return buf->flags; +} + + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + return buf->size; +} + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + /* + * Noop. The kernel handles all fencing. + */ + + return 0; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + return (drmBO *) private; +} + +static int +pool_waitIdle(struct _DriBufferPool *pool, void *private, int lazy) +{ + drmBO *buf = (drmBO *) private; + return drmBOWaitIdle(pool->fd, buf, (lazy) ? DRM_BO_HINT_WAIT_LAZY:0); +} + + +static void +pool_takedown(struct _DriBufferPool *pool) +{ + free(pool); +} + + +struct _DriBufferPool * +driDRMPoolInit(int fd) +{ + struct _DriBufferPool *pool; + + pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); + + if (!pool) + return NULL; + + pool->fd = fd; + pool->map = &pool_map; + pool->unmap = &pool_unmap; + pool->destroy = &pool_destroy; + pool->offset = &pool_offset; + pool->flags = &pool_flags; + pool->size = &pool_size; + pool->create = &pool_create; + pool->fence = &pool_fence; + pool->kernel = &pool_kernel; + pool->validate = NULL; + pool->setstatic = NULL; + pool->waitIdle = &pool_waitIdle; + pool->takeDown = &pool_takedown; + pool->data = NULL; + return pool; +} + + +static void * +pool_setstatic(struct _DriBufferPool *pool, unsigned long offset, + unsigned long size, void *virtual, unsigned flags) +{ + drmBO *buf = (drmBO *) malloc(sizeof(*buf)); + int ret; + + if (!buf) + return NULL; + + ret = drmBOCreate(pool->fd, offset, size, 0, NULL, drm_bo_type_fake, + flags, 0, buf); + + if (ret) { + free(buf); + return NULL; + } + + buf->virtual = virtual; + + return (void *) buf; +} + + +struct _DriBufferPool * +driDRMStaticPoolInit(int fd) +{ + struct _DriBufferPool *pool; + + pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); + + if (!pool) + return NULL; + + pool->fd = fd; + pool->map = &pool_map; + pool->unmap = &pool_unmap; + pool->destroy = &pool_destroy; + pool->offset = &pool_offset; + pool->flags = &pool_flags; + pool->size = &pool_size; + pool->create = NULL; + pool->fence = &pool_fence; + pool->kernel = &pool_kernel; + pool->validate = NULL; + pool->setstatic = &pool_setstatic; + pool->waitIdle = &pool_waitIdle; + pool->takeDown = &pool_takedown; + pool->data = NULL; + return pool; +} diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c index 1ca2756e01..e7f07569f4 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -849,7 +849,7 @@ static void driDestroyScreen(__DRInativeDisplay *dpy, int scrn, void *screenPriv (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX); (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize); _mesa_free(psp->pDevPriv); - (void)drmClose(psp->fd); + (void)drmCloseOnce(psp->fd); if ( psp->modes != NULL ) { (*dri_interface->destroyContextModes)( psp->modes ); } diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h index 885d5899e0..e43e653250 100644 --- a/src/mesa/drivers/dri/common/dri_util.h +++ b/src/mesa/drivers/dri/common/dri_util.h @@ -87,15 +87,15 @@ typedef struct __DRIutilversionRec2 __DRIutilversion2; #define DRI_VALIDATE_DRAWABLE_INFO(psp, pdp) \ do { \ while (*(pdp->pStamp) != pdp->lastStamp) { \ - DRM_UNLOCK(psp->fd, &psp->pSAREA->lock, \ - pdp->driContextPriv->hHWContext); \ + register unsigned int hwContext = psp->pSAREA->lock.lock & \ + ~(DRM_LOCK_HELD | DRM_LOCK_CONT); \ + DRM_UNLOCK(psp->fd, &psp->pSAREA->lock, hwContext); \ \ DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); \ DRI_VALIDATE_DRAWABLE_INFO_ONCE(pdp); \ DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); \ \ - DRM_LIGHT_LOCK(psp->fd, &psp->pSAREA->lock, \ - pdp->driContextPriv->hHWContext); \ + DRM_LIGHT_LOCK(psp->fd, &psp->pSAREA->lock, hwContext); \ } \ } while (0) diff --git a/src/mesa/drivers/dri/ffb/ffb_clear.c b/src/mesa/drivers/dri/ffb/ffb_clear.c index 9cd5a12b7d..e8dfcbe254 100644 --- a/src/mesa/drivers/dri/ffb/ffb_clear.c +++ b/src/mesa/drivers/dri/ffb/ffb_clear.c @@ -249,8 +249,7 @@ ffb_do_clear(GLcontext *ctx, __DRIdrawablePrivate *dPriv) } } -void ffbDDClear(GLcontext *ctx, GLbitfield mask, GLboolean allFoo, - GLint cxFoo, GLint cyFoo, GLint cwidthFoo, GLint cheightFoo) +void ffbDDClear(GLcontext *ctx, GLbitfield mask) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = fmesa->driDrawable; @@ -334,6 +333,6 @@ void ffbDDClear(GLcontext *ctx, GLbitfield mask, GLboolean allFoo, } if (mask) - _swrast_Clear(ctx, mask, 0, 0, 0, 0, 0); + _swrast_Clear(ctx, mask); } diff --git a/src/mesa/drivers/dri/ffb/ffb_clear.h b/src/mesa/drivers/dri/ffb/ffb_clear.h index 4b707f19b2..c3b8ce714b 100644 --- a/src/mesa/drivers/dri/ffb/ffb_clear.h +++ b/src/mesa/drivers/dri/ffb/ffb_clear.h @@ -1,9 +1,6 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_clear.h,v 1.2 2002/02/22 21:32:58 dawes Exp $ */ - #ifndef _FFB_CLEAR_H #define _FFB_CLEAR_H -extern void ffbDDClear(GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint cx, GLint cy, GLint cwidth, GLint cheight); +extern void ffbDDClear(GLcontext *ctx, GLbitfield mask); #endif /* !(_FFB_CLEAR_H) */ diff --git a/src/mesa/drivers/dri/ffb/ffb_xmesa.c b/src/mesa/drivers/dri/ffb/ffb_xmesa.c index 7c1e439364..215aaf8ffb 100644 --- a/src/mesa/drivers/dri/ffb/ffb_xmesa.c +++ b/src/mesa/drivers/dri/ffb/ffb_xmesa.c @@ -568,8 +568,7 @@ ffbMakeCurrent(__DRIcontextPrivate *driContextPriv, */ ffbDDClear(fmesa->glCtx, (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT | - BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL), - 1, 0, 0, 0, 0); + BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)); } } else { _mesa_make_current(NULL, NULL, NULL); diff --git a/src/mesa/drivers/dri/gamma/gamma_state.c b/src/mesa/drivers/dri/gamma/gamma_state.c index 1d5ce20995..8dbe0a97ca 100644 --- a/src/mesa/drivers/dri/gamma/gamma_state.c +++ b/src/mesa/drivers/dri/gamma/gamma_state.c @@ -205,8 +205,7 @@ static void gammaDDBlendFuncSeparate( GLcontext *ctx, * Buffer clear */ -static void gammaDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint cx, GLint cy, GLint cw, GLint ch ) +static void gammaDDClear( GLcontext *ctx, GLbitfield mask ) { gammaContextPtr gmesa = GAMMA_CONTEXT(ctx); GLINTDRIPtr gDRIPriv = (GLINTDRIPtr)gmesa->driScreen->pDevPriv; @@ -410,7 +409,7 @@ static void gammaDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, #endif if ( mask ) - _swrast_Clear( ctx, mask, all, cx, cy, cw, ch ); + _swrast_Clear( ctx, mask ); } /* ============================================================= diff --git a/src/mesa/drivers/dri/i810/i810ioctl.c b/src/mesa/drivers/dri/i810/i810ioctl.c index 9e52d80a8b..57c84193fa 100644 --- a/src/mesa/drivers/dri/i810/i810ioctl.c +++ b/src/mesa/drivers/dri/i810/i810ioctl.c @@ -48,8 +48,7 @@ static drmBufPtr i810_get_buffer_ioctl( i810ContextPtr imesa ) #define DEPTH_SCALE ((1<<16)-1) -static void i810Clear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, - GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo ) +static void i810Clear( GLcontext *ctx, GLbitfield mask ) { i810ContextPtr imesa = I810_CONTEXT( ctx ); __DRIdrawablePrivate *dPriv = imesa->driDrawable; @@ -142,7 +141,7 @@ static void i810Clear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, } if (mask) - _swrast_Clear( ctx, mask, 0, 0, 0, 0, 0 ); + _swrast_Clear( ctx, mask ); } diff --git a/src/mesa/drivers/dri/i915/i830_metaops.c b/src/mesa/drivers/dri/i915/i830_metaops.c index 17fde2f480..dbf5f04349 100644 --- a/src/mesa/drivers/dri/i915/i830_metaops.c +++ b/src/mesa/drivers/dri/i915/i830_metaops.c @@ -395,13 +395,15 @@ static void draw_poly(i830ContextPtr i830, void i830ClearWithTris(intelContextPtr intel, GLbitfield mask, - GLboolean all, - GLint cx, GLint cy, GLint cw, GLint ch) + GLboolean allFoo, + GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo) { i830ContextPtr i830 = I830_CONTEXT( intel ); __DRIdrawablePrivate *dPriv = intel->driDrawable; intelScreenPrivate *screen = intel->intelScreen; int x0, y0, x1, y1; + GLint cx, cy, cw, ch; + GLboolean all; INTEL_FIREVERTICES(intel); SET_STATE( i830, meta ); @@ -411,6 +413,14 @@ i830ClearWithTris(intelContextPtr intel, GLbitfield mask, LOCK_HARDWARE(intel); + /* get clear bounds after locking */ + cx = intel->ctx.DrawBuffer->_Xmin; + cy = intel->ctx.DrawBuffer->_Ymin; + cw = intel->ctx.DrawBuffer->_Xmax - cx; + ch = intel->ctx.DrawBuffer->_Ymax - cy; + all = (cw == intel->ctx.DrawBuffer->Width && + ch == intel->ctx.DrawBuffer->Height); + if(!all) { x0 = cx; y0 = cy; diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c index 0f3e6885f3..7160234bce 100644 --- a/src/mesa/drivers/dri/i915/i915_fragprog.c +++ b/src/mesa/drivers/dri/i915/i915_fragprog.c @@ -29,6 +29,7 @@ #include "macros.h" #include "enums.h" +#include "tnl/tnl.h" #include "tnl/t_context.h" #include "intel_batchbuffer.h" @@ -937,6 +938,8 @@ static void i915ProgramStringNotify( GLcontext *ctx, ctx->Driver.Enable( ctx, GL_FRAGMENT_PROGRAM_ARB, ctx->FragmentProgram.Enabled ); } + + _tnl_program_string(ctx, target, prog); } diff --git a/src/mesa/drivers/dri/i915/i915_metaops.c b/src/mesa/drivers/dri/i915/i915_metaops.c index 3ab5dbfd68..1be7ac4c48 100644 --- a/src/mesa/drivers/dri/i915/i915_metaops.c +++ b/src/mesa/drivers/dri/i915/i915_metaops.c @@ -493,14 +493,16 @@ static void draw_poly(i915ContextPtr i915, void -i915ClearWithTris(intelContextPtr intel, GLbitfield mask, - GLboolean all, - GLint cx, GLint cy, GLint cw, GLint ch) +i915ClearWithTris(intelContextPtr intel, GLbitfield buffers, + GLboolean allFoo, + GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo) { i915ContextPtr i915 = I915_CONTEXT( intel ); __DRIdrawablePrivate *dPriv = intel->driDrawable; intelScreenPrivate *screen = intel->intelScreen; int x0, y0, x1, y1; + GLint cx, cy, cw, ch; + GLboolean all; SET_STATE( i915, meta ); set_initial_state( i915 ); @@ -509,6 +511,14 @@ i915ClearWithTris(intelContextPtr intel, GLbitfield mask, LOCK_HARDWARE(intel); + /* get clear bounds after locking */ + cx = intel->ctx.DrawBuffer->_Xmin; + cy = intel->ctx.DrawBuffer->_Ymin; + cw = intel->ctx.DrawBuffer->_Xmax - cx; + ch = intel->ctx.DrawBuffer->_Ymax - cy; + all = (cw == intel->ctx.DrawBuffer->Width && + ch == intel->ctx.DrawBuffer->Height); + if (!all) { x0 = cx; y0 = cy; @@ -525,7 +535,7 @@ i915ClearWithTris(intelContextPtr intel, GLbitfield mask, * The active cliprects will be applied as for any other geometry. */ - if (mask & BUFFER_BIT_FRONT_LEFT) { + if (buffers & BUFFER_BIT_FRONT_LEFT) { set_no_depth_stencil_write( i915 ); set_color_mask( i915, GL_TRUE ); set_draw_region( i915, &screen->front ); @@ -536,7 +546,7 @@ i915ClearWithTris(intelContextPtr intel, GLbitfield mask, 0, 0, 0, 0); } - if (mask & BUFFER_BIT_BACK_LEFT) { + if (buffers & BUFFER_BIT_BACK_LEFT) { set_no_depth_stencil_write( i915 ); set_color_mask( i915, GL_TRUE ); set_draw_region( i915, &screen->back ); @@ -547,7 +557,7 @@ i915ClearWithTris(intelContextPtr intel, GLbitfield mask, 0, 0, 0, 0); } - if (mask & BUFFER_BIT_STENCIL) { + if (buffers & BUFFER_BIT_STENCIL) { set_stencil_replace( i915, intel->ctx.Stencil.WriteMask[0], intel->ctx.Stencil.Clear); diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.c b/src/mesa/drivers/dri/i915/intel_batchbuffer.c index 865f15e79f..803b41b256 100644 --- a/src/mesa/drivers/dri/i915/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915/intel_batchbuffer.c @@ -621,13 +621,14 @@ void intelEmitCopyBlitLocked( intelContextPtr intel, -void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, - GLint cx1, GLint cy1, GLint cw, GLint ch) +void intelClearWithBlit(GLcontext *ctx, GLbitfield buffers, GLboolean allFoo, + GLint cx1Foo, GLint cy1Foo, GLint cwFoo, GLint chFoo) { intelContextPtr intel = INTEL_CONTEXT( ctx ); intelScreenPrivate *intelScreen = intel->intelScreen; GLuint clear_depth, clear_color; - GLint cx, cy; + GLint cx, cy, cw, ch; + GLboolean all; GLint pitch; GLint cpp = intelScreen->cpp; GLint i; @@ -637,16 +638,24 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, intelFlush( &intel->ctx ); LOCK_HARDWARE( intel ); + /* get clear bounds after locking */ + cx = intel->ctx.DrawBuffer->_Xmin; + cy = intel->ctx.DrawBuffer->_Ymin; + cw = intel->ctx.DrawBuffer->_Xmax - cx; + ch = intel->ctx.DrawBuffer->_Ymax - cy; + all = (cw == intel->ctx.DrawBuffer->Width && + ch == intel->ctx.DrawBuffer->Height); + pitch = intelScreen->front.pitch; clear_color = intel->ClearColor; clear_depth = 0; - if (flags & BUFFER_BIT_DEPTH) { + if (buffers & BUFFER_BIT_DEPTH) { clear_depth = (GLuint)(ctx->Depth.Clear * intel->ClearDepth); } - if (flags & BUFFER_BIT_STENCIL) { + if (buffers & BUFFER_BIT_STENCIL) { clear_depth |= (ctx->Stencil.Clear & 0xff) << 24; } @@ -661,8 +670,8 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB); D_CMD = XY_COLOR_BLT_CMD; - if (flags & BUFFER_BIT_DEPTH) D_CMD |= XY_COLOR_BLT_WRITE_RGB; - if (flags & BUFFER_BIT_STENCIL) D_CMD |= XY_COLOR_BLT_WRITE_ALPHA; + if (buffers & BUFFER_BIT_DEPTH) D_CMD |= XY_COLOR_BLT_WRITE_RGB; + if (buffers & BUFFER_BIT_STENCIL) D_CMD |= XY_COLOR_BLT_WRITE_ALPHA; break; default: BR13 = (0xF0 << 16) | (pitch) | (1<<24); @@ -672,17 +681,17 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, { /* flip top to bottom */ - cy = intel->driDrawable->h-cy1-ch; - cx = cx1 + intel->drawX; + cy = intel->driDrawable->h - cy - ch; + cx = cx + intel->drawX; cy += intel->drawY; /* adjust for page flipping */ if ( intel->sarea->pf_current_page == 1 ) { - GLuint tmp = flags; + GLuint tmp = buffers; - flags &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT); - if ( tmp & BUFFER_BIT_FRONT_LEFT ) flags |= BUFFER_BIT_BACK_LEFT; - if ( tmp & BUFFER_BIT_BACK_LEFT ) flags |= BUFFER_BIT_FRONT_LEFT; + buffers &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT); + if ( tmp & BUFFER_BIT_FRONT_LEFT ) buffers |= BUFFER_BIT_BACK_LEFT; + if ( tmp & BUFFER_BIT_BACK_LEFT ) buffers |= BUFFER_BIT_FRONT_LEFT; } for (i = 0 ; i < intel->numClipRects ; i++) @@ -718,7 +727,7 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, b.y2 > intelScreen->height) continue; - if ( flags & BUFFER_BIT_FRONT_LEFT ) { + if ( buffers & BUFFER_BIT_FRONT_LEFT ) { BEGIN_BATCH( 6); OUT_BATCH( CMD ); OUT_BATCH( BR13 ); @@ -729,7 +738,7 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, ADVANCE_BATCH(); } - if ( flags & BUFFER_BIT_BACK_LEFT ) { + if ( buffers & BUFFER_BIT_BACK_LEFT ) { BEGIN_BATCH( 6); OUT_BATCH( CMD ); OUT_BATCH( BR13 ); @@ -740,7 +749,7 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, ADVANCE_BATCH(); } - if ( flags & (BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH) ) { + if ( buffers & (BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH) ) { BEGIN_BATCH( 6); OUT_BATCH( D_CMD ); OUT_BATCH( BR13 ); diff --git a/src/mesa/drivers/dri/i915/intel_ioctl.c b/src/mesa/drivers/dri/i915/intel_ioctl.c index d853036766..ede3b6378f 100644 --- a/src/mesa/drivers/dri/i915/intel_ioctl.c +++ b/src/mesa/drivers/dri/i915/intel_ioctl.c @@ -375,8 +375,7 @@ void intelFinish( GLcontext *ctx ) } -void intelClear(GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint cx, GLint cy, GLint cw, GLint ch) +void intelClear(GLcontext *ctx, GLbitfield mask) { intelContextPtr intel = INTEL_CONTEXT( ctx ); const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); @@ -429,13 +428,13 @@ void intelClear(GLcontext *ctx, GLbitfield mask, GLboolean all, swrast_mask |= (mask & BUFFER_BIT_ACCUM); if (blit_mask) - intelClearWithBlit( ctx, blit_mask, all, cx, cy, cw, ch ); + intelClearWithBlit( ctx, blit_mask, 0, 0, 0, 0, 0); if (tri_mask) - intel->vtbl.clear_with_tris( intel, tri_mask, all, cx, cy, cw, ch); + intel->vtbl.clear_with_tris( intel, tri_mask, 0, 0, 0, 0, 0); if (swrast_mask) - _swrast_Clear( ctx, swrast_mask, all, cx, cy, cw, ch ); + _swrast_Clear( ctx, swrast_mask ); } diff --git a/src/mesa/drivers/dri/i915/intel_ioctl.h b/src/mesa/drivers/dri/i915/intel_ioctl.h index 099a7e1a44..6ea47e462e 100644 --- a/src/mesa/drivers/dri/i915/intel_ioctl.h +++ b/src/mesa/drivers/dri/i915/intel_ioctl.h @@ -32,8 +32,7 @@ extern void intelWaitAgeLocked( intelContextPtr intel, int age, GLboolean unlock ); -extern void intelClear(GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint cx, GLint cy, GLint cw, GLint ch); +extern void intelClear(GLcontext *ctx, GLbitfield mask); extern void intelPageFlip( const __DRIdrawablePrivate *dpriv ); diff --git a/src/mesa/drivers/dri/i915tex/Makefile b/src/mesa/drivers/dri/i915tex/Makefile new file mode 100644 index 0000000000..94879d209f --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/Makefile @@ -0,0 +1,66 @@ + +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = i915tex_dri.so + +MINIGLX_SOURCES = server/intel_dri.c + +DRIVER_SOURCES = \ + i830_context.c \ + i830_metaops.c \ + i830_state.c \ + i830_texblend.c \ + i830_tex.c \ + i830_texstate.c \ + i830_vtbl.c \ + intel_render.c \ + intel_regions.c \ + intel_buffer_objects.c \ + intel_batchbuffer.c \ + intel_mipmap_tree.c \ + i915_tex_layout.c \ + intel_tex_image.c \ + intel_tex_subimage.c \ + intel_tex_copy.c \ + intel_tex_validate.c \ + intel_tex_format.c \ + intel_tex.c \ + intel_pixel.c \ + intel_pixel_copy.c \ + intel_pixel_read.c \ + intel_pixel_draw.c \ + intel_buffers.c \ + intel_blit.c \ + i915_tex.c \ + i915_texstate.c \ + i915_context.c \ + i915_debug.c \ + i915_fragprog.c \ + i915_metaops.c \ + i915_program.c \ + i915_state.c \ + i915_vtbl.c \ + intel_context.c \ + intel_ioctl.c \ + intel_rotate.c \ + intel_screen.c \ + intel_span.c \ + intel_state.c \ + intel_tris.c \ + intel_fbo.c \ + intel_depthstencil.c \ + intel_batchpool.c + +C_SOURCES = \ + $(COMMON_SOURCES) \ + $(COMMON_BM_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + + + +include ../Makefile.template + +symlinks: diff --git a/src/mesa/drivers/dri/i915tex/i830_context.c b/src/mesa/drivers/dri/i915tex/i830_context.c new file mode 100644 index 0000000000..2ff8621c42 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i830_context.c @@ -0,0 +1,104 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#include "i830_context.h" +#include "imports.h" +#include "texmem.h" +#include "intel_tex.h" +#include "tnl/tnl.h" +#include "tnl/t_vertex.h" +#include "tnl/t_context.h" +#include "utils.h" + +/*************************************** + * Mesa's Driver Functions + ***************************************/ + +static const struct dri_extension i830_extensions[] = { + {"GL_ARB_texture_env_crossbar", NULL}, + {NULL, NULL} +}; + + +static void +i830InitDriverFunctions(struct dd_function_table *functions) +{ + intelInitDriverFunctions(functions); + i830InitStateFuncs(functions); + i830InitTextureFuncs(functions); +} + + +GLboolean +i830CreateContext(const __GLcontextModes * mesaVis, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate) +{ + struct dd_function_table functions; + struct i830_context *i830 = CALLOC_STRUCT(i830_context); + struct intel_context *intel = &i830->intel; + GLcontext *ctx = &intel->ctx; + if (!i830) + return GL_FALSE; + + i830InitVtbl(i830); + i830InitDriverFunctions(&functions); + + if (!intelInitContext(intel, mesaVis, driContextPriv, + sharedContextPrivate, &functions)) { + FREE(i830); + return GL_FALSE; + } + + intel->ctx.Const.MaxTextureUnits = I830_TEX_UNITS; + intel->ctx.Const.MaxTextureImageUnits = I830_TEX_UNITS; + intel->ctx.Const.MaxTextureCoordUnits = I830_TEX_UNITS; + + /* Advertise the full hardware capabilities. The new memory + * manager should cope much better with overload situations: + */ + ctx->Const.MaxTextureLevels = 12; + ctx->Const.Max3DTextureLevels = 9; + ctx->Const.MaxCubeTextureLevels = 11; + ctx->Const.MaxTextureRectSize = (1 << 11); + ctx->Const.MaxTextureUnits = I830_TEX_UNITS; + + _tnl_init_vertices(ctx, ctx->Const.MaxArrayLockSize + 12, + 18 * sizeof(GLfloat)); + + intel->verts = TNL_CONTEXT(ctx)->clipspace.vertex_buf; + + driInitExtensions(ctx, i830_extensions, GL_FALSE); + + i830InitState(i830); + i830InitMetaFuncs(i830); + + _tnl_allow_vertex_fog(ctx, 1); + _tnl_allow_pixel_fog(ctx, 0); + + return GL_TRUE; +} diff --git a/src/mesa/drivers/dri/i915tex/i830_context.h b/src/mesa/drivers/dri/i915tex/i830_context.h new file mode 100644 index 0000000000..e5377b300a --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i830_context.h @@ -0,0 +1,208 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#ifndef I830CONTEXT_INC +#define I830CONTEXT_INC + +#include "intel_context.h" + +#define I830_FALLBACK_TEXTURE 0x1000 +#define I830_FALLBACK_COLORMASK 0x2000 +#define I830_FALLBACK_STENCIL 0x4000 +#define I830_FALLBACK_STIPPLE 0x8000 +#define I830_FALLBACK_LOGICOP 0x10000 + +#define I830_UPLOAD_CTX 0x1 +#define I830_UPLOAD_BUFFERS 0x2 +#define I830_UPLOAD_STIPPLE 0x4 +#define I830_UPLOAD_INVARIENT 0x8 +#define I830_UPLOAD_TEX(i) (0x10<<(i)) +#define I830_UPLOAD_TEXBLEND(i) (0x100<<(i)) +#define I830_UPLOAD_TEX_ALL (0x0f0) +#define I830_UPLOAD_TEXBLEND_ALL (0xf00) + +/* State structure offsets - these will probably disappear. + */ +#define I830_DESTREG_CBUFADDR0 0 +#define I830_DESTREG_CBUFADDR1 1 +#define I830_DESTREG_DBUFADDR0 2 +#define I830_DESTREG_DBUFADDR1 3 +#define I830_DESTREG_DV0 4 +#define I830_DESTREG_DV1 5 +#define I830_DESTREG_SENABLE 6 +#define I830_DESTREG_SR0 7 +#define I830_DESTREG_SR1 8 +#define I830_DESTREG_SR2 9 +#define I830_DEST_SETUP_SIZE 10 + +#define I830_CTXREG_STATE1 0 +#define I830_CTXREG_STATE2 1 +#define I830_CTXREG_STATE3 2 +#define I830_CTXREG_STATE4 3 +#define I830_CTXREG_STATE5 4 +#define I830_CTXREG_IALPHAB 5 +#define I830_CTXREG_STENCILTST 6 +#define I830_CTXREG_ENABLES_1 7 +#define I830_CTXREG_ENABLES_2 8 +#define I830_CTXREG_AA 9 +#define I830_CTXREG_FOGCOLOR 10 +#define I830_CTXREG_BLENDCOLOR0 11 +#define I830_CTXREG_BLENDCOLOR1 12 +#define I830_CTXREG_VF 13 +#define I830_CTXREG_VF2 14 +#define I830_CTXREG_MCSB0 15 +#define I830_CTXREG_MCSB1 16 +#define I830_CTX_SETUP_SIZE 17 + +#define I830_STPREG_ST0 0 +#define I830_STPREG_ST1 1 +#define I830_STP_SETUP_SIZE 2 + +#define I830_TEXREG_TM0LI 0 /* load immediate 2 texture map n */ +#define I830_TEXREG_TM0S1 1 +#define I830_TEXREG_TM0S2 2 +#define I830_TEXREG_TM0S3 3 +#define I830_TEXREG_TM0S4 4 +#define I830_TEXREG_MCS 5 /* _3DSTATE_MAP_COORD_SETS */ +#define I830_TEXREG_CUBE 6 /* _3DSTATE_MAP_SUBE */ +#define I830_TEX_SETUP_SIZE 7 + +#define I830_TEXBLEND_SIZE 12 /* (4 args + op) * 2 + COLOR_FACTOR */ + +struct i830_texture_object +{ + struct intel_texture_object intel; + GLuint Setup[I830_TEX_SETUP_SIZE]; +}; + +#define I830_TEX_UNITS 4 + +struct i830_hw_state +{ + GLuint Ctx[I830_CTX_SETUP_SIZE]; + GLuint Buffer[I830_DEST_SETUP_SIZE]; + GLuint Stipple[I830_STP_SETUP_SIZE]; + GLuint Tex[I830_TEX_UNITS][I830_TEX_SETUP_SIZE]; + GLuint TexBlend[I830_TEX_UNITS][I830_TEXBLEND_SIZE]; + GLuint TexBlendWordsUsed[I830_TEX_UNITS]; + + struct intel_region *draw_region; + struct intel_region *depth_region; + + /* Regions aren't actually that appropriate here as the memory may + * be from a PBO or FBO. Just use the buffer id. Will have to do + * this for draw and depth for FBO's... + */ + struct _DriBufferObject *tex_buffer[I830_TEX_UNITS]; + GLuint tex_offset[I830_TEX_UNITS]; + + GLuint emitted; /* I810_UPLOAD_* */ + GLuint active; +}; + +struct i830_context +{ + struct intel_context intel; + + GLuint lodbias_tm0s3[MAX_TEXTURE_UNITS]; + DECLARE_RENDERINPUTS(last_index_bitset); + + struct i830_hw_state meta, initial, state, *current; +}; + + + + +#define I830_STATECHANGE(i830, flag) \ +do { \ + INTEL_FIREVERTICES( &i830->intel ); \ + i830->state.emitted &= ~flag; \ +} while (0) + +#define I830_ACTIVESTATE(i830, flag, mode) \ +do { \ + INTEL_FIREVERTICES( &i830->intel ); \ + if (mode) \ + i830->state.active |= flag; \ + else \ + i830->state.active &= ~flag; \ +} while (0) + +/* i830_vtbl.c + */ +extern void i830InitVtbl(struct i830_context *i830); + +/* i830_context.c + */ +extern GLboolean +i830CreateContext(const __GLcontextModes * mesaVis, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate); + +/* i830_tex.c, i830_texstate.c + */ +extern void i830UpdateTextureState(struct intel_context *intel); + +extern void i830InitTextureFuncs(struct dd_function_table *functions); + +/* i830_texblend.c + */ +extern GLuint i830SetTexEnvCombine(struct i830_context *i830, + const struct gl_tex_env_combine_state + *combine, GLint blendUnit, GLuint texel_op, + GLuint * state, const GLfloat * factor); + +extern void i830EmitTextureBlend(struct i830_context *i830); + + +/* i830_state.c + */ +extern void i830InitStateFuncs(struct dd_function_table *functions); + +extern void i830EmitState(struct i830_context *i830); + +extern void i830InitState(struct i830_context *i830); + +/* i830_metaops.c + */ +extern void i830InitMetaFuncs(struct i830_context *i830); + +extern void +i830RotateWindow(struct intel_context *intel, __DRIdrawablePrivate * dPriv, + GLuint srcBuf); + +/*====================================================================== + * Inline conversion functions. These are better-typed than the + * macros used previously: + */ +static INLINE struct i830_context * +i830_context(GLcontext * ctx) +{ + return (struct i830_context *) ctx; +} + +#endif diff --git a/src/mesa/drivers/dri/i915tex/i830_metaops.c b/src/mesa/drivers/dri/i915tex/i830_metaops.c new file mode 100644 index 0000000000..c90f502222 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i830_metaops.c @@ -0,0 +1,485 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#include "glheader.h" +#include "enums.h" +#include "mtypes.h" +#include "macros.h" +#include "utils.h" + +#include "intel_screen.h" +#include "intel_batchbuffer.h" +#include "intel_ioctl.h" +#include "intel_regions.h" + +#include "i830_context.h" +#include "i830_reg.h" + +/* A large amount of state doesn't need to be uploaded. + */ +#define ACTIVE (I830_UPLOAD_INVARIENT | \ + I830_UPLOAD_CTX | \ + I830_UPLOAD_BUFFERS | \ + I830_UPLOAD_STIPPLE | \ + I830_UPLOAD_TEXBLEND(0) | \ + I830_UPLOAD_TEX(0)) + + +#define SET_STATE( i830, STATE ) \ +do { \ + i830->current->emitted &= ~ACTIVE; \ + i830->current = &i830->STATE; \ + i830->current->emitted &= ~ACTIVE; \ +} while (0) + + +static void +set_no_stencil_write(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + + /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE ) + */ + i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_STENCIL_TEST; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_STENCIL_WRITE; + i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_STENCIL_TEST; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_STENCIL_WRITE; + + i830->meta.emitted &= ~I830_UPLOAD_CTX; +} + +static void +set_no_depth_write(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + + /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) + */ + i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK; + i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE; + + i830->meta.emitted &= ~I830_UPLOAD_CTX; +} + +/* Set depth unit to replace. + */ +static void +set_depth_replace(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + + /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) + * ctx->Driver.DepthMask( ctx, GL_TRUE ) + */ + i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK; + i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_DEPTH_TEST; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_DEPTH_WRITE; + + /* ctx->Driver.DepthFunc( ctx, GL_ALWAYS ) + */ + i830->meta.Ctx[I830_CTXREG_STATE3] &= ~DEPTH_TEST_FUNC_MASK; + i830->meta.Ctx[I830_CTXREG_STATE3] |= (ENABLE_DEPTH_TEST_FUNC | + DEPTH_TEST_FUNC + (COMPAREFUNC_ALWAYS)); + + i830->meta.emitted &= ~I830_UPLOAD_CTX; +} + + +/* Set stencil unit to replace always with the reference value. + */ +static void +set_stencil_replace(struct intel_context *intel, + GLuint s_mask, GLuint s_clear) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + + /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_TRUE ) + */ + i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_STENCIL_TEST; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_STENCIL_WRITE; + + /* ctx->Driver.StencilMask( ctx, s_mask ) + */ + i830->meta.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; + i830->meta.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | + STENCIL_WRITE_MASK((s_mask & + 0xff))); + + /* ctx->Driver.StencilOp( ctx, GL_REPLACE, GL_REPLACE, GL_REPLACE ) + */ + i830->meta.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_OPS_MASK); + i830->meta.Ctx[I830_CTXREG_STENCILTST] |= + (ENABLE_STENCIL_PARMS | + STENCIL_FAIL_OP(STENCILOP_REPLACE) | + STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_REPLACE) | + STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_REPLACE)); + + /* ctx->Driver.StencilFunc( ctx, GL_ALWAYS, s_clear, ~0 ) + */ + i830->meta.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; + i830->meta.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | + STENCIL_TEST_MASK(0xff)); + + i830->meta.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_REF_VALUE_MASK | + ENABLE_STENCIL_TEST_FUNC_MASK); + i830->meta.Ctx[I830_CTXREG_STENCILTST] |= + (ENABLE_STENCIL_REF_VALUE | + ENABLE_STENCIL_TEST_FUNC | + STENCIL_REF_VALUE((s_clear & 0xff)) | + STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS)); + + + + i830->meta.emitted &= ~I830_UPLOAD_CTX; +} + + +static void +set_color_mask(struct intel_context *intel, GLboolean state) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + + const GLuint mask = ((1 << WRITEMASK_RED_SHIFT) | + (1 << WRITEMASK_GREEN_SHIFT) | + (1 << WRITEMASK_BLUE_SHIFT) | + (1 << WRITEMASK_ALPHA_SHIFT)); + + i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~mask; + + if (state) { + i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= + (i830->state.Ctx[I830_CTXREG_ENABLES_2] & mask); + } + + i830->meta.emitted &= ~I830_UPLOAD_CTX; +} + +/* Installs a one-stage passthrough texture blend pipeline. Is there + * more that can be done to turn off texturing? + */ +static void +set_no_texture(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + static const struct gl_tex_env_combine_state comb = { + GL_NONE, GL_NONE, + {GL_TEXTURE, 0, 0,}, {GL_TEXTURE, 0, 0,}, + {GL_SRC_COLOR, 0, 0}, {GL_SRC_ALPHA, 0, 0}, + 0, 0, 0, 0 + }; + + i830->meta.TexBlendWordsUsed[0] = + i830SetTexEnvCombine(i830, &comb, 0, TEXBLENDARG_TEXEL0, + i830->meta.TexBlend[0], NULL); + + i830->meta.TexBlend[0][0] |= TEXOP_LAST_STAGE; + i830->meta.emitted &= ~I830_UPLOAD_TEXBLEND(0); +} + +/* Set up a single element blend stage for 'replace' texturing with no + * funny ops. + */ +static void +set_texture_blend_replace(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + static const struct gl_tex_env_combine_state comb = { + GL_REPLACE, GL_REPLACE, + {GL_TEXTURE, GL_TEXTURE, GL_TEXTURE,}, {GL_TEXTURE, GL_TEXTURE, + GL_TEXTURE,}, + {GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR}, {GL_SRC_ALPHA, GL_SRC_ALPHA, + GL_SRC_ALPHA}, + 0, 0, 1, 1 + }; + + i830->meta.TexBlendWordsUsed[0] = + i830SetTexEnvCombine(i830, &comb, 0, TEXBLENDARG_TEXEL0, + i830->meta.TexBlend[0], NULL); + + i830->meta.TexBlend[0][0] |= TEXOP_LAST_STAGE; + i830->meta.emitted &= ~I830_UPLOAD_TEXBLEND(0); + +/* fprintf(stderr, "%s: TexBlendWordsUsed[0]: %d\n", */ +/* __FUNCTION__, i830->meta.TexBlendWordsUsed[0]); */ +} + + + +/* Set up an arbitary piece of memory as a rectangular texture + * (including the front or back buffer). + */ +static GLboolean +set_tex_rect_source(struct intel_context *intel, + struct _DriBufferObject *buffer, + GLuint offset, + GLuint pitch, GLuint height, GLenum format, GLenum type) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + GLuint *setup = i830->meta.Tex[0]; + GLint numLevels = 1; + GLuint textureFormat; + GLuint cpp; + + /* A full implementation of this would do the upload through + * glTexImage2d, and get all the conversion operations at that + * point. We are restricted, but still at least have access to the + * fragment program swizzle. + */ + switch (format) { + case GL_BGRA: + switch (type) { + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_UNSIGNED_BYTE: + textureFormat = (MAPSURF_32BIT | MT_32BIT_ARGB8888); + cpp = 4; + break; + default: + return GL_FALSE; + } + break; + case GL_RGBA: + switch (type) { + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_UNSIGNED_BYTE: + textureFormat = (MAPSURF_32BIT | MT_32BIT_ABGR8888); + cpp = 4; + break; + default: + return GL_FALSE; + } + break; + case GL_BGR: + switch (type) { + case GL_UNSIGNED_SHORT_5_6_5_REV: + textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); + cpp = 2; + break; + default: + return GL_FALSE; + } + break; + case GL_RGB: + switch (type) { + case GL_UNSIGNED_SHORT_5_6_5: + textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); + cpp = 2; + break; + default: + return GL_FALSE; + } + break; + + default: + return GL_FALSE; + } + + i830->meta.tex_buffer[0] = buffer; + i830->meta.tex_offset[0] = offset; + + setup[I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 | + (LOAD_TEXTURE_MAP0 << 0) | 4); + setup[I830_TEXREG_TM0S1] = (((height - 1) << TM0S1_HEIGHT_SHIFT) | + ((pitch - 1) << TM0S1_WIDTH_SHIFT) | + textureFormat); + setup[I830_TEXREG_TM0S2] = + (((((pitch * cpp) / 4) - + 1) << TM0S2_PITCH_SHIFT) | TM0S2_CUBE_FACE_ENA_MASK); + + setup[I830_TEXREG_TM0S3] = + ((((numLevels - + 1) * + 4) << TM0S3_MIN_MIP_SHIFT) | (FILTER_NEAREST << + TM0S3_MIN_FILTER_SHIFT) | + (MIPFILTER_NONE << TM0S3_MIP_FILTER_SHIFT) | (FILTER_NEAREST << + TM0S3_MAG_FILTER_SHIFT)); + + setup[I830_TEXREG_CUBE] = (_3DSTATE_MAP_CUBE | MAP_UNIT(0)); + + setup[I830_TEXREG_MCS] = (_3DSTATE_MAP_COORD_SET_CMD | + MAP_UNIT(0) | + ENABLE_TEXCOORD_PARAMS | + TEXCOORDS_ARE_IN_TEXELUNITS | + TEXCOORDTYPE_CARTESIAN | + ENABLE_ADDR_V_CNTL | + TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP) | + ENABLE_ADDR_U_CNTL | + TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP)); + + i830->meta.emitted &= ~I830_UPLOAD_TEX(0); + return GL_TRUE; +} + + +static void +set_vertex_format(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + i830->meta.Ctx[I830_CTXREG_VF] = (_3DSTATE_VFT0_CMD | + VFT0_TEX_COUNT(1) | + VFT0_DIFFUSE | VFT0_XYZ); + i830->meta.Ctx[I830_CTXREG_VF2] = (_3DSTATE_VFT1_CMD | + VFT1_TEX0_FMT(TEXCOORDFMT_2D) | + VFT1_TEX1_FMT(TEXCOORDFMT_2D) | + VFT1_TEX2_FMT(TEXCOORDFMT_2D) | + VFT1_TEX3_FMT(TEXCOORDFMT_2D)); + i830->meta.emitted &= ~I830_UPLOAD_CTX; +} + + +static void +meta_import_pixel_state(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + + i830->meta.Ctx[I830_CTXREG_STATE1] = i830->state.Ctx[I830_CTXREG_STATE1]; + i830->meta.Ctx[I830_CTXREG_STATE2] = i830->state.Ctx[I830_CTXREG_STATE2]; + i830->meta.Ctx[I830_CTXREG_STATE3] = i830->state.Ctx[I830_CTXREG_STATE3]; + i830->meta.Ctx[I830_CTXREG_STATE4] = i830->state.Ctx[I830_CTXREG_STATE4]; + i830->meta.Ctx[I830_CTXREG_STATE5] = i830->state.Ctx[I830_CTXREG_STATE5]; + i830->meta.Ctx[I830_CTXREG_IALPHAB] = i830->state.Ctx[I830_CTXREG_IALPHAB]; + i830->meta.Ctx[I830_CTXREG_STENCILTST] = + i830->state.Ctx[I830_CTXREG_STENCILTST]; + i830->meta.Ctx[I830_CTXREG_ENABLES_1] = + i830->state.Ctx[I830_CTXREG_ENABLES_1]; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] = + i830->state.Ctx[I830_CTXREG_ENABLES_2]; + i830->meta.Ctx[I830_CTXREG_AA] = i830->state.Ctx[I830_CTXREG_AA]; + i830->meta.Ctx[I830_CTXREG_FOGCOLOR] = + i830->state.Ctx[I830_CTXREG_FOGCOLOR]; + i830->meta.Ctx[I830_CTXREG_BLENDCOLOR0] = + i830->state.Ctx[I830_CTXREG_BLENDCOLOR0]; + i830->meta.Ctx[I830_CTXREG_BLENDCOLOR1] = + i830->state.Ctx[I830_CTXREG_BLENDCOLOR1]; + i830->meta.Ctx[I830_CTXREG_MCSB0] = i830->state.Ctx[I830_CTXREG_MCSB0]; + i830->meta.Ctx[I830_CTXREG_MCSB1] = i830->state.Ctx[I830_CTXREG_MCSB1]; + + + i830->meta.Ctx[I830_CTXREG_STATE3] &= ~CULLMODE_MASK; + i830->meta.Stipple[I830_STPREG_ST1] &= ~ST1_ENABLE; + i830->meta.emitted &= ~I830_UPLOAD_CTX; + + + i830->meta.Buffer[I830_DESTREG_SENABLE] = + i830->state.Buffer[I830_DESTREG_SENABLE]; + i830->meta.Buffer[I830_DESTREG_SR1] = i830->state.Buffer[I830_DESTREG_SR1]; + i830->meta.Buffer[I830_DESTREG_SR2] = i830->state.Buffer[I830_DESTREG_SR2]; + i830->meta.emitted &= ~I830_UPLOAD_BUFFERS; +} + + + +/* Select between front and back draw buffers. + */ +static void +meta_draw_region(struct intel_context *intel, + struct intel_region *draw_region, + struct intel_region *depth_region) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + GLuint format; + GLuint depth_format = DEPTH_FRMT_16_FIXED; + + intel_region_release(&i830->meta.draw_region); + intel_region_reference(&i830->meta.draw_region, draw_region); + + intel_region_release(&i830->meta.depth_region); + intel_region_reference(&i830->meta.depth_region, depth_region); + + /* XXX FBO: grab code from i915 meta_draw_region */ + + /* XXX: 555 support? + */ + if (draw_region->cpp == 2) + format = DV_PF_565; + else + format = DV_PF_8888; + + if (depth_region) { + if (depth_region->cpp == 2) + depth_format = DEPTH_FRMT_16_FIXED; + else + depth_format = DEPTH_FRMT_24_FIXED_8_OTHER; + } + + i830->meta.Buffer[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ + DSTORG_VERT_BIAS(0x8) | /* .5 */ + format | DEPTH_IS_Z | depth_format); + + i830->meta.emitted &= ~I830_UPLOAD_BUFFERS; +} + + +/* Operations where the 3D engine is decoupled temporarily from the + * current GL state and used for other purposes than simply rendering + * incoming triangles. + */ +static void +install_meta_state(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + memcpy(&i830->meta, &i830->initial, sizeof(i830->meta)); + + i830->meta.active = ACTIVE; + i830->meta.emitted = 0; + + SET_STATE(i830, meta); + set_vertex_format(intel); + set_no_texture(intel); +} + +static void +leave_meta_state(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + intel_region_release(&i830->meta.draw_region); + intel_region_release(&i830->meta.depth_region); +/* intel_region_release(intel, &i830->meta.tex_region[0]); */ + SET_STATE(i830, state); +} + + + +void +i830InitMetaFuncs(struct i830_context *i830) +{ + i830->intel.vtbl.install_meta_state = install_meta_state; + i830->intel.vtbl.leave_meta_state = leave_meta_state; + i830->intel.vtbl.meta_no_depth_write = set_no_depth_write; + i830->intel.vtbl.meta_no_stencil_write = set_no_stencil_write; + i830->intel.vtbl.meta_stencil_replace = set_stencil_replace; + i830->intel.vtbl.meta_depth_replace = set_depth_replace; + i830->intel.vtbl.meta_color_mask = set_color_mask; + i830->intel.vtbl.meta_no_texture = set_no_texture; + i830->intel.vtbl.meta_texture_blend_replace = set_texture_blend_replace; + i830->intel.vtbl.meta_tex_rect_source = set_tex_rect_source; + i830->intel.vtbl.meta_draw_region = meta_draw_region; + i830->intel.vtbl.meta_import_pixel_state = meta_import_pixel_state; +} diff --git a/src/mesa/drivers/dri/i915tex/i830_reg.h b/src/mesa/drivers/dri/i915tex/i830_reg.h new file mode 100644 index 0000000000..24ac524500 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i830_reg.h @@ -0,0 +1,641 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + + +#ifndef _I830_REG_H_ +#define _I830_REG_H_ + + +#include "intel_reg.h" + +#define I830_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value) + +#define _3DSTATE_AA_CMD (CMD_3D | (0x06<<24)) +#define AA_LINE_ECAAR_WIDTH_ENABLE (1<<16) +#define AA_LINE_ECAAR_WIDTH_0_5 0 +#define AA_LINE_ECAAR_WIDTH_1_0 (1<<14) +#define AA_LINE_ECAAR_WIDTH_2_0 (2<<14) +#define AA_LINE_ECAAR_WIDTH_4_0 (3<<14) +#define AA_LINE_REGION_WIDTH_ENABLE (1<<8) +#define AA_LINE_REGION_WIDTH_0_5 0 +#define AA_LINE_REGION_WIDTH_1_0 (1<<6) +#define AA_LINE_REGION_WIDTH_2_0 (2<<6) +#define AA_LINE_REGION_WIDTH_4_0 (3<<6) +#define AA_LINE_ENABLE ((1<<1) | 1) +#define AA_LINE_DISABLE (1<<1) + +#define _3DSTATE_BUF_INFO_CMD (CMD_3D | (0x1d<<24) | (0x8e<<16) | 1) +/* Dword 1 */ +#define BUF_3D_ID_COLOR_BACK (0x3<<24) +#define BUF_3D_ID_DEPTH (0x7<<24) +#define BUF_3D_USE_FENCE (1<<23) +#define BUF_3D_TILED_SURFACE (1<<22) +#define BUF_3D_TILE_WALK_X 0 +#define BUF_3D_TILE_WALK_Y (1<<21) +#define BUF_3D_PITCH(x) (((x)/4)<<2) +/* Dword 2 */ +#define BUF_3D_ADDR(x) ((x) & ~0x3) + + +#define _3DSTATE_COLOR_FACTOR_CMD (CMD_3D | (0x1d<<24) | (0x1<<16)) + +#define _3DSTATE_COLOR_FACTOR_N_CMD(stage) (CMD_3D | (0x1d<<24) | \ + ((0x90+(stage))<<16)) + +#define _3DSTATE_CONST_BLEND_COLOR_CMD (CMD_3D | (0x1d<<24) | (0x88<<16)) + +#define _3DSTATE_DFLT_DIFFUSE_CMD (CMD_3D | (0x1d<<24) | (0x99<<16)) + +#define _3DSTATE_DFLT_SPEC_CMD (CMD_3D | (0x1d<<24) | (0x9a<<16)) + +#define _3DSTATE_DFLT_Z_CMD (CMD_3D | (0x1d<<24) | (0x98<<16)) + + +#define _3DSTATE_DST_BUF_VARS_CMD (CMD_3D | (0x1d<<24) | (0x85<<16)) +/* Dword 1 */ +#define DSTORG_HORT_BIAS(x) ((x)<<20) +#define DSTORG_VERT_BIAS(x) ((x)<<16) +#define COLOR_4_2_2_CHNL_WRT_ALL 0 +#define COLOR_4_2_2_CHNL_WRT_Y (1<<12) +#define COLOR_4_2_2_CHNL_WRT_CR (2<<12) +#define COLOR_4_2_2_CHNL_WRT_CB (3<<12) +#define COLOR_4_2_2_CHNL_WRT_CRCB (4<<12) +#define COLR_BUF_8BIT 0 +#define COLR_BUF_RGB555 (1<<8) +#define COLR_BUF_RGB565 (2<<8) +#define COLR_BUF_ARGB8888 (3<<8) +#define DEPTH_IS_Z 0 +#define DEPTH_IS_W (1<<6) +#define DEPTH_FRMT_16_FIXED 0 +#define DEPTH_FRMT_16_FLOAT (1<<2) +#define DEPTH_FRMT_24_FIXED_8_OTHER (2<<2) +#define DEPTH_FRMT_24_FLOAT_8_OTHER (3<<2) +#define VERT_LINE_STRIDE_1 (1<<1) +#define VERT_LINE_STRIDE_0 0 +#define VERT_LINE_STRIDE_OFS_1 1 +#define VERT_LINE_STRIDE_OFS_0 0 + + +#define _3DSTATE_DRAW_RECT_CMD (CMD_3D|(0x1d<<24)|(0x80<<16)|3) +/* Dword 1 */ +#define DRAW_RECT_DIS_DEPTH_OFS (1<<30) +#define DRAW_DITHER_OFS_X(x) ((x)<<26) +#define DRAW_DITHER_OFS_Y(x) ((x)<<24) +/* Dword 2 */ +#define DRAW_YMIN(x) ((x)<<16) +#define DRAW_XMIN(x) (x) +/* Dword 3 */ +#define DRAW_YMAX(x) ((x)<<16) +#define DRAW_XMAX(x) (x) +/* Dword 4 */ +#define DRAW_YORG(x) ((x)<<16) +#define DRAW_XORG(x) (x) + + +#define _3DSTATE_ENABLES_1_CMD (CMD_3D|(0x3<<24)) +#define ENABLE_LOGIC_OP_MASK ((1<<23)|(1<<22)) +#define ENABLE_LOGIC_OP ((1<<23)|(1<<22)) +#define DISABLE_LOGIC_OP (1<<23) +#define ENABLE_STENCIL_TEST ((1<<21)|(1<<20)) +#define DISABLE_STENCIL_TEST (1<<21) +#define ENABLE_DEPTH_BIAS ((1<<11)|(1<<10)) +#define DISABLE_DEPTH_BIAS (1<<11) +#define ENABLE_SPEC_ADD_MASK ((1<<9)|(1<<8)) +#define ENABLE_SPEC_ADD ((1<<9)|(1<<8)) +#define DISABLE_SPEC_ADD (1<<9) +#define ENABLE_DIS_FOG_MASK ((1<<7)|(1<<6)) +#define ENABLE_FOG ((1<<7)|(1<<6)) +#define DISABLE_FOG (1<<7) +#define ENABLE_DIS_ALPHA_TEST_MASK ((1<<5)|(1<<4)) +#define ENABLE_ALPHA_TEST ((1<<5)|(1<<4)) +#define DISABLE_ALPHA_TEST (1<<5) +#define ENABLE_DIS_CBLEND_MASK ((1<<3)|(1<<2)) +#define ENABLE_COLOR_BLEND ((1<<3)|(1<<2)) +#define DISABLE_COLOR_BLEND (1<<3) +#define ENABLE_DIS_DEPTH_TEST_MASK ((1<<1)|1) +#define ENABLE_DEPTH_TEST ((1<<1)|1) +#define DISABLE_DEPTH_TEST (1<<1) + +/* _3DSTATE_ENABLES_2, p138 */ +#define _3DSTATE_ENABLES_2_CMD (CMD_3D|(0x4<<24)) +#define ENABLE_STENCIL_WRITE ((1<<21)|(1<<20)) +#define DISABLE_STENCIL_WRITE (1<<21) +#define ENABLE_TEX_CACHE ((1<<17)|(1<<16)) +#define DISABLE_TEX_CACHE (1<<17) +#define ENABLE_DITHER ((1<<9)|(1<<8)) +#define DISABLE_DITHER (1<<9) +#define ENABLE_COLOR_MASK (1<<10) +#define WRITEMASK_ALPHA (1<<7) +#define WRITEMASK_ALPHA_SHIFT 7 +#define WRITEMASK_RED (1<<6) +#define WRITEMASK_RED_SHIFT 6 +#define WRITEMASK_GREEN (1<<5) +#define WRITEMASK_GREEN_SHIFT 5 +#define WRITEMASK_BLUE (1<<4) +#define WRITEMASK_BLUE_SHIFT 4 +#define WRITEMASK_MASK ((1<<4)|(1<<5)|(1<<6)|(1<<7)) +#define ENABLE_COLOR_WRITE ((1<<3)|(1<<2)) +#define DISABLE_COLOR_WRITE (1<<3) +#define ENABLE_DIS_DEPTH_WRITE_MASK 0x3 +#define ENABLE_DEPTH_WRITE ((1<<1)|1) +#define DISABLE_DEPTH_WRITE (1<<1) + +/* _3DSTATE_FOG_COLOR, p139 */ +#define _3DSTATE_FOG_COLOR_CMD (CMD_3D|(0x15<<24)) +#define FOG_COLOR_RED(x) ((x)<<16) +#define FOG_COLOR_GREEN(x) ((x)<<8) +#define FOG_COLOR_BLUE(x) (x) + +/* _3DSTATE_FOG_MODE, p140 */ +#define _3DSTATE_FOG_MODE_CMD (CMD_3D|(0x1d<<24)|(0x89<<16)|2) +/* Dword 1 */ +#define FOGFUNC_ENABLE (1<<31) +#define FOGFUNC_VERTEX 0 +#define FOGFUNC_PIXEL_EXP (1<<28) +#define FOGFUNC_PIXEL_EXP2 (2<<28) +#define FOGFUNC_PIXEL_LINEAR (3<<28) +#define FOGSRC_INDEX_Z (1<<27) +#define FOGSRC_INDEX_W ((1<<27)|(1<<25)) +#define FOG_LINEAR_CONST (1<<24) +#define FOG_CONST_1(x) ((x)<<4) +#define ENABLE_FOG_DENSITY (1<<23) +/* Dword 2 */ +#define FOG_CONST_2(x) (x) +/* Dword 3 */ +#define FOG_DENSITY(x) (x) + +/* _3DSTATE_INDEPENDENT_ALPHA_BLEND, p142 */ +#define _3DSTATE_INDPT_ALPHA_BLEND_CMD (CMD_3D|(0x0b<<24)) +#define ENABLE_INDPT_ALPHA_BLEND ((1<<23)|(1<<22)) +#define DISABLE_INDPT_ALPHA_BLEND (1<<23) +#define ALPHA_BLENDFUNC_MASK 0x3f0000 +#define ENABLE_ALPHA_BLENDFUNC (1<<21) +#define ABLENDFUNC_ADD 0 +#define ABLENDFUNC_SUB (1<<16) +#define ABLENDFUNC_RVSE_SUB (2<<16) +#define ABLENDFUNC_MIN (3<<16) +#define ABLENDFUNC_MAX (4<<16) +#define SRC_DST_ABLEND_MASK 0xfff +#define ENABLE_SRC_ABLEND_FACTOR (1<<11) +#define SRC_ABLEND_FACT(x) ((x)<<6) +#define ENABLE_DST_ABLEND_FACTOR (1<<5) +#define DST_ABLEND_FACT(x) (x) + + +/* _3DSTATE_MAP_BLEND_ARG, p152 */ +#define _3DSTATE_MAP_BLEND_ARG_CMD(stage) (CMD_3D|(0x0e<<24)|((stage)<<20)) + +#define TEXPIPE_COLOR 0 +#define TEXPIPE_ALPHA (1<<18) +#define TEXPIPE_KILL (2<<18) +#define TEXBLEND_ARG0 0 +#define TEXBLEND_ARG1 (1<<15) +#define TEXBLEND_ARG2 (2<<15) +#define TEXBLEND_ARG3 (3<<15) +#define TEXBLENDARG_MODIFY_PARMS (1<<6) +#define TEXBLENDARG_REPLICATE_ALPHA (1<<5) +#define TEXBLENDARG_INV_ARG (1<<4) +#define TEXBLENDARG_ONE 0 +#define TEXBLENDARG_FACTOR 0x01 +#define TEXBLENDARG_ACCUM 0x02 +#define TEXBLENDARG_DIFFUSE 0x03 +#define TEXBLENDARG_SPEC 0x04 +#define TEXBLENDARG_CURRENT 0x05 +#define TEXBLENDARG_TEXEL0 0x06 +#define TEXBLENDARG_TEXEL1 0x07 +#define TEXBLENDARG_TEXEL2 0x08 +#define TEXBLENDARG_TEXEL3 0x09 +#define TEXBLENDARG_FACTOR_N 0x0e + +/* _3DSTATE_MAP_BLEND_OP, p155 */ +#define _3DSTATE_MAP_BLEND_OP_CMD(stage) (CMD_3D|(0x0d<<24)|((stage)<<20)) +#if 0 +# define TEXPIPE_COLOR 0 +# define TEXPIPE_ALPHA (1<<18) +# define TEXPIPE_KILL (2<<18) +#endif +#define ENABLE_TEXOUTPUT_WRT_SEL (1<<17) +#define TEXOP_OUTPUT_CURRENT 0 +#define TEXOP_OUTPUT_ACCUM (1<<15) +#define ENABLE_TEX_CNTRL_STAGE ((1<<12)|(1<<11)) +#define DISABLE_TEX_CNTRL_STAGE (1<<12) +#define TEXOP_SCALE_SHIFT 9 +#define TEXOP_SCALE_1X (0 << TEXOP_SCALE_SHIFT) +#define TEXOP_SCALE_2X (1 << TEXOP_SCALE_SHIFT) +#define TEXOP_SCALE_4X (2 << TEXOP_SCALE_SHIFT) +#define TEXOP_MODIFY_PARMS (1<<8) +#define TEXOP_LAST_STAGE (1<<7) +#define TEXBLENDOP_KILLPIXEL 0x02 +#define TEXBLENDOP_ARG1 0x01 +#define TEXBLENDOP_ARG2 0x02 +#define TEXBLENDOP_MODULATE 0x03 +#define TEXBLENDOP_ADD 0x06 +#define TEXBLENDOP_ADDSIGNED 0x07 +#define TEXBLENDOP_BLEND 0x08 +#define TEXBLENDOP_BLEND_AND_ADD 0x09 +#define TEXBLENDOP_SUBTRACT 0x0a +#define TEXBLENDOP_DOT3 0x0b +#define TEXBLENDOP_DOT4 0x0c +#define TEXBLENDOP_MODULATE_AND_ADD 0x0d +#define TEXBLENDOP_MODULATE_2X_AND_ADD 0x0e +#define TEXBLENDOP_MODULATE_4X_AND_ADD 0x0f + +/* _3DSTATE_MAP_BUMP_TABLE, p160 TODO */ +/* _3DSTATE_MAP_COLOR_CHROMA_KEY, p161 TODO */ + +#define _3DSTATE_MAP_COORD_TRANSFORM ((3<<29)|(0x1d<<24)|(0x8c<<16)) +#define DISABLE_TEX_TRANSFORM (1<<28) +#define TEXTURE_SET(x) (x<<29) + +#define _3DSTATE_VERTEX_TRANSFORM ((3<<29)|(0x1d<<24)|(0x8b<<16)) +#define DISABLE_VIEWPORT_TRANSFORM (1<<31) +#define DISABLE_PERSPECTIVE_DIVIDE (1<<29) + + +/* _3DSTATE_MAP_COORD_SET_BINDINGS, p162 */ +#define _3DSTATE_MAP_COORD_SETBIND_CMD (CMD_3D|(0x1d<<24)|(0x02<<16)) +#define TEXBIND_MASK3 ((1<<15)|(1<<14)|(1<<13)|(1<<12)) +#define TEXBIND_MASK2 ((1<<11)|(1<<10)|(1<<9)|(1<<8)) +#define TEXBIND_MASK1 ((1<<7)|(1<<6)|(1<<5)|(1<<4)) +#define TEXBIND_MASK0 ((1<<3)|(1<<2)|(1<<1)|1) + +#define TEXBIND_SET3(x) ((x)<<12) +#define TEXBIND_SET2(x) ((x)<<8) +#define TEXBIND_SET1(x) ((x)<<4) +#define TEXBIND_SET0(x) (x) + +#define TEXCOORDSRC_KEEP 0 +#define TEXCOORDSRC_DEFAULT 0x01 +#define TEXCOORDSRC_VTXSET_0 0x08 +#define TEXCOORDSRC_VTXSET_1 0x09 +#define TEXCOORDSRC_VTXSET_2 0x0a +#define TEXCOORDSRC_VTXSET_3 0x0b +#define TEXCOORDSRC_VTXSET_4 0x0c +#define TEXCOORDSRC_VTXSET_5 0x0d +#define TEXCOORDSRC_VTXSET_6 0x0e +#define TEXCOORDSRC_VTXSET_7 0x0f + +#define MAP_UNIT(unit) ((unit)<<16) +#define MAP_UNIT_MASK (0x7<<16) + +/* _3DSTATE_MAP_COORD_SETS, p164 */ +#define _3DSTATE_MAP_COORD_SET_CMD (CMD_3D|(0x1c<<24)|(0x01<<19)) +#define ENABLE_TEXCOORD_PARAMS (1<<15) +#define TEXCOORDS_ARE_NORMAL (1<<14) +#define TEXCOORDS_ARE_IN_TEXELUNITS 0 +#define TEXCOORDTYPE_CARTESIAN 0 +#define TEXCOORDTYPE_HOMOGENEOUS (1<<11) +#define TEXCOORDTYPE_VECTOR (2<<11) +#define TEXCOORDTYPE_MASK (0x7<<11) +#define ENABLE_ADDR_V_CNTL (1<<7) +#define ENABLE_ADDR_U_CNTL (1<<3) +#define TEXCOORD_ADDR_V_MODE(x) ((x)<<4) +#define TEXCOORD_ADDR_U_MODE(x) (x) +#define TEXCOORDMODE_WRAP 0 +#define TEXCOORDMODE_MIRROR 1 +#define TEXCOORDMODE_CLAMP 2 +#define TEXCOORDMODE_WRAP_SHORTEST 3 +#define TEXCOORDMODE_CLAMP_BORDER 4 +#define TEXCOORD_ADDR_V_MASK 0x70 +#define TEXCOORD_ADDR_U_MASK 0x7 + +/* _3DSTATE_MAP_CUBE, p168 TODO */ +#define _3DSTATE_MAP_CUBE (CMD_3D|(0x1c<<24)|(0x0a<<19)) +#define CUBE_NEGX_ENABLE (1<<5) +#define CUBE_POSX_ENABLE (1<<4) +#define CUBE_NEGY_ENABLE (1<<3) +#define CUBE_POSY_ENABLE (1<<2) +#define CUBE_NEGZ_ENABLE (1<<1) +#define CUBE_POSZ_ENABLE (1<<0) + + +/* _3DSTATE_MODES_1, p190 */ +#define _3DSTATE_MODES_1_CMD (CMD_3D|(0x08<<24)) +#define BLENDFUNC_MASK 0x3f0000 +#define ENABLE_COLR_BLND_FUNC (1<<21) +#define BLENDFUNC_ADD 0 +#define BLENDFUNC_SUB (1<<16) +#define BLENDFUNC_RVRSE_SUB (2<<16) +#define BLENDFUNC_MIN (3<<16) +#define BLENDFUNC_MAX (4<<16) +#define SRC_DST_BLND_MASK 0xfff +#define ENABLE_SRC_BLND_FACTOR (1<<11) +#define ENABLE_DST_BLND_FACTOR (1<<5) +#define SRC_BLND_FACT(x) ((x)<<6) +#define DST_BLND_FACT(x) (x) + + +/* _3DSTATE_MODES_2, p192 */ +#define _3DSTATE_MODES_2_CMD (CMD_3D|(0x0f<<24)) +#define ENABLE_GLOBAL_DEPTH_BIAS (1<<22) +#define GLOBAL_DEPTH_BIAS(x) ((x)<<14) +#define ENABLE_ALPHA_TEST_FUNC (1<<13) +#define ENABLE_ALPHA_REF_VALUE (1<<8) +#define ALPHA_TEST_FUNC(x) ((x)<<9) +#define ALPHA_REF_VALUE(x) (x) + +#define ALPHA_TEST_REF_MASK 0x3fff + +/* _3DSTATE_MODES_3, p193 */ +#define _3DSTATE_MODES_3_CMD (CMD_3D|(0x02<<24)) +#define DEPTH_TEST_FUNC_MASK 0x1f0000 +#define ENABLE_DEPTH_TEST_FUNC (1<<20) +/* Uses COMPAREFUNC */ +#define DEPTH_TEST_FUNC(x) ((x)<<16) +#define ENABLE_ALPHA_SHADE_MODE (1<<11) +#define ENABLE_FOG_SHADE_MODE (1<<9) +#define ENABLE_SPEC_SHADE_MODE (1<<7) +#define ENABLE_COLOR_SHADE_MODE (1<<5) +#define ALPHA_SHADE_MODE(x) ((x)<<10) +#define FOG_SHADE_MODE(x) ((x)<<8) +#define SPEC_SHADE_MODE(x) ((x)<<6) +#define COLOR_SHADE_MODE(x) ((x)<<4) +#define CULLMODE_MASK 0xf +#define ENABLE_CULL_MODE (1<<3) +#define CULLMODE_BOTH 0 +#define CULLMODE_NONE 1 +#define CULLMODE_CW 2 +#define CULLMODE_CCW 3 + +#define SHADE_MODE_LINEAR 0 +#define SHADE_MODE_FLAT 0x1 + +/* _3DSTATE_MODES_4, p195 */ +#define _3DSTATE_MODES_4_CMD (CMD_3D|(0x16<<24)) +#define ENABLE_LOGIC_OP_FUNC (1<<23) +#define LOGIC_OP_FUNC(x) ((x)<<18) +#define LOGICOP_MASK ((1<<18)|(1<<19)|(1<<20)|(1<<21)) +#define LOGICOP_CLEAR 0 +#define LOGICOP_NOR 0x1 +#define LOGICOP_AND_INV 0x2 +#define LOGICOP_COPY_INV 0x3 +#define LOGICOP_AND_RVRSE 0x4 +#define LOGICOP_INV 0x5 +#define LOGICOP_XOR 0x6 +#define LOGICOP_NAND 0x7 +#define LOGICOP_AND 0x8 +#define LOGICOP_EQUIV 0x9 +#define LOGICOP_NOOP 0xa +#define LOGICOP_OR_INV 0xb +#define LOGICOP_COPY 0xc +#define LOGICOP_OR_RVRSE 0xd +#define LOGICOP_OR 0xe +#define LOGICOP_SET 0xf +#define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00)) +#define ENABLE_STENCIL_TEST_MASK (1<<17) +#define STENCIL_TEST_MASK(x) (((x)&0xff)<<8) +#define MODE4_ENABLE_STENCIL_WRITE_MASK ((1<<16)|(0x00ff)) +#define ENABLE_STENCIL_WRITE_MASK (1<<16) +#define STENCIL_WRITE_MASK(x) ((x)&0xff) + +/* _3DSTATE_MODES_5, p196 */ +#define _3DSTATE_MODES_5_CMD (CMD_3D|(0x0c<<24)) +#define ENABLE_SPRITE_POINT_TEX (1<<23) +#define SPRITE_POINT_TEX_ON (1<<22) +#define SPRITE_POINT_TEX_OFF 0 +#define FLUSH_RENDER_CACHE (1<<18) +#define FLUSH_TEXTURE_CACHE (1<<16) +#define FIXED_LINE_WIDTH_MASK 0xfc00 +#define ENABLE_FIXED_LINE_WIDTH (1<<15) +#define FIXED_LINE_WIDTH(x) ((x)<<10) +#define FIXED_POINT_WIDTH_MASK 0x3ff +#define ENABLE_FIXED_POINT_WIDTH (1<<9) +#define FIXED_POINT_WIDTH(x) (x) + +/* _3DSTATE_RASTERIZATION_RULES, p198 */ +#define _3DSTATE_RASTER_RULES_CMD (CMD_3D|(0x07<<24)) +#define ENABLE_POINT_RASTER_RULE (1<<15) +#define OGL_POINT_RASTER_RULE (1<<13) +#define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8) +#define ENABLE_TRI_FAN_PROVOKE_VRTX (1<<5) +#define ENABLE_TRI_STRIP_PROVOKE_VRTX (1<<2) +#define LINE_STRIP_PROVOKE_VRTX(x) ((x)<<6) +#define TRI_FAN_PROVOKE_VRTX(x) ((x)<<3) +#define TRI_STRIP_PROVOKE_VRTX(x) (x) + +/* _3DSTATE_SCISSOR_ENABLE, p200 */ +#define _3DSTATE_SCISSOR_ENABLE_CMD (CMD_3D|(0x1c<<24)|(0x10<<19)) +#define ENABLE_SCISSOR_RECT ((1<<1) | 1) +#define DISABLE_SCISSOR_RECT (1<<1) + +/* _3DSTATE_SCISSOR_RECTANGLE_0, p201 */ +#define _3DSTATE_SCISSOR_RECT_0_CMD (CMD_3D|(0x1d<<24)|(0x81<<16)|1) +/* Dword 1 */ +#define SCISSOR_RECT_0_YMIN(x) ((x)<<16) +#define SCISSOR_RECT_0_XMIN(x) (x) +/* Dword 2 */ +#define SCISSOR_RECT_0_YMAX(x) ((x)<<16) +#define SCISSOR_RECT_0_XMAX(x) (x) + +/* _3DSTATE_STENCIL_TEST, p202 */ +#define _3DSTATE_STENCIL_TEST_CMD (CMD_3D|(0x09<<24)) +#define ENABLE_STENCIL_PARMS (1<<23) +#define STENCIL_OPS_MASK (0xffc000) +#define STENCIL_FAIL_OP(x) ((x)<<20) +#define STENCIL_PASS_DEPTH_FAIL_OP(x) ((x)<<17) +#define STENCIL_PASS_DEPTH_PASS_OP(x) ((x)<<14) + +#define ENABLE_STENCIL_TEST_FUNC_MASK ((1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)) +#define ENABLE_STENCIL_TEST_FUNC (1<<13) +/* Uses COMPAREFUNC */ +#define STENCIL_TEST_FUNC(x) ((x)<<9) +#define STENCIL_REF_VALUE_MASK ((1<<8)|0xff) +#define ENABLE_STENCIL_REF_VALUE (1<<8) +#define STENCIL_REF_VALUE(x) (x) + +/* _3DSTATE_VERTEX_FORMAT, p204 */ +#define _3DSTATE_VFT0_CMD (CMD_3D|(0x05<<24)) +#define VFT0_POINT_WIDTH (1<<12) +#define VFT0_TEX_COUNT_MASK (7<<8) +#define VFT0_TEX_COUNT_SHIFT 8 +#define VFT0_TEX_COUNT(x) ((x)<<8) +#define VFT0_SPEC (1<<7) +#define VFT0_DIFFUSE (1<<6) +#define VFT0_DEPTH_OFFSET (1<<5) +#define VFT0_XYZ (1<<1) +#define VFT0_XYZW (2<<1) +#define VFT0_XY (3<<1) +#define VFT0_XYW (4<<1) +#define VFT0_XYZW_MASK (7<<1) + +/* _3DSTATE_VERTEX_FORMAT_2, p206 */ +#define _3DSTATE_VFT1_CMD (CMD_3D|(0x0a<<24)) +#define VFT1_TEX7_FMT(x) ((x)<<14) +#define VFT1_TEX6_FMT(x) ((x)<<12) +#define VFT1_TEX5_FMT(x) ((x)<<10) +#define VFT1_TEX4_FMT(x) ((x)<<8) +#define VFT1_TEX3_FMT(x) ((x)<<6) +#define VFT1_TEX2_FMT(x) ((x)<<4) +#define VFT1_TEX1_FMT(x) ((x)<<2) +#define VFT1_TEX0_FMT(x) (x) +#define VFT1_TEX0_MASK 3 +#define VFT1_TEX1_SHIFT 2 +#define TEXCOORDFMT_2D 0 +#define TEXCOORDFMT_3D 1 +#define TEXCOORDFMT_4D 2 +#define TEXCOORDFMT_1D 3 + +/*New stuff picked up along the way */ + +#define MLC_LOD_BIAS_MASK ((1<<7)-1) + + +/* _3DSTATE_VERTEX_TRANSFORM, p207 */ +#define _3DSTATE_VERTEX_TRANS_CMD (CMD_3D|(0x1d<<24)|(0x8b<<16)|0) +#define _3DSTATE_VERTEX_TRANS_MTX_CMD (CMD_3D|(0x1d<<24)|(0x8b<<16)|6) +/* Dword 1 */ +#define ENABLE_VIEWPORT_TRANSFORM ((1<<31)|(1<<30)) +#define DISABLE_VIEWPORT_TRANSFORM (1<<31) +#define ENABLE_PERSP_DIVIDE ((1<<29)|(1<<28)) +#define DISABLE_PERSP_DIVIDE (1<<29) +#define VRTX_TRANS_LOAD_MATRICES 0x7421 +#define VRTX_TRANS_NO_LOAD_MATRICES 0x0000 +/* Dword 2 -> 7 are matrix elements */ + +/* _3DSTATE_W_STATE, p209 */ +#define _3DSTATE_W_STATE_CMD (CMD_3D|(0x1d<<24)|(0x8d<<16)|1) +/* Dword 1 */ +#define MAGIC_W_STATE_DWORD1 0x00000008 +/* Dword 2 */ +#define WFAR_VALUE(x) (x) + + +/* Stipple command, carried over from the i810, apparently: + */ +#define _3DSTATE_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) +#define ST1_ENABLE (1<<16) +#define ST1_MASK (0xffff) + + + +#define _3DSTATE_LOAD_STATE_IMMEDIATE_2 ((0x3<<29)|(0x1d<<24)|(0x03<<16)) +#define LOAD_TEXTURE_MAP0 (1<<11) +#define LOAD_GLOBAL_COLOR_FACTOR (1<<6) + +#define TM0S0_ADDRESS_MASK 0xfffffffc +#define TM0S0_USE_FENCE (1<<1) + +#define TM0S1_HEIGHT_SHIFT 21 +#define TM0S1_WIDTH_SHIFT 10 +#define TM0S1_PALETTE_SELECT (1<<9) +#define TM0S1_MAPSURF_FORMAT_MASK (0x7 << 6) +#define TM0S1_MAPSURF_FORMAT_SHIFT 6 +#define MAPSURF_8BIT_INDEXED (0<<6) +#define MAPSURF_8BIT (1<<6) +#define MAPSURF_16BIT (2<<6) +#define MAPSURF_32BIT (3<<6) +#define MAPSURF_411 (4<<6) +#define MAPSURF_422 (5<<6) +#define MAPSURF_COMPRESSED (6<<6) +#define MAPSURF_4BIT_INDEXED (7<<6) +#define TM0S1_MT_FORMAT_MASK (0x7 << 3) +#define TM0S1_MT_FORMAT_SHIFT 3 +#define MT_4BIT_IDX_ARGB8888 (7<<3) /* SURFACE_4BIT_INDEXED */ +#define MT_8BIT_IDX_RGB565 (0<<3) /* SURFACE_8BIT_INDEXED */ +#define MT_8BIT_IDX_ARGB1555 (1<<3) +#define MT_8BIT_IDX_ARGB4444 (2<<3) +#define MT_8BIT_IDX_AY88 (3<<3) +#define MT_8BIT_IDX_ABGR8888 (4<<3) +#define MT_8BIT_IDX_BUMP_88DVDU (5<<3) +#define MT_8BIT_IDX_BUMP_655LDVDU (6<<3) +#define MT_8BIT_IDX_ARGB8888 (7<<3) +#define MT_8BIT_I8 (0<<3) /* SURFACE_8BIT */ +#define MT_8BIT_L8 (1<<3) +#define MT_16BIT_RGB565 (0<<3) /* SURFACE_16BIT */ +#define MT_16BIT_ARGB1555 (1<<3) +#define MT_16BIT_ARGB4444 (2<<3) +#define MT_16BIT_AY88 (3<<3) +#define MT_16BIT_DIB_ARGB1555_8888 (4<<3) +#define MT_16BIT_BUMP_88DVDU (5<<3) +#define MT_16BIT_BUMP_655LDVDU (6<<3) +#define MT_16BIT_DIB_RGB565_8888 (7<<3) +#define MT_32BIT_ARGB8888 (0<<3) /* SURFACE_32BIT */ +#define MT_32BIT_ABGR8888 (1<<3) +#define MT_32BIT_BUMP_XLDVDU_8888 (6<<3) +#define MT_32BIT_DIB_8888 (7<<3) +#define MT_411_YUV411 (0<<3) /* SURFACE_411 */ +#define MT_422_YCRCB_SWAPY (0<<3) /* SURFACE_422 */ +#define MT_422_YCRCB_NORMAL (1<<3) +#define MT_422_YCRCB_SWAPUV (2<<3) +#define MT_422_YCRCB_SWAPUVY (3<<3) +#define MT_COMPRESS_DXT1 (0<<3) /* SURFACE_COMPRESSED */ +#define MT_COMPRESS_DXT2_3 (1<<3) +#define MT_COMPRESS_DXT4_5 (2<<3) +#define MT_COMPRESS_FXT1 (3<<3) +#define TM0S1_COLORSPACE_CONVERSION (1 << 2) +#define TM0S1_TILED_SURFACE (1 << 1) +#define TM0S1_TILE_WALK (1 << 0) + +#define TM0S2_PITCH_SHIFT 21 +#define TM0S2_CUBE_FACE_ENA_SHIFT 15 +#define TM0S2_CUBE_FACE_ENA_MASK (1<<15) +#define TM0S2_MAP_FORMAT (1<<14) +#define TM0S2_VERTICAL_LINE_STRIDE (1<<13) +#define TM0S2_VERITCAL_LINE_STRIDE_OFF (1<<12) +#define TM0S2_OUTPUT_CHAN_SHIFT 10 +#define TM0S2_OUTPUT_CHAN_MASK (3<<10) + +#define TM0S3_MIP_FILTER_MASK (0x3<<30) +#define TM0S3_MIP_FILTER_SHIFT 30 +#define MIPFILTER_NONE 0 +#define MIPFILTER_NEAREST 1 +#define MIPFILTER_LINEAR 3 +#define TM0S3_MAG_FILTER_MASK (0x3<<28) +#define TM0S3_MAG_FILTER_SHIFT 28 +#define TM0S3_MIN_FILTER_MASK (0x3<<26) +#define TM0S3_MIN_FILTER_SHIFT 26 +#define FILTER_NEAREST 0 +#define FILTER_LINEAR 1 +#define FILTER_ANISOTROPIC 2 + +#define TM0S3_LOD_BIAS_SHIFT 17 +#define TM0S3_LOD_BIAS_MASK (0x1ff<<17) +#define TM0S3_MAX_MIP_SHIFT 9 +#define TM0S3_MAX_MIP_MASK (0xff<<9) +#define TM0S3_MIN_MIP_SHIFT 3 +#define TM0S3_MIN_MIP_MASK (0x3f<<3) +#define TM0S3_KILL_PIXEL (1<<2) +#define TM0S3_KEYED_FILTER (1<<1) +#define TM0S3_CHROMA_KEY (1<<0) + + +/* _3DSTATE_MAP_TEXEL_STREAM, p188 */ +#define _3DSTATE_MAP_TEX_STREAM_CMD (CMD_3D|(0x1c<<24)|(0x05<<19)) +#define DISABLE_TEX_STREAM_BUMP (1<<12) +#define ENABLE_TEX_STREAM_BUMP ((1<<12)|(1<<11)) +#define TEX_MODIFY_UNIT_0 0 +#define TEX_MODIFY_UNIT_1 (1<<8) +#define ENABLE_TEX_STREAM_COORD_SET (1<<7) +#define TEX_STREAM_COORD_SET(x) ((x)<<4) +#define ENABLE_TEX_STREAM_MAP_IDX (1<<3) +#define TEX_STREAM_MAP_IDX(x) (x) + + +#define MI_FLUSH ((0<<29)|(4<<23)) +#define FLUSH_MAP_CACHE (1<<0) + +#endif diff --git a/src/mesa/drivers/dri/i915tex/i830_state.c b/src/mesa/drivers/dri/i915tex/i830_state.c new file mode 100644 index 0000000000..83d82882a6 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i830_state.c @@ -0,0 +1,1113 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + + +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "enums.h" +#include "dd.h" + +#include "texmem.h" + +#include "intel_screen.h" +#include "intel_batchbuffer.h" +#include "intel_fbo.h" + +#include "i830_context.h" +#include "i830_reg.h" + +#define FILE_DEBUG_FLAG DEBUG_STATE + +static void +i830StencilFuncSeparate(GLcontext * ctx, GLenum face, GLenum func, GLint ref, + GLuint mask) +{ + struct i830_context *i830 = i830_context(ctx); + int test = intel_translate_compare_func(func); + + mask = mask & 0xff; + + DBG("%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(func), ref, mask); + + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; + i830->state.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | + STENCIL_TEST_MASK(mask)); + i830->state.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_REF_VALUE_MASK | + ENABLE_STENCIL_TEST_FUNC_MASK); + i830->state.Ctx[I830_CTXREG_STENCILTST] |= (ENABLE_STENCIL_REF_VALUE | + ENABLE_STENCIL_TEST_FUNC | + STENCIL_REF_VALUE(ref) | + STENCIL_TEST_FUNC(test)); +} + +static void +i830StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask) +{ + struct i830_context *i830 = i830_context(ctx); + + DBG("%s : mask 0x%x\n", __FUNCTION__, mask); + + mask = mask & 0xff; + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; + i830->state.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | + STENCIL_WRITE_MASK(mask)); +} + +static void +i830StencilOpSeparate(GLcontext * ctx, GLenum face, GLenum fail, GLenum zfail, + GLenum zpass) +{ + struct i830_context *i830 = i830_context(ctx); + int fop, dfop, dpop; + + DBG("%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(fail), + _mesa_lookup_enum_by_nr(zfail), + _mesa_lookup_enum_by_nr(zpass)); + + fop = 0; + dfop = 0; + dpop = 0; + + switch (fail) { + case GL_KEEP: + fop = STENCILOP_KEEP; + break; + case GL_ZERO: + fop = STENCILOP_ZERO; + break; + case GL_REPLACE: + fop = STENCILOP_REPLACE; + break; + case GL_INCR: + fop = STENCILOP_INCRSAT; + break; + case GL_DECR: + fop = STENCILOP_DECRSAT; + break; + case GL_INCR_WRAP: + fop = STENCILOP_INCR; + break; + case GL_DECR_WRAP: + fop = STENCILOP_DECR; + break; + case GL_INVERT: + fop = STENCILOP_INVERT; + break; + default: + break; + } + switch (zfail) { + case GL_KEEP: + dfop = STENCILOP_KEEP; + break; + case GL_ZERO: + dfop = STENCILOP_ZERO; + break; + case GL_REPLACE: + dfop = STENCILOP_REPLACE; + break; + case GL_INCR: + dfop = STENCILOP_INCRSAT; + break; + case GL_DECR: + dfop = STENCILOP_DECRSAT; + break; + case GL_INCR_WRAP: + dfop = STENCILOP_INCR; + break; + case GL_DECR_WRAP: + dfop = STENCILOP_DECR; + break; + case GL_INVERT: + dfop = STENCILOP_INVERT; + break; + default: + break; + } + switch (zpass) { + case GL_KEEP: + dpop = STENCILOP_KEEP; + break; + case GL_ZERO: + dpop = STENCILOP_ZERO; + break; + case GL_REPLACE: + dpop = STENCILOP_REPLACE; + break; + case GL_INCR: + dpop = STENCILOP_INCRSAT; + break; + case GL_DECR: + dpop = STENCILOP_DECRSAT; + break; + case GL_INCR_WRAP: + dpop = STENCILOP_INCR; + break; + case GL_DECR_WRAP: + dpop = STENCILOP_DECR; + break; + case GL_INVERT: + dpop = STENCILOP_INVERT; + break; + default: + break; + } + + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_OPS_MASK); + i830->state.Ctx[I830_CTXREG_STENCILTST] |= (ENABLE_STENCIL_PARMS | + STENCIL_FAIL_OP(fop) | + STENCIL_PASS_DEPTH_FAIL_OP + (dfop) | + STENCIL_PASS_DEPTH_PASS_OP + (dpop)); +} + +static void +i830AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref) +{ + struct i830_context *i830 = i830_context(ctx); + int test = intel_translate_compare_func(func); + GLubyte refByte; + GLuint refInt; + + UNCLAMPED_FLOAT_TO_UBYTE(refByte, ref); + refInt = (GLuint) refByte; + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_STATE2] &= ~ALPHA_TEST_REF_MASK; + i830->state.Ctx[I830_CTXREG_STATE2] |= (ENABLE_ALPHA_TEST_FUNC | + ENABLE_ALPHA_REF_VALUE | + ALPHA_TEST_FUNC(test) | + ALPHA_REF_VALUE(refInt)); +} + +/** + * Makes sure that the proper enables are set for LogicOp, Independant Alpha + * Blend, and Blending. It needs to be called from numerous places where we + * could change the LogicOp or Independant Alpha Blend without subsequent + * calls to glEnable. + * + * \todo + * This function is substantially different from the old i830-specific driver. + * I'm not sure which is correct. + */ +static void +i830EvalLogicOpBlendState(GLcontext * ctx) +{ + struct i830_context *i830 = i830_context(ctx); + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + + if (ctx->Color._LogicOpEnabled) { + i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND | + ENABLE_LOGIC_OP_MASK); + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= (DISABLE_COLOR_BLEND | + ENABLE_LOGIC_OP); + } + else if (ctx->Color.BlendEnabled) { + i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND | + ENABLE_LOGIC_OP_MASK); + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= (ENABLE_COLOR_BLEND | + DISABLE_LOGIC_OP); + } + else { + i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND | + ENABLE_LOGIC_OP_MASK); + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= (DISABLE_COLOR_BLEND | + DISABLE_LOGIC_OP); + } +} + +static void +i830BlendColor(GLcontext * ctx, const GLfloat color[4]) +{ + struct i830_context *i830 = i830_context(ctx); + GLubyte r, g, b, a; + + DBG("%s\n", __FUNCTION__); + + UNCLAMPED_FLOAT_TO_UBYTE(r, color[RCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(g, color[GCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(b, color[BCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(a, color[ACOMP]); + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_BLENDCOLOR1] = + (a << 24) | (r << 16) | (g << 8) | b; +} + +/** + * Sets both the blend equation (called "function" in i830 docs) and the + * blend function (called "factor" in i830 docs). This is done in a single + * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX) + * change the interpretation of the blend function. + */ +static void +i830_set_blend_state(GLcontext * ctx) +{ + struct i830_context *i830 = i830_context(ctx); + int funcA; + int funcRGB; + int eqnA; + int eqnRGB; + int iab; + int s1; + + + funcRGB = + SRC_BLND_FACT(intel_translate_blend_factor(ctx->Color.BlendSrcRGB)) + | DST_BLND_FACT(intel_translate_blend_factor(ctx->Color.BlendDstRGB)); + + switch (ctx->Color.BlendEquationRGB) { + case GL_FUNC_ADD: + eqnRGB = BLENDFUNC_ADD; + break; + case GL_MIN: + eqnRGB = BLENDFUNC_MIN; + funcRGB = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE); + break; + case GL_MAX: + eqnRGB = BLENDFUNC_MAX; + funcRGB = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE); + break; + case GL_FUNC_SUBTRACT: + eqnRGB = BLENDFUNC_SUB; + break; + case GL_FUNC_REVERSE_SUBTRACT: + eqnRGB = BLENDFUNC_RVRSE_SUB; + break; + default: + fprintf(stderr, "[%s:%u] Invalid RGB blend equation (0x%04x).\n", + __FUNCTION__, __LINE__, ctx->Color.BlendEquationRGB); + return; + } + + + funcA = SRC_ABLEND_FACT(intel_translate_blend_factor(ctx->Color.BlendSrcA)) + | DST_ABLEND_FACT(intel_translate_blend_factor(ctx->Color.BlendDstA)); + + switch (ctx->Color.BlendEquationA) { + case GL_FUNC_ADD: + eqnA = BLENDFUNC_ADD; + break; + case GL_MIN: + eqnA = BLENDFUNC_MIN; + funcA = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE); + break; + case GL_MAX: + eqnA = BLENDFUNC_MAX; + funcA = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE); + break; + case GL_FUNC_SUBTRACT: + eqnA = BLENDFUNC_SUB; + break; + case GL_FUNC_REVERSE_SUBTRACT: + eqnA = BLENDFUNC_RVRSE_SUB; + break; + default: + fprintf(stderr, "[%s:%u] Invalid alpha blend equation (0x%04x).\n", + __FUNCTION__, __LINE__, ctx->Color.BlendEquationA); + return; + } + + iab = eqnA | funcA + | _3DSTATE_INDPT_ALPHA_BLEND_CMD + | ENABLE_SRC_ABLEND_FACTOR | ENABLE_DST_ABLEND_FACTOR + | ENABLE_ALPHA_BLENDFUNC; + s1 = eqnRGB | funcRGB + | _3DSTATE_MODES_1_CMD + | ENABLE_SRC_BLND_FACTOR | ENABLE_DST_BLND_FACTOR + | ENABLE_COLR_BLND_FUNC; + + if ((eqnA | funcA) != (eqnRGB | funcRGB)) + iab |= ENABLE_INDPT_ALPHA_BLEND; + else + iab |= DISABLE_INDPT_ALPHA_BLEND; + + if (iab != i830->state.Ctx[I830_CTXREG_IALPHAB] || + s1 != i830->state.Ctx[I830_CTXREG_STATE1]) { + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_IALPHAB] = iab; + i830->state.Ctx[I830_CTXREG_STATE1] = s1; + } + + /* This will catch a logicop blend equation. It will also ensure + * independant alpha blend is really in the correct state (either enabled + * or disabled) if blending is already enabled. + */ + + i830EvalLogicOpBlendState(ctx); + + if (0) { + fprintf(stderr, + "[%s:%u] STATE1: 0x%08x IALPHAB: 0x%08x blend is %sabled\n", + __FUNCTION__, __LINE__, i830->state.Ctx[I830_CTXREG_STATE1], + i830->state.Ctx[I830_CTXREG_IALPHAB], + (ctx->Color.BlendEnabled) ? "en" : "dis"); + } +} + + +static void +i830BlendEquationSeparate(GLcontext * ctx, GLenum modeRGB, GLenum modeA) +{ + DBG("%s -> %s, %s\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(modeRGB), + _mesa_lookup_enum_by_nr(modeA)); + + (void) modeRGB; + (void) modeA; + i830_set_blend_state(ctx); +} + + +static void +i830BlendFuncSeparate(GLcontext * ctx, GLenum sfactorRGB, + GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA) +{ + DBG("%s -> RGB(%s, %s) A(%s, %s)\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(sfactorRGB), + _mesa_lookup_enum_by_nr(dfactorRGB), + _mesa_lookup_enum_by_nr(sfactorA), + _mesa_lookup_enum_by_nr(dfactorA)); + + (void) sfactorRGB; + (void) dfactorRGB; + (void) sfactorA; + (void) dfactorA; + i830_set_blend_state(ctx); +} + + + +static void +i830DepthFunc(GLcontext * ctx, GLenum func) +{ + struct i830_context *i830 = i830_context(ctx); + int test = intel_translate_compare_func(func); + + DBG("%s\n", __FUNCTION__); + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_STATE3] &= ~DEPTH_TEST_FUNC_MASK; + i830->state.Ctx[I830_CTXREG_STATE3] |= (ENABLE_DEPTH_TEST_FUNC | + DEPTH_TEST_FUNC(test)); +} + +static void +i830DepthMask(GLcontext * ctx, GLboolean flag) +{ + struct i830_context *i830 = i830_context(ctx); + + DBG("%s flag (%d)\n", __FUNCTION__, flag); + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + + i830->state.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK; + + if (flag && ctx->Depth.Test) + i830->state.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_DEPTH_WRITE; + else + i830->state.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE; +} + +/* ============================================================= + * Polygon stipple + * + * The i830 supports a 4x4 stipple natively, GL wants 32x32. + * Fortunately stipple is usually a repeating pattern. + */ +static void +i830PolygonStipple(GLcontext * ctx, const GLubyte * mask) +{ + struct i830_context *i830 = i830_context(ctx); + const GLubyte *m = mask; + GLubyte p[4]; + int i, j, k; + int active = (ctx->Polygon.StippleFlag && + i830->intel.reduced_primitive == GL_TRIANGLES); + GLuint newMask; + + if (active) { + I830_STATECHANGE(i830, I830_UPLOAD_STIPPLE); + i830->state.Stipple[I830_STPREG_ST1] &= ~ST1_ENABLE; + } + + p[0] = mask[12] & 0xf; + p[0] |= p[0] << 4; + p[1] = mask[8] & 0xf; + p[1] |= p[1] << 4; + p[2] = mask[4] & 0xf; + p[2] |= p[2] << 4; + p[3] = mask[0] & 0xf; + p[3] |= p[3] << 4; + + for (k = 0; k < 8; k++) + for (j = 3; j >= 0; j--) + for (i = 0; i < 4; i++, m++) + if (*m != p[j]) { + i830->intel.hw_stipple = 0; + return; + } + + newMask = (((p[0] & 0xf) << 0) | + ((p[1] & 0xf) << 4) | + ((p[2] & 0xf) << 8) | ((p[3] & 0xf) << 12)); + + + if (newMask == 0xffff || newMask == 0x0) { + /* this is needed to make conform pass */ + i830->intel.hw_stipple = 0; + return; + } + + i830->state.Stipple[I830_STPREG_ST1] &= ~0xffff; + i830->state.Stipple[I830_STPREG_ST1] |= newMask; + i830->intel.hw_stipple = 1; + + if (active) + i830->state.Stipple[I830_STPREG_ST1] |= ST1_ENABLE; +} + + +/* ============================================================= + * Hardware clipping + */ +static void +i830Scissor(GLcontext * ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + struct i830_context *i830 = i830_context(ctx); + int x1, y1, x2, y2; + + if (!ctx->DrawBuffer) + return; + + DBG("%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); + + if (ctx->DrawBuffer->Name == 0) { + x1 = x; + y1 = ctx->DrawBuffer->Height - (y + h); + x2 = x + w - 1; + y2 = y1 + h - 1; + DBG("%s %d..%d,%d..%d (inverted)\n", __FUNCTION__, x1, x2, y1, y2); + } + else { + /* FBO - not inverted + */ + x1 = x; + y1 = y; + x2 = x + w - 1; + y2 = y + h - 1; + DBG("%s %d..%d,%d..%d (not inverted)\n", __FUNCTION__, x1, x2, y1, y2); + } + + x1 = CLAMP(x1, 0, ctx->DrawBuffer->Width - 1); + y1 = CLAMP(y1, 0, ctx->DrawBuffer->Height - 1); + x2 = CLAMP(x2, 0, ctx->DrawBuffer->Width - 1); + y2 = CLAMP(y2, 0, ctx->DrawBuffer->Height - 1); + + DBG("%s %d..%d,%d..%d (clamped)\n", __FUNCTION__, x1, x2, y1, y2); + + I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS); + i830->state.Buffer[I830_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff); + i830->state.Buffer[I830_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff); +} + +static void +i830LogicOp(GLcontext * ctx, GLenum opcode) +{ + struct i830_context *i830 = i830_context(ctx); + int tmp = intel_translate_logic_op(opcode); + + DBG("%s\n", __FUNCTION__); + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_STATE4] &= ~LOGICOP_MASK; + i830->state.Ctx[I830_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp); +} + + + +static void +i830CullFaceFrontFace(GLcontext * ctx, GLenum unused) +{ + struct i830_context *i830 = i830_context(ctx); + GLuint mode; + + DBG("%s\n", __FUNCTION__); + + if (!ctx->Polygon.CullFlag) { + mode = CULLMODE_NONE; + } + else if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) { + mode = CULLMODE_CW; + + if (ctx->Polygon.CullFaceMode == GL_FRONT) + mode ^= (CULLMODE_CW ^ CULLMODE_CCW); + if (ctx->Polygon.FrontFace != GL_CCW) + mode ^= (CULLMODE_CW ^ CULLMODE_CCW); + } + else { + mode = CULLMODE_BOTH; + } + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_STATE3] &= ~CULLMODE_MASK; + i830->state.Ctx[I830_CTXREG_STATE3] |= ENABLE_CULL_MODE | mode; +} + +static void +i830LineWidth(GLcontext * ctx, GLfloat widthf) +{ + struct i830_context *i830 = i830_context(ctx); + int width; + int state5; + + DBG("%s\n", __FUNCTION__); + + width = (int) (widthf * 2); + CLAMP_SELF(width, 1, 15); + + state5 = i830->state.Ctx[I830_CTXREG_STATE5] & ~FIXED_LINE_WIDTH_MASK; + state5 |= (ENABLE_FIXED_LINE_WIDTH | FIXED_LINE_WIDTH(width)); + + if (state5 != i830->state.Ctx[I830_CTXREG_STATE5]) { + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_STATE5] = state5; + } +} + +static void +i830PointSize(GLcontext * ctx, GLfloat size) +{ + struct i830_context *i830 = i830_context(ctx); + GLint point_size = (int) size; + + DBG("%s\n", __FUNCTION__); + + CLAMP_SELF(point_size, 1, 256); + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_STATE5] &= ~FIXED_POINT_WIDTH_MASK; + i830->state.Ctx[I830_CTXREG_STATE5] |= (ENABLE_FIXED_POINT_WIDTH | + FIXED_POINT_WIDTH(point_size)); +} + + +/* ============================================================= + * Color masks + */ + +static void +i830ColorMask(GLcontext * ctx, + GLboolean r, GLboolean g, GLboolean b, GLboolean a) +{ + struct i830_context *i830 = i830_context(ctx); + GLuint tmp = 0; + + DBG("%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, r, g, b, a); + + tmp = ((i830->state.Ctx[I830_CTXREG_ENABLES_2] & ~WRITEMASK_MASK) | + ENABLE_COLOR_MASK | + ENABLE_COLOR_WRITE | + ((!r) << WRITEMASK_RED_SHIFT) | + ((!g) << WRITEMASK_GREEN_SHIFT) | + ((!b) << WRITEMASK_BLUE_SHIFT) | ((!a) << WRITEMASK_ALPHA_SHIFT)); + + if (tmp != i830->state.Ctx[I830_CTXREG_ENABLES_2]) { + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_ENABLES_2] = tmp; + } +} + +static void +update_specular(GLcontext * ctx) +{ + struct i830_context *i830 = i830_context(ctx); + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK; + + if (NEED_SECONDARY_COLOR(ctx)) + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_SPEC_ADD; + else + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_SPEC_ADD; +} + +static void +i830LightModelfv(GLcontext * ctx, GLenum pname, const GLfloat * param) +{ + DBG("%s\n", __FUNCTION__); + + if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { + update_specular(ctx); + } +} + +/* In Mesa 3.5 we can reliably do native flatshading. + */ +static void +i830ShadeModel(GLcontext * ctx, GLenum mode) +{ + struct i830_context *i830 = i830_context(ctx); + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + + +#define SHADE_MODE_MASK ((1<<10)|(1<<8)|(1<<6)|(1<<4)) + + i830->state.Ctx[I830_CTXREG_STATE3] &= ~SHADE_MODE_MASK; + + if (mode == GL_FLAT) { + i830->state.Ctx[I830_CTXREG_STATE3] |= + (ALPHA_SHADE_MODE(SHADE_MODE_FLAT) | FOG_SHADE_MODE(SHADE_MODE_FLAT) + | SPEC_SHADE_MODE(SHADE_MODE_FLAT) | + COLOR_SHADE_MODE(SHADE_MODE_FLAT)); + } + else { + i830->state.Ctx[I830_CTXREG_STATE3] |= + (ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) | + FOG_SHADE_MODE(SHADE_MODE_LINEAR) | + SPEC_SHADE_MODE(SHADE_MODE_LINEAR) | + COLOR_SHADE_MODE(SHADE_MODE_LINEAR)); + } +} + +/* ============================================================= + * Fog + */ +static void +i830Fogfv(GLcontext * ctx, GLenum pname, const GLfloat * param) +{ + struct i830_context *i830 = i830_context(ctx); + + DBG("%s\n", __FUNCTION__); + + if (pname == GL_FOG_COLOR) { + GLuint color = (((GLubyte) (ctx->Fog.Color[0] * 255.0F) << 16) | + ((GLubyte) (ctx->Fog.Color[1] * 255.0F) << 8) | + ((GLubyte) (ctx->Fog.Color[2] * 255.0F) << 0)); + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_FOGCOLOR] = + (_3DSTATE_FOG_COLOR_CMD | color); + } +} + +/* ============================================================= + */ + +static void +i830Enable(GLcontext * ctx, GLenum cap, GLboolean state) +{ + struct i830_context *i830 = i830_context(ctx); + + switch (cap) { + case GL_LIGHTING: + case GL_COLOR_SUM: + update_specular(ctx); + break; + + case GL_ALPHA_TEST: + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_ALPHA_TEST_MASK; + if (state) + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_ALPHA_TEST; + else + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_ALPHA_TEST; + + break; + + case GL_BLEND: + i830EvalLogicOpBlendState(ctx); + break; + + case GL_COLOR_LOGIC_OP: + i830EvalLogicOpBlendState(ctx); + + /* Logicop doesn't seem to work at 16bpp: + */ + if (i830->intel.intelScreen->cpp == 2) + FALLBACK(&i830->intel, I830_FALLBACK_LOGICOP, state); + break; + + case GL_DITHER: + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DITHER; + + if (state) + i830->state.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_DITHER; + else + i830->state.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DITHER; + break; + + case GL_DEPTH_TEST: + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; + + if (state) + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_DEPTH_TEST; + else + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST; + + /* Also turn off depth writes when GL_DEPTH_TEST is disabled: + */ + i830DepthMask(ctx, ctx->Depth.Mask); + break; + + case GL_SCISSOR_TEST: + I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS); + + if (state) + i830->state.Buffer[I830_DESTREG_SENABLE] = + (_3DSTATE_SCISSOR_ENABLE_CMD | ENABLE_SCISSOR_RECT); + else + i830->state.Buffer[I830_DESTREG_SENABLE] = + (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); + + break; + + case GL_LINE_SMOOTH: + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + + i830->state.Ctx[I830_CTXREG_AA] &= ~AA_LINE_ENABLE; + if (state) + i830->state.Ctx[I830_CTXREG_AA] |= AA_LINE_ENABLE; + else + i830->state.Ctx[I830_CTXREG_AA] |= AA_LINE_DISABLE; + break; + + case GL_FOG: + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_FOG_MASK; + if (state) + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_FOG; + else + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_FOG; + break; + + case GL_CULL_FACE: + i830CullFaceFrontFace(ctx, 0); + break; + + case GL_TEXTURE_2D: + break; + + case GL_STENCIL_TEST: + { + GLboolean hw_stencil = GL_FALSE; + if (ctx->DrawBuffer) { + struct intel_renderbuffer *irbStencil + = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL); + hw_stencil = (irbStencil && irbStencil->region); + } + if (hw_stencil) { + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + + if (state) { + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_STENCIL_TEST; + i830->state.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_STENCIL_WRITE; + } + else { + i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_STENCIL_TEST; + i830->state.Ctx[I830_CTXREG_ENABLES_2] &= + ~ENABLE_STENCIL_WRITE; + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_STENCIL_TEST; + i830->state.Ctx[I830_CTXREG_ENABLES_2] |= + DISABLE_STENCIL_WRITE; + } + } + else { + FALLBACK(&i830->intel, I830_FALLBACK_STENCIL, state); + } + } + break; + + case GL_POLYGON_STIPPLE: + /* The stipple command worked on my 855GM box, but not my 845G. + * I'll do more testing later to find out exactly which hardware + * supports it. Disabled for now. + */ + if (i830->intel.hw_stipple && + i830->intel.reduced_primitive == GL_TRIANGLES) { + I830_STATECHANGE(i830, I830_UPLOAD_STIPPLE); + i830->state.Stipple[I830_STPREG_ST1] &= ~ST1_ENABLE; + if (state) + i830->state.Stipple[I830_STPREG_ST1] |= ST1_ENABLE; + } + break; + + default: + ; + } +} + + +static void +i830_init_packets(struct i830_context *i830) +{ + intelScreenPrivate *screen = i830->intel.intelScreen; + + /* Zero all state */ + memset(&i830->state, 0, sizeof(i830->state)); + + /* Set default blend state */ + i830->state.TexBlend[0][0] = (_3DSTATE_MAP_BLEND_OP_CMD(0) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXOP_LAST_STAGE | TEXBLENDOP_ARG1); + i830->state.TexBlend[0][1] = (_3DSTATE_MAP_BLEND_OP_CMD(0) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | TEXBLENDOP_ARG1); + i830->state.TexBlend[0][2] = (_3DSTATE_MAP_BLEND_ARG_CMD(0) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_DIFFUSE); + i830->state.TexBlend[0][3] = (_3DSTATE_MAP_BLEND_ARG_CMD(0) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_DIFFUSE); + + i830->state.TexBlendWordsUsed[0] = 4; + + + i830->state.Ctx[I830_CTXREG_VF] = 0; + i830->state.Ctx[I830_CTXREG_VF2] = 0; + + i830->state.Ctx[I830_CTXREG_AA] = (_3DSTATE_AA_CMD | + AA_LINE_ECAAR_WIDTH_ENABLE | + AA_LINE_ECAAR_WIDTH_1_0 | + AA_LINE_REGION_WIDTH_ENABLE | + AA_LINE_REGION_WIDTH_1_0 | + AA_LINE_DISABLE); + + i830->state.Ctx[I830_CTXREG_ENABLES_1] = (_3DSTATE_ENABLES_1_CMD | + DISABLE_LOGIC_OP | + DISABLE_STENCIL_TEST | + DISABLE_DEPTH_BIAS | + DISABLE_SPEC_ADD | + DISABLE_FOG | + DISABLE_ALPHA_TEST | + DISABLE_COLOR_BLEND | + DISABLE_DEPTH_TEST); + +#if 000 /* XXX all the stencil enable state is set in i830Enable(), right? */ + if (i830->intel.hw_stencil) { + i830->state.Ctx[I830_CTXREG_ENABLES_2] = (_3DSTATE_ENABLES_2_CMD | + ENABLE_STENCIL_WRITE | + ENABLE_TEX_CACHE | + ENABLE_DITHER | + ENABLE_COLOR_MASK | + /* set no color comps disabled */ + ENABLE_COLOR_WRITE | + ENABLE_DEPTH_WRITE); + } + else +#endif + { + i830->state.Ctx[I830_CTXREG_ENABLES_2] = (_3DSTATE_ENABLES_2_CMD | + DISABLE_STENCIL_WRITE | + ENABLE_TEX_CACHE | + ENABLE_DITHER | + ENABLE_COLOR_MASK | + /* set no color comps disabled */ + ENABLE_COLOR_WRITE | + ENABLE_DEPTH_WRITE); + } + + i830->state.Ctx[I830_CTXREG_STATE1] = (_3DSTATE_MODES_1_CMD | + ENABLE_COLR_BLND_FUNC | + BLENDFUNC_ADD | + ENABLE_SRC_BLND_FACTOR | + SRC_BLND_FACT(BLENDFACT_ONE) | + ENABLE_DST_BLND_FACTOR | + DST_BLND_FACT(BLENDFACT_ZERO)); + + i830->state.Ctx[I830_CTXREG_STATE2] = (_3DSTATE_MODES_2_CMD | + ENABLE_GLOBAL_DEPTH_BIAS | + GLOBAL_DEPTH_BIAS(0) | + ENABLE_ALPHA_TEST_FUNC | + ALPHA_TEST_FUNC(COMPAREFUNC_ALWAYS) + | ALPHA_REF_VALUE(0)); + + i830->state.Ctx[I830_CTXREG_STATE3] = (_3DSTATE_MODES_3_CMD | + ENABLE_DEPTH_TEST_FUNC | + DEPTH_TEST_FUNC(COMPAREFUNC_LESS) | + ENABLE_ALPHA_SHADE_MODE | + ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) + | ENABLE_FOG_SHADE_MODE | + FOG_SHADE_MODE(SHADE_MODE_LINEAR) | + ENABLE_SPEC_SHADE_MODE | + SPEC_SHADE_MODE(SHADE_MODE_LINEAR) | + ENABLE_COLOR_SHADE_MODE | + COLOR_SHADE_MODE(SHADE_MODE_LINEAR) + | ENABLE_CULL_MODE | CULLMODE_NONE); + + i830->state.Ctx[I830_CTXREG_STATE4] = (_3DSTATE_MODES_4_CMD | + ENABLE_LOGIC_OP_FUNC | + LOGIC_OP_FUNC(LOGICOP_COPY) | + ENABLE_STENCIL_TEST_MASK | + STENCIL_TEST_MASK(0xff) | + ENABLE_STENCIL_WRITE_MASK | + STENCIL_WRITE_MASK(0xff)); + + i830->state.Ctx[I830_CTXREG_STENCILTST] = (_3DSTATE_STENCIL_TEST_CMD | + ENABLE_STENCIL_PARMS | + STENCIL_FAIL_OP(STENCILOP_KEEP) + | + STENCIL_PASS_DEPTH_FAIL_OP + (STENCILOP_KEEP) | + STENCIL_PASS_DEPTH_PASS_OP + (STENCILOP_KEEP) | + ENABLE_STENCIL_TEST_FUNC | + STENCIL_TEST_FUNC + (COMPAREFUNC_ALWAYS) | + ENABLE_STENCIL_REF_VALUE | + STENCIL_REF_VALUE(0)); + + i830->state.Ctx[I830_CTXREG_STATE5] = (_3DSTATE_MODES_5_CMD | FLUSH_TEXTURE_CACHE | ENABLE_SPRITE_POINT_TEX | SPRITE_POINT_TEX_OFF | ENABLE_FIXED_LINE_WIDTH | FIXED_LINE_WIDTH(0x2) | /* 1.0 */ + ENABLE_FIXED_POINT_WIDTH | + FIXED_POINT_WIDTH(1)); + + i830->state.Ctx[I830_CTXREG_IALPHAB] = (_3DSTATE_INDPT_ALPHA_BLEND_CMD | + DISABLE_INDPT_ALPHA_BLEND | + ENABLE_ALPHA_BLENDFUNC | + ABLENDFUNC_ADD); + + i830->state.Ctx[I830_CTXREG_FOGCOLOR] = (_3DSTATE_FOG_COLOR_CMD | + FOG_COLOR_RED(0) | + FOG_COLOR_GREEN(0) | + FOG_COLOR_BLUE(0)); + + i830->state.Ctx[I830_CTXREG_BLENDCOLOR0] = _3DSTATE_CONST_BLEND_COLOR_CMD; + i830->state.Ctx[I830_CTXREG_BLENDCOLOR1] = 0; + + i830->state.Ctx[I830_CTXREG_MCSB0] = _3DSTATE_MAP_COORD_SETBIND_CMD; + i830->state.Ctx[I830_CTXREG_MCSB1] = (TEXBIND_SET3(TEXCOORDSRC_VTXSET_3) | + TEXBIND_SET2(TEXCOORDSRC_VTXSET_2) | + TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) | + TEXBIND_SET0(TEXCOORDSRC_VTXSET_0)); + + + i830->state.Stipple[I830_STPREG_ST0] = _3DSTATE_STIPPLE; + + i830->state.Buffer[I830_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD; + i830->state.Buffer[I830_DESTREG_CBUFADDR1] = (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(screen->front.pitch) | /* pitch in bytes */ + BUF_3D_USE_FENCE); + + + i830->state.Buffer[I830_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD; + i830->state.Buffer[I830_DESTREG_DBUFADDR1] = (BUF_3D_ID_DEPTH | BUF_3D_PITCH(screen->depth.pitch) | /* pitch in bytes */ + BUF_3D_USE_FENCE); + + i830->state.Buffer[I830_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD; + + switch (screen->fbFormat) { + case DV_PF_565: + i830->state.Buffer[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ + DSTORG_VERT_BIAS(0x8) | /* .5 */ + screen->fbFormat | + DEPTH_IS_Z | + DEPTH_FRMT_16_FIXED); + break; + case DV_PF_8888: + i830->state.Buffer[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ + DSTORG_VERT_BIAS(0x8) | /* .5 */ + screen->fbFormat | + DEPTH_IS_Z | + DEPTH_FRMT_24_FIXED_8_OTHER); + break; + } + + i830->state.Buffer[I830_DESTREG_SENABLE] = (_3DSTATE_SCISSOR_ENABLE_CMD | + DISABLE_SCISSOR_RECT); + i830->state.Buffer[I830_DESTREG_SR0] = _3DSTATE_SCISSOR_RECT_0_CMD; + i830->state.Buffer[I830_DESTREG_SR1] = 0; + i830->state.Buffer[I830_DESTREG_SR2] = 0; +} + + +void +i830InitStateFuncs(struct dd_function_table *functions) +{ + functions->AlphaFunc = i830AlphaFunc; + functions->BlendColor = i830BlendColor; + functions->BlendEquationSeparate = i830BlendEquationSeparate; + functions->BlendFuncSeparate = i830BlendFuncSeparate; + functions->ColorMask = i830ColorMask; + functions->CullFace = i830CullFaceFrontFace; + functions->DepthFunc = i830DepthFunc; + functions->DepthMask = i830DepthMask; + functions->Enable = i830Enable; + functions->Fogfv = i830Fogfv; + functions->FrontFace = i830CullFaceFrontFace; + functions->LightModelfv = i830LightModelfv; + functions->LineWidth = i830LineWidth; + functions->LogicOpcode = i830LogicOp; + functions->PointSize = i830PointSize; + functions->PolygonStipple = i830PolygonStipple; + functions->Scissor = i830Scissor; + functions->ShadeModel = i830ShadeModel; + functions->StencilFuncSeparate = i830StencilFuncSeparate; + functions->StencilMaskSeparate = i830StencilMaskSeparate; + functions->StencilOpSeparate = i830StencilOpSeparate; +} + +void +i830InitState(struct i830_context *i830) +{ + GLcontext *ctx = &i830->intel.ctx; + + i830_init_packets(i830); + + intelInitState(ctx); + + memcpy(&i830->initial, &i830->state, sizeof(i830->state)); + + i830->current = &i830->state; + i830->state.emitted = 0; + i830->state.active = (I830_UPLOAD_INVARIENT | + I830_UPLOAD_TEXBLEND(0) | + I830_UPLOAD_STIPPLE | + I830_UPLOAD_CTX | I830_UPLOAD_BUFFERS); +} diff --git a/src/mesa/drivers/dri/i915tex/i830_tex.c b/src/mesa/drivers/dri/i915tex/i830_tex.c new file mode 100644 index 0000000000..fed464d1aa --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i830_tex.c @@ -0,0 +1,100 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#include "glheader.h" +#include "mtypes.h" +#include "imports.h" +#include "simple_list.h" +#include "enums.h" +#include "image.h" +#include "texstore.h" +#include "texformat.h" +#include "texmem.h" +#include "swrast/swrast.h" + +#include "mm.h" + +#include "intel_ioctl.h" + +#include "i830_context.h" +#include "i830_reg.h" + + + +static void +i830TexEnv(GLcontext * ctx, GLenum target, + GLenum pname, const GLfloat * param) +{ + + switch (pname) { + case GL_TEXTURE_ENV_COLOR: + case GL_TEXTURE_ENV_MODE: + case GL_COMBINE_RGB: + case GL_COMBINE_ALPHA: + case GL_SOURCE0_RGB: + case GL_SOURCE1_RGB: + case GL_SOURCE2_RGB: + case GL_SOURCE0_ALPHA: + case GL_SOURCE1_ALPHA: + case GL_SOURCE2_ALPHA: + case GL_OPERAND0_RGB: + case GL_OPERAND1_RGB: + case GL_OPERAND2_RGB: + case GL_OPERAND0_ALPHA: + case GL_OPERAND1_ALPHA: + case GL_OPERAND2_ALPHA: + case GL_RGB_SCALE: + case GL_ALPHA_SCALE: + break; + + case GL_TEXTURE_LOD_BIAS:{ + struct i830_context *i830 = i830_context(ctx); + GLuint unit = ctx->Texture.CurrentUnit; + int b = (int) ((*param) * 16.0); + if (b > 63) + b = 63; + if (b < -64) + b = -64; + I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit)); + i830->lodbias_tm0s3[unit] = + ((b << TM0S3_LOD_BIAS_SHIFT) & TM0S3_LOD_BIAS_MASK); + break; + } + + default: + break; + } +} + + + + +void +i830InitTextureFuncs(struct dd_function_table *functions) +{ + functions->TexEnv = i830TexEnv; +} diff --git a/src/mesa/drivers/dri/i915tex/i830_texblend.c b/src/mesa/drivers/dri/i915tex/i830_texblend.c new file mode 100644 index 0000000000..58f220eb7c --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i830_texblend.c @@ -0,0 +1,463 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#include "glheader.h" +#include "macros.h" +#include "mtypes.h" +#include "simple_list.h" +#include "enums.h" +#include "texformat.h" +#include "texstore.h" + +#include "mm.h" + +#include "intel_screen.h" +#include "intel_ioctl.h" +#include "intel_tex.h" + +#include "i830_context.h" +#include "i830_reg.h" + + +/* ================================================================ + * Texture combine functions + */ +static GLuint +pass_through(GLuint * state, GLuint blendUnit) +{ + state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | TEXOP_MODIFY_PARMS | TEXBLENDOP_ARG1); + state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | TEXOP_MODIFY_PARMS | TEXBLENDOP_ARG1); + state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | TEXBLENDARG_CURRENT); + state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | TEXBLENDARG_CURRENT); + + return 4; +} + +static GLuint +emit_factor(GLuint blendUnit, GLuint * state, GLuint count, + const GLfloat * factor) +{ + GLubyte r, g, b, a; + GLuint col; + + if (0) + fprintf(stderr, "emit constant %d: %.2f %.2f %.2f %.2f\n", + blendUnit, factor[0], factor[1], factor[2], factor[3]); + + UNCLAMPED_FLOAT_TO_UBYTE(r, factor[0]); + UNCLAMPED_FLOAT_TO_UBYTE(g, factor[1]); + UNCLAMPED_FLOAT_TO_UBYTE(b, factor[2]); + UNCLAMPED_FLOAT_TO_UBYTE(a, factor[3]); + + col = ((a << 24) | (r << 16) | (g << 8) | b); + + state[count++] = _3DSTATE_COLOR_FACTOR_N_CMD(blendUnit); + state[count++] = col; + + return count; +} + + +static INLINE GLuint +GetTexelOp(GLint unit) +{ + switch (unit) { + case 0: + return TEXBLENDARG_TEXEL0; + case 1: + return TEXBLENDARG_TEXEL1; + case 2: + return TEXBLENDARG_TEXEL2; + case 3: + return TEXBLENDARG_TEXEL3; + default: + return TEXBLENDARG_TEXEL0; + } +} + + +/** + * Calculate the hardware instuctions to setup the current texture enviromnemt + * settings. Since \c gl_texture_unit::_CurrentCombine is used, both + * "classic" texture enviroments and GL_ARB_texture_env_combine type texture + * environments are treated identically. + * + * \todo + * This function should return \c GLboolean. When \c GL_FALSE is returned, + * it means that an environment is selected that the hardware cannot do. This + * is the way the Radeon and R200 drivers work. + * + * \todo + * Looking at i830_3d_regs.h, it seems the i830 can do part of + * GL_ATI_texture_env_combine3. It can handle using \c GL_ONE and + * \c GL_ZERO as combine inputs (which the code already supports). It can + * also handle the \c GL_MODULATE_ADD_ATI mode. Is it worth investigating + * partial support for the extension? + */ +GLuint +i830SetTexEnvCombine(struct i830_context * i830, + const struct gl_tex_env_combine_state * combine, + GLint blendUnit, + GLuint texel_op, GLuint * state, const GLfloat * factor) +{ + const GLuint numColorArgs = combine->_NumArgsRGB; + const GLuint numAlphaArgs = combine->_NumArgsA; + + GLuint blendop; + GLuint ablendop; + GLuint args_RGB[3]; + GLuint args_A[3]; + GLuint rgb_shift; + GLuint alpha_shift; + GLboolean need_factor = 0; + int i; + unsigned used; + static const GLuint tex_blend_rgb[3] = { + TEXPIPE_COLOR | TEXBLEND_ARG1 | TEXBLENDARG_MODIFY_PARMS, + TEXPIPE_COLOR | TEXBLEND_ARG2 | TEXBLENDARG_MODIFY_PARMS, + TEXPIPE_COLOR | TEXBLEND_ARG0 | TEXBLENDARG_MODIFY_PARMS, + }; + static const GLuint tex_blend_a[3] = { + TEXPIPE_ALPHA | TEXBLEND_ARG1 | TEXBLENDARG_MODIFY_PARMS, + TEXPIPE_ALPHA | TEXBLEND_ARG2 | TEXBLENDARG_MODIFY_PARMS, + TEXPIPE_ALPHA | TEXBLEND_ARG0 | TEXBLENDARG_MODIFY_PARMS, + }; + + if (INTEL_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, "%s\n", __FUNCTION__); + + + /* The EXT version of the DOT3 extension does not support the + * scale factor, but the ARB version (and the version in OpenGL + * 1.3) does. + */ + switch (combine->ModeRGB) { + case GL_DOT3_RGB_EXT: + alpha_shift = combine->ScaleShiftA; + rgb_shift = 0; + break; + + case GL_DOT3_RGBA_EXT: + alpha_shift = 0; + rgb_shift = 0; + break; + + default: + rgb_shift = combine->ScaleShiftRGB; + alpha_shift = combine->ScaleShiftA; + break; + } + + + switch (combine->ModeRGB) { + case GL_REPLACE: + blendop = TEXBLENDOP_ARG1; + break; + case GL_MODULATE: + blendop = TEXBLENDOP_MODULATE; + break; + case GL_ADD: + blendop = TEXBLENDOP_ADD; + break; + case GL_ADD_SIGNED: + blendop = TEXBLENDOP_ADDSIGNED; + break; + case GL_INTERPOLATE: + blendop = TEXBLENDOP_BLEND; + break; + case GL_SUBTRACT: + blendop = TEXBLENDOP_SUBTRACT; + break; + case GL_DOT3_RGB_EXT: + case GL_DOT3_RGB: + blendop = TEXBLENDOP_DOT3; + break; + case GL_DOT3_RGBA_EXT: + case GL_DOT3_RGBA: + blendop = TEXBLENDOP_DOT3; + break; + default: + return pass_through(state, blendUnit); + } + + blendop |= (rgb_shift << TEXOP_SCALE_SHIFT); + + + /* Handle RGB args */ + for (i = 0; i < 3; i++) { + switch (combine->SourceRGB[i]) { + case GL_TEXTURE: + args_RGB[i] = texel_op; + break; + case GL_TEXTURE0: + case GL_TEXTURE1: + case GL_TEXTURE2: + case GL_TEXTURE3: + args_RGB[i] = GetTexelOp(combine->SourceRGB[i] - GL_TEXTURE0); + break; + case GL_CONSTANT: + args_RGB[i] = TEXBLENDARG_FACTOR_N; + need_factor = 1; + break; + case GL_PRIMARY_COLOR: + args_RGB[i] = TEXBLENDARG_DIFFUSE; + break; + case GL_PREVIOUS: + args_RGB[i] = TEXBLENDARG_CURRENT; + break; + default: + return pass_through(state, blendUnit); + } + + switch (combine->OperandRGB[i]) { + case GL_SRC_COLOR: + args_RGB[i] |= 0; + break; + case GL_ONE_MINUS_SRC_COLOR: + args_RGB[i] |= TEXBLENDARG_INV_ARG; + break; + case GL_SRC_ALPHA: + args_RGB[i] |= TEXBLENDARG_REPLICATE_ALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: + args_RGB[i] |= (TEXBLENDARG_REPLICATE_ALPHA | TEXBLENDARG_INV_ARG); + break; + default: + return pass_through(state, blendUnit); + } + } + + + /* Need to knobble the alpha calculations of TEXBLENDOP_DOT4 to + * match the spec. Can't use DOT3 as it won't propogate values + * into alpha as required: + * + * Note - the global factor is set up with alpha == .5, so + * the alpha part of the DOT4 calculation should be zero. + */ + if (combine->ModeRGB == GL_DOT3_RGBA_EXT || + combine->ModeRGB == GL_DOT3_RGBA) { + ablendop = TEXBLENDOP_DOT4; + args_A[0] = TEXBLENDARG_FACTOR; /* the global factor */ + args_A[1] = TEXBLENDARG_FACTOR; + args_A[2] = TEXBLENDARG_FACTOR; + } + else { + switch (combine->ModeA) { + case GL_REPLACE: + ablendop = TEXBLENDOP_ARG1; + break; + case GL_MODULATE: + ablendop = TEXBLENDOP_MODULATE; + break; + case GL_ADD: + ablendop = TEXBLENDOP_ADD; + break; + case GL_ADD_SIGNED: + ablendop = TEXBLENDOP_ADDSIGNED; + break; + case GL_INTERPOLATE: + ablendop = TEXBLENDOP_BLEND; + break; + case GL_SUBTRACT: + ablendop = TEXBLENDOP_SUBTRACT; + break; + default: + return pass_through(state, blendUnit); + } + + + ablendop |= (alpha_shift << TEXOP_SCALE_SHIFT); + + /* Handle A args */ + for (i = 0; i < 3; i++) { + switch (combine->SourceA[i]) { + case GL_TEXTURE: + args_A[i] = texel_op; + break; + case GL_TEXTURE0: + case GL_TEXTURE1: + case GL_TEXTURE2: + case GL_TEXTURE3: + args_A[i] = GetTexelOp(combine->SourceA[i] - GL_TEXTURE0); + break; + case GL_CONSTANT: + args_A[i] = TEXBLENDARG_FACTOR_N; + need_factor = 1; + break; + case GL_PRIMARY_COLOR: + args_A[i] = TEXBLENDARG_DIFFUSE; + break; + case GL_PREVIOUS: + args_A[i] = TEXBLENDARG_CURRENT; + break; + default: + return pass_through(state, blendUnit); + } + + switch (combine->OperandA[i]) { + case GL_SRC_ALPHA: + args_A[i] |= 0; + break; + case GL_ONE_MINUS_SRC_ALPHA: + args_A[i] |= TEXBLENDARG_INV_ARG; + break; + default: + return pass_through(state, blendUnit); + } + } + } + + + + /* Native Arg1 == Arg0 in GL_EXT_texture_env_combine spec */ + /* Native Arg2 == Arg1 in GL_EXT_texture_env_combine spec */ + /* Native Arg0 == Arg2 in GL_EXT_texture_env_combine spec */ + + /* When we render we need to figure out which is the last really enabled + * tex unit, and put last stage on it + */ + + + /* Build color & alpha pipelines */ + + used = 0; + state[used++] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | TEXOP_MODIFY_PARMS | blendop); + state[used++] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | TEXOP_MODIFY_PARMS | ablendop); + + for (i = 0; i < numColorArgs; i++) { + state[used++] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + tex_blend_rgb[i] | args_RGB[i]); + } + + for (i = 0; i < numAlphaArgs; i++) { + state[used++] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + tex_blend_a[i] | args_A[i]); + } + + + if (need_factor) + return emit_factor(blendUnit, state, used, factor); + else + return used; +} + + +static void +emit_texblend(struct i830_context *i830, GLuint unit, GLuint blendUnit, + GLboolean last_stage) +{ + struct gl_texture_unit *texUnit = &i830->intel.ctx.Texture.Unit[unit]; + GLuint tmp[I830_TEXBLEND_SIZE], tmp_sz; + + + if (0) + fprintf(stderr, "%s unit %d\n", __FUNCTION__, unit); + + /* Update i830->state.TexBlend + */ + tmp_sz = i830SetTexEnvCombine(i830, texUnit->_CurrentCombine, blendUnit, + GetTexelOp(unit), tmp, texUnit->EnvColor); + + if (last_stage) + tmp[0] |= TEXOP_LAST_STAGE; + + if (tmp_sz != i830->state.TexBlendWordsUsed[blendUnit] || + memcmp(tmp, i830->state.TexBlend[blendUnit], + tmp_sz * sizeof(GLuint))) { + + I830_STATECHANGE(i830, I830_UPLOAD_TEXBLEND(blendUnit)); + memcpy(i830->state.TexBlend[blendUnit], tmp, tmp_sz * sizeof(GLuint)); + i830->state.TexBlendWordsUsed[blendUnit] = tmp_sz; + } + + I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND(blendUnit), GL_TRUE); +} + +static void +emit_passthrough(struct i830_context *i830) +{ + GLuint tmp[I830_TEXBLEND_SIZE], tmp_sz; + GLuint unit = 0; + + tmp_sz = pass_through(tmp, unit); + tmp[0] |= TEXOP_LAST_STAGE; + + if (tmp_sz != i830->state.TexBlendWordsUsed[unit] || + memcmp(tmp, i830->state.TexBlend[unit], tmp_sz * sizeof(GLuint))) { + + I830_STATECHANGE(i830, I830_UPLOAD_TEXBLEND(unit)); + memcpy(i830->state.TexBlend[unit], tmp, tmp_sz * sizeof(GLuint)); + i830->state.TexBlendWordsUsed[unit] = tmp_sz; + } + + I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND(unit), GL_TRUE); +} + +void +i830EmitTextureBlend(struct i830_context *i830) +{ + GLcontext *ctx = &i830->intel.ctx; + GLuint unit, last_stage = 0, blendunit = 0; + + I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND_ALL, GL_FALSE); + + if (ctx->Texture._EnabledUnits) { + for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) + if (ctx->Texture.Unit[unit]._ReallyEnabled) + last_stage = unit; + + for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) + if (ctx->Texture.Unit[unit]._ReallyEnabled) + emit_texblend(i830, unit, blendunit++, last_stage == unit); + } + else { + emit_passthrough(i830); + } +} diff --git a/src/mesa/drivers/dri/i915tex/i830_texstate.c b/src/mesa/drivers/dri/i915tex/i830_texstate.c new file mode 100644 index 0000000000..ba79cf9459 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i830_texstate.c @@ -0,0 +1,316 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#include "glheader.h" +#include "macros.h" +#include "mtypes.h" +#include "simple_list.h" +#include "enums.h" +#include "texformat.h" +#include "texstore.h" + +#include "mm.h" + +#include "intel_screen.h" +#include "intel_ioctl.h" +#include "intel_tex.h" +#include "intel_mipmap_tree.h" +#include "intel_regions.h" + +#include "i830_context.h" +#include "i830_reg.h" + + + +static GLuint +translate_texture_format(GLuint mesa_format) +{ + switch (mesa_format) { + case MESA_FORMAT_L8: + return MAPSURF_8BIT | MT_8BIT_L8; + case MESA_FORMAT_I8: + return MAPSURF_8BIT | MT_8BIT_I8; + case MESA_FORMAT_A8: + return MAPSURF_8BIT | MT_8BIT_I8; /* Kludge! */ + case MESA_FORMAT_AL88: + return MAPSURF_16BIT | MT_16BIT_AY88; + case MESA_FORMAT_RGB565: + return MAPSURF_16BIT | MT_16BIT_RGB565; + case MESA_FORMAT_ARGB1555: + return MAPSURF_16BIT | MT_16BIT_ARGB1555; + case MESA_FORMAT_ARGB4444: + return MAPSURF_16BIT | MT_16BIT_ARGB4444; + case MESA_FORMAT_ARGB8888: + return MAPSURF_32BIT | MT_32BIT_ARGB8888; + case MESA_FORMAT_YCBCR_REV: + return (MAPSURF_422 | MT_422_YCRCB_NORMAL); + case MESA_FORMAT_YCBCR: + return (MAPSURF_422 | MT_422_YCRCB_SWAPY); + case MESA_FORMAT_RGB_FXT1: + case MESA_FORMAT_RGBA_FXT1: + return (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1); + case MESA_FORMAT_RGBA_DXT1: + case MESA_FORMAT_RGB_DXT1: + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); + case MESA_FORMAT_RGBA_DXT3: + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3); + case MESA_FORMAT_RGBA_DXT5: + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); + default: + fprintf(stderr, "%s: bad image format %x\n", __FUNCTION__, mesa_format); + abort(); + return 0; + } +} + + + + +/* The i915 (and related graphics cores) do not support GL_CLAMP. The + * Intel drivers for "other operating systems" implement GL_CLAMP as + * GL_CLAMP_TO_EDGE, so the same is done here. + */ +static GLuint +translate_wrap_mode(GLenum wrap) +{ + switch (wrap) { + case GL_REPEAT: + return TEXCOORDMODE_WRAP; + case GL_CLAMP: + case GL_CLAMP_TO_EDGE: + return TEXCOORDMODE_CLAMP; /* not really correct */ + case GL_CLAMP_TO_BORDER: + return TEXCOORDMODE_CLAMP_BORDER; + case GL_MIRRORED_REPEAT: + return TEXCOORDMODE_MIRROR; + default: + return TEXCOORDMODE_WRAP; + } +} + + +/* Recalculate all state from scratch. Perhaps not the most + * efficient, but this has gotten complex enough that we need + * something which is understandable and reliable. + */ +static GLboolean +i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) +{ + GLcontext *ctx = &intel->ctx; + struct i830_context *i830 = i830_context(ctx); + struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current; + struct intel_texture_object *intelObj = intel_texture_object(tObj); + struct gl_texture_image *firstImage; + GLuint *state = i830->state.Tex[unit]; + + memset(state, 0, sizeof(state)); + + if (!intel_finalize_mipmap_tree(intel, unit)) + return GL_FALSE; + + /* Get first image here, since intelObj->firstLevel will get set in + * the intel_finalize_mipmap_tree() call above. + */ + firstImage = tObj->Image[0][intelObj->firstLevel]; + + i830->state.tex_buffer[unit] = intelObj->mt->region->buffer; + i830->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt, 0, + intelObj-> + firstLevel); + + + state[I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 | + (LOAD_TEXTURE_MAP0 << unit) | 4); + +/* state[I830_TEXREG_TM0S0] = (TM0S0_USE_FENCE | */ +/* t->intel.TextureOffset); */ + + + state[I830_TEXREG_TM0S1] = + (((firstImage->Height - 1) << TM0S1_HEIGHT_SHIFT) | + ((firstImage->Width - 1) << TM0S1_WIDTH_SHIFT) | + translate_texture_format(firstImage->TexFormat->MesaFormat)); + + state[I830_TEXREG_TM0S2] = + (((((intelObj->mt->pitch * intelObj->mt->cpp) / 4) - + 1) << TM0S2_PITCH_SHIFT) | TM0S2_CUBE_FACE_ENA_MASK); + + { + if (tObj->Target == GL_TEXTURE_CUBE_MAP) + state[I830_TEXREG_CUBE] = (_3DSTATE_MAP_CUBE | MAP_UNIT(unit) | + CUBE_NEGX_ENABLE | + CUBE_POSX_ENABLE | + CUBE_NEGY_ENABLE | + CUBE_POSY_ENABLE | + CUBE_NEGZ_ENABLE | CUBE_POSZ_ENABLE); + else + state[I830_TEXREG_CUBE] = (_3DSTATE_MAP_CUBE | MAP_UNIT(unit)); + } + + + + + { + GLuint minFilt, mipFilt, magFilt; + + switch (tObj->MinFilter) { + case GL_NEAREST: + minFilt = FILTER_NEAREST; + mipFilt = MIPFILTER_NONE; + break; + case GL_LINEAR: + minFilt = FILTER_LINEAR; + mipFilt = MIPFILTER_NONE; + break; + case GL_NEAREST_MIPMAP_NEAREST: + minFilt = FILTER_NEAREST; + mipFilt = MIPFILTER_NEAREST; + break; + case GL_LINEAR_MIPMAP_NEAREST: + minFilt = FILTER_LINEAR; + mipFilt = MIPFILTER_NEAREST; + break; + case GL_NEAREST_MIPMAP_LINEAR: + minFilt = FILTER_NEAREST; + mipFilt = MIPFILTER_LINEAR; + break; + case GL_LINEAR_MIPMAP_LINEAR: + minFilt = FILTER_LINEAR; + mipFilt = MIPFILTER_LINEAR; + break; + default: + return GL_FALSE; + } + + if (tObj->MaxAnisotropy > 1.0) { + minFilt = FILTER_ANISOTROPIC; + magFilt = FILTER_ANISOTROPIC; + } + else { + switch (tObj->MagFilter) { + case GL_NEAREST: + magFilt = FILTER_NEAREST; + break; + case GL_LINEAR: + magFilt = FILTER_LINEAR; + break; + default: + return GL_FALSE; + } + } + + state[I830_TEXREG_TM0S3] = i830->lodbias_tm0s3[unit]; + +#if 0 + /* YUV conversion: + */ + if (firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR || + firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV) + state[I830_TEXREG_TM0S3] |= SS2_COLORSPACE_CONVERSION; +#endif + + state[I830_TEXREG_TM0S3] |= ((intelObj->lastLevel - + intelObj->firstLevel) * + 4) << TM0S3_MIN_MIP_SHIFT; + + state[I830_TEXREG_TM0S3] |= ((minFilt << TM0S3_MIN_FILTER_SHIFT) | + (mipFilt << TM0S3_MIP_FILTER_SHIFT) | + (magFilt << TM0S3_MAG_FILTER_SHIFT)); + } + + { + GLenum ws = tObj->WrapS; + GLenum wt = tObj->WrapT; + + + /* 3D textures not available on i830 + */ + if (tObj->Target == GL_TEXTURE_3D) + return GL_FALSE; + + state[I830_TEXREG_MCS] = (_3DSTATE_MAP_COORD_SET_CMD | + MAP_UNIT(unit) | + ENABLE_TEXCOORD_PARAMS | + ss3 | + ENABLE_ADDR_V_CNTL | + TEXCOORD_ADDR_V_MODE(translate_wrap_mode(wt)) + | ENABLE_ADDR_U_CNTL | + TEXCOORD_ADDR_U_MODE(translate_wrap_mode + (ws))); + } + + + state[I830_TEXREG_TM0S4] = INTEL_PACKCOLOR8888(tObj->_BorderChan[0], + tObj->_BorderChan[1], + tObj->_BorderChan[2], + tObj->_BorderChan[3]); + + + I830_ACTIVESTATE(i830, I830_UPLOAD_TEX(unit), GL_TRUE); + /* memcmp was already disabled, but definitely won't work as the + * region might now change and that wouldn't be detected: + */ + I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit)); + return GL_TRUE; +} + + + + +void +i830UpdateTextureState(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + GLboolean ok = GL_TRUE; + GLuint i; + + for (i = 0; i < I830_TEX_UNITS && ok; i++) { + switch (intel->ctx.Texture.Unit[i]._ReallyEnabled) { + case TEXTURE_1D_BIT: + case TEXTURE_2D_BIT: + case TEXTURE_CUBE_BIT: + ok = i830_update_tex_unit(intel, i, TEXCOORDS_ARE_NORMAL); + break; + case TEXTURE_RECT_BIT: + ok = i830_update_tex_unit(intel, i, TEXCOORDS_ARE_IN_TEXELUNITS); + break; + case 0: + if (i830->state.active & I830_UPLOAD_TEX(i)) + I830_ACTIVESTATE(i830, I830_UPLOAD_TEX(i), GL_FALSE); + break; + case TEXTURE_3D_BIT: + default: + ok = GL_FALSE; + break; + } + } + + FALLBACK(intel, I830_FALLBACK_TEXTURE, !ok); + + if (ok) + i830EmitTextureBlend(i830); +} diff --git a/src/mesa/drivers/dri/i915tex/i830_vtbl.c b/src/mesa/drivers/dri/i915tex/i830_vtbl.c new file mode 100644 index 0000000000..45502da290 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i830_vtbl.c @@ -0,0 +1,606 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + + +#include "i830_context.h" +#include "i830_reg.h" +#include "intel_batchbuffer.h" +#include "intel_regions.h" +#include "tnl/t_context.h" +#include "tnl/t_vertex.h" + +#define FILE_DEBUG_FLAG DEBUG_STATE + +static GLboolean i830_check_vertex_size(struct intel_context *intel, + GLuint expected); + +#define SZ_TO_HW(sz) ((sz-2)&0x3) +#define EMIT_SZ(sz) (EMIT_1F + (sz) - 1) +#define EMIT_ATTR( ATTR, STYLE, V0 ) \ +do { \ + intel->vertex_attrs[intel->vertex_attr_count].attrib = (ATTR); \ + intel->vertex_attrs[intel->vertex_attr_count].format = (STYLE); \ + intel->vertex_attr_count++; \ + v0 |= V0; \ +} while (0) + +#define EMIT_PAD( N ) \ +do { \ + intel->vertex_attrs[intel->vertex_attr_count].attrib = 0; \ + intel->vertex_attrs[intel->vertex_attr_count].format = EMIT_PAD; \ + intel->vertex_attrs[intel->vertex_attr_count].offset = (N); \ + intel->vertex_attr_count++; \ +} while (0) + + +#define VRTX_TEX_SET_FMT(n, x) ((x)<<((n)*2)) +#define TEXBIND_SET(n, x) ((x)<<((n)*4)) + +static void +i830_render_start(struct intel_context *intel) +{ + GLcontext *ctx = &intel->ctx; + struct i830_context *i830 = i830_context(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + DECLARE_RENDERINPUTS(index_bitset); + GLuint v0 = _3DSTATE_VFT0_CMD; + GLuint v2 = _3DSTATE_VFT1_CMD; + GLuint mcsb1 = 0; + + RENDERINPUTS_COPY(index_bitset, tnl->render_inputs_bitset); + + /* Important: + */ + VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr; + intel->vertex_attr_count = 0; + + /* EMIT_ATTR's must be in order as they tell t_vertex.c how to + * build up a hardware vertex. + */ + if (RENDERINPUTS_TEST_RANGE(index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX)) { + EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, VFT0_XYZW); + intel->coloroffset = 4; + } + else { + EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, VFT0_XYZ); + intel->coloroffset = 3; + } + + if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_POINTSIZE)) { + EMIT_ATTR(_TNL_ATTRIB_POINTSIZE, EMIT_1F, VFT0_POINT_WIDTH); + } + + EMIT_ATTR(_TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, VFT0_DIFFUSE); + + intel->specoffset = 0; + if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_COLOR1) || + RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_FOG)) { + if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_COLOR1)) { + intel->specoffset = intel->coloroffset + 1; + EMIT_ATTR(_TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, VFT0_SPEC); + } + else + EMIT_PAD(3); + + if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_FOG)) + EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1UB_1F, VFT0_SPEC); + else + EMIT_PAD(1); + } + + if (RENDERINPUTS_TEST_RANGE(index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX)) { + int i, count = 0; + + for (i = 0; i < I830_TEX_UNITS; i++) { + if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_TEX(i))) { + GLuint sz = VB->TexCoordPtr[i]->size; + GLuint emit; + GLuint mcs = (i830->state.Tex[i][I830_TEXREG_MCS] & + ~TEXCOORDTYPE_MASK); + + switch (sz) { + case 1: + case 2: + emit = EMIT_2F; + sz = 2; + mcs |= TEXCOORDTYPE_CARTESIAN; + break; + case 3: + emit = EMIT_3F; + sz = 3; + mcs |= TEXCOORDTYPE_VECTOR; + break; + case 4: + emit = EMIT_3F_XYW; + sz = 3; + mcs |= TEXCOORDTYPE_HOMOGENEOUS; + break; + default: + continue; + }; + + + EMIT_ATTR(_TNL_ATTRIB_TEX0 + i, emit, 0); + v2 |= VRTX_TEX_SET_FMT(count, SZ_TO_HW(sz)); + mcsb1 |= (count + 8) << (i * 4); + + if (mcs != i830->state.Tex[i][I830_TEXREG_MCS]) { + I830_STATECHANGE(i830, I830_UPLOAD_TEX(i)); + i830->state.Tex[i][I830_TEXREG_MCS] = mcs; + } + + count++; + } + } + + v0 |= VFT0_TEX_COUNT(count); + } + + /* Only need to change the vertex emit code if there has been a + * statechange to a new hardware vertex format: + */ + if (v0 != i830->state.Ctx[I830_CTXREG_VF] || + v2 != i830->state.Ctx[I830_CTXREG_VF2] || + mcsb1 != i830->state.Ctx[I830_CTXREG_MCSB1] || + !RENDERINPUTS_EQUAL(index_bitset, i830->last_index_bitset)) { + int k; + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + + /* Must do this *after* statechange, so as not to affect + * buffered vertices reliant on the old state: + */ + intel->vertex_size = + _tnl_install_attrs(ctx, + intel->vertex_attrs, + intel->vertex_attr_count, + intel->ViewportMatrix.m, 0); + + intel->vertex_size >>= 2; + + i830->state.Ctx[I830_CTXREG_VF] = v0; + i830->state.Ctx[I830_CTXREG_VF2] = v2; + i830->state.Ctx[I830_CTXREG_MCSB1] = mcsb1; + RENDERINPUTS_COPY(i830->last_index_bitset, index_bitset); + + k = i830_check_vertex_size(intel, intel->vertex_size); + assert(k); + } +} + +static void +i830_reduced_primitive_state(struct intel_context *intel, GLenum rprim) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + GLuint st1 = i830->state.Stipple[I830_STPREG_ST1]; + + st1 &= ~ST1_ENABLE; + + switch (rprim) { + case GL_TRIANGLES: + if (intel->ctx.Polygon.StippleFlag && intel->hw_stipple) + st1 |= ST1_ENABLE; + break; + case GL_LINES: + case GL_POINTS: + default: + break; + } + + i830->intel.reduced_primitive = rprim; + + if (st1 != i830->state.Stipple[I830_STPREG_ST1]) { + INTEL_FIREVERTICES(intel); + + I830_STATECHANGE(i830, I830_UPLOAD_STIPPLE); + i830->state.Stipple[I830_STPREG_ST1] = st1; + } +} + +/* Pull apart the vertex format registers and figure out how large a + * vertex is supposed to be. + */ +static GLboolean +i830_check_vertex_size(struct intel_context *intel, GLuint expected) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + int vft0 = i830->current->Ctx[I830_CTXREG_VF]; + int vft1 = i830->current->Ctx[I830_CTXREG_VF2]; + int nrtex = (vft0 & VFT0_TEX_COUNT_MASK) >> VFT0_TEX_COUNT_SHIFT; + int i, sz = 0; + + switch (vft0 & VFT0_XYZW_MASK) { + case VFT0_XY: + sz = 2; + break; + case VFT0_XYZ: + sz = 3; + break; + case VFT0_XYW: + sz = 3; + break; + case VFT0_XYZW: + sz = 4; + break; + default: + fprintf(stderr, "no xyzw specified\n"); + return 0; + } + + if (vft0 & VFT0_SPEC) + sz++; + if (vft0 & VFT0_DIFFUSE) + sz++; + if (vft0 & VFT0_DEPTH_OFFSET) + sz++; + if (vft0 & VFT0_POINT_WIDTH) + sz++; + + for (i = 0; i < nrtex; i++) { + switch (vft1 & VFT1_TEX0_MASK) { + case TEXCOORDFMT_2D: + sz += 2; + break; + case TEXCOORDFMT_3D: + sz += 3; + break; + case TEXCOORDFMT_4D: + sz += 4; + break; + case TEXCOORDFMT_1D: + sz += 1; + break; + } + vft1 >>= VFT1_TEX1_SHIFT; + } + + if (sz != expected) + fprintf(stderr, "vertex size mismatch %d/%d\n", sz, expected); + + return sz == expected; +} + +static void +i830_emit_invarient_state(struct intel_context *intel) +{ + BATCH_LOCALS; + + BEGIN_BATCH(40, 0); + + OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_DFLT_Z_CMD); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_FOG_MODE_CMD); + OUT_BATCH(FOGFUNC_ENABLE | + FOG_LINEAR_CONST | FOGSRC_INDEX_Z | ENABLE_FOG_DENSITY); + OUT_BATCH(0); + OUT_BATCH(0); + + + OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | + MAP_UNIT(0) | + DISABLE_TEX_STREAM_BUMP | + ENABLE_TEX_STREAM_COORD_SET | + TEX_STREAM_COORD_SET(0) | + ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(0)); + OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | + MAP_UNIT(1) | + DISABLE_TEX_STREAM_BUMP | + ENABLE_TEX_STREAM_COORD_SET | + TEX_STREAM_COORD_SET(1) | + ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(1)); + OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | + MAP_UNIT(2) | + DISABLE_TEX_STREAM_BUMP | + ENABLE_TEX_STREAM_COORD_SET | + TEX_STREAM_COORD_SET(2) | + ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(2)); + OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | + MAP_UNIT(3) | + DISABLE_TEX_STREAM_BUMP | + ENABLE_TEX_STREAM_COORD_SET | + TEX_STREAM_COORD_SET(3) | + ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(3)); + + OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM); + OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(0)); + OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM); + OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(1)); + OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM); + OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(2)); + OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM); + OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(3)); + + OUT_BATCH(_3DSTATE_RASTER_RULES_CMD | + ENABLE_POINT_RASTER_RULE | + OGL_POINT_RASTER_RULE | + ENABLE_LINE_STRIP_PROVOKE_VRTX | + ENABLE_TRI_FAN_PROVOKE_VRTX | + ENABLE_TRI_STRIP_PROVOKE_VRTX | + LINE_STRIP_PROVOKE_VRTX(1) | + TRI_FAN_PROVOKE_VRTX(2) | TRI_STRIP_PROVOKE_VRTX(2)); + + OUT_BATCH(_3DSTATE_VERTEX_TRANSFORM); + OUT_BATCH(DISABLE_VIEWPORT_TRANSFORM | DISABLE_PERSPECTIVE_DIVIDE); + + OUT_BATCH(_3DSTATE_W_STATE_CMD); + OUT_BATCH(MAGIC_W_STATE_DWORD1); + OUT_BATCH(0x3f800000 /* 1.0 in IEEE float */ ); + + + OUT_BATCH(_3DSTATE_COLOR_FACTOR_CMD); + OUT_BATCH(0x80808080); /* .5 required in alpha for GL_DOT3_RGBA_EXT */ + + ADVANCE_BATCH(); +} + + +#define emit( intel, state, size ) \ +do { \ + int k; \ + BEGIN_BATCH(size / sizeof(GLuint), 0); \ + for (k = 0 ; k < size / sizeof(GLuint) ; k++) { \ + if (0) _mesa_printf(" 0x%08x\n", state[k]); \ + OUT_BATCH(state[k]); \ + } \ + ADVANCE_BATCH(); \ +} while (0) + +static GLuint +get_state_size(struct i830_hw_state *state) +{ + GLuint dirty = state->active & ~state->emitted; + GLuint sz = 0; + GLuint i; + + if (dirty & I830_UPLOAD_INVARIENT) + sz += 40 * sizeof(int); + + if (dirty & I830_UPLOAD_CTX) + sz += sizeof(state->Ctx); + + if (dirty & I830_UPLOAD_BUFFERS) + sz += sizeof(state->Buffer); + + if (dirty & I830_UPLOAD_STIPPLE) + sz += sizeof(state->Stipple); + + for (i = 0; i < I830_TEX_UNITS; i++) { + if ((dirty & I830_UPLOAD_TEX(i))) + sz += sizeof(state->Tex[i]); + + if (dirty & I830_UPLOAD_TEXBLEND(i)) + sz += state->TexBlendWordsUsed[i] * 4; + } + + return sz; +} + + +/* Push the state into the sarea and/or texture memory. + */ +static void +i830_emit_state(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + struct i830_hw_state *state = i830->current; + int i; + GLuint dirty; + BATCH_LOCALS; + + /* We don't hold the lock at this point, so want to make sure that + * there won't be a buffer wrap. + * + * It might be better to talk about explicit places where + * scheduling is allowed, rather than assume that it is whenever a + * batchbuffer fills up. + */ + intel_batchbuffer_require_space(intel->batch, get_state_size(state), 0); + + /* Do this here as we may have flushed the batchbuffer above, + * causing more state to be dirty! + */ + dirty = state->active & ~state->emitted; + + if (dirty & I830_UPLOAD_INVARIENT) { + DBG("I830_UPLOAD_INVARIENT:\n"); + i830_emit_invarient_state(intel); + } + + if (dirty & I830_UPLOAD_CTX) { + DBG("I830_UPLOAD_CTX:\n"); + emit(i830, state->Ctx, sizeof(state->Ctx)); + + } + + if (dirty & I830_UPLOAD_BUFFERS) { + DBG("I830_UPLOAD_BUFFERS:\n"); + BEGIN_BATCH(I830_DEST_SETUP_SIZE + 2, 0); + OUT_BATCH(state->Buffer[I830_DESTREG_CBUFADDR0]); + OUT_BATCH(state->Buffer[I830_DESTREG_CBUFADDR1]); + OUT_RELOC(state->draw_region->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); + + if (state->depth_region) { + OUT_BATCH(state->Buffer[I830_DESTREG_DBUFADDR0]); + OUT_BATCH(state->Buffer[I830_DESTREG_DBUFADDR1]); + OUT_RELOC(state->depth_region->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); + } + + OUT_BATCH(state->Buffer[I830_DESTREG_DV0]); + OUT_BATCH(state->Buffer[I830_DESTREG_DV1]); + OUT_BATCH(state->Buffer[I830_DESTREG_SENABLE]); + OUT_BATCH(state->Buffer[I830_DESTREG_SR0]); + OUT_BATCH(state->Buffer[I830_DESTREG_SR1]); + OUT_BATCH(state->Buffer[I830_DESTREG_SR2]); + ADVANCE_BATCH(); + } + + if (dirty & I830_UPLOAD_STIPPLE) { + DBG("I830_UPLOAD_STIPPLE:\n"); + emit(i830, state->Stipple, sizeof(state->Stipple)); + } + + for (i = 0; i < I830_TEX_UNITS; i++) { + if ((dirty & I830_UPLOAD_TEX(i))) { + DBG("I830_UPLOAD_TEX(%d):\n", i); + + BEGIN_BATCH(I830_TEX_SETUP_SIZE + 1, 0); + OUT_BATCH(state->Tex[i][I830_TEXREG_TM0LI]); + + if (state->tex_buffer[i]) { + OUT_RELOC(state->tex_buffer[i], + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, + state->tex_offset[i] | TM0S0_USE_FENCE); + } + else { + assert(i == 0); + assert(state == &i830->meta); + OUT_BATCH(0); + } + + OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S1]); + OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S2]); + OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S3]); + OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S4]); + OUT_BATCH(state->Tex[i][I830_TEXREG_MCS]); + OUT_BATCH(state->Tex[i][I830_TEXREG_CUBE]); + } + + if (dirty & I830_UPLOAD_TEXBLEND(i)) { + DBG("I830_UPLOAD_TEXBLEND(%d): %d words\n", i, + state->TexBlendWordsUsed[i]); + emit(i830, state->TexBlend[i], state->TexBlendWordsUsed[i] * 4); + } + } + + state->emitted |= dirty; +} + +static void +i830_destroy_context(struct intel_context *intel) +{ + _tnl_free_vertices(&intel->ctx); +} + +static void +i830_set_draw_region(struct intel_context *intel, + struct intel_region *draw_region, + struct intel_region *depth_region) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + + intel_region_release(&i830->state.draw_region); + intel_region_release(&i830->state.depth_region); + intel_region_reference(&i830->state.draw_region, draw_region); + intel_region_reference(&i830->state.depth_region, depth_region); + + /* XXX FBO: Need code from i915_set_draw_region() */ + + I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS); + I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS); + i830->state.Buffer[I830_DESTREG_CBUFADDR1] = + (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(draw_region->pitch) | + BUF_3D_USE_FENCE); + i830->state.Buffer[I830_DESTREG_DBUFADDR1] = + (BUF_3D_ID_DEPTH | BUF_3D_PITCH(depth_region->pitch) | + BUF_3D_USE_FENCE); +} + +#if 0 +static void +i830_update_color_z_regions(intelContextPtr intel, + const intelRegion * colorRegion, + const intelRegion * depthRegion) +{ + i830ContextPtr i830 = I830_CONTEXT(intel); + + i830->state.Buffer[I830_DESTREG_CBUFADDR1] = + (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(colorRegion->pitch) | + BUF_3D_USE_FENCE); + i830->state.Buffer[I830_DESTREG_CBUFADDR2] = colorRegion->offset; + + i830->state.Buffer[I830_DESTREG_DBUFADDR1] = + (BUF_3D_ID_DEPTH | BUF_3D_PITCH(depthRegion->pitch) | BUF_3D_USE_FENCE); + i830->state.Buffer[I830_DESTREG_DBUFADDR2] = depthRegion->offset; +} +#endif + + +/* This isn't really handled at the moment. + */ +static void +i830_lost_hardware(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + i830->state.emitted = 0; +} + + + +static GLuint +i830_flush_cmd(void) +{ + return MI_FLUSH | FLUSH_MAP_CACHE; +} + + +static void +i830_assert_not_dirty( struct intel_context *intel ) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + struct i830_hw_state *state = i830->current; + GLuint dirty = state->active & ~state->emitted; + assert(!dirty); +} + + +void +i830InitVtbl(struct i830_context *i830) +{ + i830->intel.vtbl.check_vertex_size = i830_check_vertex_size; + i830->intel.vtbl.destroy = i830_destroy_context; + i830->intel.vtbl.emit_state = i830_emit_state; + i830->intel.vtbl.lost_hardware = i830_lost_hardware; + i830->intel.vtbl.reduced_primitive_state = i830_reduced_primitive_state; + i830->intel.vtbl.set_draw_region = i830_set_draw_region; + i830->intel.vtbl.update_texture_state = i830UpdateTextureState; + i830->intel.vtbl.flush_cmd = i830_flush_cmd; + i830->intel.vtbl.render_start = i830_render_start; + i830->intel.vtbl.assert_not_dirty = i830_assert_not_dirty; +} diff --git a/src/mesa/drivers/dri/i915tex/i915_context.c b/src/mesa/drivers/dri/i915tex/i915_context.c new file mode 100644 index 0000000000..4cbe29d79d --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_context.c @@ -0,0 +1,175 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#include "i915_context.h" +#include "imports.h" +#include "intel_tex.h" +#include "intel_tris.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" +#include "tnl/t_vertex.h" + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/tnl.h" +#include "array_cache/acache.h" + +#include "utils.h" +#include "i915_reg.h" + +#include "intel_regions.h" +#include "intel_batchbuffer.h" + +/*************************************** + * Mesa's Driver Functions + ***************************************/ + +static const struct dri_extension i915_extensions[] = { + {"GL_ARB_depth_texture", NULL}, + {"GL_ARB_fragment_program", NULL}, + {"GL_ARB_shadow", NULL}, + {"GL_ARB_texture_env_crossbar", NULL}, + {"GL_ARB_texture_non_power_of_two", NULL}, + {"GL_EXT_shadow_funcs", NULL}, + /* ARB extn won't work if not enabled */ + {"GL_SGIX_depth_texture", NULL}, + {NULL, NULL} +}; + +/* Override intel default. + */ +static void +i915InvalidateState(GLcontext * ctx, GLuint new_state) +{ + _swrast_InvalidateState(ctx, new_state); + _swsetup_InvalidateState(ctx, new_state); + _ac_InvalidateState(ctx, new_state); + _tnl_InvalidateState(ctx, new_state); + _tnl_invalidate_vertex_state(ctx, new_state); + intel_context(ctx)->NewGLState |= new_state; + + /* Todo: gather state values under which tracked parameters become + * invalidated, add callbacks for things like + * ProgramLocalParameters, etc. + */ + { + struct i915_fragment_program *p = + (struct i915_fragment_program *) ctx->FragmentProgram._Current; + if (p && p->nr_params) + p->params_uptodate = 0; + } + + if (new_state & (_NEW_FOG | _NEW_HINT | _NEW_PROGRAM)) + i915_update_fog(ctx); +} + + +static void +i915InitDriverFunctions(struct dd_function_table *functions) +{ + intelInitDriverFunctions(functions); + i915InitStateFunctions(functions); + i915InitTextureFuncs(functions); + i915InitFragProgFuncs(functions); + functions->UpdateState = i915InvalidateState; +} + + + +GLboolean +i915CreateContext(const __GLcontextModes * mesaVis, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate) +{ + struct dd_function_table functions; + struct i915_context *i915 = + (struct i915_context *) CALLOC_STRUCT(i915_context); + struct intel_context *intel = &i915->intel; + GLcontext *ctx = &intel->ctx; + + if (!i915) + return GL_FALSE; + + if (0) + _mesa_printf("\ntexmem-0-3 branch\n\n"); + + i915InitVtbl(i915); + i915InitMetaFuncs(i915); + + i915InitDriverFunctions(&functions); + + if (!intelInitContext(intel, mesaVis, driContextPriv, + sharedContextPrivate, &functions)) { + FREE(i915); + return GL_FALSE; + } + + ctx->Const.MaxTextureUnits = I915_TEX_UNITS; + ctx->Const.MaxTextureImageUnits = I915_TEX_UNITS; + ctx->Const.MaxTextureCoordUnits = I915_TEX_UNITS; + + + /* Advertise the full hardware capabilities. The new memory + * manager should cope much better with overload situations: + */ + ctx->Const.MaxTextureLevels = 12; + ctx->Const.Max3DTextureLevels = 9; + ctx->Const.MaxCubeTextureLevels = 12; + ctx->Const.MaxTextureRectSize = (1 << 11); + ctx->Const.MaxTextureUnits = I915_TEX_UNITS; + + /* GL_ARB_fragment_program limits - don't think Mesa actually + * validates programs against these, and in any case one ARB + * instruction can translate to more than one HW instruction, so + * we'll still have to check and fallback each time. + */ + ctx->Const.FragmentProgram.MaxNativeTemps = I915_MAX_TEMPORARY; + ctx->Const.FragmentProgram.MaxNativeAttribs = 11; /* 8 tex, 2 color, fog */ + ctx->Const.FragmentProgram.MaxNativeParameters = I915_MAX_CONSTANT; + ctx->Const.FragmentProgram.MaxNativeAluInstructions = I915_MAX_ALU_INSN; + ctx->Const.FragmentProgram.MaxNativeTexInstructions = I915_MAX_TEX_INSN; + ctx->Const.FragmentProgram.MaxNativeInstructions = (I915_MAX_ALU_INSN + + I915_MAX_TEX_INSN); + ctx->Const.FragmentProgram.MaxNativeTexIndirections = + I915_MAX_TEX_INDIRECT; + ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; /* I don't think we have one */ + + ctx->_MaintainTexEnvProgram = 1; + ctx->_UseTexEnvProgram = 1; + + driInitExtensions(ctx, i915_extensions, GL_FALSE); + + + _tnl_init_vertices(ctx, ctx->Const.MaxArrayLockSize + 12, + 36 * sizeof(GLfloat)); + + intel->verts = TNL_CONTEXT(ctx)->clipspace.vertex_buf; + + i915InitState(i915); + + return GL_TRUE; +} diff --git a/src/mesa/drivers/dri/i915tex/i915_context.h b/src/mesa/drivers/dri/i915tex/i915_context.h new file mode 100644 index 0000000000..5ae76fcd18 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_context.h @@ -0,0 +1,367 @@ + /************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#ifndef I915CONTEXT_INC +#define I915CONTEXT_INC + +#include "intel_context.h" + +#define I915_FALLBACK_TEXTURE 0x1000 +#define I915_FALLBACK_COLORMASK 0x2000 +#define I915_FALLBACK_STENCIL 0x4000 +#define I915_FALLBACK_STIPPLE 0x8000 +#define I915_FALLBACK_PROGRAM 0x10000 +#define I915_FALLBACK_LOGICOP 0x20000 +#define I915_FALLBACK_POLYGON_SMOOTH 0x40000 +#define I915_FALLBACK_POINT_SMOOTH 0x80000 + +#define I915_UPLOAD_CTX 0x1 +#define I915_UPLOAD_BUFFERS 0x2 +#define I915_UPLOAD_STIPPLE 0x4 +#define I915_UPLOAD_PROGRAM 0x8 +#define I915_UPLOAD_CONSTANTS 0x10 +#define I915_UPLOAD_FOG 0x20 +#define I915_UPLOAD_INVARIENT 0x40 +#define I915_UPLOAD_DEFAULTS 0x80 +#define I915_UPLOAD_TEX(i) (0x00010000<<(i)) +#define I915_UPLOAD_TEX_ALL (0x00ff0000) +#define I915_UPLOAD_TEX_0_SHIFT 16 + + +/* State structure offsets - these will probably disappear. + */ +#define I915_DESTREG_CBUFADDR0 0 +#define I915_DESTREG_CBUFADDR1 1 +#define I915_DESTREG_DBUFADDR0 3 +#define I915_DESTREG_DBUFADDR1 4 +#define I915_DESTREG_DV0 6 +#define I915_DESTREG_DV1 7 +#define I915_DESTREG_SENABLE 8 +#define I915_DESTREG_SR0 9 +#define I915_DESTREG_SR1 10 +#define I915_DESTREG_SR2 11 +#define I915_DEST_SETUP_SIZE 12 + +#define I915_CTXREG_STATE4 0 +#define I915_CTXREG_LI 1 +#define I915_CTXREG_LIS2 2 +#define I915_CTXREG_LIS4 3 +#define I915_CTXREG_LIS5 4 +#define I915_CTXREG_LIS6 5 +#define I915_CTXREG_IAB 6 +#define I915_CTXREG_BLENDCOLOR0 7 +#define I915_CTXREG_BLENDCOLOR1 8 +#define I915_CTX_SETUP_SIZE 9 + +#define I915_FOGREG_COLOR 0 +#define I915_FOGREG_MODE0 1 +#define I915_FOGREG_MODE1 2 +#define I915_FOGREG_MODE2 3 +#define I915_FOGREG_MODE3 4 +#define I915_FOG_SETUP_SIZE 5 + +#define I915_STPREG_ST0 0 +#define I915_STPREG_ST1 1 +#define I915_STP_SETUP_SIZE 2 + +#define I915_TEXREG_MS3 1 +#define I915_TEXREG_MS4 2 +#define I915_TEXREG_SS2 3 +#define I915_TEXREG_SS3 4 +#define I915_TEXREG_SS4 5 +#define I915_TEX_SETUP_SIZE 6 + +#define I915_DEFREG_C0 0 +#define I915_DEFREG_C1 1 +#define I915_DEFREG_S0 2 +#define I915_DEFREG_S1 3 +#define I915_DEFREG_Z0 4 +#define I915_DEFREG_Z1 5 +#define I915_DEF_SETUP_SIZE 6 + + +#define I915_MAX_CONSTANT 32 +#define I915_CONSTANT_SIZE (2+(4*I915_MAX_CONSTANT)) + + +#define I915_PROGRAM_SIZE 192 + + +/* Hardware version of a parsed fragment program. "Derived" from the + * mesa fragment_program struct. + */ +struct i915_fragment_program +{ + struct gl_fragment_program FragProg; + + GLboolean translated; + GLboolean params_uptodate; + GLboolean on_hardware; + GLboolean error; /* If program is malformed for any reason. */ + + GLuint nr_tex_indirect; + GLuint nr_tex_insn; + GLuint nr_alu_insn; + GLuint nr_decl_insn; + + + + + /* TODO: split between the stored representation of a program and + * the state used to build that representation. + */ + GLcontext *ctx; + + GLuint declarations[I915_PROGRAM_SIZE]; + GLuint program[I915_PROGRAM_SIZE]; + + GLfloat constant[I915_MAX_CONSTANT][4]; + GLuint constant_flags[I915_MAX_CONSTANT]; + GLuint nr_constants; + + GLuint *csr; /* Cursor, points into program. + */ + + GLuint *decl; /* Cursor, points into declarations. + */ + + GLuint decl_s; /* flags for which s regs need to be decl'd */ + GLuint decl_t; /* flags for which t regs need to be decl'd */ + + GLuint temp_flag; /* Tracks temporary regs which are in + * use. + */ + + GLuint utemp_flag; /* Tracks TYPE_U temporary regs which are in + * use. + */ + + + + /* Helpers for i915_fragprog.c: + */ + GLuint wpos_tex; + GLboolean depth_written; + + struct + { + GLuint reg; /* Hardware constant idx */ + const GLfloat *values; /* Pointer to tracked values */ + } param[I915_MAX_CONSTANT]; + GLuint nr_params; + + + /* Helpers for i915_texprog.c: + */ + GLuint src_texture; /* Reg containing sampled texture color, + * else UREG_BAD. + */ + + GLuint src_previous; /* Reg containing color from previous + * stage. May need to be decl'd. + */ + + GLuint last_tex_stage; /* Number of last enabled texture unit */ + + struct vertex_buffer *VB; +}; + + + + + + + +#define I915_TEX_UNITS 8 + + +struct i915_hw_state +{ + GLuint Ctx[I915_CTX_SETUP_SIZE]; + GLuint Buffer[I915_DEST_SETUP_SIZE]; + GLuint Stipple[I915_STP_SETUP_SIZE]; + GLuint Fog[I915_FOG_SETUP_SIZE]; + GLuint Defaults[I915_DEF_SETUP_SIZE]; + GLuint Tex[I915_TEX_UNITS][I915_TEX_SETUP_SIZE]; + GLuint Constant[I915_CONSTANT_SIZE]; + GLuint ConstantSize; + GLuint Program[I915_PROGRAM_SIZE]; + GLuint ProgramSize; + + /* Region pointers for relocation: + */ + struct intel_region *draw_region; + struct intel_region *depth_region; +/* struct intel_region *tex_region[I915_TEX_UNITS]; */ + + /* Regions aren't actually that appropriate here as the memory may + * be from a PBO or FBO. Just use the buffer id. Will have to do + * this for draw and depth for FBO's... + */ + struct _DriBufferObject *tex_buffer[I915_TEX_UNITS]; + GLuint tex_offset[I915_TEX_UNITS]; + + + GLuint active; /* I915_UPLOAD_* */ + GLuint emitted; /* I915_UPLOAD_* */ +}; + +#define I915_FOG_PIXEL 2 +#define I915_FOG_VERTEX 1 +#define I915_FOG_NONE 0 + +struct i915_context +{ + struct intel_context intel; + + GLuint last_ReallyEnabled; + GLuint vertex_fog; + GLuint lodbias_ss2[MAX_TEXTURE_UNITS]; + + + struct i915_fragment_program tex_program; + struct i915_fragment_program *current_program; + + struct i915_hw_state meta, initial, state, *current; +}; + + +#define I915_STATECHANGE(i915, flag) \ +do { \ + INTEL_FIREVERTICES( &(i915)->intel ); \ + (i915)->state.emitted &= ~(flag); \ +} while (0) + +#define I915_ACTIVESTATE(i915, flag, mode) \ +do { \ + INTEL_FIREVERTICES( &(i915)->intel ); \ + if (mode) \ + (i915)->state.active |= (flag); \ + else \ + (i915)->state.active &= ~(flag); \ +} while (0) + + +/*====================================================================== + * i915_vtbl.c + */ +extern void i915InitVtbl(struct i915_context *i915); + +extern void +i915_state_draw_region(struct intel_context *intel, + struct i915_hw_state *state, + struct intel_region *color_region, + struct intel_region *depth_region); + + + +#define SZ_TO_HW(sz) ((sz-2)&0x3) +#define EMIT_SZ(sz) (EMIT_1F + (sz) - 1) +#define EMIT_ATTR( ATTR, STYLE, S4, SZ ) \ +do { \ + intel->vertex_attrs[intel->vertex_attr_count].attrib = (ATTR); \ + intel->vertex_attrs[intel->vertex_attr_count].format = (STYLE); \ + s4 |= S4; \ + intel->vertex_attr_count++; \ + offset += (SZ); \ +} while (0) + +#define EMIT_PAD( N ) \ +do { \ + intel->vertex_attrs[intel->vertex_attr_count].attrib = 0; \ + intel->vertex_attrs[intel->vertex_attr_count].format = EMIT_PAD; \ + intel->vertex_attrs[intel->vertex_attr_count].offset = (N); \ + intel->vertex_attr_count++; \ + offset += (N); \ +} while (0) + + + +/*====================================================================== + * i915_context.c + */ +extern GLboolean i915CreateContext(const __GLcontextModes * mesaVis, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate); + + +/*====================================================================== + * i915_texprog.c + */ +extern void i915ValidateTextureProgram(struct i915_context *i915); + + +/*====================================================================== + * i915_debug.c + */ +extern void i915_disassemble_program(const GLuint * program, GLuint sz); +extern void i915_print_ureg(const char *msg, GLuint ureg); + + +/*====================================================================== + * i915_state.c + */ +extern void i915InitStateFunctions(struct dd_function_table *functions); +extern void i915InitState(struct i915_context *i915); +extern void i915_update_fog(GLcontext * ctx); + + +/*====================================================================== + * i915_tex.c + */ +extern void i915UpdateTextureState(struct intel_context *intel); +extern void i915InitTextureFuncs(struct dd_function_table *functions); + +/*====================================================================== + * i915_metaops.c + */ +void i915InitMetaFuncs(struct i915_context *i915); + + +/*====================================================================== + * i915_fragprog.c + */ +extern void i915ValidateFragmentProgram(struct i915_context *i915); +extern void i915InitFragProgFuncs(struct dd_function_table *functions); + +/*====================================================================== + * Inline conversion functions. These are better-typed than the + * macros used previously: + */ +static INLINE struct i915_context * +i915_context(GLcontext * ctx) +{ + return (struct i915_context *) ctx; +} + + + +#define I915_CONTEXT(ctx) i915_context(ctx) + + + +#endif diff --git a/src/mesa/drivers/dri/i915tex/i915_debug.c b/src/mesa/drivers/dri/i915tex/i915_debug.c new file mode 100644 index 0000000000..974527e14c --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_debug.c @@ -0,0 +1,334 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#include "i915_reg.h" +#include "i915_context.h" +#include + + +static const char *opcodes[0x20] = { + "NOP", + "ADD", + "MOV", + "MUL", + "MAD", + "DP2ADD", + "DP3", + "DP4", + "FRC", + "RCP", + "RSQ", + "EXP", + "LOG", + "CMP", + "MIN", + "MAX", + "FLR", + "MOD", + "TRC", + "SGE", + "SLT", + "TEXLD", + "TEXLDP", + "TEXLDB", + "TEXKILL", + "DCL", + "0x1a", + "0x1b", + "0x1c", + "0x1d", + "0x1e", + "0x1f", +}; + + +static const int args[0x20] = { + 0, /* 0 nop */ + 2, /* 1 add */ + 1, /* 2 mov */ + 2, /* 3 m ul */ + 3, /* 4 mad */ + 3, /* 5 dp2add */ + 2, /* 6 dp3 */ + 2, /* 7 dp4 */ + 1, /* 8 frc */ + 1, /* 9 rcp */ + 1, /* a rsq */ + 1, /* b exp */ + 1, /* c log */ + 3, /* d cmp */ + 2, /* e min */ + 2, /* f max */ + 1, /* 10 flr */ + 1, /* 11 mod */ + 1, /* 12 trc */ + 2, /* 13 sge */ + 2, /* 14 slt */ + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + + +static const char *regname[0x8] = { + "R", + "T", + "CONST", + "S", + "OC", + "OD", + "U", + "UNKNOWN", +}; + +static void +print_reg_type_nr(GLuint type, GLuint nr) +{ + switch (type) { + case REG_TYPE_T: + switch (nr) { + case T_DIFFUSE: + fprintf(stderr, "T_DIFFUSE"); + return; + case T_SPECULAR: + fprintf(stderr, "T_SPECULAR"); + return; + case T_FOG_W: + fprintf(stderr, "T_FOG_W"); + return; + default: + fprintf(stderr, "T_TEX%d", nr); + return; + } + case REG_TYPE_OC: + if (nr == 0) { + fprintf(stderr, "oC"); + return; + } + break; + case REG_TYPE_OD: + if (nr == 0) { + fprintf(stderr, "oD"); + return; + } + break; + default: + break; + } + + fprintf(stderr, "%s[%d]", regname[type], nr); +} + +#define REG_SWIZZLE_MASK 0x7777 +#define REG_NEGATE_MASK 0x8888 + +#define REG_SWIZZLE_XYZW ((SRC_X << A2_SRC2_CHANNEL_X_SHIFT) | \ + (SRC_Y << A2_SRC2_CHANNEL_Y_SHIFT) | \ + (SRC_Z << A2_SRC2_CHANNEL_Z_SHIFT) | \ + (SRC_W << A2_SRC2_CHANNEL_W_SHIFT)) + + +static void +print_reg_neg_swizzle(GLuint reg) +{ + int i; + + if ((reg & REG_SWIZZLE_MASK) == REG_SWIZZLE_XYZW && + (reg & REG_NEGATE_MASK) == 0) + return; + + fprintf(stderr, "."); + + for (i = 3; i >= 0; i--) { + if (reg & (1 << ((i * 4) + 3))) + fprintf(stderr, "-"); + + switch ((reg >> (i * 4)) & 0x7) { + case 0: + fprintf(stderr, "x"); + break; + case 1: + fprintf(stderr, "y"); + break; + case 2: + fprintf(stderr, "z"); + break; + case 3: + fprintf(stderr, "w"); + break; + case 4: + fprintf(stderr, "0"); + break; + case 5: + fprintf(stderr, "1"); + break; + default: + fprintf(stderr, "?"); + break; + } + } +} + + +static void +print_src_reg(GLuint dword) +{ + GLuint nr = (dword >> A2_SRC2_NR_SHIFT) & REG_NR_MASK; + GLuint type = (dword >> A2_SRC2_TYPE_SHIFT) & REG_TYPE_MASK; + print_reg_type_nr(type, nr); + print_reg_neg_swizzle(dword); +} + +void +i915_print_ureg(const char *msg, GLuint ureg) +{ + fprintf(stderr, "%s: ", msg); + print_src_reg(ureg >> 8); + fprintf(stderr, "\n"); +} + +static void +print_dest_reg(GLuint dword) +{ + GLuint nr = (dword >> A0_DEST_NR_SHIFT) & REG_NR_MASK; + GLuint type = (dword >> A0_DEST_TYPE_SHIFT) & REG_TYPE_MASK; + print_reg_type_nr(type, nr); + if ((dword & A0_DEST_CHANNEL_ALL) == A0_DEST_CHANNEL_ALL) + return; + fprintf(stderr, "."); + if (dword & A0_DEST_CHANNEL_X) + fprintf(stderr, "x"); + if (dword & A0_DEST_CHANNEL_Y) + fprintf(stderr, "y"); + if (dword & A0_DEST_CHANNEL_Z) + fprintf(stderr, "z"); + if (dword & A0_DEST_CHANNEL_W) + fprintf(stderr, "w"); +} + + +#define GET_SRC0_REG(r0, r1) ((r0<<14)|(r1>>A1_SRC0_CHANNEL_W_SHIFT)) +#define GET_SRC1_REG(r0, r1) ((r0<<8)|(r1>>A2_SRC1_CHANNEL_W_SHIFT)) +#define GET_SRC2_REG(r) (r) + + +static void +print_arith_op(GLuint opcode, const GLuint * program) +{ + if (opcode != A0_NOP) { + print_dest_reg(program[0]); + if (program[0] & A0_DEST_SATURATE) + fprintf(stderr, " = SATURATE "); + else + fprintf(stderr, " = "); + } + + fprintf(stderr, "%s ", opcodes[opcode]); + + print_src_reg(GET_SRC0_REG(program[0], program[1])); + if (args[opcode] == 1) { + fprintf(stderr, "\n"); + return; + } + + fprintf(stderr, ", "); + print_src_reg(GET_SRC1_REG(program[1], program[2])); + if (args[opcode] == 2) { + fprintf(stderr, "\n"); + return; + } + + fprintf(stderr, ", "); + print_src_reg(GET_SRC2_REG(program[2])); + fprintf(stderr, "\n"); + return; +} + + +static void +print_tex_op(GLuint opcode, const GLuint * program) +{ + print_dest_reg(program[0] | A0_DEST_CHANNEL_ALL); + fprintf(stderr, " = "); + + fprintf(stderr, "%s ", opcodes[opcode]); + + fprintf(stderr, "S[%d],", program[0] & T0_SAMPLER_NR_MASK); + + print_reg_type_nr((program[1] >> T1_ADDRESS_REG_TYPE_SHIFT) & + REG_TYPE_MASK, + (program[1] >> T1_ADDRESS_REG_NR_SHIFT) & REG_NR_MASK); + fprintf(stderr, "\n"); +} + +static void +print_dcl_op(GLuint opcode, const GLuint * program) +{ + fprintf(stderr, "%s ", opcodes[opcode]); + print_dest_reg(program[0] | A0_DEST_CHANNEL_ALL); + fprintf(stderr, "\n"); +} + + +void +i915_disassemble_program(const GLuint * program, GLuint sz) +{ + GLuint size = program[0] & 0x1ff; + GLint i; + + fprintf(stderr, "BEGIN\n"); + + if (size + 2 != sz) { + fprintf(stderr, "%s: program size mismatch %d/%d\n", __FUNCTION__, + size + 2, sz); + exit(1); + } + + program++; + for (i = 1; i < sz; i += 3, program += 3) { + GLuint opcode = program[0] & (0x1f << 24); + + if ((GLint) opcode >= A0_NOP && opcode <= A0_SLT) + print_arith_op(opcode >> 24, program); + else if (opcode >= T0_TEXLD && opcode <= T0_TEXKILL) + print_tex_op(opcode >> 24, program); + else if (opcode == D0_DCL) + print_dcl_op(opcode >> 24, program); + else + fprintf(stderr, "Unknown opcode 0x%x\n", opcode); + } + + fprintf(stderr, "END\n\n"); +} diff --git a/src/mesa/drivers/dri/i915tex/i915_fragprog.c b/src/mesa/drivers/dri/i915tex/i915_fragprog.c new file mode 100644 index 0000000000..2ddcbc4325 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_fragprog.c @@ -0,0 +1,1072 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#include "glheader.h" +#include "macros.h" +#include "enums.h" + +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "intel_batchbuffer.h" + +#include "i915_reg.h" +#include "i915_context.h" +#include "i915_program.h" + +#include "program_instruction.h" +#include "program.h" + + + +/* 1, -1/3!, 1/5!, -1/7! */ +static const GLfloat sin_constants[4] = { 1.0, + -1.0 / (3 * 2 * 1), + 1.0 / (5 * 4 * 3 * 2 * 1), + -1.0 / (7 * 6 * 5 * 4 * 3 * 2 * 1) +}; + +/* 1, -1/2!, 1/4!, -1/6! */ +static const GLfloat cos_constants[4] = { 1.0, + -1.0 / (2 * 1), + 1.0 / (4 * 3 * 2 * 1), + -1.0 / (6 * 5 * 4 * 3 * 2 * 1) +}; + +/** + * Retrieve a ureg for the given source register. Will emit + * constants, apply swizzling and negation as needed. + */ +static GLuint +src_vector(struct i915_fragment_program *p, + const struct prog_src_register *source, + const struct gl_fragment_program *program) +{ + GLuint src; + + switch (source->File) { + + /* Registers: + */ + case PROGRAM_TEMPORARY: + if (source->Index >= I915_MAX_TEMPORARY) { + i915_program_error(p, "Exceeded max temporary reg"); + return 0; + } + src = UREG(REG_TYPE_R, source->Index); + break; + case PROGRAM_INPUT: + switch (source->Index) { + case FRAG_ATTRIB_WPOS: + src = i915_emit_decl(p, REG_TYPE_T, p->wpos_tex, D0_CHANNEL_ALL); + break; + case FRAG_ATTRIB_COL0: + src = i915_emit_decl(p, REG_TYPE_T, T_DIFFUSE, D0_CHANNEL_ALL); + break; + case FRAG_ATTRIB_COL1: + src = i915_emit_decl(p, REG_TYPE_T, T_SPECULAR, D0_CHANNEL_XYZ); + src = swizzle(src, X, Y, Z, ONE); + break; + case FRAG_ATTRIB_FOGC: + src = i915_emit_decl(p, REG_TYPE_T, T_FOG_W, D0_CHANNEL_W); + src = swizzle(src, W, W, W, W); + break; + case FRAG_ATTRIB_TEX0: + case FRAG_ATTRIB_TEX1: + case FRAG_ATTRIB_TEX2: + case FRAG_ATTRIB_TEX3: + case FRAG_ATTRIB_TEX4: + case FRAG_ATTRIB_TEX5: + case FRAG_ATTRIB_TEX6: + case FRAG_ATTRIB_TEX7: + src = i915_emit_decl(p, REG_TYPE_T, + T_TEX0 + (source->Index - FRAG_ATTRIB_TEX0), + D0_CHANNEL_ALL); + break; + + default: + i915_program_error(p, "Bad source->Index"); + return 0; + } + break; + + /* Various paramters and env values. All emitted to + * hardware as program constants. + */ + case PROGRAM_LOCAL_PARAM: + src = i915_emit_param4fv(p, program->Base.LocalParams[source->Index]); + break; + + case PROGRAM_ENV_PARAM: + src = + i915_emit_param4fv(p, + p->ctx->FragmentProgram.Parameters[source-> + Index]); + break; + + case PROGRAM_STATE_VAR: + case PROGRAM_NAMED_PARAM: + src = + i915_emit_param4fv(p, + program->Base.Parameters->ParameterValues[source-> + Index]); + break; + + default: + i915_program_error(p, "Bad source->File"); + return 0; + } + + src = swizzle(src, + GET_SWZ(source->Swizzle, 0), + GET_SWZ(source->Swizzle, 1), + GET_SWZ(source->Swizzle, 2), GET_SWZ(source->Swizzle, 3)); + + if (source->NegateBase) + src = negate(src, + GET_BIT(source->NegateBase, 0), + GET_BIT(source->NegateBase, 1), + GET_BIT(source->NegateBase, 2), + GET_BIT(source->NegateBase, 3)); + + return src; +} + + +static GLuint +get_result_vector(struct i915_fragment_program *p, + const struct prog_instruction *inst) +{ + switch (inst->DstReg.File) { + case PROGRAM_OUTPUT: + switch (inst->DstReg.Index) { + case FRAG_RESULT_COLR: + return UREG(REG_TYPE_OC, 0); + case FRAG_RESULT_DEPR: + p->depth_written = 1; + return UREG(REG_TYPE_OD, 0); + default: + i915_program_error(p, "Bad inst->DstReg.Index"); + return 0; + } + case PROGRAM_TEMPORARY: + return UREG(REG_TYPE_R, inst->DstReg.Index); + default: + i915_program_error(p, "Bad inst->DstReg.File"); + return 0; + } +} + +static GLuint +get_result_flags(const struct prog_instruction *inst) +{ + GLuint flags = 0; + + if (inst->SaturateMode == SATURATE_ZERO_ONE) + flags |= A0_DEST_SATURATE; + if (inst->DstReg.WriteMask & WRITEMASK_X) + flags |= A0_DEST_CHANNEL_X; + if (inst->DstReg.WriteMask & WRITEMASK_Y) + flags |= A0_DEST_CHANNEL_Y; + if (inst->DstReg.WriteMask & WRITEMASK_Z) + flags |= A0_DEST_CHANNEL_Z; + if (inst->DstReg.WriteMask & WRITEMASK_W) + flags |= A0_DEST_CHANNEL_W; + + return flags; +} + +static GLuint +translate_tex_src_target(struct i915_fragment_program *p, GLubyte bit) +{ + switch (bit) { + case TEXTURE_1D_INDEX: + return D0_SAMPLE_TYPE_2D; + case TEXTURE_2D_INDEX: + return D0_SAMPLE_TYPE_2D; + case TEXTURE_RECT_INDEX: + return D0_SAMPLE_TYPE_2D; + case TEXTURE_3D_INDEX: + return D0_SAMPLE_TYPE_VOLUME; + case TEXTURE_CUBE_INDEX: + return D0_SAMPLE_TYPE_CUBE; + default: + i915_program_error(p, "TexSrcBit"); + return 0; + } +} + +#define EMIT_TEX( OP ) \ +do { \ + GLuint dim = translate_tex_src_target( p, inst->TexSrcTarget ); \ + GLuint sampler = i915_emit_decl(p, REG_TYPE_S, \ + inst->TexSrcUnit, dim); \ + GLuint coord = src_vector( p, &inst->SrcReg[0], program); \ + /* Texel lookup */ \ + \ + i915_emit_texld( p, \ + get_result_vector( p, inst ), \ + get_result_flags( inst ), \ + sampler, \ + coord, \ + OP); \ +} while (0) + +#define EMIT_ARITH( OP, N ) \ +do { \ + i915_emit_arith( p, \ + OP, \ + get_result_vector( p, inst ), \ + get_result_flags( inst ), 0, \ + (N<1)?0:src_vector( p, &inst->SrcReg[0], program), \ + (N<2)?0:src_vector( p, &inst->SrcReg[1], program), \ + (N<3)?0:src_vector( p, &inst->SrcReg[2], program)); \ +} while (0) + +#define EMIT_1ARG_ARITH( OP ) EMIT_ARITH( OP, 1 ) +#define EMIT_2ARG_ARITH( OP ) EMIT_ARITH( OP, 2 ) +#define EMIT_3ARG_ARITH( OP ) EMIT_ARITH( OP, 3 ) + + +/* Possible concerns: + * + * SIN, COS -- could use another taylor step? + * LIT -- results seem a little different to sw mesa + * LOG -- different to mesa on negative numbers, but this is conformant. + * + * Parse failures -- Mesa doesn't currently give a good indication + * internally whether a particular program string parsed or not. This + * can lead to confusion -- hopefully we cope with it ok now. + * + */ +static void +upload_program(struct i915_fragment_program *p) +{ + const struct gl_fragment_program *program = + p->ctx->FragmentProgram._Current; + const struct prog_instruction *inst = program->Base.Instructions; + +/* _mesa_debug_fp_inst(program->Base.NumInstructions, inst); */ + + /* Is this a parse-failed program? Ensure a valid program is + * loaded, as the flagging of an error isn't sufficient to stop + * this being uploaded to hardware. + */ + if (inst[0].Opcode == OPCODE_END) { + GLuint tmp = i915_get_utemp(p); + i915_emit_arith(p, + A0_MOV, + UREG(REG_TYPE_OC, 0), + A0_DEST_CHANNEL_ALL, 0, + swizzle(tmp, ONE, ZERO, ONE, ONE), 0, 0); + return; + } + + while (1) { + GLuint src0, src1, src2, flags; + GLuint tmp = 0; + + switch (inst->Opcode) { + case OPCODE_ABS: + src0 = src_vector(p, &inst->SrcReg[0], program); + i915_emit_arith(p, + A0_MAX, + get_result_vector(p, inst), + get_result_flags(inst), 0, + src0, negate(src0, 1, 1, 1, 1), 0); + break; + + case OPCODE_ADD: + EMIT_2ARG_ARITH(A0_ADD); + break; + + case OPCODE_CMP: + src0 = src_vector(p, &inst->SrcReg[0], program); + src1 = src_vector(p, &inst->SrcReg[1], program); + src2 = src_vector(p, &inst->SrcReg[2], program); + i915_emit_arith(p, A0_CMP, get_result_vector(p, inst), get_result_flags(inst), 0, src0, src2, src1); /* NOTE: order of src2, src1 */ + break; + + case OPCODE_COS: + src0 = src_vector(p, &inst->SrcReg[0], program); + tmp = i915_get_utemp(p); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_X, 0, + src0, i915_emit_const1f(p, 1.0 / (M_PI * 2)), 0); + + i915_emit_arith(p, A0_MOD, tmp, A0_DEST_CHANNEL_X, 0, tmp, 0, 0); + + /* By choosing different taylor constants, could get rid of this mul: + */ + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_X, 0, + tmp, i915_emit_const1f(p, (M_PI * 2)), 0); + + /* + * t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1 + * t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, 1 + * t0 = MUL t0.xxz1 t0.z111 ; x^6 x^4 x^2 1 + * result = DP4 t0, cos_constants + */ + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_XY, 0, + swizzle(tmp, X, X, ONE, ONE), + swizzle(tmp, X, ONE, ONE, ONE), 0); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_XYZ, 0, + swizzle(tmp, X, Y, X, ONE), + swizzle(tmp, X, X, ONE, ONE), 0); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_XYZ, 0, + swizzle(tmp, X, X, Z, ONE), + swizzle(tmp, Z, ONE, ONE, ONE), 0); + + i915_emit_arith(p, + A0_DP4, + get_result_vector(p, inst), + get_result_flags(inst), 0, + swizzle(tmp, ONE, Z, Y, X), + i915_emit_const4fv(p, cos_constants), 0); + + break; + + case OPCODE_DP3: + EMIT_2ARG_ARITH(A0_DP3); + break; + + case OPCODE_DP4: + EMIT_2ARG_ARITH(A0_DP4); + break; + + case OPCODE_DPH: + src0 = src_vector(p, &inst->SrcReg[0], program); + src1 = src_vector(p, &inst->SrcReg[1], program); + + i915_emit_arith(p, + A0_DP4, + get_result_vector(p, inst), + get_result_flags(inst), 0, + swizzle(src0, X, Y, Z, ONE), src1, 0); + break; + + case OPCODE_DST: + src0 = src_vector(p, &inst->SrcReg[0], program); + src1 = src_vector(p, &inst->SrcReg[1], program); + + /* result[0] = 1 * 1; + * result[1] = a[1] * b[1]; + * result[2] = a[2] * 1; + * result[3] = 1 * b[3]; + */ + i915_emit_arith(p, + A0_MUL, + get_result_vector(p, inst), + get_result_flags(inst), 0, + swizzle(src0, ONE, Y, Z, ONE), + swizzle(src1, ONE, Y, ONE, W), 0); + break; + + case OPCODE_EX2: + src0 = src_vector(p, &inst->SrcReg[0], program); + + i915_emit_arith(p, + A0_EXP, + get_result_vector(p, inst), + get_result_flags(inst), 0, + swizzle(src0, X, X, X, X), 0, 0); + break; + + case OPCODE_FLR: + EMIT_1ARG_ARITH(A0_FLR); + break; + + case OPCODE_FRC: + EMIT_1ARG_ARITH(A0_FRC); + break; + + case OPCODE_KIL: + src0 = src_vector(p, &inst->SrcReg[0], program); + tmp = i915_get_utemp(p); + + i915_emit_texld(p, tmp, A0_DEST_CHANNEL_ALL, /* use a dummy dest reg */ + 0, src0, T0_TEXKILL); + break; + + case OPCODE_LG2: + src0 = src_vector(p, &inst->SrcReg[0], program); + + i915_emit_arith(p, + A0_LOG, + get_result_vector(p, inst), + get_result_flags(inst), 0, + swizzle(src0, X, X, X, X), 0, 0); + break; + + case OPCODE_LIT: + src0 = src_vector(p, &inst->SrcReg[0], program); + tmp = i915_get_utemp(p); + + /* tmp = max( a.xyzw, a.00zw ) + * XXX: Clamp tmp.w to -128..128 + * tmp.y = log(tmp.y) + * tmp.y = tmp.w * tmp.y + * tmp.y = exp(tmp.y) + * result = cmp (a.11-x1, a.1x01, a.1xy1 ) + */ + i915_emit_arith(p, A0_MAX, tmp, A0_DEST_CHANNEL_ALL, 0, + src0, swizzle(src0, ZERO, ZERO, Z, W), 0); + + i915_emit_arith(p, A0_LOG, tmp, A0_DEST_CHANNEL_Y, 0, + swizzle(tmp, Y, Y, Y, Y), 0, 0); + + i915_emit_arith(p, A0_MUL, tmp, A0_DEST_CHANNEL_Y, 0, + swizzle(tmp, ZERO, Y, ZERO, ZERO), + swizzle(tmp, ZERO, W, ZERO, ZERO), 0); + + i915_emit_arith(p, A0_EXP, tmp, A0_DEST_CHANNEL_Y, 0, + swizzle(tmp, Y, Y, Y, Y), 0, 0); + + i915_emit_arith(p, A0_CMP, + get_result_vector(p, inst), + get_result_flags(inst), 0, + negate(swizzle(tmp, ONE, ONE, X, ONE), 0, 0, 1, 0), + swizzle(tmp, ONE, X, ZERO, ONE), + swizzle(tmp, ONE, X, Y, ONE)); + + break; + + case OPCODE_LRP: + src0 = src_vector(p, &inst->SrcReg[0], program); + src1 = src_vector(p, &inst->SrcReg[1], program); + src2 = src_vector(p, &inst->SrcReg[2], program); + flags = get_result_flags(inst); + tmp = i915_get_utemp(p); + + /* b*a + c*(1-a) + * + * b*a + c - ca + * + * tmp = b*a + c, + * result = (-c)*a + tmp + */ + i915_emit_arith(p, A0_MAD, tmp, + flags & A0_DEST_CHANNEL_ALL, 0, src1, src0, src2); + + i915_emit_arith(p, A0_MAD, + get_result_vector(p, inst), + flags, 0, negate(src2, 1, 1, 1, 1), src0, tmp); + break; + + case OPCODE_MAD: + EMIT_3ARG_ARITH(A0_MAD); + break; + + case OPCODE_MAX: + EMIT_2ARG_ARITH(A0_MAX); + break; + + case OPCODE_MIN: + src0 = src_vector(p, &inst->SrcReg[0], program); + src1 = src_vector(p, &inst->SrcReg[1], program); + tmp = i915_get_utemp(p); + flags = get_result_flags(inst); + + i915_emit_arith(p, + A0_MAX, + tmp, flags & A0_DEST_CHANNEL_ALL, 0, + negate(src0, 1, 1, 1, 1), + negate(src1, 1, 1, 1, 1), 0); + + i915_emit_arith(p, + A0_MOV, + get_result_vector(p, inst), + flags, 0, negate(tmp, 1, 1, 1, 1), 0, 0); + break; + + case OPCODE_MOV: + EMIT_1ARG_ARITH(A0_MOV); + break; + + case OPCODE_MUL: + EMIT_2ARG_ARITH(A0_MUL); + break; + + case OPCODE_POW: + src0 = src_vector(p, &inst->SrcReg[0], program); + src1 = src_vector(p, &inst->SrcReg[1], program); + tmp = i915_get_utemp(p); + flags = get_result_flags(inst); + + /* XXX: masking on intermediate values, here and elsewhere. + */ + i915_emit_arith(p, + A0_LOG, + tmp, A0_DEST_CHANNEL_X, 0, + swizzle(src0, X, X, X, X), 0, 0); + + i915_emit_arith(p, A0_MUL, tmp, A0_DEST_CHANNEL_X, 0, tmp, src1, 0); + + + i915_emit_arith(p, + A0_EXP, + get_result_vector(p, inst), + flags, 0, swizzle(tmp, X, X, X, X), 0, 0); + + break; + + case OPCODE_RCP: + src0 = src_vector(p, &inst->SrcReg[0], program); + + i915_emit_arith(p, + A0_RCP, + get_result_vector(p, inst), + get_result_flags(inst), 0, + swizzle(src0, X, X, X, X), 0, 0); + break; + + case OPCODE_RSQ: + + src0 = src_vector(p, &inst->SrcReg[0], program); + + i915_emit_arith(p, + A0_RSQ, + get_result_vector(p, inst), + get_result_flags(inst), 0, + swizzle(src0, X, X, X, X), 0, 0); + break; + + case OPCODE_SCS: + src0 = src_vector(p, &inst->SrcReg[0], program); + tmp = i915_get_utemp(p); + + /* + * t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1 + * t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, x + * t1 = MUL t0.xyyw t0.yz11 ; x^7 x^5 x^3 x + * scs.x = DP4 t1, sin_constants + * t1 = MUL t0.xxz1 t0.z111 ; x^6 x^4 x^2 1 + * scs.y = DP4 t1, cos_constants + */ + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_XY, 0, + swizzle(src0, X, X, ONE, ONE), + swizzle(src0, X, ONE, ONE, ONE), 0); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_ALL, 0, + swizzle(tmp, X, Y, X, Y), + swizzle(tmp, X, X, ONE, ONE), 0); + + if (inst->DstReg.WriteMask & WRITEMASK_Y) { + GLuint tmp1; + + if (inst->DstReg.WriteMask & WRITEMASK_X) + tmp1 = i915_get_utemp(p); + else + tmp1 = tmp; + + i915_emit_arith(p, + A0_MUL, + tmp1, A0_DEST_CHANNEL_ALL, 0, + swizzle(tmp, X, Y, Y, W), + swizzle(tmp, X, Z, ONE, ONE), 0); + + i915_emit_arith(p, + A0_DP4, + get_result_vector(p, inst), + A0_DEST_CHANNEL_Y, 0, + swizzle(tmp1, W, Z, Y, X), + i915_emit_const4fv(p, sin_constants), 0); + } + + if (inst->DstReg.WriteMask & WRITEMASK_X) { + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_XYZ, 0, + swizzle(tmp, X, X, Z, ONE), + swizzle(tmp, Z, ONE, ONE, ONE), 0); + + i915_emit_arith(p, + A0_DP4, + get_result_vector(p, inst), + A0_DEST_CHANNEL_X, 0, + swizzle(tmp, ONE, Z, Y, X), + i915_emit_const4fv(p, cos_constants), 0); + } + break; + + case OPCODE_SGE: + EMIT_2ARG_ARITH(A0_SGE); + break; + + case OPCODE_SIN: + src0 = src_vector(p, &inst->SrcReg[0], program); + tmp = i915_get_utemp(p); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_X, 0, + src0, i915_emit_const1f(p, 1.0 / (M_PI * 2)), 0); + + i915_emit_arith(p, A0_MOD, tmp, A0_DEST_CHANNEL_X, 0, tmp, 0, 0); + + /* By choosing different taylor constants, could get rid of this mul: + */ + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_X, 0, + tmp, i915_emit_const1f(p, (M_PI * 2)), 0); + + /* + * t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1 + * t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, x + * t1 = MUL t0.xyyw t0.yz11 ; x^7 x^5 x^3 x + * result = DP4 t1.wzyx, sin_constants + */ + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_XY, 0, + swizzle(tmp, X, X, ONE, ONE), + swizzle(tmp, X, ONE, ONE, ONE), 0); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_ALL, 0, + swizzle(tmp, X, Y, X, Y), + swizzle(tmp, X, X, ONE, ONE), 0); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_ALL, 0, + swizzle(tmp, X, Y, Y, W), + swizzle(tmp, X, Z, ONE, ONE), 0); + + i915_emit_arith(p, + A0_DP4, + get_result_vector(p, inst), + get_result_flags(inst), 0, + swizzle(tmp, W, Z, Y, X), + i915_emit_const4fv(p, sin_constants), 0); + break; + + case OPCODE_SLT: + EMIT_2ARG_ARITH(A0_SLT); + break; + + case OPCODE_SUB: + src0 = src_vector(p, &inst->SrcReg[0], program); + src1 = src_vector(p, &inst->SrcReg[1], program); + + i915_emit_arith(p, + A0_ADD, + get_result_vector(p, inst), + get_result_flags(inst), 0, + src0, negate(src1, 1, 1, 1, 1), 0); + break; + + case OPCODE_SWZ: + EMIT_1ARG_ARITH(A0_MOV); /* extended swizzle handled natively */ + break; + + case OPCODE_TEX: + EMIT_TEX(T0_TEXLD); + break; + + case OPCODE_TXB: + EMIT_TEX(T0_TEXLDB); + break; + + case OPCODE_TXP: + EMIT_TEX(T0_TEXLDP); + break; + + case OPCODE_XPD: + /* Cross product: + * result.x = src0.y * src1.z - src0.z * src1.y; + * result.y = src0.z * src1.x - src0.x * src1.z; + * result.z = src0.x * src1.y - src0.y * src1.x; + * result.w = undef; + */ + src0 = src_vector(p, &inst->SrcReg[0], program); + src1 = src_vector(p, &inst->SrcReg[1], program); + tmp = i915_get_utemp(p); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_ALL, 0, + swizzle(src0, Z, X, Y, ONE), + swizzle(src1, Y, Z, X, ONE), 0); + + i915_emit_arith(p, + A0_MAD, + get_result_vector(p, inst), + get_result_flags(inst), 0, + swizzle(src0, Y, Z, X, ONE), + swizzle(src1, Z, X, Y, ONE), + negate(tmp, 1, 1, 1, 0)); + break; + + case OPCODE_END: + return; + + default: + i915_program_error(p, "bad opcode"); + return; + } + + inst++; + i915_release_utemps(p); + } +} + +/* Rather than trying to intercept and jiggle depth writes during + * emit, just move the value into its correct position at the end of + * the program: + */ +static void +fixup_depth_write(struct i915_fragment_program *p) +{ + if (p->depth_written) { + GLuint depth = UREG(REG_TYPE_OD, 0); + + i915_emit_arith(p, + A0_MOV, + depth, A0_DEST_CHANNEL_W, 0, + swizzle(depth, X, Y, Z, Z), 0, 0); + } +} + + +#define FRAG_BIT_TEX(n) (FRAG_BIT_TEX0 << (n)) + + +static void +check_wpos(struct i915_fragment_program *p) +{ + GLuint inputs = p->FragProg.Base.InputsRead; + GLint i; + + p->wpos_tex = -1; + + for (i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) { + if (inputs & FRAG_BIT_TEX(i)) + continue; + else if (inputs & FRAG_BIT_WPOS) { + p->wpos_tex = i; + inputs &= ~FRAG_BIT_WPOS; + } + } + + if (inputs & FRAG_BIT_WPOS) { + i915_program_error(p, "No free texcoord for wpos value"); + } +} + + +static void +translate_program(struct i915_fragment_program *p) +{ + struct i915_context *i915 = I915_CONTEXT(p->ctx); + + i915_init_program(i915, p); + check_wpos(p); + upload_program(p); + fixup_depth_write(p); + i915_fini_program(p); + + p->translated = 1; +} + + +static void +track_params(struct i915_fragment_program *p) +{ + GLint i; + + if (p->nr_params) + _mesa_load_state_parameters(p->ctx, p->FragProg.Base.Parameters); + + for (i = 0; i < p->nr_params; i++) { + GLint reg = p->param[i].reg; + COPY_4V(p->constant[reg], p->param[i].values); + } + + p->params_uptodate = 1; + p->on_hardware = 0; /* overkill */ +} + + +static void +i915BindProgram(GLcontext * ctx, GLenum target, struct gl_program *prog) +{ + if (target == GL_FRAGMENT_PROGRAM_ARB) { + struct i915_context *i915 = I915_CONTEXT(ctx); + struct i915_fragment_program *p = (struct i915_fragment_program *) prog; + + if (i915->current_program == p) + return; + + if (i915->current_program) { + i915->current_program->on_hardware = 0; + i915->current_program->params_uptodate = 0; + } + + i915->current_program = p; + + assert(p->on_hardware == 0); + assert(p->params_uptodate == 0); + + /* Hack: make sure fog is correctly enabled according to this + * fragment program's fog options. + */ + ctx->Driver.Enable(ctx, GL_FRAGMENT_PROGRAM_ARB, + ctx->FragmentProgram.Enabled); + } +} + +static struct gl_program * +i915NewProgram(GLcontext * ctx, GLenum target, GLuint id) +{ + switch (target) { + case GL_VERTEX_PROGRAM_ARB: + return _mesa_init_vertex_program(ctx, CALLOC_STRUCT(gl_vertex_program), + target, id); + + case GL_FRAGMENT_PROGRAM_ARB:{ + struct i915_fragment_program *prog = + CALLOC_STRUCT(i915_fragment_program); + if (prog) { + i915_init_program(I915_CONTEXT(ctx), prog); + + return _mesa_init_fragment_program(ctx, &prog->FragProg, + target, id); + } + else + return NULL; + } + + default: + /* Just fallback: + */ + return _mesa_new_program(ctx, target, id); + } +} + +static void +i915DeleteProgram(GLcontext * ctx, struct gl_program *prog) +{ + if (prog->Target == GL_FRAGMENT_PROGRAM_ARB) { + struct i915_context *i915 = I915_CONTEXT(ctx); + struct i915_fragment_program *p = (struct i915_fragment_program *) prog; + + if (i915->current_program == p) + i915->current_program = 0; + } + + _mesa_delete_program(ctx, prog); +} + + +static GLboolean +i915IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog) +{ + if (target == GL_FRAGMENT_PROGRAM_ARB) { + struct i915_fragment_program *p = (struct i915_fragment_program *) prog; + + if (!p->translated) + translate_program(p); + + return !p->error; + } + else + return GL_TRUE; +} + +static void +i915ProgramStringNotify(GLcontext * ctx, + GLenum target, struct gl_program *prog) +{ + if (target == GL_FRAGMENT_PROGRAM_ARB) { + struct i915_fragment_program *p = (struct i915_fragment_program *) prog; + p->translated = 0; + + /* Hack: make sure fog is correctly enabled according to this + * fragment program's fog options. + */ + ctx->Driver.Enable(ctx, GL_FRAGMENT_PROGRAM_ARB, + ctx->FragmentProgram.Enabled); + } + + _tnl_program_string(ctx, target, prog); +} + + +void +i915ValidateFragmentProgram(struct i915_context *i915) +{ + GLcontext *ctx = &i915->intel.ctx; + struct intel_context *intel = intel_context(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + + struct i915_fragment_program *p = + (struct i915_fragment_program *) ctx->FragmentProgram._Current; + + const GLuint inputsRead = p->FragProg.Base.InputsRead; + GLuint s4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_VFMT_MASK; + GLuint s2 = S2_TEXCOORD_NONE; + int i, offset = 0; + + if (i915->current_program != p) { + if (i915->current_program) { + i915->current_program->on_hardware = 0; + i915->current_program->params_uptodate = 0; + } + + i915->current_program = p; + } + + + /* Important: + */ + VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr; + + if (!p->translated) + translate_program(p); + + intel->vertex_attr_count = 0; + intel->wpos_offset = 0; + intel->wpos_size = 0; + intel->coloroffset = 0; + intel->specoffset = 0; + + if (inputsRead & FRAG_BITS_TEX_ANY) { + EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, S4_VFMT_XYZW, 16); + } + else { + EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, S4_VFMT_XYZ, 12); + } + + if (inputsRead & FRAG_BIT_COL0) { + intel->coloroffset = offset / 4; + EMIT_ATTR(_TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, S4_VFMT_COLOR, 4); + } + + if ((inputsRead & (FRAG_BIT_COL1 | FRAG_BIT_FOGC)) || + i915->vertex_fog != I915_FOG_NONE) { + + if (inputsRead & FRAG_BIT_COL1) { + intel->specoffset = offset / 4; + EMIT_ATTR(_TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, S4_VFMT_SPEC_FOG, 3); + } + else + EMIT_PAD(3); + + if ((inputsRead & FRAG_BIT_FOGC) || i915->vertex_fog != I915_FOG_NONE) + EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1UB_1F, S4_VFMT_SPEC_FOG, 1); + else + EMIT_PAD(1); + } + +#if 0 + if ((inputsRead & FRAG_BIT_FOGC) || i915->vertex_fog != I915_FOG_NONE) { + EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1F, S4_VFMT_FOG_PARAM, 4); + } +#endif + + for (i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) { + if (inputsRead & FRAG_BIT_TEX(i)) { + int sz = VB->TexCoordPtr[i]->size; + + s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK); + s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(sz)); + + EMIT_ATTR(_TNL_ATTRIB_TEX0 + i, EMIT_SZ(sz), 0, sz * 4); + } + else if (i == p->wpos_tex) { + + /* If WPOS is required, duplicate the XYZ position data in an + * unused texture coordinate: + */ + s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK); + s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(3)); + + intel->wpos_offset = offset; + intel->wpos_size = 3 * sizeof(GLuint); + + EMIT_PAD(intel->wpos_size); + } + } + + if (s2 != i915->state.Ctx[I915_CTXREG_LIS2] || + s4 != i915->state.Ctx[I915_CTXREG_LIS4]) { + int k; + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + + /* Must do this *after* statechange, so as not to affect + * buffered vertices reliant on the old state: + */ + intel->vertex_size = _tnl_install_attrs(&intel->ctx, + intel->vertex_attrs, + intel->vertex_attr_count, + intel->ViewportMatrix.m, 0); + + intel->vertex_size >>= 2; + + i915->state.Ctx[I915_CTXREG_LIS2] = s2; + i915->state.Ctx[I915_CTXREG_LIS4] = s4; + + k = intel->vtbl.check_vertex_size(intel, intel->vertex_size); + assert(k); + } + + if (!p->params_uptodate) + track_params(p); + + if (!p->on_hardware) + i915_upload_program(i915, p); +} + +void +i915InitFragProgFuncs(struct dd_function_table *functions) +{ + functions->BindProgram = i915BindProgram; + functions->NewProgram = i915NewProgram; + functions->DeleteProgram = i915DeleteProgram; + functions->IsProgramNative = i915IsProgramNative; + functions->ProgramStringNotify = i915ProgramStringNotify; +} diff --git a/src/mesa/drivers/dri/i915tex/i915_metaops.c b/src/mesa/drivers/dri/i915tex/i915_metaops.c new file mode 100644 index 0000000000..3ab62bc806 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_metaops.c @@ -0,0 +1,509 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#include "glheader.h" +#include "enums.h" +#include "mtypes.h" +#include "macros.h" +#include "utils.h" + +#include "intel_screen.h" +#include "intel_batchbuffer.h" +#include "intel_ioctl.h" +#include "intel_regions.h" +#include "intel_rotate.h" + +#include "i915_context.h" +#include "i915_reg.h" + +/* We touch almost everything: + */ +#define ACTIVE (I915_UPLOAD_INVARIENT | \ + I915_UPLOAD_CTX | \ + I915_UPLOAD_BUFFERS | \ + I915_UPLOAD_STIPPLE | \ + I915_UPLOAD_PROGRAM | \ + I915_UPLOAD_FOG | \ + I915_UPLOAD_TEX(0)) + +#define SET_STATE( i915, STATE ) \ +do { \ + i915->current->emitted &= ~ACTIVE; \ + i915->current = &i915->STATE; \ + i915->current->emitted &= ~ACTIVE; \ +} while (0) + + +static void +meta_no_stencil_write(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + + /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE ) + */ + i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_TEST_ENABLE | + S5_STENCIL_WRITE_ENABLE); + + i915->meta.emitted &= ~I915_UPLOAD_CTX; +} + +static void +meta_no_depth_write(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + + /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) + */ + i915->meta.Ctx[I915_CTXREG_LIS6] &= ~(S6_DEPTH_TEST_ENABLE | + S6_DEPTH_WRITE_ENABLE); + + i915->meta.emitted &= ~I915_UPLOAD_CTX; +} + +static void +meta_depth_replace(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + + /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_TRUE ) + * ctx->Driver.DepthMask( ctx, GL_TRUE ) + */ + i915->meta.Ctx[I915_CTXREG_LIS6] |= (S6_DEPTH_TEST_ENABLE | + S6_DEPTH_WRITE_ENABLE); + + /* ctx->Driver.DepthFunc( ctx, GL_REPLACE ) + */ + i915->meta.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_FUNC_MASK; + i915->meta.Ctx[I915_CTXREG_LIS6] |= + COMPAREFUNC_ALWAYS << S6_DEPTH_TEST_FUNC_SHIFT; + + i915->meta.emitted &= ~I915_UPLOAD_CTX; +} + + +/* Set stencil unit to replace always with the reference value. + */ +static void +meta_stencil_replace(struct intel_context *intel, + GLuint s_mask, GLuint s_clear) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + GLuint op = STENCILOP_REPLACE; + GLuint func = COMPAREFUNC_ALWAYS; + + /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_TRUE ) + */ + i915->meta.Ctx[I915_CTXREG_LIS5] |= (S5_STENCIL_TEST_ENABLE | + S5_STENCIL_WRITE_ENABLE); + + /* ctx->Driver.StencilMask( ctx, s_mask ) + */ + i915->meta.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; + + i915->meta.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | + STENCIL_WRITE_MASK(s_mask)); + + /* ctx->Driver.StencilOp( ctx, GL_REPLACE, GL_REPLACE, GL_REPLACE ) + */ + i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_FAIL_MASK | + S5_STENCIL_PASS_Z_FAIL_MASK | + S5_STENCIL_PASS_Z_PASS_MASK); + + i915->meta.Ctx[I915_CTXREG_LIS5] |= ((op << S5_STENCIL_FAIL_SHIFT) | + (op << S5_STENCIL_PASS_Z_FAIL_SHIFT) | + (op << S5_STENCIL_PASS_Z_PASS_SHIFT)); + + + /* ctx->Driver.StencilFunc( ctx, GL_ALWAYS, s_ref, ~0 ) + */ + i915->meta.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; + i915->meta.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | + STENCIL_TEST_MASK(0xff)); + + i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_REF_MASK | + S5_STENCIL_TEST_FUNC_MASK); + + i915->meta.Ctx[I915_CTXREG_LIS5] |= ((s_clear << S5_STENCIL_REF_SHIFT) | + (func << S5_STENCIL_TEST_FUNC_SHIFT)); + + + i915->meta.emitted &= ~I915_UPLOAD_CTX; +} + + +static void +meta_color_mask(struct intel_context *intel, GLboolean state) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + const GLuint mask = (S5_WRITEDISABLE_RED | + S5_WRITEDISABLE_GREEN | + S5_WRITEDISABLE_BLUE | S5_WRITEDISABLE_ALPHA); + + /* Copy colormask state from "regular" hw context. + */ + if (state) { + i915->meta.Ctx[I915_CTXREG_LIS5] &= ~mask; + i915->meta.Ctx[I915_CTXREG_LIS5] |= + (i915->state.Ctx[I915_CTXREG_LIS5] & mask); + } + else + i915->meta.Ctx[I915_CTXREG_LIS5] |= mask; + + i915->meta.emitted &= ~I915_UPLOAD_CTX; +} + + + +static void +meta_import_pixel_state(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + memcpy(i915->meta.Fog, i915->state.Fog, I915_FOG_SETUP_SIZE * 4); + + i915->meta.Ctx[I915_CTXREG_LIS5] = i915->state.Ctx[I915_CTXREG_LIS5]; + i915->meta.Ctx[I915_CTXREG_LIS6] = i915->state.Ctx[I915_CTXREG_LIS6]; + i915->meta.Ctx[I915_CTXREG_STATE4] = i915->state.Ctx[I915_CTXREG_STATE4]; + i915->meta.Ctx[I915_CTXREG_BLENDCOLOR1] = + i915->state.Ctx[I915_CTXREG_BLENDCOLOR1]; + i915->meta.Ctx[I915_CTXREG_IAB] = i915->state.Ctx[I915_CTXREG_IAB]; + + i915->meta.Buffer[I915_DESTREG_SENABLE] = + i915->state.Buffer[I915_DESTREG_SENABLE]; + i915->meta.Buffer[I915_DESTREG_SR1] = i915->state.Buffer[I915_DESTREG_SR1]; + i915->meta.Buffer[I915_DESTREG_SR2] = i915->state.Buffer[I915_DESTREG_SR2]; + + i915->meta.emitted &= ~I915_UPLOAD_FOG; + i915->meta.emitted &= ~I915_UPLOAD_BUFFERS; + i915->meta.emitted &= ~I915_UPLOAD_CTX; +} + + + + +#define REG( type, nr ) (((type)<<5)|(nr)) + +#define REG_R(x) REG(REG_TYPE_R, x) +#define REG_T(x) REG(REG_TYPE_T, x) +#define REG_CONST(x) REG(REG_TYPE_CONST, x) +#define REG_S(x) REG(REG_TYPE_S, x) +#define REG_OC REG(REG_TYPE_OC, 0) +#define REG_OD REG(REG_TYPE_OD, 0) +#define REG_U(x) REG(REG_TYPE_U, x) + +#define REG_T_DIFFUSE REG(REG_TYPE_T, T_DIFFUSE) +#define REG_T_SPECULAR REG(REG_TYPE_T, T_SPECULAR) +#define REG_T_FOG_W REG(REG_TYPE_T, T_FOG_W) +#define REG_T_TEX(x) REG(REG_TYPE_T, x) + + +#define A0_DEST_REG( reg ) ( (reg) << A0_DEST_NR_SHIFT ) +#define A0_SRC0_REG( reg ) ( (reg) << A0_SRC0_NR_SHIFT ) +#define A1_SRC1_REG( reg ) ( (reg) << A1_SRC1_NR_SHIFT ) +#define A1_SRC2_REG( reg ) ( (reg) << A1_SRC2_NR_SHIFT ) +#define A2_SRC2_REG( reg ) ( (reg) << A2_SRC2_NR_SHIFT ) +#define D0_DECL_REG( reg ) ( (reg) << D0_NR_SHIFT ) +#define T0_DEST_REG( reg ) ( (reg) << T0_DEST_NR_SHIFT ) + +#define T0_SAMPLER( unit ) ((unit)<ctx); + + static const GLuint prog[] = { + _3DSTATE_PIXEL_SHADER_PROGRAM, + + /* Declare incoming diffuse color: + */ + (D0_DCL | D0_DECL_REG(REG_T_DIFFUSE) | D0_CHANNEL_ALL), + D1_MBZ, + D2_MBZ, + + /* output-color = mov(t_diffuse) + */ + (A0_MOV | + A0_DEST_REG(REG_OC) | + A0_DEST_CHANNEL_ALL | A0_SRC0_REG(REG_T_DIFFUSE)), + (A1_SRC0_XYZW), + 0, + }; + + + memcpy(i915->meta.Program, prog, sizeof(prog)); + i915->meta.ProgramSize = sizeof(prog) / sizeof(*prog); + i915->meta.Program[0] |= i915->meta.ProgramSize - 2; + i915->meta.emitted &= ~I915_UPLOAD_PROGRAM; +} + +static void +meta_texture_blend_replace(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + + static const GLuint prog[] = { + _3DSTATE_PIXEL_SHADER_PROGRAM, + + /* Declare the sampler: + */ + (D0_DCL | D0_DECL_REG(REG_S(0)) | D0_SAMPLE_TYPE_2D | D0_CHANNEL_NONE), + D1_MBZ, + D2_MBZ, + + /* Declare the interpolated texture coordinate: + */ + (D0_DCL | D0_DECL_REG(REG_T_TEX(0)) | D0_CHANNEL_ALL), + D1_MBZ, + D2_MBZ, + + /* output-color = texld(sample0, texcoord0) + */ + (T0_TEXLD | T0_DEST_REG(REG_OC) | T0_SAMPLER(0)), + T1_ADDRESS_REG(REG_TYPE_T, 0), + T2_MBZ + }; + + memcpy(i915->meta.Program, prog, sizeof(prog)); + i915->meta.ProgramSize = sizeof(prog) / sizeof(*prog); + i915->meta.Program[0] |= i915->meta.ProgramSize - 2; + i915->meta.emitted &= ~I915_UPLOAD_PROGRAM; +} + + + + + +/* Set up an arbitary piece of memory as a rectangular texture + * (including the front or back buffer). + */ +static GLboolean +meta_tex_rect_source(struct intel_context *intel, + struct _DriBufferObject *buffer, + GLuint offset, + GLuint pitch, GLuint height, GLenum format, GLenum type) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + GLuint unit = 0; + GLint numLevels = 1; + GLuint *state = i915->meta.Tex[0]; + GLuint textureFormat; + GLuint cpp; + + /* A full implementation of this would do the upload through + * glTexImage2d, and get all the conversion operations at that + * point. We are restricted, but still at least have access to the + * fragment program swizzle. + */ + switch (format) { + case GL_BGRA: + switch (type) { + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_UNSIGNED_BYTE: + textureFormat = (MAPSURF_32BIT | MT_32BIT_ARGB8888); + cpp = 4; + break; + default: + return GL_FALSE; + } + break; + case GL_RGBA: + switch (type) { + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_UNSIGNED_BYTE: + textureFormat = (MAPSURF_32BIT | MT_32BIT_ABGR8888); + cpp = 4; + break; + default: + return GL_FALSE; + } + break; + case GL_BGR: + switch (type) { + case GL_UNSIGNED_SHORT_5_6_5_REV: + textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); + cpp = 2; + break; + default: + return GL_FALSE; + } + break; + case GL_RGB: + switch (type) { + case GL_UNSIGNED_SHORT_5_6_5: + textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); + cpp = 2; + break; + default: + return GL_FALSE; + } + break; + + default: + return GL_FALSE; + } + + + if ((pitch * cpp) & 3) { + _mesa_printf("%s: texture is not dword pitch\n", __FUNCTION__); + return GL_FALSE; + } + +/* intel_region_release(&i915->meta.tex_region[0]); */ +/* intel_region_reference(&i915->meta.tex_region[0], region); */ + i915->meta.tex_buffer[0] = buffer; + i915->meta.tex_offset[0] = offset; + + state[I915_TEXREG_MS3] = (((height - 1) << MS3_HEIGHT_SHIFT) | + ((pitch - 1) << MS3_WIDTH_SHIFT) | + textureFormat | MS3_USE_FENCE_REGS); + + state[I915_TEXREG_MS4] = (((((pitch * cpp) / 4) - 1) << MS4_PITCH_SHIFT) | + MS4_CUBE_FACE_ENA_MASK | + ((((numLevels - 1) * 4)) << MS4_MAX_LOD_SHIFT)); + + state[I915_TEXREG_SS2] = ((FILTER_NEAREST << SS2_MIN_FILTER_SHIFT) | + (MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT) | + (FILTER_NEAREST << SS2_MAG_FILTER_SHIFT)); + + state[I915_TEXREG_SS3] = ((TEXCOORDMODE_WRAP << SS3_TCX_ADDR_MODE_SHIFT) | + (TEXCOORDMODE_WRAP << SS3_TCY_ADDR_MODE_SHIFT) | + (TEXCOORDMODE_WRAP << SS3_TCZ_ADDR_MODE_SHIFT) | + (unit << SS3_TEXTUREMAP_INDEX_SHIFT)); + + state[I915_TEXREG_SS4] = 0; + + i915->meta.emitted &= ~I915_UPLOAD_TEX(0); + return GL_TRUE; +} + + +/** + * Set the color and depth drawing region for meta ops. + */ +static void +meta_draw_region(struct intel_context *intel, + struct intel_region *color_region, + struct intel_region *depth_region) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + i915_state_draw_region(intel, &i915->meta, color_region, depth_region); +} + + +static void +set_vertex_format(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + + i915->meta.Ctx[I915_CTXREG_LIS2] = + (S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D) | + S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT) | + S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT) | + S2_TEXCOORD_FMT(3, TEXCOORDFMT_NOT_PRESENT) | + S2_TEXCOORD_FMT(4, TEXCOORDFMT_NOT_PRESENT) | + S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT) | + S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT) | + S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT)); + + i915->meta.Ctx[I915_CTXREG_LIS4] &= ~S4_VFMT_MASK; + + i915->meta.Ctx[I915_CTXREG_LIS4] |= (S4_VFMT_COLOR | S4_VFMT_XYZ); + + i915->meta.emitted &= ~I915_UPLOAD_CTX; +} + + + +/* Operations where the 3D engine is decoupled temporarily from the + * current GL state and used for other purposes than simply rendering + * incoming triangles. + */ +static void +install_meta_state(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + memcpy(&i915->meta, &i915->initial, sizeof(i915->meta)); + i915->meta.active = ACTIVE; + i915->meta.emitted = 0; + + SET_STATE(i915, meta); + set_vertex_format(intel); + meta_no_texture(intel); +} + +static void +leave_meta_state(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + intel_region_release(&i915->meta.draw_region); + intel_region_release(&i915->meta.depth_region); +/* intel_region_release(&i915->meta.tex_region[0]); */ + SET_STATE(i915, state); +} + + + +void +i915InitMetaFuncs(struct i915_context *i915) +{ + i915->intel.vtbl.install_meta_state = install_meta_state; + i915->intel.vtbl.leave_meta_state = leave_meta_state; + i915->intel.vtbl.meta_no_depth_write = meta_no_depth_write; + i915->intel.vtbl.meta_no_stencil_write = meta_no_stencil_write; + i915->intel.vtbl.meta_stencil_replace = meta_stencil_replace; + i915->intel.vtbl.meta_depth_replace = meta_depth_replace; + i915->intel.vtbl.meta_color_mask = meta_color_mask; + i915->intel.vtbl.meta_no_texture = meta_no_texture; + i915->intel.vtbl.meta_texture_blend_replace = meta_texture_blend_replace; + i915->intel.vtbl.meta_tex_rect_source = meta_tex_rect_source; + i915->intel.vtbl.meta_draw_region = meta_draw_region; + i915->intel.vtbl.meta_import_pixel_state = meta_import_pixel_state; +} diff --git a/src/mesa/drivers/dri/i915tex/i915_program.c b/src/mesa/drivers/dri/i915tex/i915_program.c new file mode 100644 index 0000000000..4fb56222c6 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_program.c @@ -0,0 +1,518 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#include + +#include "glheader.h" +#include "macros.h" +#include "enums.h" + +#include "tnl/t_context.h" +#include "intel_batchbuffer.h" + +#include "i915_reg.h" +#include "i915_context.h" +#include "i915_program.h" + + +#define A0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) +#define D0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) +#define T0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) +#define A0_SRC0( reg ) (((reg)&UREG_MASK)>>UREG_A0_SRC0_SHIFT_LEFT) +#define A1_SRC0( reg ) (((reg)&UREG_MASK)<>UREG_A1_SRC1_SHIFT_LEFT) +#define A2_SRC1( reg ) (((reg)&UREG_MASK)<>UREG_A2_SRC2_SHIFT_LEFT) + +/* These are special, and don't have swizzle/negate bits. + */ +#define T0_SAMPLER( reg ) (GET_UREG_NR(reg)<temp_flag); + if (!bit) { + fprintf(stderr, "%s: out of temporaries\n", __FILE__); + exit(1); + } + + p->temp_flag |= 1 << (bit - 1); + return UREG(REG_TYPE_R, (bit - 1)); +} + + +GLuint +i915_get_utemp(struct i915_fragment_program * p) +{ + int bit = ffs(~p->utemp_flag); + if (!bit) { + fprintf(stderr, "%s: out of temporaries\n", __FILE__); + exit(1); + } + + p->utemp_flag |= 1 << (bit - 1); + return UREG(REG_TYPE_U, (bit - 1)); +} + +void +i915_release_utemps(struct i915_fragment_program *p) +{ + p->utemp_flag = ~0x7; +} + + +GLuint +i915_emit_decl(struct i915_fragment_program *p, + GLuint type, GLuint nr, GLuint d0_flags) +{ + GLuint reg = UREG(type, nr); + + if (type == REG_TYPE_T) { + if (p->decl_t & (1 << nr)) + return reg; + + p->decl_t |= (1 << nr); + } + else if (type == REG_TYPE_S) { + if (p->decl_s & (1 << nr)) + return reg; + + p->decl_s |= (1 << nr); + } + else + return reg; + + *(p->decl++) = (D0_DCL | D0_DEST(reg) | d0_flags); + *(p->decl++) = D1_MBZ; + *(p->decl++) = D2_MBZ; + + p->nr_decl_insn++; + return reg; +} + +GLuint +i915_emit_arith(struct i915_fragment_program * p, + GLuint op, + GLuint dest, + GLuint mask, + GLuint saturate, GLuint src0, GLuint src1, GLuint src2) +{ + GLuint c[3]; + GLuint nr_const = 0; + + assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST); + dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)); + assert(dest); + + if (GET_UREG_TYPE(src0) == REG_TYPE_CONST) + c[nr_const++] = 0; + if (GET_UREG_TYPE(src1) == REG_TYPE_CONST) + c[nr_const++] = 1; + if (GET_UREG_TYPE(src2) == REG_TYPE_CONST) + c[nr_const++] = 2; + + /* Recursively call this function to MOV additional const values + * into temporary registers. Use utemp registers for this - + * currently shouldn't be possible to run out, but keep an eye on + * this. + */ + if (nr_const > 1) { + GLuint s[3], first, i, old_utemp_flag; + + s[0] = src0; + s[1] = src1; + s[2] = src2; + old_utemp_flag = p->utemp_flag; + + first = GET_UREG_NR(s[c[0]]); + for (i = 1; i < nr_const; i++) { + if (GET_UREG_NR(s[c[i]]) != first) { + GLuint tmp = i915_get_utemp(p); + + i915_emit_arith(p, A0_MOV, tmp, A0_DEST_CHANNEL_ALL, 0, + s[c[i]], 0, 0); + s[c[i]] = tmp; + } + } + + src0 = s[0]; + src1 = s[1]; + src2 = s[2]; + p->utemp_flag = old_utemp_flag; /* restore */ + } + + *(p->csr++) = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0)); + *(p->csr++) = (A1_SRC0(src0) | A1_SRC1(src1)); + *(p->csr++) = (A2_SRC1(src1) | A2_SRC2(src2)); + + p->nr_alu_insn++; + return dest; +} + +GLuint i915_emit_texld( struct i915_fragment_program *p, + GLuint dest, + GLuint destmask, + GLuint sampler, + GLuint coord, + GLuint op ) +{ + if (coord != UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord))) { + /* No real way to work around this in the general case - need to + * allocate and declare a new temporary register (a utemp won't + * do). Will fallback for now. + */ + i915_program_error(p, "Can't (yet) swizzle TEX arguments"); + return 0; + } + + /* Don't worry about saturate as we only support + */ + if (destmask != A0_DEST_CHANNEL_ALL) { + GLuint tmp = i915_get_utemp(p); + i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, op ); + i915_emit_arith( p, A0_MOV, dest, destmask, 0, tmp, 0, 0 ); + return dest; + } + else { + assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST); + assert(dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest))); + + if (GET_UREG_TYPE(coord) != REG_TYPE_T) { + p->nr_tex_indirect++; + } + + *(p->csr++) = (op | + T0_DEST( dest ) | + T0_SAMPLER( sampler )); + + *(p->csr++) = T1_ADDRESS_REG( coord ); + *(p->csr++) = T2_MBZ; + + p->nr_tex_insn++; + return dest; + } +} + + +GLuint +i915_emit_const1f(struct i915_fragment_program * p, GLfloat c0) +{ + GLint reg, idx; + + if (c0 == 0.0) + return swizzle(UREG(REG_TYPE_R, 0), ZERO, ZERO, ZERO, ZERO); + if (c0 == 1.0) + return swizzle(UREG(REG_TYPE_R, 0), ONE, ONE, ONE, ONE); + + for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { + if (p->constant_flags[reg] == I915_CONSTFLAG_PARAM) + continue; + for (idx = 0; idx < 4; idx++) { + if (!(p->constant_flags[reg] & (1 << idx)) || + p->constant[reg][idx] == c0) { + p->constant[reg][idx] = c0; + p->constant_flags[reg] |= 1 << idx; + if (reg + 1 > p->nr_constants) + p->nr_constants = reg + 1; + return swizzle(UREG(REG_TYPE_CONST, reg), idx, ZERO, ZERO, ONE); + } + } + } + + fprintf(stderr, "%s: out of constants\n", __FUNCTION__); + p->error = 1; + return 0; +} + +GLuint +i915_emit_const2f(struct i915_fragment_program * p, GLfloat c0, GLfloat c1) +{ + GLint reg, idx; + + if (c0 == 0.0) + return swizzle(i915_emit_const1f(p, c1), ZERO, X, Z, W); + if (c0 == 1.0) + return swizzle(i915_emit_const1f(p, c1), ONE, X, Z, W); + + if (c1 == 0.0) + return swizzle(i915_emit_const1f(p, c0), X, ZERO, Z, W); + if (c1 == 1.0) + return swizzle(i915_emit_const1f(p, c0), X, ONE, Z, W); + + for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { + if (p->constant_flags[reg] == 0xf || + p->constant_flags[reg] == I915_CONSTFLAG_PARAM) + continue; + for (idx = 0; idx < 3; idx++) { + if (!(p->constant_flags[reg] & (3 << idx))) { + p->constant[reg][idx] = c0; + p->constant[reg][idx + 1] = c1; + p->constant_flags[reg] |= 3 << idx; + if (reg + 1 > p->nr_constants) + p->nr_constants = reg + 1; + return swizzle(UREG(REG_TYPE_CONST, reg), idx, idx + 1, ZERO, + ONE); + } + } + } + + fprintf(stderr, "%s: out of constants\n", __FUNCTION__); + p->error = 1; + return 0; +} + + + +GLuint +i915_emit_const4f(struct i915_fragment_program * p, + GLfloat c0, GLfloat c1, GLfloat c2, GLfloat c3) +{ + GLint reg; + + for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { + if (p->constant_flags[reg] == 0xf && + p->constant[reg][0] == c0 && + p->constant[reg][1] == c1 && + p->constant[reg][2] == c2 && p->constant[reg][3] == c3) { + return UREG(REG_TYPE_CONST, reg); + } + else if (p->constant_flags[reg] == 0) { + p->constant[reg][0] = c0; + p->constant[reg][1] = c1; + p->constant[reg][2] = c2; + p->constant[reg][3] = c3; + p->constant_flags[reg] = 0xf; + if (reg + 1 > p->nr_constants) + p->nr_constants = reg + 1; + return UREG(REG_TYPE_CONST, reg); + } + } + + fprintf(stderr, "%s: out of constants\n", __FUNCTION__); + p->error = 1; + return 0; +} + + +GLuint +i915_emit_const4fv(struct i915_fragment_program * p, const GLfloat * c) +{ + return i915_emit_const4f(p, c[0], c[1], c[2], c[3]); +} + + +GLuint +i915_emit_param4fv(struct i915_fragment_program * p, const GLfloat * values) +{ + GLint reg, i; + + for (i = 0; i < p->nr_params; i++) { + if (p->param[i].values == values) + return UREG(REG_TYPE_CONST, p->param[i].reg); + } + + + for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { + if (p->constant_flags[reg] == 0) { + p->constant_flags[reg] = I915_CONSTFLAG_PARAM; + i = p->nr_params++; + + p->param[i].values = values; + p->param[i].reg = reg; + p->params_uptodate = 0; + + if (reg + 1 > p->nr_constants) + p->nr_constants = reg + 1; + return UREG(REG_TYPE_CONST, reg); + } + } + + fprintf(stderr, "%s: out of constants\n", __FUNCTION__); + p->error = 1; + return 0; +} + + + + +void +i915_program_error(struct i915_fragment_program *p, const char *msg) +{ + /* XXX we shouldn't print anything to stdout, record GL error or + * call _mesa_problem() + */ + fprintf(stderr, "%s\n", msg); + p->error = 1; +} + +void +i915_init_program(struct i915_context *i915, struct i915_fragment_program *p) +{ + GLcontext *ctx = &i915->intel.ctx; + TNLcontext *tnl = TNL_CONTEXT(ctx); + + p->translated = 0; + p->params_uptodate = 0; + p->on_hardware = 0; + p->error = 0; + + p->nr_tex_indirect = 1; /* correct? */ + p->nr_tex_insn = 0; + p->nr_alu_insn = 0; + p->nr_decl_insn = 0; + + p->ctx = ctx; + memset(p->constant_flags, 0, sizeof(p->constant_flags)); + + p->nr_constants = 0; + p->csr = p->program; + p->decl = p->declarations; + p->decl_s = 0; + p->decl_t = 0; + p->temp_flag = 0xffff000; + p->utemp_flag = ~0x7; + p->wpos_tex = -1; + p->depth_written = 0; + p->nr_params = 0; + + p->src_texture = UREG_BAD; + p->src_previous = UREG(REG_TYPE_T, T_DIFFUSE); + p->last_tex_stage = 0; + p->VB = &tnl->vb; + + *(p->decl++) = _3DSTATE_PIXEL_SHADER_PROGRAM; +} + + +void +i915_fini_program(struct i915_fragment_program *p) +{ + GLuint program_size = p->csr - p->program; + GLuint decl_size = p->decl - p->declarations; + + if (p->nr_tex_indirect > I915_MAX_TEX_INDIRECT) + i915_program_error(p, "Exceeded max nr indirect texture lookups"); + + if (p->nr_tex_insn > I915_MAX_TEX_INSN) + i915_program_error(p, "Exceeded max TEX instructions"); + + if (p->nr_alu_insn > I915_MAX_ALU_INSN) + i915_program_error(p, "Exceeded max ALU instructions"); + + if (p->nr_decl_insn > I915_MAX_DECL_INSN) + i915_program_error(p, "Exceeded max DECL instructions"); + + if (p->error) { + p->FragProg.Base.NumNativeInstructions = 0; + p->FragProg.NumNativeAluInstructions = 0; + p->FragProg.NumNativeTexInstructions = 0; + p->FragProg.NumNativeTexIndirections = 0; + } + else { + p->FragProg.Base.NumNativeInstructions = (p->nr_alu_insn + + p->nr_tex_insn + + p->nr_decl_insn); + p->FragProg.NumNativeAluInstructions = p->nr_alu_insn; + p->FragProg.NumNativeTexInstructions = p->nr_tex_insn; + p->FragProg.NumNativeTexIndirections = p->nr_tex_indirect; + } + + p->declarations[0] |= program_size + decl_size - 2; +} + +void +i915_upload_program(struct i915_context *i915, + struct i915_fragment_program *p) +{ + GLuint program_size = p->csr - p->program; + GLuint decl_size = p->decl - p->declarations; + + FALLBACK(&i915->intel, I915_FALLBACK_PROGRAM, p->error); + + /* Could just go straight to the batchbuffer from here: + */ + if (i915->state.ProgramSize != (program_size + decl_size) || + memcmp(i915->state.Program + decl_size, p->program, + program_size * sizeof(int)) != 0) { + I915_STATECHANGE(i915, I915_UPLOAD_PROGRAM); + memcpy(i915->state.Program, p->declarations, decl_size * sizeof(int)); + memcpy(i915->state.Program + decl_size, p->program, + program_size * sizeof(int)); + i915->state.ProgramSize = decl_size + program_size; + } + + /* Always seemed to get a failure if I used memcmp() to + * shortcircuit this state upload. Needs further investigation? + */ + if (p->nr_constants) { + GLuint nr = p->nr_constants; + + I915_ACTIVESTATE(i915, I915_UPLOAD_CONSTANTS, 1); + I915_STATECHANGE(i915, I915_UPLOAD_CONSTANTS); + + i915->state.Constant[0] = _3DSTATE_PIXEL_SHADER_CONSTANTS | ((nr) * 4); + i915->state.Constant[1] = (1 << (nr - 1)) | ((1 << (nr - 1)) - 1); + + memcpy(&i915->state.Constant[2], p->constant, 4 * sizeof(int) * (nr)); + i915->state.ConstantSize = 2 + (nr) * 4; + + if (0) { + GLuint i; + for (i = 0; i < nr; i++) { + fprintf(stderr, "const[%d]: %f %f %f %f\n", i, + p->constant[i][0], + p->constant[i][1], p->constant[i][2], p->constant[i][3]); + } + } + } + else { + I915_ACTIVESTATE(i915, I915_UPLOAD_CONSTANTS, 0); + } + + p->on_hardware = 1; +} diff --git a/src/mesa/drivers/dri/i915tex/i915_program.h b/src/mesa/drivers/dri/i915tex/i915_program.h new file mode 100644 index 0000000000..3c12b34f16 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_program.h @@ -0,0 +1,160 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + + +#ifndef I915_PROGRAM_H +#define I915_PROGRAM_H + +#include "i915_context.h" +#include "i915_reg.h" + + + +/* Having zero and one in here makes the definition of swizzle a lot + * easier. + */ +#define UREG_TYPE_SHIFT 29 +#define UREG_NR_SHIFT 24 +#define UREG_CHANNEL_X_NEGATE_SHIFT 23 +#define UREG_CHANNEL_X_SHIFT 20 +#define UREG_CHANNEL_Y_NEGATE_SHIFT 19 +#define UREG_CHANNEL_Y_SHIFT 16 +#define UREG_CHANNEL_Z_NEGATE_SHIFT 15 +#define UREG_CHANNEL_Z_SHIFT 12 +#define UREG_CHANNEL_W_NEGATE_SHIFT 11 +#define UREG_CHANNEL_W_SHIFT 8 +#define UREG_CHANNEL_ZERO_NEGATE_MBZ 5 +#define UREG_CHANNEL_ZERO_SHIFT 4 +#define UREG_CHANNEL_ONE_NEGATE_MBZ 1 +#define UREG_CHANNEL_ONE_SHIFT 0 + +#define UREG_BAD 0xffffffff /* not a valid ureg */ + +#define X SRC_X +#define Y SRC_Y +#define Z SRC_Z +#define W SRC_W +#define ZERO SRC_ZERO +#define ONE SRC_ONE + +/* Construct a ureg: + */ +#define UREG( type, nr ) (((type)<< UREG_TYPE_SHIFT) | \ + ((nr) << UREG_NR_SHIFT) | \ + (X << UREG_CHANNEL_X_SHIFT) | \ + (Y << UREG_CHANNEL_Y_SHIFT) | \ + (Z << UREG_CHANNEL_Z_SHIFT) | \ + (W << UREG_CHANNEL_W_SHIFT) | \ + (ZERO << UREG_CHANNEL_ZERO_SHIFT) | \ + (ONE << UREG_CHANNEL_ONE_SHIFT)) + +#define GET_CHANNEL_SRC( reg, channel ) ((reg<<(channel*4)) & (0xf<<20)) +#define CHANNEL_SRC( src, channel ) (src>>(channel*4)) + +#define GET_UREG_TYPE(reg) (((reg)>>UREG_TYPE_SHIFT)®_TYPE_MASK) +#define GET_UREG_NR(reg) (((reg)>>UREG_NR_SHIFT)®_NR_MASK) + + + +#define UREG_XYZW_CHANNEL_MASK 0x00ffff00 + +/* One neat thing about the UREG representation: + */ +static INLINE int +swizzle(int reg, int x, int y, int z, int w) +{ + return ((reg & ~UREG_XYZW_CHANNEL_MASK) | + CHANNEL_SRC(GET_CHANNEL_SRC(reg, x), 0) | + CHANNEL_SRC(GET_CHANNEL_SRC(reg, y), 1) | + CHANNEL_SRC(GET_CHANNEL_SRC(reg, z), 2) | + CHANNEL_SRC(GET_CHANNEL_SRC(reg, w), 3)); +} + +/* Another neat thing about the UREG representation: + */ +static INLINE int +negate(int reg, int x, int y, int z, int w) +{ + return reg ^ (((x & 1) << UREG_CHANNEL_X_NEGATE_SHIFT) | + ((y & 1) << UREG_CHANNEL_Y_NEGATE_SHIFT) | + ((z & 1) << UREG_CHANNEL_Z_NEGATE_SHIFT) | + ((w & 1) << UREG_CHANNEL_W_NEGATE_SHIFT)); +} + + +extern GLuint i915_get_temp(struct i915_fragment_program *p); +extern GLuint i915_get_utemp(struct i915_fragment_program *p); +extern void i915_release_utemps(struct i915_fragment_program *p); + + +extern GLuint i915_emit_texld(struct i915_fragment_program *p, + GLuint dest, + GLuint destmask, + GLuint sampler, GLuint coord, GLuint op); + +extern GLuint i915_emit_arith(struct i915_fragment_program *p, + GLuint op, + GLuint dest, + GLuint mask, + GLuint saturate, + GLuint src0, GLuint src1, GLuint src2); + +extern GLuint i915_emit_decl(struct i915_fragment_program *p, + GLuint type, GLuint nr, GLuint d0_flags); + + +extern GLuint i915_emit_const1f(struct i915_fragment_program *p, GLfloat c0); + +extern GLuint i915_emit_const2f(struct i915_fragment_program *p, + GLfloat c0, GLfloat c1); + +extern GLuint i915_emit_const4fv(struct i915_fragment_program *p, + const GLfloat * c); + +extern GLuint i915_emit_const4f(struct i915_fragment_program *p, + GLfloat c0, GLfloat c1, + GLfloat c2, GLfloat c3); + + +extern GLuint i915_emit_param4fv(struct i915_fragment_program *p, + const GLfloat * values); + +extern void i915_program_error(struct i915_fragment_program *p, + const char *msg); + +extern void i915_init_program(struct i915_context *i915, + struct i915_fragment_program *p); + +extern void i915_upload_program(struct i915_context *i915, + struct i915_fragment_program *p); + +extern void i915_fini_program(struct i915_fragment_program *p); + + + + +#endif diff --git a/src/mesa/drivers/dri/i915tex/i915_reg.h b/src/mesa/drivers/dri/i915tex/i915_reg.h new file mode 100644 index 0000000000..04b199905c --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_reg.h @@ -0,0 +1,841 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + + +#ifndef _I915_REG_H_ +#define _I915_REG_H_ + + +#include "intel_reg.h" + +#define I915_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value) + +#define CMD_3D (0x3<<29) + +#define PRIM3D_INLINE (CMD_3D | (0x1f<<24)) +#define PRIM3D_TRILIST (0x0<<18) +#define PRIM3D_TRISTRIP (0x1<<18) +#define PRIM3D_TRISTRIP_RVRSE (0x2<<18) +#define PRIM3D_TRIFAN (0x3<<18) +#define PRIM3D_POLY (0x4<<18) +#define PRIM3D_LINELIST (0x5<<18) +#define PRIM3D_LINESTRIP (0x6<<18) +#define PRIM3D_RECTLIST (0x7<<18) +#define PRIM3D_POINTLIST (0x8<<18) +#define PRIM3D_DIB (0x9<<18) +#define PRIM3D_CLEAR_RECT (0xa<<18) +#define PRIM3D_ZONE_INIT (0xd<<18) +#define PRIM3D_MASK (0x1f<<18) + +/* p137 */ +#define _3DSTATE_AA_CMD (CMD_3D | (0x06<<24)) +#define AA_LINE_ECAAR_WIDTH_ENABLE (1<<16) +#define AA_LINE_ECAAR_WIDTH_0_5 0 +#define AA_LINE_ECAAR_WIDTH_1_0 (1<<14) +#define AA_LINE_ECAAR_WIDTH_2_0 (2<<14) +#define AA_LINE_ECAAR_WIDTH_4_0 (3<<14) +#define AA_LINE_REGION_WIDTH_ENABLE (1<<8) +#define AA_LINE_REGION_WIDTH_0_5 0 +#define AA_LINE_REGION_WIDTH_1_0 (1<<6) +#define AA_LINE_REGION_WIDTH_2_0 (2<<6) +#define AA_LINE_REGION_WIDTH_4_0 (3<<6) + +/* 3DSTATE_BACKFACE_STENCIL_OPS, p138*/ +#define _3DSTATE_BACKFACE_STENCIL_OPS (CMD_3D | (0x8<<24)) +#define BFO_ENABLE_STENCIL_REF (1<<23) +#define BFO_STENCIL_REF_SHIFT 15 +#define BFO_STENCIL_REF_MASK (0xff<<15) +#define BFO_ENABLE_STENCIL_FUNCS (1<<14) +#define BFO_STENCIL_TEST_SHIFT 11 +#define BFO_STENCIL_TEST_MASK (0x7<<11) +#define BFO_STENCIL_FAIL_SHIFT 8 +#define BFO_STENCIL_FAIL_MASK (0x7<<8) +#define BFO_STENCIL_PASS_Z_FAIL_SHIFT 5 +#define BFO_STENCIL_PASS_Z_FAIL_MASK (0x7<<5) +#define BFO_STENCIL_PASS_Z_PASS_SHIFT 2 +#define BFO_STENCIL_PASS_Z_PASS_MASK (0x7<<2) +#define BFO_ENABLE_STENCIL_TWO_SIDE (1<<1) +#define BFO_STENCIL_TWO_SIDE (1<<0) + + +/* 3DSTATE_BACKFACE_STENCIL_MASKS, p140 */ +#define _3DSTATE_BACKFACE_STENCIL_MASKS (CMD_3D | (0x9<<24)) +#define BFM_ENABLE_STENCIL_TEST_MASK (1<<17) +#define BFM_ENABLE_STENCIL_WRITE_MASK (1<<16) +#define BFM_STENCIL_TEST_MASK_SHIFT 8 +#define BFM_STENCIL_TEST_MASK_MASK (0xff<<8) +#define BFM_STENCIL_WRITE_MASK_SHIFT 0 +#define BFM_STENCIL_WRITE_MASK_MASK (0xff<<0) + + + +/* 3DSTATE_BIN_CONTROL p141 */ + +/* p143 */ +#define _3DSTATE_BUF_INFO_CMD (CMD_3D | (0x1d<<24) | (0x8e<<16) | 1) +/* Dword 1 */ +#define BUF_3D_ID_COLOR_BACK (0x3<<24) +#define BUF_3D_ID_DEPTH (0x7<<24) +#define BUF_3D_USE_FENCE (1<<23) +#define BUF_3D_TILED_SURFACE (1<<22) +#define BUF_3D_TILE_WALK_X 0 +#define BUF_3D_TILE_WALK_Y (1<<21) +#define BUF_3D_PITCH(x) (((x)/4)<<2) +/* Dword 2 */ +#define BUF_3D_ADDR(x) ((x) & ~0x3) + + +/* 3DSTATE_CHROMA_KEY */ + +/* 3DSTATE_CLEAR_PARAMETERS, p150 */ + +/* 3DSTATE_CONSTANT_BLEND_COLOR, p153 */ +#define _3DSTATE_CONST_BLEND_COLOR_CMD (CMD_3D | (0x1d<<24) | (0x88<<16)) + + + +/* 3DSTATE_COORD_SET_BINDINGS, p154 */ +#define _3DSTATE_COORD_SET_BINDINGS (CMD_3D | (0x16<<24)) +#define CSB_TCB(iunit, eunit) ((eunit)<<(iunit*3)) + +/* p156 */ +#define _3DSTATE_DFLT_DIFFUSE_CMD (CMD_3D | (0x1d<<24) | (0x99<<16)) + +/* p157 */ +#define _3DSTATE_DFLT_SPEC_CMD (CMD_3D | (0x1d<<24) | (0x9a<<16)) + +/* p158 */ +#define _3DSTATE_DFLT_Z_CMD (CMD_3D | (0x1d<<24) | (0x98<<16)) + + +/* 3DSTATE_DEPTH_OFFSET_SCALE, p159 */ +#define _3DSTATE_DEPTH_OFFSET_SCALE (CMD_3D | (0x1d<<24) | (0x97<<16)) +/* scale in dword 1 */ + + +/* 3DSTATE_DEPTH_SUBRECT_DISABLE, p160 */ +#define _3DSTATE_DEPTH_SUBRECT_DISABLE (CMD_3D | (0x1c<<24) | (0x11<19) | 0x2) + +/* p161 */ +#define _3DSTATE_DST_BUF_VARS_CMD (CMD_3D | (0x1d<<24) | (0x85<<16)) +/* Dword 1 */ +#define TEX_DEFAULT_COLOR_OGL (0<<30) +#define TEX_DEFAULT_COLOR_D3D (1<<30) +#define ZR_EARLY_DEPTH (1<<29) +#define LOD_PRECLAMP_OGL (1<<28) +#define LOD_PRECLAMP_D3D (0<<28) +#define DITHER_FULL_ALWAYS (0<<26) +#define DITHER_FULL_ON_FB_BLEND (1<<26) +#define DITHER_CLAMPED_ALWAYS (2<<26) +#define LINEAR_GAMMA_BLEND_32BPP (1<<25) +#define DEBUG_DISABLE_ENH_DITHER (1<<24) +#define DSTORG_HORT_BIAS(x) ((x)<<20) +#define DSTORG_VERT_BIAS(x) ((x)<<16) +#define COLOR_4_2_2_CHNL_WRT_ALL 0 +#define COLOR_4_2_2_CHNL_WRT_Y (1<<12) +#define COLOR_4_2_2_CHNL_WRT_CR (2<<12) +#define COLOR_4_2_2_CHNL_WRT_CB (3<<12) +#define COLOR_4_2_2_CHNL_WRT_CRCB (4<<12) +#define COLR_BUF_8BIT 0 +#define COLR_BUF_RGB555 (1<<8) +#define COLR_BUF_RGB565 (2<<8) +#define COLR_BUF_ARGB8888 (3<<8) +#define DEPTH_FRMT_16_FIXED 0 +#define DEPTH_FRMT_16_FLOAT (1<<2) +#define DEPTH_FRMT_24_FIXED_8_OTHER (2<<2) +#define VERT_LINE_STRIDE_1 (1<<1) +#define VERT_LINE_STRIDE_0 (0<<1) +#define VERT_LINE_STRIDE_OFS_1 1 +#define VERT_LINE_STRIDE_OFS_0 0 + +/* p166 */ +#define _3DSTATE_DRAW_RECT_CMD (CMD_3D|(0x1d<<24)|(0x80<<16)|3) +/* Dword 1 */ +#define DRAW_RECT_DIS_DEPTH_OFS (1<<30) +#define DRAW_DITHER_OFS_X(x) ((x)<<26) +#define DRAW_DITHER_OFS_Y(x) ((x)<<24) +/* Dword 2 */ +#define DRAW_YMIN(x) ((x)<<16) +#define DRAW_XMIN(x) (x) +/* Dword 3 */ +#define DRAW_YMAX(x) ((x)<<16) +#define DRAW_XMAX(x) (x) +/* Dword 4 */ +#define DRAW_YORG(x) ((x)<<16) +#define DRAW_XORG(x) (x) + + +/* 3DSTATE_FILTER_COEFFICIENTS_4X4, p170 */ + +/* 3DSTATE_FILTER_COEFFICIENTS_6X5, p172 */ + + +/* _3DSTATE_FOG_COLOR, p173 */ +#define _3DSTATE_FOG_COLOR_CMD (CMD_3D|(0x15<<24)) +#define FOG_COLOR_RED(x) ((x)<<16) +#define FOG_COLOR_GREEN(x) ((x)<<8) +#define FOG_COLOR_BLUE(x) (x) + +/* _3DSTATE_FOG_MODE, p174 */ +#define _3DSTATE_FOG_MODE_CMD (CMD_3D|(0x1d<<24)|(0x89<<16)|2) +/* Dword 1 */ +#define FMC1_FOGFUNC_MODIFY_ENABLE (1<<31) +#define FMC1_FOGFUNC_VERTEX (0<<28) +#define FMC1_FOGFUNC_PIXEL_EXP (1<<28) +#define FMC1_FOGFUNC_PIXEL_EXP2 (2<<28) +#define FMC1_FOGFUNC_PIXEL_LINEAR (3<<28) +#define FMC1_FOGFUNC_MASK (3<<28) +#define FMC1_FOGINDEX_MODIFY_ENABLE (1<<27) +#define FMC1_FOGINDEX_Z (0<<25) +#define FMC1_FOGINDEX_W (1<<25) +#define FMC1_C1_C2_MODIFY_ENABLE (1<<24) +#define FMC1_DENSITY_MODIFY_ENABLE (1<<23) +#define FMC1_C1_ONE (1<<13) +#define FMC1_C1_MASK (0xffff<<4) +/* Dword 2 */ +#define FMC2_C2_ONE (1<<16) +/* Dword 3 */ +#define FMC3_D_ONE (1<<16) + + + +/* _3DSTATE_INDEPENDENT_ALPHA_BLEND, p177 */ +#define _3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD (CMD_3D|(0x0b<<24)) +#define IAB_MODIFY_ENABLE (1<<23) +#define IAB_ENABLE (1<<22) +#define IAB_MODIFY_FUNC (1<<21) +#define IAB_FUNC_SHIFT 16 +#define IAB_MODIFY_SRC_FACTOR (1<<11) +#define IAB_SRC_FACTOR_SHIFT 6 +#define IAB_SRC_FACTOR_MASK (BLENDFACT_MASK<<6) +#define IAB_MODIFY_DST_FACTOR (1<<5) +#define IAB_DST_FACTOR_SHIFT 0 +#define IAB_DST_FACTOR_MASK (BLENDFACT_MASK<<0) + + +#define BLENDFUNC_ADD 0x0 +#define BLENDFUNC_SUBTRACT 0x1 +#define BLENDFUNC_REVERSE_SUBTRACT 0x2 +#define BLENDFUNC_MIN 0x3 +#define BLENDFUNC_MAX 0x4 +#define BLENDFUNC_MASK 0x7 + +/* 3DSTATE_LOAD_INDIRECT, p180 */ + +#define _3DSTATE_LOAD_INDIRECT (CMD_3D|(0x1d<<24)|(0x7<<16)) +#define LI0_STATE_STATIC_INDIRECT (0x01<<8) +#define LI0_STATE_DYNAMIC_INDIRECT (0x02<<8) +#define LI0_STATE_SAMPLER (0x04<<8) +#define LI0_STATE_MAP (0x08<<8) +#define LI0_STATE_PROGRAM (0x10<<8) +#define LI0_STATE_CONSTANTS (0x20<<8) + +#define SIS0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define SIS0_FORCE_LOAD (1<<1) +#define SIS0_BUFFER_VALID (1<<0) +#define SIS1_BUFFER_LENGTH(x) ((x)&0xff) + +#define DIS0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define DIS0_BUFFER_RESET (1<<1) +#define DIS0_BUFFER_VALID (1<<0) + +#define SSB0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define SSB0_FORCE_LOAD (1<<1) +#define SSB0_BUFFER_VALID (1<<0) +#define SSB1_BUFFER_LENGTH(x) ((x)&0xff) + +#define MSB0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define MSB0_FORCE_LOAD (1<<1) +#define MSB0_BUFFER_VALID (1<<0) +#define MSB1_BUFFER_LENGTH(x) ((x)&0xff) + +#define PSP0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define PSP0_FORCE_LOAD (1<<1) +#define PSP0_BUFFER_VALID (1<<0) +#define PSP1_BUFFER_LENGTH(x) ((x)&0xff) + +#define PSC0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define PSC0_FORCE_LOAD (1<<1) +#define PSC0_BUFFER_VALID (1<<0) +#define PSC1_BUFFER_LENGTH(x) ((x)&0xff) + + + + + +/* _3DSTATE_RASTERIZATION_RULES */ +#define _3DSTATE_RASTER_RULES_CMD (CMD_3D|(0x07<<24)) +#define ENABLE_POINT_RASTER_RULE (1<<15) +#define OGL_POINT_RASTER_RULE (1<<13) +#define ENABLE_TEXKILL_3D_4D (1<<10) +#define TEXKILL_3D (0<<9) +#define TEXKILL_4D (1<<9) +#define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8) +#define ENABLE_TRI_FAN_PROVOKE_VRTX (1<<5) +#define LINE_STRIP_PROVOKE_VRTX(x) ((x)<<6) +#define TRI_FAN_PROVOKE_VRTX(x) ((x)<<3) + +/* _3DSTATE_SCISSOR_ENABLE, p256 */ +#define _3DSTATE_SCISSOR_ENABLE_CMD (CMD_3D|(0x1c<<24)|(0x10<<19)) +#define ENABLE_SCISSOR_RECT ((1<<1) | 1) +#define DISABLE_SCISSOR_RECT (1<<1) + +/* _3DSTATE_SCISSOR_RECTANGLE_0, p257 */ +#define _3DSTATE_SCISSOR_RECT_0_CMD (CMD_3D|(0x1d<<24)|(0x81<<16)|1) +/* Dword 1 */ +#define SCISSOR_RECT_0_YMIN(x) ((x)<<16) +#define SCISSOR_RECT_0_XMIN(x) (x) +/* Dword 2 */ +#define SCISSOR_RECT_0_YMAX(x) ((x)<<16) +#define SCISSOR_RECT_0_XMAX(x) (x) + +/* p189 */ +#define _3DSTATE_LOAD_STATE_IMMEDIATE_1 ((0x3<<29)|(0x1d<<24)|(0x04<<16)) +#define I1_LOAD_S(n) (1<<(4+n)) + +#define S0_VB_OFFSET_MASK 0xffffffc +#define S0_AUTO_CACHE_INV_DISABLE (1<<0) + +#define S1_VERTEX_WIDTH_SHIFT 24 +#define S1_VERTEX_WIDTH_MASK (0x3f<<24) +#define S1_VERTEX_PITCH_SHIFT 16 +#define S1_VERTEX_PITCH_MASK (0x3f<<16) + +#define TEXCOORDFMT_2D 0x0 +#define TEXCOORDFMT_3D 0x1 +#define TEXCOORDFMT_4D 0x2 +#define TEXCOORDFMT_1D 0x3 +#define TEXCOORDFMT_2D_16 0x4 +#define TEXCOORDFMT_4D_16 0x5 +#define TEXCOORDFMT_NOT_PRESENT 0xf +#define S2_TEXCOORD_FMT0_MASK 0xf +#define S2_TEXCOORD_FMT1_SHIFT 4 +#define S2_TEXCOORD_FMT(unit, type) ((type)<<(unit*4)) +#define S2_TEXCOORD_NONE (~0) + +/* S3 not interesting */ + +#define S4_POINT_WIDTH_SHIFT 23 +#define S4_POINT_WIDTH_MASK (0x1ff<<23) +#define S4_LINE_WIDTH_SHIFT 19 +#define S4_LINE_WIDTH_ONE (0x2<<19) +#define S4_LINE_WIDTH_MASK (0xf<<19) +#define S4_FLATSHADE_ALPHA (1<<18) +#define S4_FLATSHADE_FOG (1<<17) +#define S4_FLATSHADE_SPECULAR (1<<16) +#define S4_FLATSHADE_COLOR (1<<15) +#define S4_CULLMODE_BOTH (0<<13) +#define S4_CULLMODE_NONE (1<<13) +#define S4_CULLMODE_CW (2<<13) +#define S4_CULLMODE_CCW (3<<13) +#define S4_CULLMODE_MASK (3<<13) +#define S4_VFMT_POINT_WIDTH (1<<12) +#define S4_VFMT_SPEC_FOG (1<<11) +#define S4_VFMT_COLOR (1<<10) +#define S4_VFMT_DEPTH_OFFSET (1<<9) +#define S4_VFMT_XYZ (1<<6) +#define S4_VFMT_XYZW (2<<6) +#define S4_VFMT_XY (3<<6) +#define S4_VFMT_XYW (4<<6) +#define S4_VFMT_XYZW_MASK (7<<6) +#define S4_FORCE_DEFAULT_DIFFUSE (1<<5) +#define S4_FORCE_DEFAULT_SPECULAR (1<<4) +#define S4_LOCAL_DEPTH_OFFSET_ENABLE (1<<3) +#define S4_VFMT_FOG_PARAM (1<<2) +#define S4_SPRITE_POINT_ENABLE (1<<1) +#define S4_LINE_ANTIALIAS_ENABLE (1<<0) + +#define S4_VFMT_MASK (S4_VFMT_POINT_WIDTH | \ + S4_VFMT_SPEC_FOG | \ + S4_VFMT_COLOR | \ + S4_VFMT_DEPTH_OFFSET | \ + S4_VFMT_XYZW_MASK | \ + S4_VFMT_FOG_PARAM) + + +#define S5_WRITEDISABLE_ALPHA (1<<31) +#define S5_WRITEDISABLE_RED (1<<30) +#define S5_WRITEDISABLE_GREEN (1<<29) +#define S5_WRITEDISABLE_BLUE (1<<28) +#define S5_WRITEDISABLE_MASK (0xf<<28) +#define S5_FORCE_DEFAULT_POINT_SIZE (1<<27) +#define S5_LAST_PIXEL_ENABLE (1<<26) +#define S5_GLOBAL_DEPTH_OFFSET_ENABLE (1<<25) +#define S5_FOG_ENABLE (1<<24) +#define S5_STENCIL_REF_SHIFT 16 +#define S5_STENCIL_REF_MASK (0xff<<16) +#define S5_STENCIL_TEST_FUNC_SHIFT 13 +#define S5_STENCIL_TEST_FUNC_MASK (0x7<<13) +#define S5_STENCIL_FAIL_SHIFT 10 +#define S5_STENCIL_FAIL_MASK (0x7<<10) +#define S5_STENCIL_PASS_Z_FAIL_SHIFT 7 +#define S5_STENCIL_PASS_Z_FAIL_MASK (0x7<<7) +#define S5_STENCIL_PASS_Z_PASS_SHIFT 4 +#define S5_STENCIL_PASS_Z_PASS_MASK (0x7<<4) +#define S5_STENCIL_WRITE_ENABLE (1<<3) +#define S5_STENCIL_TEST_ENABLE (1<<2) +#define S5_COLOR_DITHER_ENABLE (1<<1) +#define S5_LOGICOP_ENABLE (1<<0) + + +#define S6_ALPHA_TEST_ENABLE (1<<31) +#define S6_ALPHA_TEST_FUNC_SHIFT 28 +#define S6_ALPHA_TEST_FUNC_MASK (0x7<<28) +#define S6_ALPHA_REF_SHIFT 20 +#define S6_ALPHA_REF_MASK (0xff<<20) +#define S6_DEPTH_TEST_ENABLE (1<<19) +#define S6_DEPTH_TEST_FUNC_SHIFT 16 +#define S6_DEPTH_TEST_FUNC_MASK (0x7<<16) +#define S6_CBUF_BLEND_ENABLE (1<<15) +#define S6_CBUF_BLEND_FUNC_SHIFT 12 +#define S6_CBUF_BLEND_FUNC_MASK (0x7<<12) +#define S6_CBUF_SRC_BLEND_FACT_SHIFT 8 +#define S6_CBUF_SRC_BLEND_FACT_MASK (0xf<<8) +#define S6_CBUF_DST_BLEND_FACT_SHIFT 4 +#define S6_CBUF_DST_BLEND_FACT_MASK (0xf<<4) +#define S6_DEPTH_WRITE_ENABLE (1<<3) +#define S6_COLOR_WRITE_ENABLE (1<<2) +#define S6_TRISTRIP_PV_SHIFT 0 +#define S6_TRISTRIP_PV_MASK (0x3<<0) + +#define S7_DEPTH_OFFSET_CONST_MASK ~0 + +/* 3DSTATE_MAP_DEINTERLACER_PARAMETERS */ + +/* 3DSTATE_MAP_PALETTE_LOAD_32, p206 */ +#define _3DSTATE_MAP_PALETTE_LOAD_32 (CMD_3D|(0x1d<<24)|(0x8f<<16)) +/* subsequent dwords up to length (max 16) are ARGB8888 color values */ + +/* _3DSTATE_MODES_4, p218 */ +#define _3DSTATE_MODES_4_CMD (CMD_3D|(0x0d<<24)) +#define ENABLE_LOGIC_OP_FUNC (1<<23) +#define LOGIC_OP_FUNC(x) ((x)<<18) +#define LOGICOP_MASK (0xf<<18) +#define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00)) +#define ENABLE_STENCIL_TEST_MASK (1<<17) +#define STENCIL_TEST_MASK(x) (((x)&0xff)<<8) +#define MODE4_ENABLE_STENCIL_WRITE_MASK ((1<<16)|(0x00ff)) +#define ENABLE_STENCIL_WRITE_MASK (1<<16) +#define STENCIL_WRITE_MASK(x) ((x)&0xff) + +/* _3DSTATE_MODES_5, p220 */ +#define _3DSTATE_MODES_5_CMD (CMD_3D|(0x0c<<24)) +#define PIPELINE_FLUSH_RENDER_CACHE (1<<18) +#define PIPELINE_FLUSH_TEXTURE_CACHE (1<<16) + + +/* p221 */ +#define _3DSTATE_PIXEL_SHADER_CONSTANTS (CMD_3D|(0x1d<<24)|(0x6<<16)) +#define PS1_REG(n) (1<<(n)) +#define PS2_CONST_X(n) (n) +#define PS3_CONST_Y(n) (n) +#define PS4_CONST_Z(n) (n) +#define PS5_CONST_W(n) (n) + +/* p222 */ + + +#define I915_MAX_TEX_INDIRECT 4 +#define I915_MAX_TEX_INSN 32 +#define I915_MAX_ALU_INSN 64 +#define I915_MAX_DECL_INSN 27 +#define I915_MAX_TEMPORARY 16 + + +/* Each instruction is 3 dwords long, though most don't require all + * this space. Maximum of 123 instructions. Smaller maxes per insn + * type. + */ +#define _3DSTATE_PIXEL_SHADER_PROGRAM (CMD_3D|(0x1d<<24)|(0x5<<16)) + +#define REG_TYPE_R 0 /* temporary regs, no need to + * dcl, must be written before + * read -- Preserved between + * phases. + */ +#define REG_TYPE_T 1 /* Interpolated values, must be + * dcl'ed before use. + * + * 0..7: texture coord, + * 8: diffuse spec, + * 9: specular color, + * 10: fog parameter in w. + */ +#define REG_TYPE_CONST 2 /* Restriction: only one const + * can be referenced per + * instruction, though it may be + * selected for multiple inputs. + * Constants not initialized + * default to zero. + */ +#define REG_TYPE_S 3 /* sampler */ +#define REG_TYPE_OC 4 /* output color (rgba) */ +#define REG_TYPE_OD 5 /* output depth (w), xyz are + * temporaries. If not written, + * interpolated depth is used? + */ +#define REG_TYPE_U 6 /* unpreserved temporaries */ +#define REG_TYPE_MASK 0x7 +#define REG_NR_MASK 0xf + + +/* REG_TYPE_T: + */ +#define T_TEX0 0 +#define T_TEX1 1 +#define T_TEX2 2 +#define T_TEX3 3 +#define T_TEX4 4 +#define T_TEX5 5 +#define T_TEX6 6 +#define T_TEX7 7 +#define T_DIFFUSE 8 +#define T_SPECULAR 9 +#define T_FOG_W 10 /* interpolated fog is in W coord */ + +/* Arithmetic instructions */ + +/* .replicate_swizzle == selection and replication of a particular + * scalar channel, ie., .xxxx, .yyyy, .zzzz or .wwww + */ +#define A0_NOP (0x0<<24) /* no operation */ +#define A0_ADD (0x1<<24) /* dst = src0 + src1 */ +#define A0_MOV (0x2<<24) /* dst = src0 */ +#define A0_MUL (0x3<<24) /* dst = src0 * src1 */ +#define A0_MAD (0x4<<24) /* dst = src0 * src1 + src2 */ +#define A0_DP2ADD (0x5<<24) /* dst.xyzw = src0.xy dot src1.xy + src2.replicate_swizzle */ +#define A0_DP3 (0x6<<24) /* dst.xyzw = src0.xyz dot src1.xyz */ +#define A0_DP4 (0x7<<24) /* dst.xyzw = src0.xyzw dot src1.xyzw */ +#define A0_FRC (0x8<<24) /* dst = src0 - floor(src0) */ +#define A0_RCP (0x9<<24) /* dst.xyzw = 1/(src0.replicate_swizzle) */ +#define A0_RSQ (0xa<<24) /* dst.xyzw = 1/(sqrt(abs(src0.replicate_swizzle))) */ +#define A0_EXP (0xb<<24) /* dst.xyzw = exp2(src0.replicate_swizzle) */ +#define A0_LOG (0xc<<24) /* dst.xyzw = log2(abs(src0.replicate_swizzle)) */ +#define A0_CMP (0xd<<24) /* dst = (src0 >= 0.0) ? src1 : src2 */ +#define A0_MIN (0xe<<24) /* dst = (src0 < src1) ? src0 : src1 */ +#define A0_MAX (0xf<<24) /* dst = (src0 >= src1) ? src0 : src1 */ +#define A0_FLR (0x10<<24) /* dst = floor(src0) */ +#define A0_MOD (0x11<<24) /* dst = src0 fmod 1.0 */ +#define A0_TRC (0x12<<24) /* dst = int(src0) */ +#define A0_SGE (0x13<<24) /* dst = src0 >= src1 ? 1.0 : 0.0 */ +#define A0_SLT (0x14<<24) /* dst = src0 < src1 ? 1.0 : 0.0 */ +#define A0_DEST_SATURATE (1<<22) +#define A0_DEST_TYPE_SHIFT 19 +/* Allow: R, OC, OD, U */ +#define A0_DEST_NR_SHIFT 14 +/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */ +#define A0_DEST_CHANNEL_X (1<<10) +#define A0_DEST_CHANNEL_Y (2<<10) +#define A0_DEST_CHANNEL_Z (4<<10) +#define A0_DEST_CHANNEL_W (8<<10) +#define A0_DEST_CHANNEL_ALL (0xf<<10) +#define A0_DEST_CHANNEL_SHIFT 10 +#define A0_SRC0_TYPE_SHIFT 7 +#define A0_SRC0_NR_SHIFT 2 + +#define A0_DEST_CHANNEL_XY (A0_DEST_CHANNEL_X|A0_DEST_CHANNEL_Y) +#define A0_DEST_CHANNEL_XYZ (A0_DEST_CHANNEL_XY|A0_DEST_CHANNEL_Z) + + +#define SRC_X 0 +#define SRC_Y 1 +#define SRC_Z 2 +#define SRC_W 3 +#define SRC_ZERO 4 +#define SRC_ONE 5 + +#define A1_SRC0_CHANNEL_X_NEGATE (1<<31) +#define A1_SRC0_CHANNEL_X_SHIFT 28 +#define A1_SRC0_CHANNEL_Y_NEGATE (1<<27) +#define A1_SRC0_CHANNEL_Y_SHIFT 24 +#define A1_SRC0_CHANNEL_Z_NEGATE (1<<23) +#define A1_SRC0_CHANNEL_Z_SHIFT 20 +#define A1_SRC0_CHANNEL_W_NEGATE (1<<19) +#define A1_SRC0_CHANNEL_W_SHIFT 16 +#define A1_SRC1_TYPE_SHIFT 13 +#define A1_SRC1_NR_SHIFT 8 +#define A1_SRC1_CHANNEL_X_NEGATE (1<<7) +#define A1_SRC1_CHANNEL_X_SHIFT 4 +#define A1_SRC1_CHANNEL_Y_NEGATE (1<<3) +#define A1_SRC1_CHANNEL_Y_SHIFT 0 + +#define A2_SRC1_CHANNEL_Z_NEGATE (1<<31) +#define A2_SRC1_CHANNEL_Z_SHIFT 28 +#define A2_SRC1_CHANNEL_W_NEGATE (1<<27) +#define A2_SRC1_CHANNEL_W_SHIFT 24 +#define A2_SRC2_TYPE_SHIFT 21 +#define A2_SRC2_NR_SHIFT 16 +#define A2_SRC2_CHANNEL_X_NEGATE (1<<15) +#define A2_SRC2_CHANNEL_X_SHIFT 12 +#define A2_SRC2_CHANNEL_Y_NEGATE (1<<11) +#define A2_SRC2_CHANNEL_Y_SHIFT 8 +#define A2_SRC2_CHANNEL_Z_NEGATE (1<<7) +#define A2_SRC2_CHANNEL_Z_SHIFT 4 +#define A2_SRC2_CHANNEL_W_NEGATE (1<<3) +#define A2_SRC2_CHANNEL_W_SHIFT 0 + + + +/* Texture instructions */ +#define T0_TEXLD (0x15<<24) /* Sample texture using predeclared + * sampler and address, and output + * filtered texel data to destination + * register */ +#define T0_TEXLDP (0x16<<24) /* Same as texld but performs a + * perspective divide of the texture + * coordinate .xyz values by .w before + * sampling. */ +#define T0_TEXLDB (0x17<<24) /* Same as texld but biases the + * computed LOD by w. Only S4.6 two's + * comp is used. This implies that a + * float to fixed conversion is + * done. */ +#define T0_TEXKILL (0x18<<24) /* Does not perform a sampling + * operation. Simply kills the pixel + * if any channel of the address + * register is < 0.0. */ +#define T0_DEST_TYPE_SHIFT 19 +/* Allow: R, OC, OD, U */ +/* Note: U (unpreserved) regs do not retain their values between + * phases (cannot be used for feedback) + * + * Note: oC and OD registers can only be used as the destination of a + * texture instruction once per phase (this is an implementation + * restriction). + */ +#define T0_DEST_NR_SHIFT 14 +/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */ +#define T0_SAMPLER_NR_SHIFT 0 /* This field ignored for TEXKILL */ +#define T0_SAMPLER_NR_MASK (0xf<<0) + +#define T1_ADDRESS_REG_TYPE_SHIFT 24 /* Reg to use as texture coord */ +/* Allow R, T, OC, OD -- R, OC, OD are 'dependent' reads, new program phase */ +#define T1_ADDRESS_REG_NR_SHIFT 17 +#define T2_MBZ 0 + +/* Declaration instructions */ +#define D0_DCL (0x19<<24) /* Declare a t (interpolated attrib) + * register or an s (sampler) + * register. */ +#define D0_SAMPLE_TYPE_SHIFT 22 +#define D0_SAMPLE_TYPE_2D (0x0<<22) +#define D0_SAMPLE_TYPE_CUBE (0x1<<22) +#define D0_SAMPLE_TYPE_VOLUME (0x2<<22) +#define D0_SAMPLE_TYPE_MASK (0x3<<22) + +#define D0_TYPE_SHIFT 19 +/* Allow: T, S */ +#define D0_NR_SHIFT 14 +/* Allow T: 0..10, S: 0..15 */ +#define D0_CHANNEL_X (1<<10) +#define D0_CHANNEL_Y (2<<10) +#define D0_CHANNEL_Z (4<<10) +#define D0_CHANNEL_W (8<<10) +#define D0_CHANNEL_ALL (0xf<<10) +#define D0_CHANNEL_NONE (0<<10) + +#define D0_CHANNEL_XY (D0_CHANNEL_X|D0_CHANNEL_Y) +#define D0_CHANNEL_XYZ (D0_CHANNEL_XY|D0_CHANNEL_Z) + +/* I915 Errata: Do not allow (xz), (xw), (xzw) combinations for diffuse + * or specular declarations. + * + * For T dcls, only allow: (x), (xy), (xyz), (w), (xyzw) + * + * Must be zero for S (sampler) dcls + */ +#define D1_MBZ 0 +#define D2_MBZ 0 + + + +/* p207 */ +#define _3DSTATE_MAP_STATE (CMD_3D|(0x1d<<24)|(0x0<<16)) + +#define MS1_MAPMASK_SHIFT 0 +#define MS1_MAPMASK_MASK (0x8fff<<0) + +#define MS2_UNTRUSTED_SURFACE (1<<31) +#define MS2_ADDRESS_MASK 0xfffffffc +#define MS2_VERTICAL_LINE_STRIDE (1<<1) +#define MS2_VERTICAL_OFFSET (1<<1) + +#define MS3_HEIGHT_SHIFT 21 +#define MS3_WIDTH_SHIFT 10 +#define MS3_PALETTE_SELECT (1<<9) +#define MS3_MAPSURF_FORMAT_SHIFT 7 +#define MS3_MAPSURF_FORMAT_MASK (0x7<<7) +#define MAPSURF_8BIT (1<<7) +#define MAPSURF_16BIT (2<<7) +#define MAPSURF_32BIT (3<<7) +#define MAPSURF_422 (5<<7) +#define MAPSURF_COMPRESSED (6<<7) +#define MAPSURF_4BIT_INDEXED (7<<7) +#define MS3_MT_FORMAT_MASK (0x7 << 3) +#define MS3_MT_FORMAT_SHIFT 3 +#define MT_4BIT_IDX_ARGB8888 (7<<3) /* SURFACE_4BIT_INDEXED */ +#define MT_8BIT_I8 (0<<3) /* SURFACE_8BIT */ +#define MT_8BIT_L8 (1<<3) +#define MT_8BIT_A8 (4<<3) +#define MT_8BIT_MONO8 (5<<3) +#define MT_16BIT_RGB565 (0<<3) /* SURFACE_16BIT */ +#define MT_16BIT_ARGB1555 (1<<3) +#define MT_16BIT_ARGB4444 (2<<3) +#define MT_16BIT_AY88 (3<<3) +#define MT_16BIT_88DVDU (5<<3) +#define MT_16BIT_BUMP_655LDVDU (6<<3) +#define MT_16BIT_I16 (7<<3) +#define MT_16BIT_L16 (8<<3) +#define MT_16BIT_A16 (9<<3) +#define MT_32BIT_ARGB8888 (0<<3) /* SURFACE_32BIT */ +#define MT_32BIT_ABGR8888 (1<<3) +#define MT_32BIT_XRGB8888 (2<<3) +#define MT_32BIT_XBGR8888 (3<<3) +#define MT_32BIT_QWVU8888 (4<<3) +#define MT_32BIT_AXVU8888 (5<<3) +#define MT_32BIT_LXVU8888 (6<<3) +#define MT_32BIT_XLVU8888 (7<<3) +#define MT_32BIT_ARGB2101010 (8<<3) +#define MT_32BIT_ABGR2101010 (9<<3) +#define MT_32BIT_AWVU2101010 (0xA<<3) +#define MT_32BIT_GR1616 (0xB<<3) +#define MT_32BIT_VU1616 (0xC<<3) +#define MT_32BIT_xI824 (0xD<<3) +#define MT_32BIT_xA824 (0xE<<3) +#define MT_32BIT_xL824 (0xF<<3) +#define MT_422_YCRCB_SWAPY (0<<3) /* SURFACE_422 */ +#define MT_422_YCRCB_NORMAL (1<<3) +#define MT_422_YCRCB_SWAPUV (2<<3) +#define MT_422_YCRCB_SWAPUVY (3<<3) +#define MT_COMPRESS_DXT1 (0<<3) /* SURFACE_COMPRESSED */ +#define MT_COMPRESS_DXT2_3 (1<<3) +#define MT_COMPRESS_DXT4_5 (2<<3) +#define MT_COMPRESS_FXT1 (3<<3) +#define MT_COMPRESS_DXT1_RGB (4<<3) +#define MS3_USE_FENCE_REGS (1<<2) +#define MS3_TILED_SURFACE (1<<1) +#define MS3_TILE_WALK (1<<0) + +#define MS4_PITCH_SHIFT 21 +#define MS4_CUBE_FACE_ENA_NEGX (1<<20) +#define MS4_CUBE_FACE_ENA_POSX (1<<19) +#define MS4_CUBE_FACE_ENA_NEGY (1<<18) +#define MS4_CUBE_FACE_ENA_POSY (1<<17) +#define MS4_CUBE_FACE_ENA_NEGZ (1<<16) +#define MS4_CUBE_FACE_ENA_POSZ (1<<15) +#define MS4_CUBE_FACE_ENA_MASK (0x3f<<15) +#define MS4_MAX_LOD_SHIFT 9 +#define MS4_MAX_LOD_MASK (0x3f<<9) +#define MS4_MIP_LAYOUT_LEGACY (0<<8) +#define MS4_MIP_LAYOUT_BELOW_LPT (0<<8) +#define MS4_MIP_LAYOUT_RIGHT_LPT (1<<8) +#define MS4_VOLUME_DEPTH_SHIFT 0 +#define MS4_VOLUME_DEPTH_MASK (0xff<<0) + +/* p244 */ +#define _3DSTATE_SAMPLER_STATE (CMD_3D|(0x1d<<24)|(0x1<<16)) + +#define SS1_MAPMASK_SHIFT 0 +#define SS1_MAPMASK_MASK (0x8fff<<0) + +#define SS2_REVERSE_GAMMA_ENABLE (1<<31) +#define SS2_PACKED_TO_PLANAR_ENABLE (1<<30) +#define SS2_COLORSPACE_CONVERSION (1<<29) +#define SS2_CHROMAKEY_SHIFT 27 +#define SS2_BASE_MIP_LEVEL_SHIFT 22 +#define SS2_BASE_MIP_LEVEL_MASK (0x1f<<22) +#define SS2_MIP_FILTER_SHIFT 20 +#define SS2_MIP_FILTER_MASK (0x3<<20) +#define MIPFILTER_NONE 0 +#define MIPFILTER_NEAREST 1 +#define MIPFILTER_LINEAR 3 +#define SS2_MAG_FILTER_SHIFT 17 +#define SS2_MAG_FILTER_MASK (0x7<<17) +#define FILTER_NEAREST 0 +#define FILTER_LINEAR 1 +#define FILTER_ANISOTROPIC 2 +#define FILTER_4X4_1 3 +#define FILTER_4X4_2 4 +#define FILTER_4X4_FLAT 5 +#define FILTER_6X5_MONO 6 /* XXX - check */ +#define SS2_MIN_FILTER_SHIFT 14 +#define SS2_MIN_FILTER_MASK (0x7<<14) +#define SS2_LOD_BIAS_SHIFT 5 +#define SS2_LOD_BIAS_ONE (0x10<<5) +#define SS2_LOD_BIAS_MASK (0x1ff<<5) +/* Shadow requires: + * MT_X8{I,L,A}24 or MT_{I,L,A}16 texture format + * FILTER_4X4_x MIN and MAG filters + */ +#define SS2_SHADOW_ENABLE (1<<4) +#define SS2_MAX_ANISO_MASK (1<<3) +#define SS2_MAX_ANISO_2 (0<<3) +#define SS2_MAX_ANISO_4 (1<<3) +#define SS2_SHADOW_FUNC_SHIFT 0 +#define SS2_SHADOW_FUNC_MASK (0x7<<0) +/* SS2_SHADOW_FUNC values: see COMPAREFUNC_* */ + +#define SS3_MIN_LOD_SHIFT 24 +#define SS3_MIN_LOD_ONE (0x10<<24) +#define SS3_MIN_LOD_MASK (0xff<<24) +#define SS3_KILL_PIXEL_ENABLE (1<<17) +#define SS3_TCX_ADDR_MODE_SHIFT 12 +#define SS3_TCX_ADDR_MODE_MASK (0x7<<12) +#define TEXCOORDMODE_WRAP 0 +#define TEXCOORDMODE_MIRROR 1 +#define TEXCOORDMODE_CLAMP_EDGE 2 +#define TEXCOORDMODE_CUBE 3 +#define TEXCOORDMODE_CLAMP_BORDER 4 +#define TEXCOORDMODE_MIRROR_ONCE 5 +#define SS3_TCY_ADDR_MODE_SHIFT 9 +#define SS3_TCY_ADDR_MODE_MASK (0x7<<9) +#define SS3_TCZ_ADDR_MODE_SHIFT 6 +#define SS3_TCZ_ADDR_MODE_MASK (0x7<<6) +#define SS3_NORMALIZED_COORDS (1<<5) +#define SS3_TEXTUREMAP_INDEX_SHIFT 1 +#define SS3_TEXTUREMAP_INDEX_MASK (0xf<<1) +#define SS3_DEINTERLACER_ENABLE (1<<0) + +#define SS4_BORDER_COLOR_MASK (~0) + +/* 3DSTATE_SPAN_STIPPLE, p258 + */ +#define _3DSTATE_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) +#define ST1_ENABLE (1<<16) +#define ST1_MASK (0xffff) + +#define _3DSTATE_DEFAULT_Z ((0x3<<29)|(0x1d<<24)|(0x98<<16)) +#define _3DSTATE_DEFAULT_DIFFUSE ((0x3<<29)|(0x1d<<24)|(0x99<<16)) +#define _3DSTATE_DEFAULT_SPECULAR ((0x3<<29)|(0x1d<<24)|(0x9a<<16)) + + +#define MI_FLUSH ((0<<29)|(4<<23)) +#define FLUSH_MAP_CACHE (1<<0) +#define INHIBIT_FLUSH_RENDER_CACHE (1<<2) + + +#endif diff --git a/src/mesa/drivers/dri/i915tex/i915_state.c b/src/mesa/drivers/dri/i915tex/i915_state.c new file mode 100644 index 0000000000..d68801d3f9 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_state.c @@ -0,0 +1,1019 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + + +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "enums.h" +#include "dd.h" +#include "tnl/tnl.h" +#include "tnl/t_context.h" + +#include "texmem.h" + +#include "intel_fbo.h" +#include "intel_screen.h" +#include "intel_batchbuffer.h" + +#include "i915_context.h" +#include "i915_reg.h" + +#define FILE_DEBUG_FLAG DEBUG_STATE + +static void +i915StencilFuncSeparate(GLcontext * ctx, GLenum face, GLenum func, GLint ref, + GLuint mask) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + int test = intel_translate_compare_func(func); + + mask = mask & 0xff; + + DBG("%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(func), ref, mask); + + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; + i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | + STENCIL_TEST_MASK(mask)); + + i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_REF_MASK | + S5_STENCIL_TEST_FUNC_MASK); + + i915->state.Ctx[I915_CTXREG_LIS5] |= ((ref << S5_STENCIL_REF_SHIFT) | + (test << + S5_STENCIL_TEST_FUNC_SHIFT)); +} + +static void +i915StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + + DBG("%s : mask 0x%x\n", __FUNCTION__, mask); + + mask = mask & 0xff; + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; + i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | + STENCIL_WRITE_MASK(mask)); +} + + +static void +i915StencilOpSeparate(GLcontext * ctx, GLenum face, GLenum fail, GLenum zfail, + GLenum zpass) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + int fop = intel_translate_stencil_op(fail); + int dfop = intel_translate_stencil_op(zfail); + int dpop = intel_translate_stencil_op(zpass); + + + DBG("%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(fail), + _mesa_lookup_enum_by_nr(zfail), _mesa_lookup_enum_by_nr(zpass)); + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + + i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_FAIL_MASK | + S5_STENCIL_PASS_Z_FAIL_MASK | + S5_STENCIL_PASS_Z_PASS_MASK); + + i915->state.Ctx[I915_CTXREG_LIS5] |= ((fop << S5_STENCIL_FAIL_SHIFT) | + (dfop << + S5_STENCIL_PASS_Z_FAIL_SHIFT) | + (dpop << + S5_STENCIL_PASS_Z_PASS_SHIFT)); +} + +static void +i915AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + int test = intel_translate_compare_func(func); + GLubyte refByte; + + UNCLAMPED_FLOAT_TO_UBYTE(refByte, ref); + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_LIS6] &= ~(S6_ALPHA_TEST_FUNC_MASK | + S6_ALPHA_REF_MASK); + i915->state.Ctx[I915_CTXREG_LIS6] |= ((test << S6_ALPHA_TEST_FUNC_SHIFT) | + (((GLuint) refByte) << + S6_ALPHA_REF_SHIFT)); +} + +/* This function makes sure that the proper enables are + * set for LogicOp, Independant Alpha Blend, and Blending. + * It needs to be called from numerous places where we + * could change the LogicOp or Independant Alpha Blend without subsequent + * calls to glEnable. + */ +static void +i915EvalLogicOpBlendState(GLcontext * ctx) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + + if (ctx->Color._LogicOpEnabled) { + i915->state.Ctx[I915_CTXREG_LIS5] |= S5_LOGICOP_ENABLE; + i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE; + } + else { + i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_LOGICOP_ENABLE; + + if (ctx->Color.BlendEnabled) { + i915->state.Ctx[I915_CTXREG_LIS6] |= S6_CBUF_BLEND_ENABLE; + } + else { + i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE; + } + } +} + +static void +i915BlendColor(GLcontext * ctx, const GLfloat color[4]) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + GLubyte r, g, b, a; + + DBG("%s\n", __FUNCTION__); + + UNCLAMPED_FLOAT_TO_UBYTE(r, color[RCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(g, color[GCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(b, color[BCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(a, color[ACOMP]); + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] = + (a << 24) | (r << 16) | (g << 8) | b; +} + + +#define DST_BLND_FACT(f) ((f)<state.Ctx[I915_CTXREG_IAB] & + ~(IAB_SRC_FACTOR_MASK | + IAB_DST_FACTOR_MASK | + (BLENDFUNC_MASK << IAB_FUNC_SHIFT) | IAB_ENABLE)); + + GLuint lis6 = (i915->state.Ctx[I915_CTXREG_LIS6] & + ~(S6_CBUF_SRC_BLEND_FACT_MASK | + S6_CBUF_DST_BLEND_FACT_MASK | S6_CBUF_BLEND_FUNC_MASK)); + + GLuint eqRGB = ctx->Color.BlendEquationRGB; + GLuint eqA = ctx->Color.BlendEquationA; + GLuint srcRGB = ctx->Color.BlendSrcRGB; + GLuint dstRGB = ctx->Color.BlendDstRGB; + GLuint srcA = ctx->Color.BlendSrcA; + GLuint dstA = ctx->Color.BlendDstA; + + if (eqRGB == GL_MIN || eqRGB == GL_MAX) { + srcRGB = dstRGB = GL_ONE; + } + + if (eqA == GL_MIN || eqA == GL_MAX) { + srcA = dstA = GL_ONE; + } + + lis6 |= SRC_BLND_FACT(intel_translate_blend_factor(srcRGB)); + lis6 |= DST_BLND_FACT(intel_translate_blend_factor(dstRGB)); + lis6 |= translate_blend_equation(eqRGB) << S6_CBUF_BLEND_FUNC_SHIFT; + + iab |= SRC_ABLND_FACT(intel_translate_blend_factor(srcA)); + iab |= DST_ABLND_FACT(intel_translate_blend_factor(dstA)); + iab |= translate_blend_equation(eqA) << IAB_FUNC_SHIFT; + + if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) + iab |= IAB_ENABLE; + + if (iab != i915->state.Ctx[I915_CTXREG_IAB] || + lis6 != i915->state.Ctx[I915_CTXREG_LIS6]) { + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_IAB] = iab; + i915->state.Ctx[I915_CTXREG_LIS6] = lis6; + } + + /* This will catch a logicop blend equation */ + i915EvalLogicOpBlendState(ctx); +} + + +static void +i915BlendFuncSeparate(GLcontext * ctx, GLenum srcRGB, + GLenum dstRGB, GLenum srcA, GLenum dstA) +{ + i915UpdateBlendState(ctx); +} + + +static void +i915BlendEquationSeparate(GLcontext * ctx, GLenum eqRGB, GLenum eqA) +{ + i915UpdateBlendState(ctx); +} + + +static void +i915DepthFunc(GLcontext * ctx, GLenum func) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + int test = intel_translate_compare_func(func); + + DBG("%s\n", __FUNCTION__); + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_FUNC_MASK; + i915->state.Ctx[I915_CTXREG_LIS6] |= test << S6_DEPTH_TEST_FUNC_SHIFT; +} + +static void +i915DepthMask(GLcontext * ctx, GLboolean flag) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + + DBG("%s flag (%d)\n", __FUNCTION__, flag); + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + + if (flag && ctx->Depth.Test) + i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_WRITE_ENABLE; + else + i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_WRITE_ENABLE; +} + +/* ============================================================= + * Polygon stipple + * + * The i915 supports a 4x4 stipple natively, GL wants 32x32. + * Fortunately stipple is usually a repeating pattern. + */ +static void +i915PolygonStipple(GLcontext * ctx, const GLubyte * mask) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + const GLubyte *m = mask; + GLubyte p[4]; + int i, j, k; + int active = (ctx->Polygon.StippleFlag && + i915->intel.reduced_primitive == GL_TRIANGLES); + GLuint newMask; + + if (active) { + I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); + i915->state.Stipple[I915_STPREG_ST1] &= ~ST1_ENABLE; + } + + p[0] = mask[12] & 0xf; + p[0] |= p[0] << 4; + p[1] = mask[8] & 0xf; + p[1] |= p[1] << 4; + p[2] = mask[4] & 0xf; + p[2] |= p[2] << 4; + p[3] = mask[0] & 0xf; + p[3] |= p[3] << 4; + + for (k = 0; k < 8; k++) + for (j = 3; j >= 0; j--) + for (i = 0; i < 4; i++, m++) + if (*m != p[j]) { + i915->intel.hw_stipple = 0; + return; + } + + newMask = (((p[0] & 0xf) << 0) | + ((p[1] & 0xf) << 4) | + ((p[2] & 0xf) << 8) | ((p[3] & 0xf) << 12)); + + + if (newMask == 0xffff || newMask == 0x0) { + /* this is needed to make conform pass */ + i915->intel.hw_stipple = 0; + return; + } + + i915->state.Stipple[I915_STPREG_ST1] &= ~0xffff; + i915->state.Stipple[I915_STPREG_ST1] |= newMask; + i915->intel.hw_stipple = 1; + + if (active) + i915->state.Stipple[I915_STPREG_ST1] |= ST1_ENABLE; +} + + +/* ============================================================= + * Hardware clipping + */ +static void +i915Scissor(GLcontext * ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + int x1, y1, x2, y2; + + if (!ctx->DrawBuffer) + return; + + DBG("%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); + + if (ctx->DrawBuffer->Name == 0) { + x1 = x; + y1 = ctx->DrawBuffer->Height - (y + h); + x2 = x + w - 1; + y2 = y1 + h - 1; + DBG("%s %d..%d,%d..%d (inverted)\n", __FUNCTION__, x1, x2, y1, y2); + } + else { + /* FBO - not inverted + */ + x1 = x; + y1 = y; + x2 = x + w - 1; + y2 = y + h - 1; + DBG("%s %d..%d,%d..%d (not inverted)\n", __FUNCTION__, x1, x2, y1, y2); + } + + x1 = CLAMP(x1, 0, ctx->DrawBuffer->Width - 1); + y1 = CLAMP(y1, 0, ctx->DrawBuffer->Height - 1); + x2 = CLAMP(x2, 0, ctx->DrawBuffer->Width - 1); + y2 = CLAMP(y2, 0, ctx->DrawBuffer->Height - 1); + + DBG("%s %d..%d,%d..%d (clamped)\n", __FUNCTION__, x1, x2, y1, y2); + + I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); + i915->state.Buffer[I915_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff); + i915->state.Buffer[I915_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff); +} + +static void +i915LogicOp(GLcontext * ctx, GLenum opcode) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + int tmp = intel_translate_logic_op(opcode); + + DBG("%s\n", __FUNCTION__); + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_STATE4] &= ~LOGICOP_MASK; + i915->state.Ctx[I915_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp); +} + + + +static void +i915CullFaceFrontFace(GLcontext * ctx, GLenum unused) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + GLuint mode; + + DBG("%s %d\n", __FUNCTION__, + ctx->DrawBuffer ? ctx->DrawBuffer->Name : 0); + + if (!ctx->Polygon.CullFlag) { + mode = S4_CULLMODE_NONE; + } + else if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) { + mode = S4_CULLMODE_CW; + + if (ctx->DrawBuffer && ctx->DrawBuffer->Name != 0) + mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); + if (ctx->Polygon.CullFaceMode == GL_FRONT) + mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); + if (ctx->Polygon.FrontFace != GL_CCW) + mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); + } + else { + mode = S4_CULLMODE_BOTH; + } + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_CULLMODE_MASK; + i915->state.Ctx[I915_CTXREG_LIS4] |= mode; +} + +static void +i915LineWidth(GLcontext * ctx, GLfloat widthf) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_LINE_WIDTH_MASK; + int width; + + DBG("%s\n", __FUNCTION__); + + width = (int) (widthf * 2); + CLAMP_SELF(width, 1, 0xf); + lis4 |= width << S4_LINE_WIDTH_SHIFT; + + if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) { + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_LIS4] = lis4; + } +} + +static void +i915PointSize(GLcontext * ctx, GLfloat size) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_POINT_WIDTH_MASK; + GLint point_size = (int) size; + + DBG("%s\n", __FUNCTION__); + + CLAMP_SELF(point_size, 1, 255); + lis4 |= point_size << S4_POINT_WIDTH_SHIFT; + + if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) { + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_LIS4] = lis4; + } +} + + +/* ============================================================= + * Color masks + */ + +static void +i915ColorMask(GLcontext * ctx, + GLboolean r, GLboolean g, GLboolean b, GLboolean a) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + GLuint tmp = i915->state.Ctx[I915_CTXREG_LIS5] & ~S5_WRITEDISABLE_MASK; + + DBG("%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, r, g, b, + a); + + if (!r) + tmp |= S5_WRITEDISABLE_RED; + if (!g) + tmp |= S5_WRITEDISABLE_GREEN; + if (!b) + tmp |= S5_WRITEDISABLE_BLUE; + if (!a) + tmp |= S5_WRITEDISABLE_ALPHA; + + if (tmp != i915->state.Ctx[I915_CTXREG_LIS5]) { + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_LIS5] = tmp; + } +} + +static void +update_specular(GLcontext * ctx) +{ + /* A hack to trigger the rebuild of the fragment program. + */ + intel_context(ctx)->NewGLState |= _NEW_TEXTURE; + I915_CONTEXT(ctx)->tex_program.translated = 0; +} + +static void +i915LightModelfv(GLcontext * ctx, GLenum pname, const GLfloat * param) +{ + DBG("%s\n", __FUNCTION__); + + if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { + update_specular(ctx); + } +} + +static void +i915ShadeModel(GLcontext * ctx, GLenum mode) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + + if (mode == GL_SMOOTH) { + i915->state.Ctx[I915_CTXREG_LIS4] &= ~(S4_FLATSHADE_ALPHA | + S4_FLATSHADE_COLOR | + S4_FLATSHADE_SPECULAR); + } + else { + i915->state.Ctx[I915_CTXREG_LIS4] |= (S4_FLATSHADE_ALPHA | + S4_FLATSHADE_COLOR | + S4_FLATSHADE_SPECULAR); + } +} + +/* ============================================================= + * Fog + */ +void +i915_update_fog(GLcontext * ctx) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + GLenum mode; + GLboolean enabled; + GLboolean try_pixel_fog; + + if (ctx->FragmentProgram._Active) { + /* Pull in static fog state from program */ + + mode = ctx->FragmentProgram._Current->FogOption; + enabled = (mode != GL_NONE); + try_pixel_fog = 0; + } + else { + enabled = ctx->Fog.Enabled; + mode = ctx->Fog.Mode; + + try_pixel_fog = (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT && ctx->Hint.Fog == GL_NICEST && 0); /* XXX - DISABLE -- Need ortho fallback */ + } + + if (!enabled) { + i915->vertex_fog = I915_FOG_NONE; + } + else if (try_pixel_fog) { + + I915_STATECHANGE(i915, I915_UPLOAD_FOG); + i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_FOGFUNC_MASK; + i915->vertex_fog = I915_FOG_PIXEL; + + switch (mode) { + case GL_LINEAR: + if (ctx->Fog.End <= ctx->Fog.Start) { + /* XXX - this won't work with fragment programs. Need to + * either fallback or append fog instructions to end of + * program in the case of linear fog. + */ + i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_VERTEX; + i915->vertex_fog = I915_FOG_VERTEX; + } + else { + GLfloat c1 = ctx->Fog.End / (ctx->Fog.End - ctx->Fog.Start); + GLfloat c2 = 1.0 / (ctx->Fog.End - ctx->Fog.Start); + + i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_C1_MASK; + i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_LINEAR; + i915->state.Fog[I915_FOGREG_MODE1] |= + ((GLuint) (c1 * FMC1_C1_ONE)) & FMC1_C1_MASK; + + if (i915->state.Fog[I915_FOGREG_MODE1] & FMC1_FOGINDEX_Z) { + i915->state.Fog[I915_FOGREG_MODE2] = + (GLuint) (c2 * FMC2_C2_ONE); + } + else { + union + { + float f; + int i; + } fi; + fi.f = c2; + i915->state.Fog[I915_FOGREG_MODE2] = fi.i; + } + } + break; + case GL_EXP: + i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_EXP; + break; + case GL_EXP2: + i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_EXP2; + break; + default: + break; + } + } + else { /* if (i915->vertex_fog != I915_FOG_VERTEX) */ + + I915_STATECHANGE(i915, I915_UPLOAD_FOG); + i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_FOGFUNC_MASK; + i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_VERTEX; + i915->vertex_fog = I915_FOG_VERTEX; + } + + { + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + I915_ACTIVESTATE(i915, I915_UPLOAD_FOG, enabled); + if (enabled) + i915->state.Ctx[I915_CTXREG_LIS5] |= S5_FOG_ENABLE; + else + i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_FOG_ENABLE; + } + + if (enabled) { + _tnl_allow_vertex_fog(ctx, (i915->vertex_fog == I915_FOG_VERTEX)); + _tnl_allow_pixel_fog(ctx, (i915->vertex_fog != I915_FOG_VERTEX)); + } +} + +static void +i915Fogfv(GLcontext * ctx, GLenum pname, const GLfloat * param) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + + switch (pname) { + case GL_FOG_COORDINATE_SOURCE_EXT: + case GL_FOG_MODE: + case GL_FOG_START: + case GL_FOG_END: + break; + + case GL_FOG_DENSITY: + I915_STATECHANGE(i915, I915_UPLOAD_FOG); + + if (i915->state.Fog[I915_FOGREG_MODE1] & FMC1_FOGINDEX_Z) { + i915->state.Fog[I915_FOGREG_MODE3] = (GLuint) (ctx->Fog.Density * + FMC3_D_ONE); + } + else { + union + { + float f; + int i; + } fi; + fi.f = ctx->Fog.Density; + i915->state.Fog[I915_FOGREG_MODE3] = fi.i; + } + break; + + case GL_FOG_COLOR: + I915_STATECHANGE(i915, I915_UPLOAD_FOG); + i915->state.Fog[I915_FOGREG_COLOR] = + (_3DSTATE_FOG_COLOR_CMD | + ((GLubyte) (ctx->Fog.Color[0] * 255.0F) << 16) | + ((GLubyte) (ctx->Fog.Color[1] * 255.0F) << 8) | + ((GLubyte) (ctx->Fog.Color[2] * 255.0F) << 0)); + break; + + default: + break; + } +} + +static void +i915Hint(GLcontext * ctx, GLenum target, GLenum state) +{ + switch (target) { + case GL_FOG_HINT: + break; + default: + break; + } +} + +/* ============================================================= + */ + +static void +i915Enable(GLcontext * ctx, GLenum cap, GLboolean state) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + + switch (cap) { + case GL_TEXTURE_2D: + break; + + case GL_LIGHTING: + case GL_COLOR_SUM: + update_specular(ctx); + break; + + case GL_ALPHA_TEST: + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + if (state) + i915->state.Ctx[I915_CTXREG_LIS6] |= S6_ALPHA_TEST_ENABLE; + else + i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_ALPHA_TEST_ENABLE; + break; + + case GL_BLEND: + i915EvalLogicOpBlendState(ctx); + break; + + case GL_COLOR_LOGIC_OP: + i915EvalLogicOpBlendState(ctx); + + /* Logicop doesn't seem to work at 16bpp: + */ + if (i915->intel.intelScreen->cpp == 2) /* XXX FBO fix */ + FALLBACK(&i915->intel, I915_FALLBACK_LOGICOP, state); + break; + + case GL_FRAGMENT_PROGRAM_ARB: + break; + + case GL_DITHER: + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + if (state) + i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE; + else + i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_COLOR_DITHER_ENABLE; + break; + + case GL_DEPTH_TEST: + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + if (state) + i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_TEST_ENABLE; + else + i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_ENABLE; + + i915DepthMask(ctx, ctx->Depth.Mask); + break; + + case GL_SCISSOR_TEST: + I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); + if (state) + i915->state.Buffer[I915_DESTREG_SENABLE] = + (_3DSTATE_SCISSOR_ENABLE_CMD | ENABLE_SCISSOR_RECT); + else + i915->state.Buffer[I915_DESTREG_SENABLE] = + (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); + break; + + case GL_LINE_SMOOTH: + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + if (state) + i915->state.Ctx[I915_CTXREG_LIS4] |= S4_LINE_ANTIALIAS_ENABLE; + else + i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_LINE_ANTIALIAS_ENABLE; + break; + + case GL_FOG: + break; + + case GL_CULL_FACE: + i915CullFaceFrontFace(ctx, 0); + break; + + case GL_STENCIL_TEST: + { + GLboolean hw_stencil = GL_FALSE; + if (ctx->DrawBuffer) { + struct intel_renderbuffer *irbStencil + = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL); + hw_stencil = (irbStencil && irbStencil->region); + } + if (hw_stencil) { + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + if (state) + i915->state.Ctx[I915_CTXREG_LIS5] |= (S5_STENCIL_TEST_ENABLE | + S5_STENCIL_WRITE_ENABLE); + else + i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_TEST_ENABLE | + S5_STENCIL_WRITE_ENABLE); + } + else { + FALLBACK(&i915->intel, I915_FALLBACK_STENCIL, state); + } + } + break; + + case GL_POLYGON_STIPPLE: + /* The stipple command worked on my 855GM box, but not my 845G. + * I'll do more testing later to find out exactly which hardware + * supports it. Disabled for now. + */ + if (i915->intel.hw_stipple && + i915->intel.reduced_primitive == GL_TRIANGLES) { + I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); + if (state) + i915->state.Stipple[I915_STPREG_ST1] |= ST1_ENABLE; + else + i915->state.Stipple[I915_STPREG_ST1] &= ~ST1_ENABLE; + } + break; + + case GL_POLYGON_SMOOTH: + break; + + case GL_POINT_SMOOTH: + break; + + default: + ; + } +} + + +static void +i915_init_packets(struct i915_context *i915) +{ + intelScreenPrivate *screen = i915->intel.intelScreen; + + /* Zero all state */ + memset(&i915->state, 0, sizeof(i915->state)); + + + { + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + /* Probably don't want to upload all this stuff every time one + * piece changes. + */ + i915->state.Ctx[I915_CTXREG_LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_1 | + I1_LOAD_S(2) | + I1_LOAD_S(4) | + I1_LOAD_S(5) | I1_LOAD_S(6) | (4)); + i915->state.Ctx[I915_CTXREG_LIS2] = 0; + i915->state.Ctx[I915_CTXREG_LIS4] = 0; + i915->state.Ctx[I915_CTXREG_LIS5] = 0; + + if (screen->cpp == 2) /* XXX FBO fix */ + i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE; + + + i915->state.Ctx[I915_CTXREG_LIS6] = (S6_COLOR_WRITE_ENABLE | + (2 << S6_TRISTRIP_PV_SHIFT)); + + i915->state.Ctx[I915_CTXREG_STATE4] = (_3DSTATE_MODES_4_CMD | + ENABLE_LOGIC_OP_FUNC | + LOGIC_OP_FUNC(LOGICOP_COPY) | + ENABLE_STENCIL_TEST_MASK | + STENCIL_TEST_MASK(0xff) | + ENABLE_STENCIL_WRITE_MASK | + STENCIL_WRITE_MASK(0xff)); + + i915->state.Ctx[I915_CTXREG_IAB] = + (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | IAB_MODIFY_ENABLE | + IAB_MODIFY_FUNC | IAB_MODIFY_SRC_FACTOR | IAB_MODIFY_DST_FACTOR); + + i915->state.Ctx[I915_CTXREG_BLENDCOLOR0] = + _3DSTATE_CONST_BLEND_COLOR_CMD; + i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] = 0; + + } + + { + I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); + i915->state.Stipple[I915_STPREG_ST0] = _3DSTATE_STIPPLE; + } + + + { + I915_STATECHANGE(i915, I915_UPLOAD_FOG); + i915->state.Fog[I915_FOGREG_MODE0] = _3DSTATE_FOG_MODE_CMD; + i915->state.Fog[I915_FOGREG_MODE1] = (FMC1_FOGFUNC_MODIFY_ENABLE | + FMC1_FOGFUNC_VERTEX | + FMC1_FOGINDEX_MODIFY_ENABLE | + FMC1_FOGINDEX_W | + FMC1_C1_C2_MODIFY_ENABLE | + FMC1_DENSITY_MODIFY_ENABLE); + i915->state.Fog[I915_FOGREG_COLOR] = _3DSTATE_FOG_COLOR_CMD; + } + + + { + I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); + /* color buffer offset/stride */ + i915->state.Buffer[I915_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD; + /* XXX FBO: remove this? Also get set in i915_set_draw_region() */ + i915->state.Buffer[I915_DESTREG_CBUFADDR1] = (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(screen->front.pitch) | /* pitch in bytes */ + BUF_3D_USE_FENCE); + + i915->state.Buffer[I915_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD; + /* XXX FBO: remove this? Also get set in i915_set_draw_region() */ + i915->state.Buffer[I915_DESTREG_DBUFADDR1] = (BUF_3D_ID_DEPTH | BUF_3D_PITCH(screen->depth.pitch) | /* pitch in bytes */ + BUF_3D_USE_FENCE); + + i915->state.Buffer[I915_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD; + + /* XXX FBO: remove this? Also get set in i915_set_draw_region() */ +#if 0 /* seems we don't need this */ + switch (screen->fbFormat) { + case DV_PF_565: + i915->state.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ + DSTORG_VERT_BIAS(0x8) | /* .5 */ + LOD_PRECLAMP_OGL | + TEX_DEFAULT_COLOR_OGL | + DITHER_FULL_ALWAYS | + screen->fbFormat | + DEPTH_FRMT_16_FIXED); + break; + case DV_PF_8888: + i915->state.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ + DSTORG_VERT_BIAS(0x8) | /* .5 */ + LOD_PRECLAMP_OGL | + TEX_DEFAULT_COLOR_OGL | + screen->fbFormat | + DEPTH_FRMT_24_FIXED_8_OTHER); + break; + } +#endif + + + /* scissor */ + i915->state.Buffer[I915_DESTREG_SENABLE] = + (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); + i915->state.Buffer[I915_DESTREG_SR0] = _3DSTATE_SCISSOR_RECT_0_CMD; + i915->state.Buffer[I915_DESTREG_SR1] = 0; + i915->state.Buffer[I915_DESTREG_SR2] = 0; + } + + +#if 0 + { + I915_STATECHANGE(i915, I915_UPLOAD_DEFAULTS); + i915->state.Default[I915_DEFREG_C0] = _3DSTATE_DEFAULT_DIFFUSE; + i915->state.Default[I915_DEFREG_C1] = 0; + i915->state.Default[I915_DEFREG_S0] = _3DSTATE_DEFAULT_SPECULAR; + i915->state.Default[I915_DEFREG_S1] = 0; + i915->state.Default[I915_DEFREG_Z0] = _3DSTATE_DEFAULT_Z; + i915->state.Default[I915_DEFREG_Z1] = 0; + } +#endif + + + /* These will be emitted every at the head of every buffer, unless + * we get hardware contexts working. + */ + i915->state.active = (I915_UPLOAD_PROGRAM | + I915_UPLOAD_STIPPLE | + I915_UPLOAD_CTX | + I915_UPLOAD_BUFFERS | I915_UPLOAD_INVARIENT); +} + +void +i915InitStateFunctions(struct dd_function_table *functions) +{ + functions->AlphaFunc = i915AlphaFunc; + functions->BlendColor = i915BlendColor; + functions->BlendEquationSeparate = i915BlendEquationSeparate; + functions->BlendFuncSeparate = i915BlendFuncSeparate; + functions->ColorMask = i915ColorMask; + functions->CullFace = i915CullFaceFrontFace; + functions->DepthFunc = i915DepthFunc; + functions->DepthMask = i915DepthMask; + functions->Enable = i915Enable; + functions->Fogfv = i915Fogfv; + functions->FrontFace = i915CullFaceFrontFace; + functions->Hint = i915Hint; + functions->LightModelfv = i915LightModelfv; + functions->LineWidth = i915LineWidth; + functions->LogicOpcode = i915LogicOp; + functions->PointSize = i915PointSize; + functions->PolygonStipple = i915PolygonStipple; + functions->Scissor = i915Scissor; + functions->ShadeModel = i915ShadeModel; + functions->StencilFuncSeparate = i915StencilFuncSeparate; + functions->StencilMaskSeparate = i915StencilMaskSeparate; + functions->StencilOpSeparate = i915StencilOpSeparate; +} + + +void +i915InitState(struct i915_context *i915) +{ + GLcontext *ctx = &i915->intel.ctx; + + i915_init_packets(i915); + + intelInitState(ctx); + + memcpy(&i915->initial, &i915->state, sizeof(i915->state)); + i915->current = &i915->state; +} diff --git a/src/mesa/drivers/dri/i915tex/i915_tex.c b/src/mesa/drivers/dri/i915tex/i915_tex.c new file mode 100644 index 0000000000..a53abe9a92 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_tex.c @@ -0,0 +1,113 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#include "glheader.h" +#include "mtypes.h" +#include "imports.h" +#include "simple_list.h" +#include "enums.h" +#include "image.h" +#include "texstore.h" +#include "texformat.h" +#include "texmem.h" +#include "swrast/swrast.h" + +#include "mm.h" + +#include "intel_ioctl.h" + +#include "i915_context.h" +#include "i915_reg.h" + + + +static void +i915TexEnv(GLcontext * ctx, GLenum target, + GLenum pname, const GLfloat * param) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + + switch (pname) { + case GL_TEXTURE_ENV_COLOR: /* Should be a tracked param */ + case GL_TEXTURE_ENV_MODE: + case GL_COMBINE_RGB: + case GL_COMBINE_ALPHA: + case GL_SOURCE0_RGB: + case GL_SOURCE1_RGB: + case GL_SOURCE2_RGB: + case GL_SOURCE0_ALPHA: + case GL_SOURCE1_ALPHA: + case GL_SOURCE2_ALPHA: + case GL_OPERAND0_RGB: + case GL_OPERAND1_RGB: + case GL_OPERAND2_RGB: + case GL_OPERAND0_ALPHA: + case GL_OPERAND1_ALPHA: + case GL_OPERAND2_ALPHA: + case GL_RGB_SCALE: + case GL_ALPHA_SCALE: + i915->tex_program.translated = 0; + break; + + case GL_TEXTURE_LOD_BIAS:{ + GLuint unit = ctx->Texture.CurrentUnit; + GLint b = (int) ((*param) * 16.0); + if (b > 255) + b = 255; + if (b < -256) + b = -256; + I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit)); + i915->lodbias_ss2[unit] = + ((b << SS2_LOD_BIAS_SHIFT) & SS2_LOD_BIAS_MASK); + break; + } + + default: + break; + } +} + + +static void +i915BindTexture(GLcontext * ctx, GLenum target, + struct gl_texture_object *texobj) +{ + /* Need this if image format changes between bound textures. + * Could try and shortcircuit by checking for differences in + * state between incoming and outgoing textures: + */ + I915_CONTEXT(ctx)->tex_program.translated = 0; +} + + + +void +i915InitTextureFuncs(struct dd_function_table *functions) +{ + functions->BindTexture = i915BindTexture; + functions->TexEnv = i915TexEnv; +} diff --git a/src/mesa/drivers/dri/i915tex/i915_tex_layout.c b/src/mesa/drivers/dri/i915tex/i915_tex_layout.c new file mode 100644 index 0000000000..e9360ecea8 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_tex_layout.c @@ -0,0 +1,380 @@ +/************************************************************************** + * + * Copyright 2006 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 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 ITS 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. + * + **************************************************************************/ + +/* Code to layout images in a mipmap tree for i915 and i945 + * respectively. + */ + +#include "intel_mipmap_tree.h" +#include "macros.h" +#include "intel_context.h" + +#define FILE_DEBUG_FLAG DEBUG_TEXTURE + +static GLint initial_offsets[6][2] = { {0, 0}, +{0, 2}, +{1, 0}, +{1, 2}, +{1, 1}, +{1, 3} +}; + + +static GLint step_offsets[6][2] = { {0, 2}, +{0, 2}, +{-1, 2}, +{-1, 2}, +{-1, 1}, +{-1, 1} +}; + +static GLuint +minify(GLuint d) +{ + return MAX2(1, d >> 1); +} + +GLboolean +i915_miptree_layout(struct intel_mipmap_tree * mt) +{ + GLint level; + + switch (mt->target) { + case GL_TEXTURE_CUBE_MAP:{ + const GLuint dim = mt->width0; + GLuint face; + + /* double pitch for cube layouts */ + mt->pitch = ((dim * mt->cpp * 2 + 3) & ~3) / mt->cpp; + mt->total_height = dim * 4; + + for (level = mt->first_level; level <= mt->last_level; level++) + intel_miptree_set_level_info(mt, level, 6, + 0, 0, + mt->pitch, mt->total_height, 1); + + for (face = 0; face < 6; face++) { + GLuint x = initial_offsets[face][0] * dim; + GLuint y = initial_offsets[face][1] * dim; + GLuint d = dim; + + for (level = mt->first_level; level <= mt->last_level; level++) { + intel_miptree_set_image_offset(mt, level, face, x, y); + + if (d == 0) + _mesa_printf("cube mipmap %d/%d (%d..%d) is 0x0\n", + face, level, mt->first_level, mt->last_level); + + d >>= 1; + x += step_offsets[face][0] * d; + y += step_offsets[face][1] * d; + } + } + break; + } + case GL_TEXTURE_3D:{ + GLuint width = mt->width0; + GLuint height = mt->height0; + GLuint depth = mt->depth0; + GLuint stack_height = 0; + + /* Calculate the size of a single slice. + */ + mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; + + /* XXX: hardware expects/requires 9 levels at minimum. + */ + for (level = mt->first_level; level <= MAX2(8, mt->last_level); + level++) { + intel_miptree_set_level_info(mt, level, 1, 0, mt->total_height, + width, height, depth); + + + stack_height += MAX2(2, height); + + width = minify(width); + height = minify(height); + depth = minify(depth); + } + + /* Fixup depth image_offsets: + */ + depth = mt->depth0; + for (level = mt->first_level; level <= mt->last_level; level++) { + GLuint i; + for (i = 0; i < depth; i++) + intel_miptree_set_image_offset(mt, level, i, + 0, i * stack_height); + + depth = minify(depth); + } + + + /* Multiply slice size by texture depth for total size. It's + * remarkable how wasteful of memory the i915 texture layouts + * are. They are largely fixed in the i945. + */ + mt->total_height = stack_height * mt->depth0; + break; + } + + default:{ + GLuint width = mt->width0; + GLuint height = mt->height0; + GLuint img_height; + + mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; + mt->total_height = 0; + + for (level = mt->first_level; level <= mt->last_level; level++) { + intel_miptree_set_level_info(mt, level, 1, + 0, mt->total_height, + width, height, 1); + + if (mt->compressed) + img_height = MAX2(1, height / 4); + else + img_height = MAX2(2, height); + + mt->total_height += img_height; + mt->total_height += 1; + mt->total_height &= ~1; + + width = minify(width); + height = minify(height); + } + break; + } + } + DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__, + mt->pitch, + mt->total_height, mt->cpp, mt->pitch * mt->total_height * mt->cpp); + + return GL_TRUE; +} + + +GLboolean +i945_miptree_layout(struct intel_mipmap_tree * mt) +{ + GLint level; + + switch (mt->target) { + case GL_TEXTURE_CUBE_MAP:{ + const GLuint dim = mt->width0; + GLuint face; + + /* Depending on the size of the largest images, pitch can be + * determined either by the old-style packing of cubemap faces, + * or the final row of 4x4, 2x2 and 1x1 faces below this. + */ + if (dim > 32) + mt->pitch = ((dim * mt->cpp * 2 + 3) & ~3) / mt->cpp; + else + mt->pitch = 14 * 8; + + mt->total_height = dim * 4 + 4; + + /* Set all the levels to effectively occupy the whole rectangular region. + */ + for (level = mt->first_level; level <= mt->last_level; level++) + intel_miptree_set_level_info(mt, level, 6, + 0, 0, + mt->pitch, mt->total_height, 1); + + + + for (face = 0; face < 6; face++) { + GLuint x = initial_offsets[face][0] * dim; + GLuint y = initial_offsets[face][1] * dim; + GLuint d = dim; + + if (dim == 4 && face >= 4) { + y = mt->total_height - 4; + x = (face - 4) * 8; + } + else if (dim < 4) { + y = mt->total_height - 4; + x = face * 8; + } + + for (level = mt->first_level; level <= mt->last_level; level++) { + intel_miptree_set_image_offset(mt, level, face, x, y); + + d >>= 1; + + switch (d) { + case 4: + switch (face) { + case FACE_POS_X: + case FACE_NEG_X: + x += step_offsets[face][0] * d; + y += step_offsets[face][1] * d; + break; + case FACE_POS_Y: + case FACE_NEG_Y: + y += 12; + x -= 8; + break; + case FACE_POS_Z: + case FACE_NEG_Z: + y = mt->total_height - 4; + x = (face - 4) * 8; + break; + } + + case 2: + y = mt->total_height - 4; + x = 16 + face * 8; + break; + + case 1: + x += 48; + break; + + default: + x += step_offsets[face][0] * d; + y += step_offsets[face][1] * d; + break; + } + } + } + break; + } + case GL_TEXTURE_3D:{ + GLuint width = mt->width0; + GLuint height = mt->height0; + GLuint depth = mt->depth0; + GLuint pack_x_pitch, pack_x_nr; + GLuint pack_y_pitch; + GLuint level; + + mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; + mt->total_height = 0; + + pack_y_pitch = MAX2(mt->height0, 2); + pack_x_pitch = mt->pitch; + pack_x_nr = 1; + + for (level = mt->first_level; level <= mt->last_level; level++) { + GLuint nr_images = mt->target == GL_TEXTURE_3D ? depth : 6; + GLint x = 0; + GLint y = 0; + GLint q, j; + + intel_miptree_set_level_info(mt, level, nr_images, + 0, mt->total_height, + width, height, depth); + + for (q = 0; q < nr_images;) { + for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) { + intel_miptree_set_image_offset(mt, level, q, x, y); + x += pack_x_pitch; + } + + x = 0; + y += pack_y_pitch; + } + + + mt->total_height += y; + + if (pack_x_pitch > 4) { + pack_x_pitch >>= 1; + pack_x_nr <<= 1; + assert(pack_x_pitch * pack_x_nr <= mt->pitch); + } + + if (pack_y_pitch > 2) { + pack_y_pitch >>= 1; + } + + width = minify(width); + height = minify(height); + depth = minify(depth); + } + break; + } + + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_RECTANGLE_ARB:{ + GLuint x = 0; + GLuint y = 0; + GLuint width = mt->width0; + GLuint height = mt->height0; + GLint align_h = 2; + + mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; + mt->total_height = 0; + + for (level = mt->first_level; level <= mt->last_level; level++) { + GLuint img_height; + + intel_miptree_set_level_info(mt, level, 1, + x, y, + width, + mt->compressed ? height/4 : height, 1); + + + if (mt->compressed) + img_height = MAX2(1, height / 4); + else + img_height = MAX2(align_h, height); + + /* LPT change: step right after second mipmap. + */ + if (level == mt->first_level + 1) { + x += mt->pitch / 2; + x = (x + 3) & ~3; + } + else { + y += img_height; + y += align_h - 1; + y &= ~(align_h - 1); + } + + /* Because the images are packed better, the final offset + * might not be the maximal one: + */ + mt->total_height = MAX2(mt->total_height, y); + + width = minify(width); + height = minify(height); + } + break; + } + default: + _mesa_problem(NULL, "Unexpected tex target in i945_miptree_layout()"); + } + + DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__, + mt->pitch, + mt->total_height, mt->cpp, mt->pitch * mt->total_height * mt->cpp); + + return GL_TRUE; +} diff --git a/src/mesa/drivers/dri/i915tex/i915_texstate.c b/src/mesa/drivers/dri/i915tex/i915_texstate.c new file mode 100644 index 0000000000..e0ecdfde24 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_texstate.c @@ -0,0 +1,338 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#include "mtypes.h" +#include "enums.h" +#include "texformat.h" +#include "dri_bufmgr.h" + +#include "intel_mipmap_tree.h" +#include "intel_tex.h" + +#include "i915_context.h" +#include "i915_reg.h" + + +static GLuint +translate_texture_format(GLuint mesa_format) +{ + switch (mesa_format) { + case MESA_FORMAT_L8: + return MAPSURF_8BIT | MT_8BIT_L8; + case MESA_FORMAT_I8: + return MAPSURF_8BIT | MT_8BIT_I8; + case MESA_FORMAT_A8: + return MAPSURF_8BIT | MT_8BIT_A8; + case MESA_FORMAT_AL88: + return MAPSURF_16BIT | MT_16BIT_AY88; + case MESA_FORMAT_RGB565: + return MAPSURF_16BIT | MT_16BIT_RGB565; + case MESA_FORMAT_ARGB1555: + return MAPSURF_16BIT | MT_16BIT_ARGB1555; + case MESA_FORMAT_ARGB4444: + return MAPSURF_16BIT | MT_16BIT_ARGB4444; + case MESA_FORMAT_ARGB8888: + return MAPSURF_32BIT | MT_32BIT_ARGB8888; + case MESA_FORMAT_YCBCR_REV: + return (MAPSURF_422 | MT_422_YCRCB_NORMAL); + case MESA_FORMAT_YCBCR: + return (MAPSURF_422 | MT_422_YCRCB_SWAPY); + case MESA_FORMAT_RGB_FXT1: + case MESA_FORMAT_RGBA_FXT1: + return (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1); + case MESA_FORMAT_Z16: + return (MAPSURF_16BIT | MT_16BIT_L16); + case MESA_FORMAT_RGBA_DXT1: + case MESA_FORMAT_RGB_DXT1: + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); + case MESA_FORMAT_RGBA_DXT3: + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3); + case MESA_FORMAT_RGBA_DXT5: + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); + case MESA_FORMAT_Z24_S8: + return (MAPSURF_32BIT | MT_32BIT_xL824); + default: + fprintf(stderr, "%s: bad image format %x\n", __FUNCTION__, mesa_format); + abort(); + return 0; + } +} + + + + +/* The i915 (and related graphics cores) do not support GL_CLAMP. The + * Intel drivers for "other operating systems" implement GL_CLAMP as + * GL_CLAMP_TO_EDGE, so the same is done here. + */ +static GLuint +translate_wrap_mode(GLenum wrap) +{ + switch (wrap) { + case GL_REPEAT: + return TEXCOORDMODE_WRAP; + case GL_CLAMP: + return TEXCOORDMODE_CLAMP_EDGE; /* not quite correct */ + case GL_CLAMP_TO_EDGE: + return TEXCOORDMODE_CLAMP_EDGE; + case GL_CLAMP_TO_BORDER: + return TEXCOORDMODE_CLAMP_BORDER; + case GL_MIRRORED_REPEAT: + return TEXCOORDMODE_MIRROR; + default: + return TEXCOORDMODE_WRAP; + } +} + + + +/* Recalculate all state from scratch. Perhaps not the most + * efficient, but this has gotten complex enough that we need + * something which is understandable and reliable. + */ +static GLboolean +i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) +{ + GLcontext *ctx = &intel->ctx; + struct i915_context *i915 = i915_context(ctx); + struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current; + struct intel_texture_object *intelObj = intel_texture_object(tObj); + struct gl_texture_image *firstImage; + GLuint *state = i915->state.Tex[unit]; + + memset(state, 0, sizeof(state)); + + /*We need to refcount these. */ + + if (i915->state.tex_buffer[unit] != NULL) { + driBOUnReference(i915->state.tex_buffer[unit]); + i915->state.tex_buffer[unit] = NULL; + } + + if (!intel_finalize_mipmap_tree(intel, unit)) + return GL_FALSE; + + /* Get first image here, since intelObj->firstLevel will get set in + * the intel_finalize_mipmap_tree() call above. + */ + firstImage = tObj->Image[0][intelObj->firstLevel]; + + i915->state.tex_buffer[unit] = driBOReference(intelObj->mt->region->buffer); + i915->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt, 0, + intelObj-> + firstLevel); + + state[I915_TEXREG_MS3] = + (((firstImage->Height - 1) << MS3_HEIGHT_SHIFT) | + ((firstImage->Width - 1) << MS3_WIDTH_SHIFT) | + translate_texture_format(firstImage->TexFormat->MesaFormat) | + MS3_USE_FENCE_REGS); + + state[I915_TEXREG_MS4] = + (((((intelObj->mt->pitch * intelObj->mt->cpp) / 4) - + 1) << MS4_PITCH_SHIFT) | MS4_CUBE_FACE_ENA_MASK | + ((((intelObj->lastLevel - + intelObj->firstLevel) * + 4)) << MS4_MAX_LOD_SHIFT) | ((firstImage->Depth - + 1) << MS4_VOLUME_DEPTH_SHIFT)); + + + { + GLuint minFilt, mipFilt, magFilt; + + switch (tObj->MinFilter) { + case GL_NEAREST: + minFilt = FILTER_NEAREST; + mipFilt = MIPFILTER_NONE; + break; + case GL_LINEAR: + minFilt = FILTER_LINEAR; + mipFilt = MIPFILTER_NONE; + break; + case GL_NEAREST_MIPMAP_NEAREST: + minFilt = FILTER_NEAREST; + mipFilt = MIPFILTER_NEAREST; + break; + case GL_LINEAR_MIPMAP_NEAREST: + minFilt = FILTER_LINEAR; + mipFilt = MIPFILTER_NEAREST; + break; + case GL_NEAREST_MIPMAP_LINEAR: + minFilt = FILTER_NEAREST; + mipFilt = MIPFILTER_LINEAR; + break; + case GL_LINEAR_MIPMAP_LINEAR: + minFilt = FILTER_LINEAR; + mipFilt = MIPFILTER_LINEAR; + break; + default: + return GL_FALSE; + } + + if (tObj->MaxAnisotropy > 1.0) { + minFilt = FILTER_ANISOTROPIC; + magFilt = FILTER_ANISOTROPIC; + } + else { + switch (tObj->MagFilter) { + case GL_NEAREST: + magFilt = FILTER_NEAREST; + break; + case GL_LINEAR: + magFilt = FILTER_LINEAR; + break; + default: + return GL_FALSE; + } + } + + state[I915_TEXREG_SS2] = i915->lodbias_ss2[unit]; + + /* YUV conversion: + */ + if (firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR || + firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV) + state[I915_TEXREG_SS2] |= SS2_COLORSPACE_CONVERSION; + + /* Shadow: + */ + if (tObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB && + tObj->Target != GL_TEXTURE_3D) { + + state[I915_TEXREG_SS2] |= + (SS2_SHADOW_ENABLE | + intel_translate_compare_func(tObj->CompareFunc)); + + minFilt = FILTER_4X4_FLAT; + magFilt = FILTER_4X4_FLAT; + } + + state[I915_TEXREG_SS2] |= ((minFilt << SS2_MIN_FILTER_SHIFT) | + (mipFilt << SS2_MIP_FILTER_SHIFT) | + (magFilt << SS2_MAG_FILTER_SHIFT)); + } + + { + GLenum ws = tObj->WrapS; + GLenum wt = tObj->WrapT; + GLenum wr = tObj->WrapR; + + + /* 3D textures don't seem to respect the border color. + * Fallback if there's ever a danger that they might refer to + * it. + * + * Effectively this means fallback on 3D clamp or + * clamp_to_border. + */ + if (tObj->Target == GL_TEXTURE_3D && + (tObj->MinFilter != GL_NEAREST || + tObj->MagFilter != GL_NEAREST) && + (ws == GL_CLAMP || + wt == GL_CLAMP || + wr == GL_CLAMP || + ws == GL_CLAMP_TO_BORDER || + wt == GL_CLAMP_TO_BORDER || wr == GL_CLAMP_TO_BORDER)) + return GL_FALSE; + + + state[I915_TEXREG_SS3] = ss3; /* SS3_NORMALIZED_COORDS */ + + state[I915_TEXREG_SS3] |= + ((translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT) | + (translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT) | + (translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT)); + + state[I915_TEXREG_SS3] |= (unit << SS3_TEXTUREMAP_INDEX_SHIFT); + } + + + state[I915_TEXREG_SS4] = INTEL_PACKCOLOR8888(tObj->_BorderChan[0], + tObj->_BorderChan[1], + tObj->_BorderChan[2], + tObj->_BorderChan[3]); + + + I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(unit), GL_TRUE); + /* memcmp was already disabled, but definitely won't work as the + * region might now change and that wouldn't be detected: + */ + I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit)); + + +#if 0 + DBG(TEXTURE, "state[I915_TEXREG_SS2] = 0x%x\n", state[I915_TEXREG_SS2]); + DBG(TEXTURE, "state[I915_TEXREG_SS3] = 0x%x\n", state[I915_TEXREG_SS3]); + DBG(TEXTURE, "state[I915_TEXREG_SS4] = 0x%x\n", state[I915_TEXREG_SS4]); + DBG(TEXTURE, "state[I915_TEXREG_MS2] = 0x%x\n", state[I915_TEXREG_MS2]); + DBG(TEXTURE, "state[I915_TEXREG_MS3] = 0x%x\n", state[I915_TEXREG_MS3]); + DBG(TEXTURE, "state[I915_TEXREG_MS4] = 0x%x\n", state[I915_TEXREG_MS4]); +#endif + + return GL_TRUE; +} + + + + +void +i915UpdateTextureState(struct intel_context *intel) +{ + GLboolean ok = GL_TRUE; + GLuint i; + + for (i = 0; i < I915_TEX_UNITS && ok; i++) { + switch (intel->ctx.Texture.Unit[i]._ReallyEnabled) { + case TEXTURE_1D_BIT: + case TEXTURE_2D_BIT: + case TEXTURE_CUBE_BIT: + case TEXTURE_3D_BIT: + ok = i915_update_tex_unit(intel, i, SS3_NORMALIZED_COORDS); + break; + case TEXTURE_RECT_BIT: + ok = i915_update_tex_unit(intel, i, 0); + break; + case 0:{ + struct i915_context *i915 = i915_context(&intel->ctx); + if (i915->state.active & I915_UPLOAD_TEX(i)) + I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(i), GL_FALSE); + + if (i915->state.tex_buffer[i] != NULL) { + driBOUnReference(i915->state.tex_buffer[i]); + i915->state.tex_buffer[i] = NULL; + } + + break; + } + default: + ok = GL_FALSE; + break; + } + } + + FALLBACK(intel, I915_FALLBACK_TEXTURE, !ok); +} diff --git a/src/mesa/drivers/dri/i915tex/i915_vtbl.c b/src/mesa/drivers/dri/i915tex/i915_vtbl.c new file mode 100644 index 0000000000..827990d2cf --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_vtbl.c @@ -0,0 +1,549 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + + + +#include "glheader.h" +#include "mtypes.h" +#include "imports.h" +#include "macros.h" +#include "colormac.h" + +#include "tnl/t_context.h" +#include "tnl/t_vertex.h" + +#include "intel_batchbuffer.h" +#include "intel_tex.h" +#include "intel_regions.h" + +#include "i915_reg.h" +#include "i915_context.h" + +static void +i915_render_start(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + + i915ValidateFragmentProgram(i915); +} + + +static void +i915_reduced_primitive_state(struct intel_context *intel, GLenum rprim) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + GLuint st1 = i915->state.Stipple[I915_STPREG_ST1]; + + st1 &= ~ST1_ENABLE; + + switch (rprim) { + case GL_TRIANGLES: + if (intel->ctx.Polygon.StippleFlag && intel->hw_stipple) + st1 |= ST1_ENABLE; + break; + case GL_LINES: + case GL_POINTS: + default: + break; + } + + i915->intel.reduced_primitive = rprim; + + if (st1 != i915->state.Stipple[I915_STPREG_ST1]) { + INTEL_FIREVERTICES(intel); + + I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); + i915->state.Stipple[I915_STPREG_ST1] = st1; + } +} + + +/* Pull apart the vertex format registers and figure out how large a + * vertex is supposed to be. + */ +static GLboolean +i915_check_vertex_size(struct intel_context *intel, GLuint expected) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + int lis2 = i915->current->Ctx[I915_CTXREG_LIS2]; + int lis4 = i915->current->Ctx[I915_CTXREG_LIS4]; + int i, sz = 0; + + switch (lis4 & S4_VFMT_XYZW_MASK) { + case S4_VFMT_XY: + sz = 2; + break; + case S4_VFMT_XYZ: + sz = 3; + break; + case S4_VFMT_XYW: + sz = 3; + break; + case S4_VFMT_XYZW: + sz = 4; + break; + default: + fprintf(stderr, "no xyzw specified\n"); + return 0; + } + + if (lis4 & S4_VFMT_SPEC_FOG) + sz++; + if (lis4 & S4_VFMT_COLOR) + sz++; + if (lis4 & S4_VFMT_DEPTH_OFFSET) + sz++; + if (lis4 & S4_VFMT_POINT_WIDTH) + sz++; + if (lis4 & S4_VFMT_FOG_PARAM) + sz++; + + for (i = 0; i < 8; i++) { + switch (lis2 & S2_TEXCOORD_FMT0_MASK) { + case TEXCOORDFMT_2D: + sz += 2; + break; + case TEXCOORDFMT_3D: + sz += 3; + break; + case TEXCOORDFMT_4D: + sz += 4; + break; + case TEXCOORDFMT_1D: + sz += 1; + break; + case TEXCOORDFMT_2D_16: + sz += 1; + break; + case TEXCOORDFMT_4D_16: + sz += 2; + break; + case TEXCOORDFMT_NOT_PRESENT: + break; + default: + fprintf(stderr, "bad texcoord fmt %d\n", i); + return GL_FALSE; + } + lis2 >>= S2_TEXCOORD_FMT1_SHIFT; + } + + if (sz != expected) + fprintf(stderr, "vertex size mismatch %d/%d\n", sz, expected); + + return sz == expected; +} + + +static void +i915_emit_invarient_state(struct intel_context *intel) +{ + BATCH_LOCALS; + + BEGIN_BATCH(200, 0); + + OUT_BATCH(_3DSTATE_AA_CMD | + AA_LINE_ECAAR_WIDTH_ENABLE | + AA_LINE_ECAAR_WIDTH_1_0 | + AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0); + + OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_DFLT_Z_CMD); + OUT_BATCH(0); + + /* Don't support texture crossbar yet */ + OUT_BATCH(_3DSTATE_COORD_SET_BINDINGS | + CSB_TCB(0, 0) | + CSB_TCB(1, 1) | + CSB_TCB(2, 2) | + CSB_TCB(3, 3) | + CSB_TCB(4, 4) | CSB_TCB(5, 5) | CSB_TCB(6, 6) | CSB_TCB(7, 7)); + + OUT_BATCH(_3DSTATE_RASTER_RULES_CMD | + ENABLE_POINT_RASTER_RULE | + OGL_POINT_RASTER_RULE | + ENABLE_LINE_STRIP_PROVOKE_VRTX | + ENABLE_TRI_FAN_PROVOKE_VRTX | + LINE_STRIP_PROVOKE_VRTX(1) | + TRI_FAN_PROVOKE_VRTX(2) | ENABLE_TEXKILL_3D_4D | TEXKILL_4D); + + /* Need to initialize this to zero. + */ + OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | (1)); + OUT_BATCH(0); + + /* XXX: Use this */ + OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); + + OUT_BATCH(_3DSTATE_SCISSOR_RECT_0_CMD); + OUT_BATCH(0); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_DEPTH_SUBRECT_DISABLE); + + OUT_BATCH(_3DSTATE_LOAD_INDIRECT | 0); /* disable indirect state */ + OUT_BATCH(0); + + + /* Don't support twosided stencil yet */ + OUT_BATCH(_3DSTATE_BACKFACE_STENCIL_OPS | BFO_ENABLE_STENCIL_TWO_SIDE | 0); + + ADVANCE_BATCH(); +} + + +#define emit(intel, state, size ) \ + intel_batchbuffer_data(intel->batch, state, size, 0 ) + +static GLuint +get_dirty(struct i915_hw_state *state) +{ + GLuint dirty; + + /* Workaround the multitex hang - if one texture unit state is + * modified, emit all texture units. + */ + dirty = state->active & ~state->emitted; + if (dirty & I915_UPLOAD_TEX_ALL) + state->emitted &= ~I915_UPLOAD_TEX_ALL; + dirty = state->active & ~state->emitted; + return dirty; +} + + +static GLuint +get_state_size(struct i915_hw_state *state) +{ + GLuint dirty = get_dirty(state); + GLuint i; + GLuint sz = 0; + + if (dirty & I915_UPLOAD_CTX) + sz += sizeof(state->Ctx); + + if (dirty & I915_UPLOAD_BUFFERS) + sz += sizeof(state->Buffer); + + if (dirty & I915_UPLOAD_STIPPLE) + sz += sizeof(state->Stipple); + + if (dirty & I915_UPLOAD_FOG) + sz += sizeof(state->Fog); + + if (dirty & I915_UPLOAD_TEX_ALL) { + int nr = 0; + for (i = 0; i < I915_TEX_UNITS; i++) + if (dirty & I915_UPLOAD_TEX(i)) + nr++; + + sz += (2 + nr * 3) * sizeof(GLuint) * 2; + } + + if (dirty & I915_UPLOAD_CONSTANTS) + sz += state->ConstantSize * sizeof(GLuint); + + if (dirty & I915_UPLOAD_PROGRAM) + sz += state->ProgramSize * sizeof(GLuint); + + return sz; +} + + +/* Push the state into the sarea and/or texture memory. + */ +static void +i915_emit_state(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + struct i915_hw_state *state = i915->current; + int i; + GLuint dirty; + BATCH_LOCALS; + + /* We don't hold the lock at this point, so want to make sure that + * there won't be a buffer wrap. + * + * It might be better to talk about explicit places where + * scheduling is allowed, rather than assume that it is whenever a + * batchbuffer fills up. + */ + intel_batchbuffer_require_space(intel->batch, get_state_size(state), 0); + + /* Do this here as we may have flushed the batchbuffer above, + * causing more state to be dirty! + */ + dirty = get_dirty(state); + + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "%s dirty: %x\n", __FUNCTION__, dirty); + + if (dirty & I915_UPLOAD_INVARIENT) { + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "I915_UPLOAD_INVARIENT:\n"); + i915_emit_invarient_state(intel); + } + + if (dirty & I915_UPLOAD_CTX) { + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "I915_UPLOAD_CTX:\n"); + emit(intel, state->Ctx, sizeof(state->Ctx)); + } + + if (dirty & I915_UPLOAD_BUFFERS) { + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "I915_UPLOAD_BUFFERS:\n"); + BEGIN_BATCH(I915_DEST_SETUP_SIZE + 2, 0); + OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR0]); + OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR1]); + OUT_RELOC(state->draw_region->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, + state->draw_region->draw_offset); + + if (state->depth_region) { + OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR0]); + OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR1]); + OUT_RELOC(state->depth_region->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, + state->depth_region->draw_offset); + } + + OUT_BATCH(state->Buffer[I915_DESTREG_DV0]); + OUT_BATCH(state->Buffer[I915_DESTREG_DV1]); + OUT_BATCH(state->Buffer[I915_DESTREG_SENABLE]); + OUT_BATCH(state->Buffer[I915_DESTREG_SR0]); + OUT_BATCH(state->Buffer[I915_DESTREG_SR1]); + OUT_BATCH(state->Buffer[I915_DESTREG_SR2]); + ADVANCE_BATCH(); + } + + if (dirty & I915_UPLOAD_STIPPLE) { + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "I915_UPLOAD_STIPPLE:\n"); + emit(intel, state->Stipple, sizeof(state->Stipple)); + } + + if (dirty & I915_UPLOAD_FOG) { + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "I915_UPLOAD_FOG:\n"); + emit(intel, state->Fog, sizeof(state->Fog)); + } + + /* Combine all the dirty texture state into a single command to + * avoid lockups on I915 hardware. + */ + if (dirty & I915_UPLOAD_TEX_ALL) { + int nr = 0; + + for (i = 0; i < I915_TEX_UNITS; i++) + if (dirty & I915_UPLOAD_TEX(i)) + nr++; + + BEGIN_BATCH(2 + nr * 3, 0); + OUT_BATCH(_3DSTATE_MAP_STATE | (3 * nr)); + OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT); + for (i = 0; i < I915_TEX_UNITS; i++) + if (dirty & I915_UPLOAD_TEX(i)) { + + if (state->tex_buffer[i]) { + OUT_RELOC(state->tex_buffer[i], + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, + state->tex_offset[i]); + } + else { + assert(i == 0); + assert(state == &i915->meta); + OUT_BATCH(0); + } + + OUT_BATCH(state->Tex[i][I915_TEXREG_MS3]); + OUT_BATCH(state->Tex[i][I915_TEXREG_MS4]); + } + ADVANCE_BATCH(); + + BEGIN_BATCH(2 + nr * 3, 0); + OUT_BATCH(_3DSTATE_SAMPLER_STATE | (3 * nr)); + OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT); + for (i = 0; i < I915_TEX_UNITS; i++) + if (dirty & I915_UPLOAD_TEX(i)) { + OUT_BATCH(state->Tex[i][I915_TEXREG_SS2]); + OUT_BATCH(state->Tex[i][I915_TEXREG_SS3]); + OUT_BATCH(state->Tex[i][I915_TEXREG_SS4]); + } + ADVANCE_BATCH(); + } + + if (dirty & I915_UPLOAD_CONSTANTS) { + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "I915_UPLOAD_CONSTANTS:\n"); + emit(intel, state->Constant, state->ConstantSize * sizeof(GLuint)); + } + + if (dirty & I915_UPLOAD_PROGRAM) { + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "I915_UPLOAD_PROGRAM:\n"); + + assert((state->Program[0] & 0x1ff) + 2 == state->ProgramSize); + + emit(intel, state->Program, state->ProgramSize * sizeof(GLuint)); + if (INTEL_DEBUG & DEBUG_STATE) + i915_disassemble_program(state->Program, state->ProgramSize); + } + + state->emitted |= dirty; +} + +static void +i915_destroy_context(struct intel_context *intel) +{ + _tnl_free_vertices(&intel->ctx); +} + + +/** + * Set the drawing regions for the color and depth/stencil buffers. + * This involves setting the pitch, cpp and buffer ID/location. + * Also set pixel format for color and Z rendering + * Used for setting both regular and meta state. + */ +void +i915_state_draw_region(struct intel_context *intel, + struct i915_hw_state *state, + struct intel_region *color_region, + struct intel_region *depth_region) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + GLuint value; + + ASSERT(state == &i915->state || state == &i915->meta); + + if (state->draw_region != color_region) { + intel_region_release(&state->draw_region); + intel_region_reference(&state->draw_region, color_region); + } + if (state->depth_region != depth_region) { + intel_region_release(&state->depth_region); + intel_region_reference(&state->depth_region, depth_region); + } + + /* + * Set stride/cpp values + */ + if (color_region) { + state->Buffer[I915_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD; + state->Buffer[I915_DESTREG_CBUFADDR1] = + (BUF_3D_ID_COLOR_BACK | + BUF_3D_PITCH(color_region->pitch * color_region->cpp) | + BUF_3D_USE_FENCE); + } + + if (depth_region) { + state->Buffer[I915_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD; + state->Buffer[I915_DESTREG_DBUFADDR1] = + (BUF_3D_ID_DEPTH | + BUF_3D_PITCH(depth_region->pitch * depth_region->cpp) | + BUF_3D_USE_FENCE); + } + + /* + * Compute/set I915_DESTREG_DV1 value + */ + value = (DSTORG_HORT_BIAS(0x8) | /* .5 */ + DSTORG_VERT_BIAS(0x8) | /* .5 */ + LOD_PRECLAMP_OGL | TEX_DEFAULT_COLOR_OGL); + if (color_region && color_region->cpp == 4) { + value |= DV_PF_8888; + } + else { + value |= (DITHER_FULL_ALWAYS | DV_PF_565); + } + if (depth_region && depth_region->cpp == 4) { + value |= DEPTH_FRMT_24_FIXED_8_OTHER; + } + else { + value |= DEPTH_FRMT_16_FIXED; + } + state->Buffer[I915_DESTREG_DV1] = value; + + I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); +} + + +static void +i915_set_draw_region(struct intel_context *intel, + struct intel_region *color_region, + struct intel_region *depth_region) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + i915_state_draw_region(intel, &i915->state, color_region, depth_region); +} + + + +static void +i915_lost_hardware(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + i915->state.emitted = 0; +} + +static GLuint +i915_flush_cmd(void) +{ + return MI_FLUSH | FLUSH_MAP_CACHE; +} + +static void +i915_assert_not_dirty( struct intel_context *intel ) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + struct i915_hw_state *state = i915->current; + GLuint dirty = get_dirty(state); + assert(!dirty); +} + + +void +i915InitVtbl(struct i915_context *i915) +{ + i915->intel.vtbl.check_vertex_size = i915_check_vertex_size; + i915->intel.vtbl.destroy = i915_destroy_context; + i915->intel.vtbl.emit_state = i915_emit_state; + i915->intel.vtbl.lost_hardware = i915_lost_hardware; + i915->intel.vtbl.reduced_primitive_state = i915_reduced_primitive_state; + i915->intel.vtbl.render_start = i915_render_start; + i915->intel.vtbl.set_draw_region = i915_set_draw_region; + i915->intel.vtbl.update_texture_state = i915UpdateTextureState; + i915->intel.vtbl.flush_cmd = i915_flush_cmd; + i915->intel.vtbl.assert_not_dirty = i915_assert_not_dirty; +} diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c new file mode 100644 index 0000000000..b4e0b74f16 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c @@ -0,0 +1,342 @@ +/************************************************************************** + * + * Copyright 2006 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 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 ITS 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. + * + **************************************************************************/ + +#include "intel_batchbuffer.h" +#include "intel_ioctl.h" + +/* Relocations in kernel space: + * - pass dma buffer seperately + * - memory manager knows how to patch + * - pass list of dependent buffers + * - pass relocation list + * + * Either: + * - get back an offset for buffer to fire + * - memory manager knows how to fire buffer + * + * Really want the buffer to be AGP and pinned. + * + */ + +/* Cliprect fence: The highest fence protecting a dma buffer + * containing explicit cliprect information. Like the old drawable + * lock but irq-driven. X server must wait for this fence to expire + * before changing cliprects [and then doing sw rendering?]. For + * other dma buffers, the scheduler will grab current cliprect info + * and mix into buffer. X server must hold the lock while changing + * cliprects??? Make per-drawable. Need cliprects in shared memory + * -- beats storing them with every cmd buffer in the queue. + * + * ==> X server must wait for this fence to expire before touching the + * framebuffer with new cliprects. + * + * ==> Cliprect-dependent buffers associated with a + * cliprect-timestamp. All of the buffers associated with a timestamp + * must go to hardware before any buffer with a newer timestamp. + * + * ==> Dma should be queued per-drawable for correct X/GL + * synchronization. Or can fences be used for this? + * + * Applies to: Blit operations, metaops, X server operations -- X + * server automatically waits on its own dma to complete before + * modifying cliprects ??? + */ + +static void +intel_dump_batchbuffer(GLuint offset, GLuint * ptr, GLuint count) +{ + int i; + fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", count / 4); + for (i = 0; i < count / 4; i += 4) + fprintf(stderr, "0x%x:\t0x%08x 0x%08x 0x%08x 0x%08x\n", + offset + i * 4, ptr[i], ptr[i + 1], ptr[i + 2], ptr[i + 3]); + fprintf(stderr, "END BATCH\n\n\n"); +} + +void +intel_batchbuffer_reset(struct intel_batchbuffer *batch) +{ + + int i; + + /* + * Get a new, free batchbuffer. + */ + + batch->size = batch->intel->intelScreen->maxBatchSize; + driBOData(batch->buffer, batch->size, NULL, 0); + + driBOResetList(&batch->list); + + /* + * Unreference buffers previously on the relocation list. + */ + + for (i = 0; i < batch->nr_relocs; i++) { + struct buffer_reloc *r = &batch->reloc[i]; + driBOUnReference(r->buf); + } + + batch->list_count = 0; + batch->nr_relocs = 0; + batch->flags = 0; + + /* + * We don't refcount the batchbuffer itself since we can't destroy it + * while it's on the list. + */ + + + driBOAddListItem(&batch->list, batch->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_EXE); + + + batch->map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0); + batch->ptr = batch->map; +} + +/*====================================================================== + * Public functions + */ +struct intel_batchbuffer * +intel_batchbuffer_alloc(struct intel_context *intel) +{ + struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); + + batch->intel = intel; + + driGenBuffers(intel->intelScreen->batchPool, "batchbuffer", 1, + &batch->buffer, 4096, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, 0); + batch->last_fence = NULL; + driBOCreateList(20, &batch->list); + intel_batchbuffer_reset(batch); + return batch; +} + +void +intel_batchbuffer_free(struct intel_batchbuffer *batch) +{ + if (batch->last_fence) { + driFenceFinish(batch->last_fence, + DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW, GL_FALSE); + driFenceUnReference(batch->last_fence); + batch->last_fence = NULL; + } + if (batch->map) { + driBOUnmap(batch->buffer); + batch->map = NULL; + } + driBOUnReference(batch->buffer); + batch->buffer = NULL; + free(batch); +} + +/* TODO: Push this whole function into bufmgr. + */ +static void +do_flush_locked(struct intel_batchbuffer *batch, + GLuint used, + GLboolean ignore_cliprects, GLboolean allow_unlock) +{ + GLuint *ptr; + GLuint i; + struct intel_context *intel = batch->intel; + unsigned fenceFlags; + struct _DriFenceObject *fo; + + driBOValidateList(batch->intel->driFd, &batch->list); + + /* Apply the relocations. This nasty map indicates to me that the + * whole task should be done internally by the memory manager, and + * that dma buffers probably need to be pinned within agp space. + */ + ptr = (GLuint *) driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, + DRM_BO_HINT_ALLOW_UNFENCED_MAP); + + + for (i = 0; i < batch->nr_relocs; i++) { + struct buffer_reloc *r = &batch->reloc[i]; + + ptr[r->offset / 4] = driBOOffset(r->buf) + r->delta; + } + + if (INTEL_DEBUG & DEBUG_BATCH) + intel_dump_batchbuffer(0, ptr, used); + + driBOUnmap(batch->buffer); + batch->map = NULL; + + /* Throw away non-effective packets. Won't work once we have + * hardware contexts which would preserve statechanges beyond a + * single buffer. + */ + + if (!(intel->numClipRects == 0 && !ignore_cliprects)) { + intel_batch_ioctl(batch->intel, + driBOOffset(batch->buffer), + used, ignore_cliprects, allow_unlock); + } + + + /* + * Kernel fencing. The flags tells the kernel that we've + * programmed an MI_FLUSH. + */ + + fenceFlags = DRM_I915_FENCE_FLAG_FLUSHED; + fo = driFenceBuffers(batch->intel->driFd, + "Batch fence", fenceFlags); + + /* + * User space fencing. + */ + + driBOFence(batch->buffer, fo); + + if (driFenceType(fo) == DRM_FENCE_TYPE_EXE) { + + /* + * Oops. We only validated a batch buffer. This means we + * didn't do any proper rendering. Discard this fence object. + */ + + driFenceUnReference(fo); + } else { + driFenceUnReference(batch->last_fence); + batch->last_fence = fo; + for (i = 0; i < batch->nr_relocs; i++) { + struct buffer_reloc *r = &batch->reloc[i]; + driBOFence(r->buf, fo); + } + } + + if (intel->numClipRects == 0 && !ignore_cliprects) { + if (allow_unlock) { + UNLOCK_HARDWARE(intel); + sched_yield(); + LOCK_HARDWARE(intel); + } + intel->vtbl.lost_hardware(intel); + } +} + + +struct _DriFenceObject * +intel_batchbuffer_flush(struct intel_batchbuffer *batch) +{ + struct intel_context *intel = batch->intel; + GLuint used = batch->ptr - batch->map; + + if (used == 0) + return batch->last_fence; + + /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a + * performance drain that we would like to avoid. + */ + if (used & 4) { + ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->ptr)[1] = 0; + ((int *) batch->ptr)[2] = MI_BATCH_BUFFER_END; + used += 12; + } + else { + ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->ptr)[1] = MI_BATCH_BUFFER_END; + used += 8; + } + + driBOUnmap(batch->buffer); + batch->ptr = NULL; + batch->map = NULL; + + /* TODO: Just pass the relocation list and dma buffer up to the + * kernel. + */ + if (!intel->locked) { + assert(!(batch->flags & INTEL_BATCH_NO_CLIPRECTS)); + + LOCK_HARDWARE(intel); + do_flush_locked(batch, used, GL_FALSE, GL_TRUE); + UNLOCK_HARDWARE(intel); + } + else { + GLboolean ignore_cliprects = !(batch->flags & INTEL_BATCH_CLIPRECTS); + do_flush_locked(batch, used, ignore_cliprects, GL_FALSE); + } + + /* Reset the buffer: + */ + intel_batchbuffer_reset(batch); + return batch->last_fence; +} + +void +intel_batchbuffer_finish(struct intel_batchbuffer *batch) +{ + struct _DriFenceObject *fence = intel_batchbuffer_flush(batch); + driFenceReference(fence); + driFenceFinish(fence, 3, GL_FALSE); + driFenceUnReference(fence); +} + + +/* This is the only way buffers get added to the validate list. + */ +GLboolean +intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, + struct _DriBufferObject *buffer, + GLuint flags, GLuint mask, GLuint delta) +{ + assert(batch->nr_relocs <= MAX_RELOCS); + + driBOAddListItem(&batch->list, buffer, flags, mask); + + { + struct buffer_reloc *r = &batch->reloc[batch->nr_relocs++]; + driBOReference(buffer); + r->buf = buffer; + r->offset = batch->ptr - batch->map; + r->delta = delta; + } + + batch->ptr += 4; + return GL_TRUE; +} + + + +void +intel_batchbuffer_data(struct intel_batchbuffer *batch, + const void *data, GLuint bytes, GLuint flags) +{ + assert((bytes & 3) == 0); + intel_batchbuffer_require_space(batch, bytes, flags); + __memcpy(batch->ptr, data, bytes); + batch->ptr += bytes; +} diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h new file mode 100644 index 0000000000..a83dbf423d --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h @@ -0,0 +1,124 @@ +#ifndef INTEL_BATCHBUFFER_H +#define INTEL_BATCHBUFFER_H + +#include "mtypes.h" +#include "dri_bufmgr.h" + +struct intel_context; + +#define BATCH_SZ 16384 +#define BATCH_RESERVED 16 + +#define MAX_RELOCS 100 + +#define INTEL_BATCH_NO_CLIPRECTS 0x1 +#define INTEL_BATCH_CLIPRECTS 0x2 + +struct buffer_reloc +{ + struct _DriBufferObject *buf; + GLuint offset; + GLuint delta; /* not needed? */ +}; + +struct intel_batchbuffer +{ + struct bufmgr *bm; + struct intel_context *intel; + + struct _DriBufferObject *buffer; + struct _DriFenceObject *last_fence; + GLuint flags; + + drmBOList list; + GLuint list_count; + GLubyte *map; + GLubyte *ptr; + + struct buffer_reloc reloc[MAX_RELOCS]; + GLuint nr_relocs; + GLuint size; +}; + +struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context + *intel); + +void intel_batchbuffer_free(struct intel_batchbuffer *batch); + + +void intel_batchbuffer_finish(struct intel_batchbuffer *batch); + +struct _DriFenceObject *intel_batchbuffer_flush(struct intel_batchbuffer + *batch); + +void intel_batchbuffer_reset(struct intel_batchbuffer *batch); + + +/* Unlike bmBufferData, this currently requires the buffer be mapped. + * Consider it a convenience function wrapping multple + * intel_buffer_dword() calls. + */ +void intel_batchbuffer_data(struct intel_batchbuffer *batch, + const void *data, GLuint bytes, GLuint flags); + +void intel_batchbuffer_release_space(struct intel_batchbuffer *batch, + GLuint bytes); + +GLboolean intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, + struct _DriBufferObject *buffer, + GLuint flags, + GLuint mask, GLuint offset); + +/* Inline functions - might actually be better off with these + * non-inlined. Certainly better off switching all command packets to + * be passed as structs rather than dwords, but that's a little bit of + * work... + */ +static INLINE GLuint +intel_batchbuffer_space(struct intel_batchbuffer *batch) +{ + return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map); +} + + +static INLINE void +intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword) +{ + assert(batch->map); + assert(intel_batchbuffer_space(batch) >= 4); + *(GLuint *) (batch->ptr) = dword; + batch->ptr += 4; +} + +static INLINE void +intel_batchbuffer_require_space(struct intel_batchbuffer *batch, + GLuint sz, GLuint flags) +{ + assert(sz < batch->size - 8); + if (intel_batchbuffer_space(batch) < sz || + (batch->flags != 0 && flags != 0 && batch->flags != flags)) + intel_batchbuffer_flush(batch); + + batch->flags |= flags; +} + +/* Here are the crusty old macros, to be removed: + */ +#define BATCH_LOCALS + +#define BEGIN_BATCH(n, flags) do { \ + assert(!intel->prim.flush); \ + intel_batchbuffer_require_space(intel->batch, (n)*4, flags); \ +} while (0) + +#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) + +#define OUT_RELOC(buf,flags,mask,delta) do { \ + assert((delta) >= 0); \ + intel_batchbuffer_emit_reloc(intel->batch, buf, flags, mask, delta); \ +} while (0) + +#define ADVANCE_BATCH() do { } while(0) + + +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_batchpool.c b/src/mesa/drivers/dri/i915tex/intel_batchpool.c new file mode 100644 index 0000000000..3c17c50204 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_batchpool.c @@ -0,0 +1,418 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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, 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 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 + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + */ + +#include +#include +#include +#include "imports.h" +#include "glthread.h" +#include "dri_bufpool.h" +#include "dri_bufmgr.h" +#include "intel_screen.h" + +typedef struct +{ + drmMMListHead head; + struct _BPool *parent; + struct _DriFenceObject *fence; + unsigned long start; + int unfenced; + int mapped; +} BBuf; + +typedef struct _BPool +{ + _glthread_Mutex mutex; + unsigned long bufSize; + unsigned poolSize; + unsigned numFree; + unsigned numTot; + unsigned numDelayed; + unsigned checkDelayed; + drmMMListHead free; + drmMMListHead delayed; + drmMMListHead head; + drmBO kernelBO; + void *virtual; + BBuf *bufs; +} BPool; + + +static BPool * +createBPool(int fd, unsigned long bufSize, unsigned numBufs, unsigned flags, + unsigned checkDelayed) +{ + BPool *p = (BPool *) malloc(sizeof(*p)); + BBuf *buf; + int i; + + if (!p) + return NULL; + + p->bufs = (BBuf *) malloc(numBufs * sizeof(*p->bufs)); + if (!p->bufs) { + free(p); + return NULL; + } + + DRMINITLISTHEAD(&p->free); + DRMINITLISTHEAD(&p->head); + DRMINITLISTHEAD(&p->delayed); + + p->numTot = numBufs; + p->numFree = numBufs; + p->bufSize = bufSize; + p->numDelayed = 0; + p->checkDelayed = checkDelayed; + + _glthread_INIT_MUTEX(p->mutex); + + if (drmBOCreate(fd, 0, numBufs * bufSize, 0, NULL, drm_bo_type_dc, + flags, 0, &p->kernelBO)) { + free(p->bufs); + free(p); + return NULL; + } + if (drmBOMap(fd, &p->kernelBO, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, + &p->virtual)) { + drmBODestroy(fd, &p->kernelBO); + free(p->bufs); + free(p); + return NULL; + } + + /* + * We unmap the buffer so that we can validate it later. Note that this is + * just a synchronizing operation. The buffer will have a virtual mapping + * until it is destroyed. + */ + + drmBOUnmap(fd, &p->kernelBO); + + buf = p->bufs; + for (i = 0; i < numBufs; ++i) { + buf->parent = p; + buf->fence = NULL; + buf->start = i * bufSize; + buf->mapped = 0; + buf->unfenced = 0; + DRMLISTADDTAIL(&buf->head, &p->free); + buf++; + } + + return p; +} + + +static void +pool_checkFree(BPool * p, int wait) +{ + drmMMListHead *list, *prev; + BBuf *buf; + int signaled = 0; + int i; + + list = p->delayed.next; + + if (p->numDelayed > 3) { + for (i = 0; i < p->numDelayed; i += 3) { + list = list->next; + } + } + + prev = list->prev; + for (; list != &p->delayed; list = prev, prev = list->prev) { + + buf = DRMLISTENTRY(BBuf, list, head); + + if (!signaled) { + if (wait) { + driFenceFinish(buf->fence, DRM_FENCE_TYPE_EXE, 1); + signaled = 1; + } + else { + signaled = driFenceSignaled(buf->fence, DRM_FENCE_TYPE_EXE); + } + } + + if (!signaled) + break; + + driFenceUnReference(buf->fence); + buf->fence = NULL; + DRMLISTDEL(list); + p->numDelayed--; + DRMLISTADD(list, &p->free); + p->numFree++; + } +} + +static void * +pool_create(struct _DriBufferPool *pool, + unsigned long size, unsigned flags, unsigned hint, + unsigned alignment) +{ + BPool *p = (BPool *) pool->data; + + drmMMListHead *item; + + if (alignment && (alignment != 4096)) + return NULL; + + _glthread_LOCK_MUTEX(p->mutex); + + if (p->numFree == 0) + pool_checkFree(p, GL_TRUE); + + if (p->numFree == 0) { + fprintf(stderr, "Out of fixed size buffer objects\n"); + BM_CKFATAL(-ENOMEM); + } + + item = p->free.next; + + if (item == &p->free) { + fprintf(stderr, "Fixed size buffer pool corruption\n"); + } + + DRMLISTDEL(item); + --p->numFree; + + _glthread_UNLOCK_MUTEX(p->mutex); + return (void *) DRMLISTENTRY(BBuf, item, head); +} + + +static int +pool_destroy(struct _DriBufferPool *pool, void *private) +{ + BBuf *buf = (BBuf *) private; + BPool *p = buf->parent; + + _glthread_LOCK_MUTEX(p->mutex); + + if (buf->fence) { + DRMLISTADDTAIL(&buf->head, &p->delayed); + p->numDelayed++; + } + else { + buf->unfenced = 0; + DRMLISTADD(&buf->head, &p->free); + p->numFree++; + } + + if ((p->numDelayed % p->checkDelayed) == 0) + pool_checkFree(p, 0); + + _glthread_UNLOCK_MUTEX(p->mutex); + return 0; +} + + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, void **virtual) +{ + + BBuf *buf = (BBuf *) private; + BPool *p = buf->parent; + + _glthread_LOCK_MUTEX(p->mutex); + + /* + * Currently Mesa doesn't have any condition variables to resolve this + * cleanly in a multithreading environment. + * We bail out instead. + */ + + if (buf->mapped) { + fprintf(stderr, "Trying to map already mapped buffer object\n"); + BM_CKFATAL(-EINVAL); + } + +#if 0 + if (buf->unfenced && !(hint & DRM_BO_HINT_ALLOW_UNFENCED_MAP)) { + fprintf(stderr, "Trying to map an unfenced buffer object 0x%08x" + " 0x%08x %d\n", hint, flags, buf->start); + BM_CKFATAL(-EINVAL); + } + +#endif + + if (buf->fence) { + _glthread_UNLOCK_MUTEX(p->mutex); + return -EBUSY; + } + + buf->mapped = GL_TRUE; + *virtual = (unsigned char *) p->virtual + buf->start; + _glthread_UNLOCK_MUTEX(p->mutex); + return 0; +} + +static int +pool_waitIdle(struct _DriBufferPool *pool, void *private, int lazy) +{ + BBuf *buf = (BBuf *) private; + driFenceFinish(buf->fence, 0, lazy); + return 0; +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + BBuf *buf = (BBuf *) private; + + buf->mapped = 0; + return 0; +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + BBuf *buf = (BBuf *) private; + BPool *p = buf->parent; + + return p->kernelBO.offset + buf->start; +} + +static unsigned +pool_flags(struct _DriBufferPool *pool, void *private) +{ + BPool *p = (BPool *) pool->data; + + return p->kernelBO.flags; +} + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + BPool *p = (BPool *) pool->data; + + return p->bufSize; +} + + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + BBuf *buf = (BBuf *) private; + BPool *p = buf->parent; + + _glthread_LOCK_MUTEX(p->mutex); + if (buf->fence) { + driFenceUnReference(buf->fence); + } + buf->fence = fence; + buf->unfenced = 0; + driFenceReference(buf->fence); + _glthread_UNLOCK_MUTEX(p->mutex); + + return 0; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + BBuf *buf = (BBuf *) private; + BPool *p = buf->parent; + + return &p->kernelBO; +} + +static int +pool_validate(struct _DriBufferPool *pool, void *private) +{ + BBuf *buf = (BBuf *) private; + BPool *p = buf->parent; + _glthread_LOCK_MUTEX(p->mutex); + buf->unfenced = GL_TRUE; + _glthread_UNLOCK_MUTEX(p->mutex); + return 0; +} + +static void +pool_takedown(struct _DriBufferPool *pool) +{ + BPool *p = (BPool *) pool->data; + + /* + * Wait on outstanding fences. + */ + + _glthread_LOCK_MUTEX(p->mutex); + while ((p->numFree < p->numTot) && p->numDelayed) { + _glthread_UNLOCK_MUTEX(p->mutex); + sched_yield(); + pool_checkFree(p, GL_TRUE); + _glthread_LOCK_MUTEX(p->mutex); + } + + drmBODestroy(pool->fd, &p->kernelBO); + free(p->bufs); + _glthread_UNLOCK_MUTEX(p->mutex); + free(p); + free(pool); +} + + +struct _DriBufferPool * +driBatchPoolInit(int fd, unsigned flags, + unsigned long bufSize, + unsigned numBufs, unsigned checkDelayed) +{ + struct _DriBufferPool *pool; + + pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); + if (!pool) + return NULL; + + pool->data = createBPool(fd, bufSize, numBufs, flags, checkDelayed); + if (!pool->data) + return NULL; + + pool->fd = fd; + pool->map = &pool_map; + pool->unmap = &pool_unmap; + pool->destroy = &pool_destroy; + pool->offset = &pool_offset; + pool->flags = &pool_flags; + pool->size = &pool_size; + pool->create = &pool_create; + pool->fence = &pool_fence; + pool->kernel = &pool_kernel; + pool->validate = &pool_validate; + pool->waitIdle = &pool_waitIdle; + pool->setstatic = NULL; + pool->takeDown = &pool_takedown; + return pool; +} diff --git a/src/mesa/drivers/dri/i915tex/intel_blit.c b/src/mesa/drivers/dri/i915tex/intel_blit.c new file mode 100644 index 0000000000..b6b6543908 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_blit.c @@ -0,0 +1,552 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + + +#include +#include + +#include "mtypes.h" +#include "context.h" +#include "enums.h" + +#include "intel_batchbuffer.h" +#include "intel_blit.h" +#include "intel_buffers.h" +#include "intel_context.h" +#include "intel_fbo.h" +#include "intel_reg.h" +#include "intel_regions.h" +#include "vblank.h" + +#define FILE_DEBUG_FLAG DEBUG_BLIT + +/** + * Copy the back color buffer to the front color buffer. + * Used for SwapBuffers(). + */ +void +intelCopyBuffer(const __DRIdrawablePrivate * dPriv, + const drm_clip_rect_t * rect) +{ + + struct intel_context *intel; + const intelScreenPrivate *intelScreen; + GLboolean missed_target; + int64_t ust; + + DBG("%s\n", __FUNCTION__); + + assert(dPriv); + + intel = intelScreenContext(dPriv->driScreenPriv->private); + if (!intel) + return; + + intelScreen = intel->intelScreen; + + if (!rect && !intel->swap_scheduled && intelScreen->drmMinor >= 6 && + !(intel->vblank_flags & VBLANK_FLAG_NO_IRQ) && + intelScreen->current_rotation == 0) { + unsigned int interval = driGetVBlankInterval(dPriv, intel->vblank_flags); + unsigned int target; + drm_i915_vblank_swap_t swap; + + swap.drawable = dPriv->hHWDrawable; + swap.seqtype = DRM_VBLANK_ABSOLUTE; + target = swap.sequence = intel->vbl_seq + interval; + + if (intel->vblank_flags & VBLANK_FLAG_SYNC) { + swap.seqtype |= DRM_VBLANK_NEXTONMISS; + } else if (interval == 0) { + goto noschedule; + } + + if ( intel->vblank_flags & VBLANK_FLAG_SECONDARY ) { + swap.seqtype |= DRM_VBLANK_SECONDARY; + } + + intel_batchbuffer_flush(intel->batch); + + if (!drmCommandWriteRead(intel->driFd, DRM_I915_VBLANK_SWAP, &swap, + sizeof(swap))) { + intel->swap_scheduled = 1; + intel->vbl_seq = swap.sequence; + swap.sequence -= target; + missed_target = swap.sequence > 0 && swap.sequence <= (1 << 23); + } + } else { + intel->swap_scheduled = 0; + } +noschedule: + + if (intel->last_swap_fence) { + driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); + driFenceUnReference(intel->last_swap_fence); + intel->last_swap_fence = NULL; + } + intel->last_swap_fence = intel->first_swap_fence; + intel->first_swap_fence = NULL; + + if (!intel->swap_scheduled) { + if (!rect) { + driWaitForVBlank(dPriv, &intel->vbl_seq, intel->vblank_flags, + &missed_target); + } + + + /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets + * should work regardless. + */ + LOCK_HARDWARE(intel); + + if (intel->driDrawable && intel->driDrawable->numClipRects) { + const intelScreenPrivate *intelScreen = intel->intelScreen; + struct gl_framebuffer *fb + = (struct gl_framebuffer *) dPriv->driverPrivate; + const struct intel_region *frontRegion + = intel_get_rb_region(fb, BUFFER_FRONT_LEFT); + const struct intel_region *backRegion + = intel_get_rb_region(fb, BUFFER_BACK_LEFT); + const int nbox = dPriv->numClipRects; + const drm_clip_rect_t *pbox = dPriv->pClipRects; + const int pitch = frontRegion->pitch; + const int cpp = frontRegion->cpp; + int BR13, CMD; + int i; + + ASSERT(fb); + ASSERT(fb->Name == 0); /* Not a user-created FBO */ + ASSERT(frontRegion); + ASSERT(backRegion); + ASSERT(frontRegion->pitch == backRegion->pitch); + ASSERT(frontRegion->cpp == backRegion->cpp); + + if (cpp == 2) { + BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24); + CMD = XY_SRC_COPY_BLT_CMD; + } + else { + BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); + CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB); + } + + for (i = 0; i < nbox; i++, pbox++) { + drm_clip_rect_t box; + + if (pbox->x1 > pbox->x2 || + pbox->y1 > pbox->y2 || + pbox->x2 > intelScreen->width || pbox->y2 > intelScreen->height) + continue; + + box = *pbox; + + if (rect) { + if (rect->x1 > box.x1) + box.x1 = rect->x1; + if (rect->y1 > box.y1) + box.y1 = rect->y1; + if (rect->x2 < box.x2) + box.x2 = rect->x2; + if (rect->y2 < box.y2) + box.y2 = rect->y2; + + if (box.x1 > box.x2 || box.y1 > box.y2) + continue; + } + + BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((pbox->y1 << 16) | pbox->x1); + OUT_BATCH((pbox->y2 << 16) | pbox->x2); + + if (intel->sarea->pf_current_page == 0) + OUT_RELOC(frontRegion->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); + else + OUT_RELOC(backRegion->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); + OUT_BATCH((pbox->y1 << 16) | pbox->x1); + OUT_BATCH(BR13 & 0xffff); + + if (intel->sarea->pf_current_page == 0) + OUT_RELOC(backRegion->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); + else + OUT_RELOC(frontRegion->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); + + ADVANCE_BATCH(); + } + + if (intel->first_swap_fence) + driFenceUnReference(intel->first_swap_fence); + intel->first_swap_fence = intel_batchbuffer_flush(intel->batch); + driFenceReference(intel->first_swap_fence); + } + + UNLOCK_HARDWARE(intel); + } + + if (!rect) { + intel->swap_count++; + (*dri_interface->getUST) (&ust); + if (missed_target) { + intel->swap_missed_count++; + intel->swap_missed_ust = ust - intel->swap_ust; + } + + intel->swap_ust = ust; + } +} + + + + +void +intelEmitFillBlit(struct intel_context *intel, + GLuint cpp, + GLshort dst_pitch, + struct _DriBufferObject *dst_buffer, + GLuint dst_offset, + GLshort x, GLshort y, GLshort w, GLshort h, GLuint color) +{ + GLuint BR13, CMD; + BATCH_LOCALS; + + dst_pitch *= cpp; + + switch (cpp) { + case 1: + case 2: + case 3: + BR13 = dst_pitch | (0xF0 << 16) | (1 << 24); + CMD = XY_COLOR_BLT_CMD; + break; + case 4: + BR13 = dst_pitch | (0xF0 << 16) | (1 << 24) | (1 << 25); + CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA | + XY_COLOR_BLT_WRITE_RGB); + break; + default: + return; + } + + DBG("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", + __FUNCTION__, dst_buffer, dst_pitch, dst_offset, x, y, w, h); + + + BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((y << 16) | x); + OUT_BATCH(((y + h) << 16) | (x + w)); + OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, dst_offset); + OUT_BATCH(color); + ADVANCE_BATCH(); +} + + +/* Copy BitBlt + */ +void +intelEmitCopyBlit(struct intel_context *intel, + GLuint cpp, + GLshort src_pitch, + struct _DriBufferObject *src_buffer, + GLuint src_offset, + GLshort dst_pitch, + struct _DriBufferObject *dst_buffer, + GLuint dst_offset, + GLshort src_x, GLshort src_y, + GLshort dst_x, GLshort dst_y, GLshort w, GLshort h) +{ + GLuint CMD, BR13; + int dst_y2 = dst_y + h; + int dst_x2 = dst_x + w; + BATCH_LOCALS; + + + DBG("%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", + __FUNCTION__, + src_buffer, src_pitch, src_offset, src_x, src_y, + dst_buffer, dst_pitch, dst_offset, dst_x, dst_y, w, h); + + src_pitch *= cpp; + dst_pitch *= cpp; + + switch (cpp) { + case 1: + case 2: + case 3: + BR13 = (((GLint) dst_pitch) & 0xffff) | (0xCC << 16) | (1 << 24); + CMD = XY_SRC_COPY_BLT_CMD; + break; + case 4: + BR13 = + (((GLint) dst_pitch) & 0xffff) | (0xCC << 16) | (1 << 24) | (1 << + 25); + CMD = + (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB); + break; + default: + return; + } + + if (dst_y2 < dst_y || dst_x2 < dst_x) { + return; + } + + /* Initial y values don't seem to work with negative pitches. If + * we adjust the offsets manually (below), it seems to work fine. + * + * On the other hand, if we always adjust, the hardware doesn't + * know which blit directions to use, so overlapping copypixels get + * the wrong result. + */ + if (dst_pitch > 0 && src_pitch > 0) { + BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((dst_y << 16) | dst_x); + OUT_BATCH((dst_y2 << 16) | dst_x2); + OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, dst_offset); + OUT_BATCH((src_y << 16) | src_x); + OUT_BATCH(((GLint) src_pitch & 0xffff)); + OUT_RELOC(src_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, src_offset); + ADVANCE_BATCH(); + } + else { + BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((0 << 16) | dst_x); + OUT_BATCH((h << 16) | dst_x2); + OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, + dst_offset + dst_y * dst_pitch); + OUT_BATCH((0 << 16) | src_x); + OUT_BATCH(((GLint) src_pitch & 0xffff)); + OUT_RELOC(src_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, + src_offset + src_y * src_pitch); + ADVANCE_BATCH(); + } +} + + +/** + * Use blitting to clear the renderbuffers named by 'flags'. + * Note: we can't use the ctx->DrawBuffer->_ColorDrawBufferMask field + * since that might include software renderbuffers or renderbuffers + * which we're clearing with triangles. + * \param mask bitmask of BUFFER_BIT_* values indicating buffers to clear + */ +void +intelClearWithBlit(GLcontext * ctx, GLbitfield mask) +{ + struct intel_context *intel = intel_context(ctx); + GLuint clear_depth; + GLbitfield skipBuffers = 0; + BATCH_LOCALS; + + DBG("%s %x\n", __FUNCTION__, mask); + + /* + * Compute values for clearing the buffers. + */ + clear_depth = 0; + if (mask & BUFFER_BIT_DEPTH) { + clear_depth = (GLuint) (ctx->DrawBuffer->_DepthMax * ctx->Depth.Clear); + } + if (mask & BUFFER_BIT_STENCIL) { + clear_depth |= (ctx->Stencil.Clear & 0xff) << 24; + } + + /* If clearing both depth and stencil, skip BUFFER_BIT_STENCIL in + * the loop below. + */ + if ((mask & BUFFER_BIT_DEPTH) && (mask & BUFFER_BIT_STENCIL)) { + skipBuffers = BUFFER_BIT_STENCIL; + } + + /* XXX Move this flush/lock into the following conditional? */ + intelFlush(&intel->ctx); + LOCK_HARDWARE(intel); + + if (intel->numClipRects) { + GLint cx, cy, cw, ch; + drm_clip_rect_t clear; + int i; + + /* Get clear bounds after locking */ + cx = ctx->DrawBuffer->_Xmin; + cy = ctx->DrawBuffer->_Ymin; + cw = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; + ch = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; + + if (intel->ctx.DrawBuffer->Name == 0) { + /* clearing a window */ + + /* flip top to bottom */ + clear.x1 = cx + intel->drawX; + clear.y1 = intel->driDrawable->y + intel->driDrawable->h - cy - ch; + clear.x2 = clear.x1 + cw; + clear.y2 = clear.y1 + ch; + + /* adjust for page flipping */ + if (intel->sarea->pf_current_page == 1) { + const GLuint tmp = mask; + mask &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT); + if (tmp & BUFFER_BIT_FRONT_LEFT) + mask |= BUFFER_BIT_BACK_LEFT; + if (tmp & BUFFER_BIT_BACK_LEFT) + mask |= BUFFER_BIT_FRONT_LEFT; + } + } + else { + /* clearing FBO */ + assert(intel->numClipRects == 1); + assert(intel->pClipRects == &intel->fboRect); + clear.x1 = cx; + clear.y1 = cy; + clear.x2 = clear.x1 + cw; + clear.y2 = clear.y1 + ch; + /* no change to mask */ + } + + for (i = 0; i < intel->numClipRects; i++) { + const drm_clip_rect_t *box = &intel->pClipRects[i]; + drm_clip_rect_t b; + GLuint buf; + GLuint clearMask = mask; /* use copy, since we modify it below */ + GLboolean all = (cw == ctx->DrawBuffer->Width && + ch == ctx->DrawBuffer->Height); + + if (!all) { + intel_intersect_cliprects(&b, &clear, box); + } + else { + b = *box; + } + + if (0) + _mesa_printf("clear %d,%d..%d,%d, mask %x\n", + b.x1, b.y1, b.x2, b.y2, mask); + + /* Loop over all renderbuffers */ + for (buf = 0; buf < BUFFER_COUNT && clearMask; buf++) { + const GLbitfield bufBit = 1 << buf; + if ((clearMask & bufBit) && !(bufBit & skipBuffers)) { + /* OK, clear this renderbuffer */ + const struct intel_renderbuffer *irb + = intel_renderbuffer(ctx->DrawBuffer-> + Attachment[buf].Renderbuffer); + struct _DriBufferObject *write_buffer = + intel_region_buffer(intel->intelScreen, irb->region, + all ? INTEL_WRITE_FULL : + INTEL_WRITE_PART); + + GLuint clearVal; + GLint pitch, cpp; + GLuint BR13, CMD; + + ASSERT(irb); + ASSERT(irb->region); + + pitch = irb->region->pitch; + cpp = irb->region->cpp; + + DBG("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", + __FUNCTION__, + irb->region->buffer, (pitch * cpp), + irb->region->draw_offset, + b.x1, b.y1, b.x2 - b.x1, b.y2 - b.y1); + + + /* Setup the blit command */ + if (cpp == 4) { + BR13 = (0xF0 << 16) | (pitch * cpp) | (1 << 24) | (1 << 25); + if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) { + CMD = XY_COLOR_BLT_CMD; + if (clearMask & BUFFER_BIT_DEPTH) + CMD |= XY_COLOR_BLT_WRITE_RGB; + if (clearMask & BUFFER_BIT_STENCIL) + CMD |= XY_COLOR_BLT_WRITE_ALPHA; + } + else { + /* clearing RGBA */ + CMD = (XY_COLOR_BLT_CMD | + XY_COLOR_BLT_WRITE_ALPHA | + XY_COLOR_BLT_WRITE_RGB); + } + } + else { + ASSERT(cpp == 2 || cpp == 0); + BR13 = (0xF0 << 16) | (pitch * cpp) | (1 << 24); + CMD = XY_COLOR_BLT_CMD; + } + + if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) { + clearVal = clear_depth; + } + else { + clearVal = (cpp == 4) + ? intel->ClearColor8888 : intel->ClearColor565; + } + /* + _mesa_debug(ctx, "hardware blit clear buf %d rb id %d\n", + buf, irb->Base.Name); + */ + BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((b.y1 << 16) | b.x1); + OUT_BATCH((b.y2 << 16) | b.x2); + OUT_RELOC(write_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, + irb->region->draw_offset); + OUT_BATCH(clearVal); + ADVANCE_BATCH(); + clearMask &= ~bufBit; /* turn off bit, for faster loop exit */ + } + } + } + intel_batchbuffer_flush(intel->batch); + } + + UNLOCK_HARDWARE(intel); +} diff --git a/src/mesa/drivers/dri/i915tex/intel_blit.h b/src/mesa/drivers/dri/i915tex/intel_blit.h new file mode 100644 index 0000000000..ee85c62633 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_blit.h @@ -0,0 +1,61 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#ifndef INTEL_BLIT_H +#define INTEL_BLIT_H + +#include "intel_context.h" +#include "intel_ioctl.h" +#include "dri_bufmgr.h" + +extern void intelCopyBuffer(const __DRIdrawablePrivate * dpriv, + const drm_clip_rect_t * rect); + +extern void intelClearWithBlit(GLcontext * ctx, GLbitfield mask); + +extern void intelEmitCopyBlit(struct intel_context *intel, + GLuint cpp, + GLshort src_pitch, + struct _DriBufferObject *src_buffer, + GLuint src_offset, + GLshort dst_pitch, + struct _DriBufferObject *dst_buffer, + GLuint dst_offset, + GLshort srcx, GLshort srcy, + GLshort dstx, GLshort dsty, + GLshort w, GLshort h); + +extern void intelEmitFillBlit(struct intel_context *intel, + GLuint cpp, + GLshort dst_pitch, + struct _DriBufferObject *dst_buffer, + GLuint dst_offset, + GLshort x, GLshort y, + GLshort w, GLshort h, GLuint color); + + +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c new file mode 100644 index 0000000000..31c41d8685 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c @@ -0,0 +1,250 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + + +#include "imports.h" +#include "mtypes.h" +#include "bufferobj.h" + +#include "intel_context.h" +#include "intel_buffer_objects.h" +#include "intel_regions.h" +#include "dri_bufmgr.h" + +/** + * There is some duplication between mesa's bufferobjects and our + * bufmgr buffers. Both have an integer handle and a hashtable to + * lookup an opaque structure. It would be nice if the handles and + * internal structure where somehow shared. + */ +static struct gl_buffer_object * +intel_bufferobj_alloc(GLcontext * ctx, GLuint name, GLenum target) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_buffer_object *obj = CALLOC_STRUCT(intel_buffer_object); + + _mesa_initialize_buffer_object(&obj->Base, name, target); + + driGenBuffers(intel->intelScreen->regionPool, + "bufferobj", 1, &obj->buffer, 64, 0, 0); + + return &obj->Base; +} + + +/* Break the COW tie to the region. The region gets to keep the data. + */ +void +intel_bufferobj_release_region(struct intel_context *intel, + struct intel_buffer_object *intel_obj) +{ + assert(intel_obj->region->buffer == intel_obj->buffer); + intel_obj->region->pbo = NULL; + intel_obj->region = NULL; + driBOUnReference(intel_obj->buffer); + intel_obj->buffer = NULL; + + /* This leads to a large number of buffer deletion/creation events. + * Currently the drm doesn't like that: + */ + driGenBuffers(intel->intelScreen->regionPool, + "buffer object", 1, &intel_obj->buffer, 64, 0, 0); + driBOData(intel_obj->buffer, intel_obj->Base.Size, NULL, 0); +} + +/* Break the COW tie to the region. Both the pbo and the region end + * up with a copy of the data. + */ +void +intel_bufferobj_cow(struct intel_context *intel, + struct intel_buffer_object *intel_obj) +{ + assert(intel_obj->region); + intel_region_cow(intel->intelScreen, intel_obj->region); +} + + +/** + * Deallocate/free a vertex/pixel buffer object. + * Called via glDeleteBuffersARB(). + */ +static void +intel_bufferobj_free(GLcontext * ctx, struct gl_buffer_object *obj) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_buffer_object *intel_obj = intel_buffer_object(obj); + + assert(intel_obj); + + if (intel_obj->region) { + intel_bufferobj_release_region(intel, intel_obj); + } + else if (intel_obj->buffer) { + driDeleteBuffers(1, &intel_obj->buffer); + } + + _mesa_free(intel_obj); +} + + + +/** + * Allocate space for and store data in a buffer object. Any data that was + * previously stored in the buffer object is lost. If data is NULL, + * memory will be allocated, but no copy will occur. + * Called via glBufferDataARB(). + */ +static void +intel_bufferobj_data(GLcontext * ctx, + GLenum target, + GLsizeiptrARB size, + const GLvoid * data, + GLenum usage, struct gl_buffer_object *obj) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_buffer_object *intel_obj = intel_buffer_object(obj); + + intel_obj->Base.Size = size; + intel_obj->Base.Usage = usage; + + if (intel_obj->region) + intel_bufferobj_release_region(intel, intel_obj); + + driBOData(intel_obj->buffer, size, data, 0); +} + + +/** + * Replace data in a subrange of buffer object. If the data range + * specified by size + offset extends beyond the end of the buffer or + * if data is NULL, no copy is performed. + * Called via glBufferSubDataARB(). + */ +static void +intel_bufferobj_subdata(GLcontext * ctx, + GLenum target, + GLintptrARB offset, + GLsizeiptrARB size, + const GLvoid * data, struct gl_buffer_object *obj) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_buffer_object *intel_obj = intel_buffer_object(obj); + + assert(intel_obj); + + if (intel_obj->region) + intel_bufferobj_cow(intel, intel_obj); + + driBOSubData(intel_obj->buffer, offset, size, data); +} + + +/** + * Called via glGetBufferSubDataARB(). + */ +static void +intel_bufferobj_get_subdata(GLcontext * ctx, + GLenum target, + GLintptrARB offset, + GLsizeiptrARB size, + GLvoid * data, struct gl_buffer_object *obj) +{ + struct intel_buffer_object *intel_obj = intel_buffer_object(obj); + + assert(intel_obj); + driBOGetSubData(intel_obj->buffer, offset, size, data); +} + + + +/** + * Called via glMapBufferARB(). + */ +static void * +intel_bufferobj_map(GLcontext * ctx, + GLenum target, + GLenum access, struct gl_buffer_object *obj) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_buffer_object *intel_obj = intel_buffer_object(obj); + + /* XXX: Translate access to flags arg below: + */ + assert(intel_obj); + + if (intel_obj->region) + intel_bufferobj_cow(intel, intel_obj); + + obj->Pointer = driBOMap(intel_obj->buffer, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); + return obj->Pointer; +} + + +/** + * Called via glMapBufferARB(). + */ +static GLboolean +intel_bufferobj_unmap(GLcontext * ctx, + GLenum target, struct gl_buffer_object *obj) +{ + struct intel_buffer_object *intel_obj = intel_buffer_object(obj); + + assert(intel_obj); + assert(obj->Pointer); + driBOUnmap(intel_obj->buffer); + obj->Pointer = NULL; + return GL_TRUE; +} + +struct _DriBufferObject * +intel_bufferobj_buffer(struct intel_context *intel, + struct intel_buffer_object *intel_obj, GLuint flag) +{ + if (intel_obj->region) { + if (flag == INTEL_WRITE_PART) + intel_bufferobj_cow(intel, intel_obj); + else if (flag == INTEL_WRITE_FULL) + intel_bufferobj_release_region(intel, intel_obj); + } + + return intel_obj->buffer; +} + +void +intel_bufferobj_init(struct intel_context *intel) +{ + GLcontext *ctx = &intel->ctx; + + ctx->Driver.NewBufferObject = intel_bufferobj_alloc; + ctx->Driver.DeleteBuffer = intel_bufferobj_free; + ctx->Driver.BufferData = intel_bufferobj_data; + ctx->Driver.BufferSubData = intel_bufferobj_subdata; + ctx->Driver.GetBufferSubData = intel_bufferobj_get_subdata; + ctx->Driver.MapBuffer = intel_bufferobj_map; + ctx->Driver.UnmapBuffer = intel_bufferobj_unmap; +} diff --git a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.h b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.h new file mode 100644 index 0000000000..afe9b2f7cf --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.h @@ -0,0 +1,86 @@ + /************************************************************************** + * + * Copyright 2005 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 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 ITS 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. + * + **************************************************************************/ + +#ifndef INTEL_BUFFEROBJ_H +#define INTEL_BUFFEROBJ_H + +#include "mtypes.h" + +struct intel_context; +struct intel_region; +struct gl_buffer_object; + + +/** + * Intel vertex/pixel buffer object, derived from Mesa's gl_buffer_object. + */ +struct intel_buffer_object +{ + struct gl_buffer_object Base; + struct _DriBufferObject *buffer; /* the low-level buffer manager's buffer handle */ + + struct intel_region *region; /* Is there a zero-copy texture + associated with this (pixel) + buffer object? */ +}; + + +/* Get the bm buffer associated with a GL bufferobject: + */ +struct _DriBufferObject *intel_bufferobj_buffer(struct intel_context *intel, + struct intel_buffer_object + *obj, GLuint flag); + +/* Hook the bufferobject implementation into mesa: + */ +void intel_bufferobj_init(struct intel_context *intel); + + + +/* Are the obj->Name tests necessary? Unfortunately yes, mesa + * allocates a couple of gl_buffer_object structs statically, and + * the Name == 0 test is the only way to identify them and avoid + * casting them erroneously to our structs. + */ +static INLINE struct intel_buffer_object * +intel_buffer_object(struct gl_buffer_object *obj) +{ + if (obj->Name) + return (struct intel_buffer_object *) obj; + else + return NULL; +} + +/* Helpers for zerocopy image uploads. See also intel_regions.h: + */ +void intel_bufferobj_cow(struct intel_context *intel, + struct intel_buffer_object *intel_obj); +void intel_bufferobj_release_region(struct intel_context *intel, + struct intel_buffer_object *intel_obj); + + +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_buffers.c b/src/mesa/drivers/dri/i915tex/intel_buffers.c new file mode 100644 index 0000000000..d3925bbc1e --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_buffers.c @@ -0,0 +1,956 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_blit.h" +#include "intel_buffers.h" +#include "intel_depthstencil.h" +#include "intel_fbo.h" +#include "intel_tris.h" +#include "intel_regions.h" +#include "intel_batchbuffer.h" +#include "context.h" +#include "utils.h" +#include "framebuffer.h" +#include "swrast/swrast.h" +#include "vblank.h" + + +/** + * XXX move this into a new dri/common/cliprects.c file. + */ +GLboolean +intel_intersect_cliprects(drm_clip_rect_t * dst, + const drm_clip_rect_t * a, + const drm_clip_rect_t * b) +{ + GLint bx = b->x1; + GLint by = b->y1; + GLint bw = b->x2 - bx; + GLint bh = b->y2 - by; + + if (bx < a->x1) + bw -= a->x1 - bx, bx = a->x1; + if (by < a->y1) + bh -= a->y1 - by, by = a->y1; + if (bx + bw > a->x2) + bw = a->x2 - bx; + if (by + bh > a->y2) + bh = a->y2 - by; + if (bw <= 0) + return GL_FALSE; + if (bh <= 0) + return GL_FALSE; + + dst->x1 = bx; + dst->y1 = by; + dst->x2 = bx + bw; + dst->y2 = by + bh; + + return GL_TRUE; +} + +/** + * Return pointer to current color drawing region, or NULL. + */ +struct intel_region * +intel_drawbuf_region(struct intel_context *intel) +{ + struct intel_renderbuffer *irbColor = + intel_renderbuffer(intel->ctx.DrawBuffer->_ColorDrawBuffers[0][0]); + if (irbColor) + return irbColor->region; + else + return NULL; +} + +/** + * Return pointer to current color reading region, or NULL. + */ +struct intel_region * +intel_readbuf_region(struct intel_context *intel) +{ + struct intel_renderbuffer *irb + = intel_renderbuffer(intel->ctx.ReadBuffer->_ColorReadBuffer); + if (irb) + return irb->region; + else + return NULL; +} + + + +static void +intelBufferSize(GLframebuffer * buffer, GLuint * width, GLuint * height) +{ + GET_CURRENT_CONTEXT(ctx); + struct intel_context *intel = intel_context(ctx); + /* Need to lock to make sure the driDrawable is uptodate. This + * information is used to resize Mesa's software buffers, so it has + * to be correct. + */ + /* XXX This isn't 100% correct, the given buffer might not be + * bound to the current context! + */ + LOCK_HARDWARE(intel); + if (intel->driDrawable) { + *width = intel->driDrawable->w; + *height = intel->driDrawable->h; + } + else { + *width = 0; + *height = 0; + } + UNLOCK_HARDWARE(intel); +} + + + +/** + * Update the following fields for rendering to a user-created FBO: + * intel->numClipRects + * intel->pClipRects + * intel->drawX + * intel->drawY + */ +static void +intelSetRenderbufferClipRects(struct intel_context *intel) +{ + assert(intel->ctx.DrawBuffer->Width > 0); + assert(intel->ctx.DrawBuffer->Height > 0); + intel->fboRect.x1 = 0; + intel->fboRect.y1 = 0; + intel->fboRect.x2 = intel->ctx.DrawBuffer->Width; + intel->fboRect.y2 = intel->ctx.DrawBuffer->Height; + intel->numClipRects = 1; + intel->pClipRects = &intel->fboRect; + intel->drawX = 0; + intel->drawY = 0; +} + + +/** + * As above, but for rendering to front buffer of a window. + * \sa intelSetRenderbufferClipRects + */ +static void +intelSetFrontClipRects(struct intel_context *intel) +{ + __DRIdrawablePrivate *dPriv = intel->driDrawable; + + if (!dPriv) + return; + + intel->numClipRects = dPriv->numClipRects; + intel->pClipRects = dPriv->pClipRects; + intel->drawX = dPriv->x; + intel->drawY = dPriv->y; +} + + +/** + * As above, but for rendering to back buffer of a window. + */ +static void +intelSetBackClipRects(struct intel_context *intel) +{ + __DRIdrawablePrivate *dPriv = intel->driDrawable; + + if (!dPriv) + return; + + if (intel->sarea->pf_enabled == 0 && dPriv->numBackClipRects == 0) { + /* use the front clip rects */ + intel->numClipRects = dPriv->numClipRects; + intel->pClipRects = dPriv->pClipRects; + intel->drawX = dPriv->x; + intel->drawY = dPriv->y; + } + else { + /* use the back clip rects */ + intel->numClipRects = dPriv->numBackClipRects; + intel->pClipRects = dPriv->pBackClipRects; + intel->drawX = dPriv->backX; + intel->drawY = dPriv->backY; + } +} + + +/** + * This will be called whenever the currently bound window is moved/resized. + * XXX: actually, it seems to NOT be called when the window is only moved (BP). + */ +void +intelWindowMoved(struct intel_context *intel) +{ + GLcontext *ctx = &intel->ctx; + + if (!intel->ctx.DrawBuffer) { + /* when would this happen? -BP */ + intelSetFrontClipRects(intel); + } + else if (intel->ctx.DrawBuffer->Name != 0) { + /* drawing to user-created FBO - do nothing */ + /* Cliprects would be set from intelDrawBuffer() */ + } + else { + /* drawing to a window */ + switch (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0]) { + case BUFFER_BIT_FRONT_LEFT: + intelSetFrontClipRects(intel); + break; + case BUFFER_BIT_BACK_LEFT: + intelSetBackClipRects(intel); + break; + default: + /* glDrawBuffer(GL_NONE or GL_FRONT_AND_BACK): software fallback */ + intelSetFrontClipRects(intel); + } + } + + /* this update Mesa's notion of window size */ + if (ctx->WinSysDrawBuffer) { + _mesa_resize_framebuffer(ctx, ctx->WinSysDrawBuffer, + intel->driDrawable->w, intel->driDrawable->h); + } + + if (intel->intelScreen->driScrnPriv->ddxMinor >= 7 && intel->driDrawable) { + __DRIdrawablePrivate *dPriv = intel->driDrawable; + drmI830Sarea *sarea = intel->sarea; + drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w, + .y1 = dPriv->y, .y2 = dPriv->y + dPriv->h }; + drm_clip_rect_t pipeA_rect = { .x1 = sarea->pipeA_x, .y1 = sarea->pipeA_y, + .x2 = sarea->pipeA_x + sarea->pipeA_w, + .y2 = sarea->pipeA_y + sarea->pipeA_h }; + drm_clip_rect_t pipeB_rect = { .x1 = sarea->pipeB_x, .y1 = sarea->pipeB_y, + .x2 = sarea->pipeB_x + sarea->pipeB_w, + .y2 = sarea->pipeB_y + sarea->pipeB_h }; + GLint areaA = driIntersectArea( drw_rect, pipeA_rect ); + GLint areaB = driIntersectArea( drw_rect, pipeB_rect ); + GLuint flags = intel->vblank_flags; + + if (areaB > areaA || (areaA == areaB && areaB > 0)) { + flags = intel->vblank_flags | VBLANK_FLAG_SECONDARY; + } else { + flags = intel->vblank_flags & ~VBLANK_FLAG_SECONDARY; + } + + if (flags != intel->vblank_flags) { + intel->vblank_flags = flags; + driGetCurrentVBlank(dPriv, intel->vblank_flags, &intel->vbl_seq); + } + } else { + intel->vblank_flags &= ~VBLANK_FLAG_SECONDARY; + } + + /* Update hardware scissor */ + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); +} + + + +/* A true meta version of this would be very simple and additionally + * machine independent. Maybe we'll get there one day. + */ +static void +intelClearWithTris(struct intel_context *intel, GLbitfield mask) +{ + GLcontext *ctx = &intel->ctx; + drm_clip_rect_t clear; + + if (INTEL_DEBUG & DEBUG_BLIT) + _mesa_printf("%s 0x%x\n", __FUNCTION__, mask); + + LOCK_HARDWARE(intel); + + /* XXX FBO: was: intel->driDrawable->numClipRects */ + if (intel->numClipRects) { + GLint cx, cy, cw, ch; + GLuint buf; + + intel->vtbl.install_meta_state(intel); + + /* Get clear bounds after locking */ + cx = ctx->DrawBuffer->_Xmin; + cy = ctx->DrawBuffer->_Ymin; + ch = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; + cw = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; + + /* note: regardless of 'all', cx, cy, cw, ch are now correct */ + clear.x1 = cx; + clear.y1 = cy; + clear.x2 = cx + cw; + clear.y2 = cy + ch; + + /* Back and stencil cliprects are the same. Try and do both + * buffers at once: + */ + if (mask & + (BUFFER_BIT_BACK_LEFT | BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH)) { + struct intel_region *backRegion = + intel_get_rb_region(ctx->DrawBuffer, BUFFER_BACK_LEFT); + struct intel_region *depthRegion = + intel_get_rb_region(ctx->DrawBuffer, BUFFER_DEPTH); + const GLuint clearColor = (backRegion && backRegion->cpp == 4) + ? intel->ClearColor8888 : intel->ClearColor565; + + intel->vtbl.meta_draw_region(intel, backRegion, depthRegion); + + if (mask & BUFFER_BIT_BACK_LEFT) + intel->vtbl.meta_color_mask(intel, GL_TRUE); + else + intel->vtbl.meta_color_mask(intel, GL_FALSE); + + if (mask & BUFFER_BIT_STENCIL) + intel->vtbl.meta_stencil_replace(intel, + intel->ctx.Stencil.WriteMask[0], + intel->ctx.Stencil.Clear); + else + intel->vtbl.meta_no_stencil_write(intel); + + if (mask & BUFFER_BIT_DEPTH) + intel->vtbl.meta_depth_replace(intel); + else + intel->vtbl.meta_no_depth_write(intel); + + /* XXX: Using INTEL_BATCH_NO_CLIPRECTS here is dangerous as the + * drawing origin may not be correctly emitted. + */ + intel_meta_draw_quad(intel, clear.x1, clear.x2, clear.y1, clear.y2, intel->ctx.Depth.Clear, clearColor, 0, 0, 0, 0); /* texcoords */ + + mask &= + ~(BUFFER_BIT_BACK_LEFT | BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH); + } + + /* clear the remaining (color) renderbuffers */ + for (buf = 0; buf < BUFFER_COUNT && mask; buf++) { + const GLuint bufBit = 1 << buf; + if (mask & bufBit) { + struct intel_renderbuffer *irbColor = + intel_renderbuffer(ctx->DrawBuffer-> + Attachment[buf].Renderbuffer); + GLuint color = (irbColor->region->cpp == 4) + ? intel->ClearColor8888 : intel->ClearColor565; + + ASSERT(irbColor); + + intel->vtbl.meta_no_depth_write(intel); + intel->vtbl.meta_no_stencil_write(intel); + intel->vtbl.meta_color_mask(intel, GL_TRUE); + intel->vtbl.meta_draw_region(intel, irbColor->region, NULL); + + /* XXX: Using INTEL_BATCH_NO_CLIPRECTS here is dangerous as the + * drawing origin may not be correctly emitted. + */ + intel_meta_draw_quad(intel, clear.x1, clear.x2, clear.y1, clear.y2, 0, /* depth clear val */ + color, 0, 0, 0, 0); /* texcoords */ + + mask &= ~bufBit; + } + } + + intel->vtbl.leave_meta_state(intel); + intel_batchbuffer_flush(intel->batch); + } + UNLOCK_HARDWARE(intel); +} + + + + +/** + * Copy the window contents named by dPriv to the rotated (or reflected) + * color buffer. + * srcBuf is BUFFER_BIT_FRONT_LEFT or BUFFER_BIT_BACK_LEFT to indicate the source. + */ +void +intelRotateWindow(struct intel_context *intel, + __DRIdrawablePrivate * dPriv, GLuint srcBuf) +{ + intelScreenPrivate *screen = intel->intelScreen; + drm_clip_rect_t fullRect; + struct intel_region *src; + const drm_clip_rect_t *clipRects; + int numClipRects; + int i; + GLenum format, type; + + int xOrig, yOrig; + int origNumClipRects; + drm_clip_rect_t *origRects; + + /* + * set up hardware state + */ + intelFlush(&intel->ctx); + + LOCK_HARDWARE(intel); + + if (!intel->numClipRects) { + UNLOCK_HARDWARE(intel); + return; + } + + intel->vtbl.install_meta_state(intel); + + intel->vtbl.meta_no_depth_write(intel); + intel->vtbl.meta_no_stencil_write(intel); + intel->vtbl.meta_color_mask(intel, GL_FALSE); + + + /* save current drawing origin and cliprects (restored at end) */ + xOrig = intel->drawX; + yOrig = intel->drawY; + origNumClipRects = intel->numClipRects; + origRects = intel->pClipRects; + + /* + * set drawing origin, cliprects for full-screen access to rotated screen + */ + fullRect.x1 = 0; + fullRect.y1 = 0; + fullRect.x2 = screen->rotatedWidth; + fullRect.y2 = screen->rotatedHeight; + intel->drawX = 0; + intel->drawY = 0; + intel->numClipRects = 1; + intel->pClipRects = &fullRect; + + intel->vtbl.meta_draw_region(intel, screen->rotated_region, NULL); /* ? */ + + if (srcBuf == BUFFER_BIT_FRONT_LEFT) { + src = intel->intelScreen->front_region; + clipRects = dPriv->pClipRects; + numClipRects = dPriv->numClipRects; + } + else { + src = intel->intelScreen->back_region; + clipRects = dPriv->pBackClipRects; + numClipRects = dPriv->numBackClipRects; + } + + if (src->cpp == 4) { + format = GL_BGRA; + type = GL_UNSIGNED_BYTE; + } + else { + format = GL_BGR; + type = GL_UNSIGNED_SHORT_5_6_5_REV; + } + + /* set the whole screen up as a texture to avoid alignment issues */ + intel->vtbl.meta_tex_rect_source(intel, + src->buffer, + screen->width, + screen->height, src->pitch, format, type); + + intel->vtbl.meta_texture_blend_replace(intel); + + /* + * loop over the source window's cliprects + */ + for (i = 0; i < numClipRects; i++) { + int srcX0 = clipRects[i].x1; + int srcY0 = clipRects[i].y1; + int srcX1 = clipRects[i].x2; + int srcY1 = clipRects[i].y2; + GLfloat verts[4][2], tex[4][2]; + int j; + + /* build vertices for four corners of clip rect */ + verts[0][0] = srcX0; + verts[0][1] = srcY0; + verts[1][0] = srcX1; + verts[1][1] = srcY0; + verts[2][0] = srcX1; + verts[2][1] = srcY1; + verts[3][0] = srcX0; + verts[3][1] = srcY1; + + /* .. and texcoords */ + tex[0][0] = srcX0; + tex[0][1] = srcY0; + tex[1][0] = srcX1; + tex[1][1] = srcY0; + tex[2][0] = srcX1; + tex[2][1] = srcY1; + tex[3][0] = srcX0; + tex[3][1] = srcY1; + + /* transform coords to rotated screen coords */ + + for (j = 0; j < 4; j++) { + matrix23TransformCoordf(&screen->rotMatrix, + &verts[j][0], &verts[j][1]); + } + + /* draw polygon to map source image to dest region */ + intel_meta_draw_poly(intel, 4, verts, 0, 0, tex); + + } /* cliprect loop */ + + intel->vtbl.leave_meta_state(intel); + intel_batchbuffer_flush(intel->batch); + + /* restore original drawing origin and cliprects */ + intel->drawX = xOrig; + intel->drawY = yOrig; + intel->numClipRects = origNumClipRects; + intel->pClipRects = origRects; + + UNLOCK_HARDWARE(intel); +} + + +/** + * Called by ctx->Driver.Clear. + */ +static void +intelClear(GLcontext *ctx, GLbitfield mask) +{ + struct intel_context *intel = intel_context(ctx); + const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask); + GLbitfield tri_mask = 0; + GLbitfield blit_mask = 0; + GLbitfield swrast_mask = 0; + GLuint i; + + if (0) + fprintf(stderr, "%s\n", __FUNCTION__); + + /* HW color buffers (front, back, aux, generic FBO, etc) */ + if (colorMask == ~0) { + /* clear all R,G,B,A */ + /* XXX FBO: need to check if colorbuffers are software RBOs! */ + blit_mask |= (mask & BUFFER_BITS_COLOR); + } + else { + /* glColorMask in effect */ + tri_mask |= (mask & BUFFER_BITS_COLOR); + } + + /* HW stencil */ + if (mask & BUFFER_BIT_STENCIL) { + const struct intel_region *stencilRegion + = intel_get_rb_region(ctx->DrawBuffer, BUFFER_STENCIL); + if (stencilRegion) { + /* have hw stencil */ + if ((ctx->Stencil.WriteMask[0] & 0xff) != 0xff) { + /* not clearing all stencil bits, so use triangle clearing */ + tri_mask |= BUFFER_BIT_STENCIL; + } + else { + /* clearing all stencil bits, use blitting */ + blit_mask |= BUFFER_BIT_STENCIL; + } + } + } + + /* HW depth */ + if (mask & BUFFER_BIT_DEPTH) { + /* clear depth with whatever method is used for stencil (see above) */ + if (tri_mask & BUFFER_BIT_STENCIL) + tri_mask |= BUFFER_BIT_DEPTH; + else + blit_mask |= BUFFER_BIT_DEPTH; + } + + /* SW fallback clearing */ + swrast_mask = mask & ~tri_mask & ~blit_mask; + + for (i = 0; i < BUFFER_COUNT; i++) { + GLuint bufBit = 1 << i; + if ((blit_mask | tri_mask) & bufBit) { + if (!ctx->DrawBuffer->Attachment[i].Renderbuffer->ClassID) { + blit_mask &= ~bufBit; + tri_mask &= ~bufBit; + swrast_mask |= bufBit; + } + } + } + + + intelFlush(ctx); /* XXX intelClearWithBlit also does this */ + + if (blit_mask) + intelClearWithBlit(ctx, blit_mask); + + if (tri_mask) + intelClearWithTris(intel, tri_mask); + + if (swrast_mask) + _swrast_Clear(ctx, swrast_mask); +} + + + +/* Flip the front & back buffers + */ +static void +intelPageFlip(const __DRIdrawablePrivate * dPriv) +{ +#if 0 + struct intel_context *intel; + int tmp, ret; + + if (INTEL_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s\n", __FUNCTION__); + + assert(dPriv); + assert(dPriv->driContextPriv); + assert(dPriv->driContextPriv->driverPrivate); + + intel = (struct intel_context *) dPriv->driContextPriv->driverPrivate; + + intelFlush(&intel->ctx); + LOCK_HARDWARE(intel); + + if (dPriv->pClipRects) { + *(drm_clip_rect_t *) intel->sarea->boxes = dPriv->pClipRects[0]; + intel->sarea->nbox = 1; + } + + ret = drmCommandNone(intel->driFd, DRM_I830_FLIP); + if (ret) { + fprintf(stderr, "%s: %d\n", __FUNCTION__, ret); + UNLOCK_HARDWARE(intel); + exit(1); + } + + tmp = intel->sarea->last_enqueue; + intelRefillBatchLocked(intel); + UNLOCK_HARDWARE(intel); + + + intelSetDrawBuffer(&intel->ctx, intel->ctx.Color.DriverDrawBuffer); +#endif +} + +#if 0 +void +intelSwapBuffers(__DRIdrawablePrivate * dPriv) +{ + if (dPriv->driverPrivate) { + const struct gl_framebuffer *fb + = (struct gl_framebuffer *) dPriv->driverPrivate; + if (fb->Visual.doubleBufferMode) { + GET_CURRENT_CONTEXT(ctx); + if (ctx && ctx->DrawBuffer == fb) { + _mesa_notifySwapBuffers(ctx); /* flush pending rendering */ + } + if (0 /*intel->doPageFlip */ ) { /* doPageFlip is never set !!! */ + intelPageFlip(dPriv); + } + else { + intelCopyBuffer(dPriv); + } + } + } + else { + _mesa_problem(NULL, + "dPriv has no gl_framebuffer pointer in intelSwapBuffers"); + } +} +#else +/* Trunk version: + */ +void +intelSwapBuffers(__DRIdrawablePrivate * dPriv) +{ + if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { + GET_CURRENT_CONTEXT(ctx); + struct intel_context *intel; + + if (ctx == NULL) + return; + + intel = intel_context(ctx); + + if (ctx->Visual.doubleBufferMode) { + intelScreenPrivate *screen = intel->intelScreen; + _mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */ + if (0 /*intel->doPageFlip */ ) { /* doPageFlip is never set !!! */ + intelPageFlip(dPriv); + } + else { + intelCopyBuffer(dPriv, NULL); + } + if (screen->current_rotation != 0) { + intelRotateWindow(intel, dPriv, BUFFER_BIT_FRONT_LEFT); + } + } + } + else { + /* XXX this shouldn't be an error but we can't handle it for now */ + fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__); + } +} +#endif + +void +intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) +{ + if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { + struct intel_context *intel = + (struct intel_context *) dPriv->driContextPriv->driverPrivate; + GLcontext *ctx = &intel->ctx; + + if (ctx->Visual.doubleBufferMode) { + drm_clip_rect_t rect; + rect.x1 = x + dPriv->x; + rect.y1 = (dPriv->h - y - h) + dPriv->y; + rect.x2 = rect.x1 + w; + rect.y2 = rect.y1 + h; + _mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */ + intelCopyBuffer(dPriv, &rect); + } + } + else { + /* XXX this shouldn't be an error but we can't handle it for now */ + fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__); + } +} + + +/** + * Update the hardware state for drawing into a window or framebuffer object. + * + * Called by glDrawBuffer, glBindFramebufferEXT, MakeCurrent, and other + * places within the driver. + * + * Basically, this needs to be called any time the current framebuffer + * changes, the renderbuffers change, or we need to draw into different + * color buffers. + */ +void +intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_region *colorRegion, *depthRegion = NULL; + struct intel_renderbuffer *irbDepth = NULL, *irbStencil = NULL; + int front = 0; /* drawing to front color buffer? */ + + if (!fb) { + /* this can happen during the initial context initialization */ + return; + } + + /* Do this here, note core Mesa, since this function is called from + * many places within the driver. + */ + if (ctx->NewState & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { + /* this updates the DrawBuffer->_NumColorDrawBuffers fields, etc */ + _mesa_update_framebuffer(ctx); + /* this updates the DrawBuffer's Width/Height if it's a FBO */ + _mesa_update_draw_buffer_bounds(ctx); + } + + if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { + /* this may occur when we're called by glBindFrameBuffer() during + * the process of someone setting up renderbuffers, etc. + */ + /*_mesa_debug(ctx, "DrawBuffer: incomplete user FBO\n");*/ + return; + } + + if (fb->Name) + intel_validate_paired_depth_stencil(ctx, fb); + + /* + * How many color buffers are we drawing into? + */ + if (fb->_NumColorDrawBuffers[0] != 1 +#if 0 + /* XXX FBO temporary - always use software rendering */ + || 1 +#endif + ) { + /* writing to 0 or 2 or 4 color buffers */ + /*_mesa_debug(ctx, "Software rendering\n");*/ + FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE); + front = 1; /* might not have back color buffer */ + } + else { + /* draw to exactly one color buffer */ + /*_mesa_debug(ctx, "Hardware rendering\n");*/ + FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE); + if (fb->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT) { + front = 1; + } + } + + /* + * Get the intel_renderbuffer for the colorbuffer we're drawing into. + * And set up cliprects. + */ + if (fb->Name == 0) { + /* drawing to window system buffer */ + if (intel->sarea->pf_current_page == 1) { + /* page flipped back/front */ + front ^= 1; + } + if (front) { + intelSetFrontClipRects(intel); + colorRegion = intel_get_rb_region(fb, BUFFER_FRONT_LEFT); + } + else { + intelSetBackClipRects(intel); + colorRegion = intel_get_rb_region(fb, BUFFER_BACK_LEFT); + } + } + else { + /* drawing to user-created FBO */ + struct intel_renderbuffer *irb; + intelSetRenderbufferClipRects(intel); + irb = intel_renderbuffer(fb->_ColorDrawBuffers[0][0]); + colorRegion = (irb && irb->region) ? irb->region : NULL; + } + + /* Update culling direction which changes depending on the + * orientation of the buffer: + */ + if (ctx->Driver.FrontFace) + ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace); + else + ctx->NewState |= _NEW_POLYGON; + + if (!colorRegion) { + FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE); + } + else { + FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE); + } + + /*** + *** Get depth buffer region and check if we need a software fallback. + *** Note that the depth buffer is usually a DEPTH_STENCIL buffer. + ***/ + if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) { + irbDepth = intel_renderbuffer(fb->_DepthBuffer->Wrapped); + if (irbDepth->region) { + FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE); + depthRegion = irbDepth->region; + } + else { + FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_TRUE); + depthRegion = NULL; + } + } + else { + /* not using depth buffer */ + FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE); + depthRegion = NULL; + } + + /*** + *** Stencil buffer + *** This can only be hardware accelerated if we're using a + *** combined DEPTH_STENCIL buffer (for now anyway). + ***/ + if (fb->_StencilBuffer && fb->_StencilBuffer->Wrapped) { + irbStencil = intel_renderbuffer(fb->_StencilBuffer->Wrapped); + if (irbStencil && irbStencil->region) { + ASSERT(irbStencil->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); + FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE); + /* need to re-compute stencil hw state */ + ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); + if (!depthRegion) + depthRegion = irbStencil->region; + } + else { + FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_TRUE); + } + } + else { + /* XXX FBO: instead of FALSE, pass ctx->Stencil.Enabled ??? */ + FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE); + /* need to re-compute stencil hw state */ + ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); + } + + + /** + ** Release old regions, reference new regions + **/ +#if 0 /* XXX FBO: this seems to be redundant with i915_state_draw_region() */ + if (intel->draw_region != colorRegion) { + intel_region_release(&intel->draw_region); + intel_region_reference(&intel->draw_region, colorRegion); + } + if (intel->intelScreen->depth_region != depthRegion) { + intel_region_release(&intel->intelScreen->depth_region); + intel_region_reference(&intel->intelScreen->depth_region, depthRegion); + } +#endif + + intel->vtbl.set_draw_region(intel, colorRegion, depthRegion); + + /* update viewport since it depends on window size */ + ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y, + ctx->Viewport.Width, ctx->Viewport.Height); + + /* Update hardware scissor */ + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); +} + + +static void +intelDrawBuffer(GLcontext * ctx, GLenum mode) +{ + intel_draw_buffer(ctx, ctx->DrawBuffer); +} + + +static void +intelReadBuffer(GLcontext * ctx, GLenum mode) +{ + if (ctx->ReadBuffer == ctx->DrawBuffer) { + /* This will update FBO completeness status. + * A framebuffer will be incomplete if the GL_READ_BUFFER setting + * refers to a missing renderbuffer. Calling glReadBuffer can set + * that straight and can make the drawing buffer complete. + */ + intel_draw_buffer(ctx, ctx->DrawBuffer); + } + /* Generally, functions which read pixels (glReadPixels, glCopyPixels, etc) + * reference ctx->ReadBuffer and do appropriate state checks. + */ +} + + +void +intelInitBufferFuncs(struct dd_function_table *functions) +{ + functions->Clear = intelClear; + functions->GetBufferSize = intelBufferSize; + functions->ResizeBuffers = _mesa_resize_framebuffer; + functions->DrawBuffer = intelDrawBuffer; + functions->ReadBuffer = intelReadBuffer; +} diff --git a/src/mesa/drivers/dri/i915tex/intel_buffers.h b/src/mesa/drivers/dri/i915tex/intel_buffers.h new file mode 100644 index 0000000000..0faf055347 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_buffers.h @@ -0,0 +1,56 @@ +/************************************************************************** + * + * Copyright 2006 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 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 ITS 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. + * + **************************************************************************/ + +#ifndef INTEL_BUFFERS_H +#define INTEL_BUFFERS_H + + +struct intel_context; + + +extern GLboolean +intel_intersect_cliprects(drm_clip_rect_t * dest, + const drm_clip_rect_t * a, + const drm_clip_rect_t * b); + +extern struct intel_region *intel_readbuf_region(struct intel_context *intel); + +extern struct intel_region *intel_drawbuf_region(struct intel_context *intel); + +extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); + +extern void intelWindowMoved(struct intel_context *intel); + +extern void intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb); + +extern void intelInitBufferFuncs(struct dd_function_table *functions); + +extern void +intelRotateWindow(struct intel_context *intel, + __DRIdrawablePrivate * dPriv, GLuint srcBuf); + +#endif /* INTEL_BUFFERS_H */ diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c b/src/mesa/drivers/dri/i915tex/intel_context.c new file mode 100644 index 0000000000..3d51a6341c --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_context.c @@ -0,0 +1,707 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + + +#include "glheader.h" +#include "context.h" +#include "matrix.h" +#include "simple_list.h" +#include "extensions.h" +#include "framebuffer.h" +#include "imports.h" + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/tnl.h" +#include "array_cache/acache.h" + +#include "tnl/t_pipeline.h" +#include "tnl/t_vertex.h" + +#include "drivers/common/driverfuncs.h" + +#include "intel_screen.h" + +#include "i830_dri.h" + +#include "intel_buffers.h" +#include "intel_tex.h" +#include "intel_span.h" +#include "intel_tris.h" +#include "intel_ioctl.h" +#include "intel_batchbuffer.h" +#include "intel_blit.h" +#include "intel_pixel.h" +#include "intel_regions.h" +#include "intel_buffer_objects.h" +#include "intel_fbo.h" + +#include "vblank.h" +#include "utils.h" +#include "xmlpool.h" /* for symbolic values of enum-type options */ +#ifndef INTEL_DEBUG +int INTEL_DEBUG = (0); +#endif + +#define need_GL_ARB_multisample +#define need_GL_ARB_point_parameters +#define need_GL_ARB_texture_compression +#define need_GL_ARB_vertex_buffer_object +#define need_GL_ARB_vertex_program +#define need_GL_ARB_window_pos +#define need_GL_EXT_blend_color +#define need_GL_EXT_blend_equation_separate +#define need_GL_EXT_blend_func_separate +#define need_GL_EXT_blend_minmax +#define need_GL_EXT_cull_vertex +#define need_GL_EXT_fog_coord +#define need_GL_EXT_framebuffer_object +#define need_GL_EXT_multi_draw_arrays +#define need_GL_EXT_secondary_color +#define need_GL_NV_vertex_program +#include "extension_helper.h" + + +#define DRIVER_DATE "20060929" + +_glthread_Mutex lockMutex; +static GLboolean lockMutexInit = GL_FALSE; + + +static const GLubyte * +intelGetString(GLcontext * ctx, GLenum name) +{ + const char *chipset; + static char buffer[128]; + + switch (name) { + case GL_VENDOR: + return (GLubyte *) "Tungsten Graphics, Inc"; + break; + + case GL_RENDERER: + switch (intel_context(ctx)->intelScreen->deviceID) { + case PCI_CHIP_845_G: + chipset = "Intel(R) 845G"; + break; + case PCI_CHIP_I830_M: + chipset = "Intel(R) 830M"; + break; + case PCI_CHIP_I855_GM: + chipset = "Intel(R) 852GM/855GM"; + break; + case PCI_CHIP_I865_G: + chipset = "Intel(R) 865G"; + break; + case PCI_CHIP_I915_G: + chipset = "Intel(R) 915G"; + break; + case PCI_CHIP_I915_GM: + chipset = "Intel(R) 915GM"; + break; + case PCI_CHIP_I945_G: + chipset = "Intel(R) 945G"; + break; + case PCI_CHIP_I945_GM: + chipset = "Intel(R) 945GM"; + break; + default: + chipset = "Unknown Intel Chipset"; + break; + } + + (void) driGetRendererString(buffer, chipset, DRIVER_DATE, 0); + return (GLubyte *) buffer; + + default: + return NULL; + } +} + + +/** + * Extension strings exported by the intel driver. + * + * \note + * It appears that ARB_texture_env_crossbar has "disappeared" compared to the + * old i830-specific driver. + */ +const struct dri_extension card_extensions[] = { + {"GL_ARB_multisample", GL_ARB_multisample_functions}, + {"GL_ARB_multitexture", NULL}, + {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, + {"GL_ARB_texture_border_clamp", NULL}, + {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions}, + {"GL_ARB_texture_cube_map", NULL}, + {"GL_ARB_texture_env_add", NULL}, + {"GL_ARB_texture_env_combine", NULL}, + {"GL_ARB_texture_env_dot3", NULL}, + {"GL_ARB_texture_mirrored_repeat", NULL}, + {"GL_ARB_texture_rectangle", NULL}, + {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, + {"GL_ARB_pixel_buffer_object", NULL}, + {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, + {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, + {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, + {"GL_EXT_blend_equation_separate", + GL_EXT_blend_equation_separate_functions}, + {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, + {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, + {"GL_EXT_blend_subtract", NULL}, + {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, + {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, + {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, + {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, +#if 1 /* XXX FBO temporary? */ + {"GL_EXT_packed_depth_stencil", NULL}, +#endif + {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, + {"GL_EXT_stencil_wrap", NULL}, + {"GL_EXT_texture_edge_clamp", NULL}, + {"GL_EXT_texture_env_combine", NULL}, + {"GL_EXT_texture_env_dot3", NULL}, + {"GL_EXT_texture_filter_anisotropic", NULL}, + {"GL_EXT_texture_lod_bias", NULL}, + {"GL_3DFX_texture_compression_FXT1", NULL}, + {"GL_APPLE_client_storage", NULL}, + {"GL_MESA_pack_invert", NULL}, + {"GL_MESA_ycbcr_texture", NULL}, + {"GL_NV_blend_square", NULL}, + {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, + {"GL_NV_vertex_program1_1", NULL}, +/* { "GL_SGIS_generate_mipmap", NULL }, */ + {NULL, NULL} +}; + +extern const struct tnl_pipeline_stage _intel_render_stage; + +static const struct tnl_pipeline_stage *intel_pipeline[] = { + &_tnl_vertex_transform_stage, + &_tnl_vertex_cull_stage, + &_tnl_normal_transform_stage, + &_tnl_lighting_stage, + &_tnl_fog_coordinate_stage, + &_tnl_texgen_stage, + &_tnl_texture_transform_stage, + &_tnl_point_attenuation_stage, + &_tnl_arb_vertex_program_stage, + &_tnl_vertex_program_stage, +#if 1 + &_intel_render_stage, /* ADD: unclipped rastersetup-to-dma */ +#endif + &_tnl_render_stage, + 0, +}; + + +static const struct dri_debug_control debug_control[] = { + {"tex", DEBUG_TEXTURE}, + {"state", DEBUG_STATE}, + {"ioctl", DEBUG_IOCTL}, + {"blit", DEBUG_BLIT}, + {"mip", DEBUG_MIPTREE}, + {"fall", DEBUG_FALLBACKS}, + {"verb", DEBUG_VERBOSE}, + {"bat", DEBUG_BATCH}, + {"pix", DEBUG_PIXEL}, + {"buf", DEBUG_BUFMGR}, + {"reg", DEBUG_REGION}, + {"fbo", DEBUG_FBO}, + {"lock", DEBUG_LOCK}, + {NULL, 0} +}; + + +static void +intelInvalidateState(GLcontext * ctx, GLuint new_state) +{ + _swrast_InvalidateState(ctx, new_state); + _swsetup_InvalidateState(ctx, new_state); + _ac_InvalidateState(ctx, new_state); + _tnl_InvalidateState(ctx, new_state); + _tnl_invalidate_vertex_state(ctx, new_state); + intel_context(ctx)->NewGLState |= new_state; +} + + +void +intelFlush(GLcontext * ctx) +{ + struct intel_context *intel = intel_context(ctx); + + if (intel->Fallback) + _swrast_flush(ctx); + + INTEL_FIREVERTICES(intel); + + if (intel->batch->map != intel->batch->ptr) + intel_batchbuffer_flush(intel->batch); + + /* XXX: Need to do an MI_FLUSH here. + */ +} + + +/** + * Check if we need to rotate/warp the front color buffer to the + * rotated screen. We generally need to do this when we get a glFlush + * or glFinish after drawing to the front color buffer. + */ +static void +intelCheckFrontRotate(GLcontext * ctx) +{ + struct intel_context *intel = intel_context(ctx); + if (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0] == + BUFFER_BIT_FRONT_LEFT) { + intelScreenPrivate *screen = intel->intelScreen; + if (screen->current_rotation != 0) { + __DRIdrawablePrivate *dPriv = intel->driDrawable; + intelRotateWindow(intel, dPriv, BUFFER_BIT_FRONT_LEFT); + } + } +} + + +/** + * Called via glFlush. + */ +static void +intelglFlush(GLcontext * ctx) +{ + intelFlush(ctx); + intelCheckFrontRotate(ctx); +} + +void +intelFinish(GLcontext * ctx) +{ + struct intel_context *intel = intel_context(ctx); + intelFlush(ctx); + if (intel->batch->last_fence) { + driFenceFinish(intel->batch->last_fence, + 0, GL_FALSE); + driFenceUnReference(intel->batch->last_fence); + intel->batch->last_fence = NULL; + } + intelCheckFrontRotate(ctx); +} + + +void +intelInitDriverFunctions(struct dd_function_table *functions) +{ + _mesa_init_driver_functions(functions); + + functions->Flush = intelglFlush; + functions->Finish = intelFinish; + functions->GetString = intelGetString; + functions->UpdateState = intelInvalidateState; + functions->CopyColorTable = _swrast_CopyColorTable; + functions->CopyColorSubTable = _swrast_CopyColorSubTable; + functions->CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; + functions->CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; + + intelInitTextureFuncs(functions); + intelInitPixelFuncs(functions); + intelInitStateFuncs(functions); + intelInitBufferFuncs(functions); +} + + +GLboolean +intelInitContext(struct intel_context *intel, + const __GLcontextModes * mesaVis, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate, + struct dd_function_table *functions) +{ + GLcontext *ctx = &intel->ctx; + GLcontext *shareCtx = (GLcontext *) sharedContextPrivate; + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; + drmI830Sarea *saPriv = (drmI830Sarea *) + (((GLubyte *) sPriv->pSAREA) + intelScreen->sarea_priv_offset); + int fthrottle_mode; + + if (!_mesa_initialize_context(&intel->ctx, + mesaVis, shareCtx, + functions, (void *) intel)) + return GL_FALSE; + + driContextPriv->driverPrivate = intel; + intel->intelScreen = intelScreen; + intel->driScreen = sPriv; + intel->sarea = saPriv; + + if (!lockMutexInit) { + lockMutexInit = GL_TRUE; + _glthread_INIT_MUTEX(lockMutex); + } + + driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache, + intel->driScreen->myNum, "i915"); + + ctx->Const.MaxTextureMaxAnisotropy = 2.0; + + /* This doesn't yet catch all non-conformant rendering, but it's a + * start. + */ + if (getenv("INTEL_STRICT_CONFORMANCE")) { + intel->strict_conformance = 1; + } + + ctx->Const.MinLineWidth = 1.0; + ctx->Const.MinLineWidthAA = 1.0; + ctx->Const.MaxLineWidth = 3.0; + ctx->Const.MaxLineWidthAA = 3.0; + ctx->Const.LineWidthGranularity = 1.0; + + ctx->Const.MinPointSize = 1.0; + ctx->Const.MinPointSizeAA = 1.0; + ctx->Const.MaxPointSize = 255.0; + ctx->Const.MaxPointSizeAA = 3.0; + ctx->Const.PointSizeGranularity = 1.0; + + ctx->Const.MaxColorAttachments = 4; /* XXX FBO: review this */ + + /* Initialize the software rasterizer and helper modules. */ + _swrast_CreateContext(ctx); + _ac_CreateContext(ctx); + _tnl_CreateContext(ctx); + _swsetup_CreateContext(ctx); + + /* Install the customized pipeline: */ + _tnl_destroy_pipeline(ctx); + _tnl_install_pipeline(ctx, intel_pipeline); + + /* Configure swrast to match hardware characteristics: */ + _swrast_allow_pixel_fog(ctx, GL_FALSE); + _swrast_allow_vertex_fog(ctx, GL_TRUE); + + /* Dri stuff */ + intel->hHWContext = driContextPriv->hHWContext; + intel->driFd = sPriv->fd; + intel->driHwLock = (drmLock *) & sPriv->pSAREA->lock; + + intel->hw_stipple = 1; + + /* XXX FBO: this doesn't seem to be used anywhere */ + switch (mesaVis->depthBits) { + case 0: /* what to do in this case? */ + case 16: + intel->polygon_offset_scale = 1.0 / 0xffff; + break; + case 24: + intel->polygon_offset_scale = 2.0 / 0xffffff; /* req'd to pass glean */ + break; + default: + assert(0); + break; + } + + /* Initialize swrast, tnl driver tables: */ + intelInitSpanFuncs(ctx); + intelInitTriFuncs(ctx); + + + intel->RenderIndex = ~0; + + fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode"); + intel->iw.irq_seq = -1; + intel->irqsEmitted = 0; + + intel->do_irqs = (intel->intelScreen->irq_active && + fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS); + + intel->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS); + + intel->vblank_flags = (intel->intelScreen->irq_active != 0) + ? driGetDefaultVBlankFlags(&intel->optionCache) : VBLANK_FLAG_NO_IRQ; + + (*dri_interface->getUST) (&intel->swap_ust); + _math_matrix_ctr(&intel->ViewportMatrix); + + /* Disable imaging extension until convolution is working in + * teximage paths: + */ + driInitExtensions(ctx, card_extensions, +/* GL_TRUE, */ + GL_FALSE); + + + intel->batch = intel_batchbuffer_alloc(intel); + intel->last_swap_fence = NULL; + intel->first_swap_fence = NULL; + + intel_bufferobj_init(intel); + intel_fbo_init(intel); + + if (intel->ctx.Mesa_DXTn) { + _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc"); + _mesa_enable_extension(ctx, "GL_S3_s3tc"); + } + else if (driQueryOptionb(&intel->optionCache, "force_s3tc_enable")) { + _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc"); + } + + intel->prim.primitive = ~0; + + +#if DO_DEBUG + INTEL_DEBUG = driParseDebugString(getenv("INTEL_DEBUG"), debug_control); +#endif + + if (getenv("INTEL_NO_RAST")) { + fprintf(stderr, "disabling 3D rasterization\n"); + FALLBACK(intel, INTEL_FALLBACK_USER, 1); + } + + return GL_TRUE; +} + +void +intelDestroyContext(__DRIcontextPrivate * driContextPriv) +{ + struct intel_context *intel = + (struct intel_context *) driContextPriv->driverPrivate; + + assert(intel); /* should never be null */ + if (intel) { + GLboolean release_texture_heaps; + + INTEL_FIREVERTICES(intel); + + intel->vtbl.destroy(intel); + + release_texture_heaps = (intel->ctx.Shared->RefCount == 1); + _swsetup_DestroyContext(&intel->ctx); + _tnl_DestroyContext(&intel->ctx); + _ac_DestroyContext(&intel->ctx); + + _swrast_DestroyContext(&intel->ctx); + intel->Fallback = 0; /* don't call _swrast_Flush later */ + + intel_batchbuffer_free(intel->batch); + + if (intel->last_swap_fence) { + driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); + driFenceUnReference(intel->last_swap_fence); + intel->last_swap_fence = NULL; + } + if (intel->first_swap_fence) { + driFenceFinish(intel->first_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); + driFenceUnReference(intel->first_swap_fence); + intel->first_swap_fence = NULL; + } + + + if (release_texture_heaps) { + /* This share group is about to go away, free our private + * texture object data. + */ + if (INTEL_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, "do something to free texture heaps\n"); + } + + /* free the Mesa context */ + _mesa_free_context_data(&intel->ctx); + } +} + +GLboolean +intelUnbindContext(__DRIcontextPrivate * driContextPriv) +{ + return GL_TRUE; +} + +GLboolean +intelMakeCurrent(__DRIcontextPrivate * driContextPriv, + __DRIdrawablePrivate * driDrawPriv, + __DRIdrawablePrivate * driReadPriv) +{ + + if (driContextPriv) { + struct intel_context *intel = + (struct intel_context *) driContextPriv->driverPrivate; + GLframebuffer *drawFb = (GLframebuffer *) driDrawPriv->driverPrivate; + GLframebuffer *readFb = (GLframebuffer *) driReadPriv->driverPrivate; + + + /* XXX FBO temporary fix-ups! */ + /* if the renderbuffers don't have regions, init them from the context */ + { + struct intel_renderbuffer *irbFront + = intel_get_renderbuffer(drawFb, BUFFER_FRONT_LEFT); + struct intel_renderbuffer *irbBack + = intel_get_renderbuffer(drawFb, BUFFER_BACK_LEFT); + struct intel_renderbuffer *irbDepth + = intel_get_renderbuffer(drawFb, BUFFER_DEPTH); + struct intel_renderbuffer *irbStencil + = intel_get_renderbuffer(drawFb, BUFFER_STENCIL); + + if (irbFront && !irbFront->region) { + intel_region_reference(&irbFront->region, intel->intelScreen->front_region); + } + if (irbBack && !irbBack->region) { + intel_region_reference(&irbBack->region, intel->intelScreen->back_region); + } + if (irbDepth && !irbDepth->region) { + intel_region_reference(&irbDepth->region, intel->intelScreen->depth_region); + } + if (irbStencil && !irbStencil->region) { + intel_region_reference(&irbStencil->region, intel->intelScreen->depth_region); + } + } + + _mesa_make_current(&intel->ctx, drawFb, readFb); + + /* The drawbuffer won't always be updated by _mesa_make_current: + */ + if (intel->ctx.DrawBuffer == drawFb) { + + if (intel->driDrawable != driDrawPriv) { + driDrawableInitVBlank(driDrawPriv, intel->vblank_flags, &intel->vbl_seq); + intel->driDrawable = driDrawPriv; + intelWindowMoved(intel); + } + + intel_draw_buffer(&intel->ctx, drawFb); + } + } + else { + _mesa_make_current(NULL, NULL, NULL); + } + + return GL_TRUE; +} + +static void +intelContendedLock(struct intel_context *intel, GLuint flags) +{ + __DRIdrawablePrivate *dPriv = intel->driDrawable; + __DRIscreenPrivate *sPriv = intel->driScreen; + intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; + drmI830Sarea *sarea = intel->sarea; + + drmGetLock(intel->driFd, intel->hHWContext, flags); + + if (INTEL_DEBUG & DEBUG_LOCK) + _mesa_printf("%s - got contended lock\n", __progname); + + /* If the window moved, may need to set a new cliprect now. + * + * NOTE: This releases and regains the hw lock, so all state + * checking must be done *after* this call: + */ + if (dPriv) + DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); + + if (sarea->width != intelScreen->width || + sarea->height != intelScreen->height || + sarea->rotation != intelScreen->current_rotation) { + + intelUpdateScreenRotation(sPriv, sarea); + + /* + * This will drop the outstanding batchbuffer on the floor + * FIXME: This should be done for all contexts? + */ + + intel_batchbuffer_reset(intel->batch); + + /* lose all primitives */ + intel->prim.primitive = ~0; + intel->prim.start_ptr = 0; + intel->prim.flush = 0; + + /* re-emit all state */ + intel->vtbl.lost_hardware(intel); + + /* force window update */ + intel->lastStamp = 0; + } + + + /* Drawable changed? + */ + if (dPriv && intel->lastStamp != dPriv->lastStamp) { + intelWindowMoved(intel); + intel->lastStamp = dPriv->lastStamp; + } +} + + +extern _glthread_Mutex lockMutex; + + +/* Lock the hardware and validate our state. + */ +void LOCK_HARDWARE( struct intel_context *intel ) +{ + char __ret=0; + + _glthread_LOCK_MUTEX(lockMutex); + assert(!intel->locked); + + if (intel->swap_scheduled) { + drmVBlank vbl; + vbl.request.type = DRM_VBLANK_ABSOLUTE; + if ( intel->vblank_flags & VBLANK_FLAG_SECONDARY ) { + vbl.request.type |= DRM_VBLANK_SECONDARY; + } + vbl.request.sequence = intel->vbl_seq; + drmWaitVBlank(intel->driFd, &vbl); + intel->swap_scheduled = 0; + } + + DRM_CAS(intel->driHwLock, intel->hHWContext, + (DRM_LOCK_HELD|intel->hHWContext), __ret); + + if (__ret) + intelContendedLock( intel, 0 ); + + if (INTEL_DEBUG & DEBUG_LOCK) + _mesa_printf("%s - locked\n", __progname); + + intel->locked = 1; +} + + + /* Unlock the hardware using the global current context + */ +void UNLOCK_HARDWARE( struct intel_context *intel ) +{ + intel->locked = 0; + + DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext); + + _glthread_UNLOCK_MUTEX(lockMutex); + + if (INTEL_DEBUG & DEBUG_LOCK) + _mesa_printf("%s - unlocked\n", __progname); +} + diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h b/src/mesa/drivers/dri/i915tex/intel_context.h new file mode 100644 index 0000000000..fa3cf58571 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_context.h @@ -0,0 +1,502 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#ifndef INTELCONTEXT_INC +#define INTELCONTEXT_INC + + + +#include "mtypes.h" +#include "drm.h" +#include "mm.h" +#include "texmem.h" + +#include "intel_screen.h" +#include "i915_drm.h" +#include "i830_common.h" +#include "tnl/t_vertex.h" + +#define TAG(x) intel##x +#include "tnl_dd/t_dd_vertex.h" +#undef TAG + +#define DV_PF_555 (1<<8) +#define DV_PF_565 (2<<8) +#define DV_PF_8888 (3<<8) + +struct intel_region; +struct intel_context; +struct _DriBufferObject; + +typedef void (*intel_tri_func) (struct intel_context *, intelVertex *, + intelVertex *, intelVertex *); +typedef void (*intel_line_func) (struct intel_context *, intelVertex *, + intelVertex *); +typedef void (*intel_point_func) (struct intel_context *, intelVertex *); + +#define INTEL_FALLBACK_DRAW_BUFFER 0x1 +#define INTEL_FALLBACK_READ_BUFFER 0x2 +#define INTEL_FALLBACK_DEPTH_BUFFER 0x4 +#define INTEL_FALLBACK_STENCIL_BUFFER 0x8 +#define INTEL_FALLBACK_USER 0x10 +#define INTEL_FALLBACK_RENDERMODE 0x20 + +extern void intelFallback(struct intel_context *intel, GLuint bit, + GLboolean mode); +#define FALLBACK( intel, bit, mode ) intelFallback( intel, bit, mode ) + + +#define INTEL_WRITE_PART 0x1 +#define INTEL_WRITE_FULL 0x2 +#define INTEL_READ 0x4 + +struct intel_texture_object +{ + struct gl_texture_object base; /* The "parent" object */ + + /* The mipmap tree must include at least these levels once + * validated: + */ + GLuint firstLevel; + GLuint lastLevel; + + /* Offset for firstLevel image: + */ + GLuint textureOffset; + + /* On validation any active images held in main memory or in other + * regions will be copied to this region and the old storage freed. + */ + struct intel_mipmap_tree *mt; +}; + + + +struct intel_texture_image +{ + struct gl_texture_image base; + + /* These aren't stored in gl_texture_image + */ + GLuint level; + GLuint face; + + /* If intelImage->mt != NULL, image data is stored here. + * Else if intelImage->base.Data != NULL, image is stored there. + * Else there is no image data. + */ + struct intel_mipmap_tree *mt; +}; + + +#define INTEL_MAX_FIXUP 64 + +struct intel_context +{ + GLcontext ctx; /* the parent class */ + + struct + { + void (*destroy) (struct intel_context * intel); + void (*emit_state) (struct intel_context * intel); + void (*lost_hardware) (struct intel_context * intel); + void (*update_texture_state) (struct intel_context * intel); + + void (*render_start) (struct intel_context * intel); + void (*set_draw_region) (struct intel_context * intel, + struct intel_region * draw_region, + struct intel_region * depth_region); + + GLuint(*flush_cmd) (void); + + void (*reduced_primitive_state) (struct intel_context * intel, + GLenum rprim); + + GLboolean(*check_vertex_size) (struct intel_context * intel, + GLuint expected); + + + /* Metaops: + */ + void (*install_meta_state) (struct intel_context * intel); + void (*leave_meta_state) (struct intel_context * intel); + + void (*meta_draw_region) (struct intel_context * intel, + struct intel_region * draw_region, + struct intel_region * depth_region); + + void (*meta_color_mask) (struct intel_context * intel, GLboolean); + + void (*meta_stencil_replace) (struct intel_context * intel, + GLuint mask, GLuint clear); + + void (*meta_depth_replace) (struct intel_context * intel); + + void (*meta_texture_blend_replace) (struct intel_context * intel); + + void (*meta_no_stencil_write) (struct intel_context * intel); + void (*meta_no_depth_write) (struct intel_context * intel); + void (*meta_no_texture) (struct intel_context * intel); + + void (*meta_import_pixel_state) (struct intel_context * intel); + + GLboolean(*meta_tex_rect_source) (struct intel_context * intel, + struct _DriBufferObject * buffer, + GLuint offset, + GLuint pitch, + GLuint height, + GLenum format, GLenum type); + void (*rotate_window) (struct intel_context * intel, + __DRIdrawablePrivate * dPriv, GLuint srcBuf); + + void (*assert_not_dirty) (struct intel_context *intel); + + } vtbl; + + GLint refcount; + GLuint Fallback; + GLuint NewGLState; + + struct _DriFenceObject *last_swap_fence; + struct _DriFenceObject *first_swap_fence; + + struct intel_batchbuffer *batch; + + struct + { + GLuint id; + GLuint primitive; + GLubyte *start_ptr; + void (*flush) (struct intel_context *); + } prim; + + GLboolean locked; + char *prevLockFile; + int prevLockLine; + + GLuint ClearColor565; + GLuint ClearColor8888; + + /* Offsets of fields within the current vertex: + */ + GLuint coloroffset; + GLuint specoffset; + GLuint wpos_offset; + GLuint wpos_size; + + struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; + GLuint vertex_attr_count; + + GLfloat polygon_offset_scale; /* dependent on depth_scale, bpp */ + + GLboolean hw_stipple; + GLboolean strict_conformance; + + /* AGP memory buffer manager: + */ + struct bufmgr *bm; + + + /* State for intelvb.c and inteltris.c. + */ + GLuint RenderIndex; + GLmatrix ViewportMatrix; + GLenum render_primitive; + GLenum reduced_primitive; + GLuint vertex_size; + GLubyte *verts; /* points to tnl->clipspace.vertex_buf */ + +#if 0 + struct intel_region *front_region; /* XXX FBO: obsolete */ + struct intel_region *rotated_region; /* XXX FBO: obsolete */ + struct intel_region *back_region; /* XXX FBO: obsolete */ + struct intel_region *draw_region; /* XXX FBO: rename to color_region */ + struct intel_region *depth_region; /**< currently bound depth/Z region */ +#endif + + /* Fallback rasterization functions + */ + intel_point_func draw_point; + intel_line_func draw_line; + intel_tri_func draw_tri; + + /* These refer to the current drawing buffer: + */ + int drawX, drawY; /**< origin of drawing area within region */ + GLuint numClipRects; /**< cliprects for drawing */ + drm_clip_rect_t *pClipRects; + drm_clip_rect_t fboRect; /**< cliprect for FBO rendering */ + + int perf_boxes; + + GLuint do_usleeps; + int do_irqs; + GLuint irqsEmitted; + drm_i915_irq_wait_t iw; + + drm_context_t hHWContext; + drmLock *driHwLock; + int driFd; + + __DRIdrawablePrivate *driDrawable; + __DRIscreenPrivate *driScreen; + intelScreenPrivate *intelScreen; + drmI830Sarea *sarea; + + GLuint lastStamp; + + /** + * Configuration cache + */ + driOptionCache optionCache; + + /* VBI + */ + GLuint vbl_seq; + GLuint vblank_flags; + + int64_t swap_ust; + int64_t swap_missed_ust; + + GLuint swap_count; + GLuint swap_missed_count; + + GLuint swap_scheduled; +}; + +/* These are functions now: + */ +void LOCK_HARDWARE( struct intel_context *intel ); +void UNLOCK_HARDWARE( struct intel_context *intel ); + +extern char *__progname; + + +#define SUBPIXEL_X 0.125 +#define SUBPIXEL_Y 0.125 + +#define INTEL_FIREVERTICES(intel) \ +do { \ + if ((intel)->prim.flush) \ + (intel)->prim.flush(intel); \ +} while (0) + +/* ================================================================ + * Color packing: + */ + +#define INTEL_PACKCOLOR4444(r,g,b,a) \ + ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) + +#define INTEL_PACKCOLOR1555(r,g,b,a) \ + ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ + ((a) ? 0x8000 : 0)) + +#define INTEL_PACKCOLOR565(r,g,b) \ + ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) + +#define INTEL_PACKCOLOR8888(r,g,b,a) \ + ((a<<24) | (r<<16) | (g<<8) | b) + + + +/* ================================================================ + * From linux kernel i386 header files, copes with odd sizes better + * than COPY_DWORDS would: + * XXX Put this in src/mesa/main/imports.h ??? + */ +#if defined(i386) || defined(__i386__) +static INLINE void * +__memcpy(void *to, const void *from, size_t n) +{ + int d0, d1, d2; + __asm__ __volatile__("rep ; movsl\n\t" + "testb $2,%b4\n\t" + "je 1f\n\t" + "movsw\n" + "1:\ttestb $1,%b4\n\t" + "je 2f\n\t" + "movsb\n" "2:":"=&c"(d0), "=&D"(d1), "=&S"(d2) + :"0"(n / 4), "q"(n), "1"((long) to), "2"((long) from) + :"memory"); + return (to); +} +#else +#define __memcpy(a,b,c) memcpy(a,b,c) +#endif + + + +/* ================================================================ + * Debugging: + */ +#define DO_DEBUG 1 +#if DO_DEBUG +extern int INTEL_DEBUG; +#else +#define INTEL_DEBUG 0 +#endif + +#define DEBUG_TEXTURE 0x1 +#define DEBUG_STATE 0x2 +#define DEBUG_IOCTL 0x4 +#define DEBUG_BLIT 0x8 +#define DEBUG_MIPTREE 0x10 +#define DEBUG_FALLBACKS 0x20 +#define DEBUG_VERBOSE 0x40 +#define DEBUG_BATCH 0x80 +#define DEBUG_PIXEL 0x100 +#define DEBUG_BUFMGR 0x200 +#define DEBUG_REGION 0x400 +#define DEBUG_FBO 0x800 +#define DEBUG_LOCK 0x1000 + +#define DBG(...) do { if (INTEL_DEBUG & FILE_DEBUG_FLAG) _mesa_printf(__VA_ARGS__); } while(0) + + +#define PCI_CHIP_845_G 0x2562 +#define PCI_CHIP_I830_M 0x3577 +#define PCI_CHIP_I855_GM 0x3582 +#define PCI_CHIP_I865_G 0x2572 +#define PCI_CHIP_I915_G 0x2582 +#define PCI_CHIP_I915_GM 0x2592 +#define PCI_CHIP_I945_G 0x2772 +#define PCI_CHIP_I945_GM 0x27A2 + + +/* ================================================================ + * intel_context.c: + */ + +extern GLboolean intelInitContext(struct intel_context *intel, + const __GLcontextModes * mesaVis, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate, + struct dd_function_table *functions); + +extern void intelGetLock(struct intel_context *intel, GLuint flags); + +extern void intelInitState(GLcontext * ctx); +extern void intelFinish(GLcontext * ctx); +extern void intelFlush(GLcontext * ctx); + +extern void intelInitDriverFunctions(struct dd_function_table *functions); + + +/* ================================================================ + * intel_state.c: + */ +extern void intelInitStateFuncs(struct dd_function_table *functions); + +#define COMPAREFUNC_ALWAYS 0 +#define COMPAREFUNC_NEVER 0x1 +#define COMPAREFUNC_LESS 0x2 +#define COMPAREFUNC_EQUAL 0x3 +#define COMPAREFUNC_LEQUAL 0x4 +#define COMPAREFUNC_GREATER 0x5 +#define COMPAREFUNC_NOTEQUAL 0x6 +#define COMPAREFUNC_GEQUAL 0x7 + +#define STENCILOP_KEEP 0 +#define STENCILOP_ZERO 0x1 +#define STENCILOP_REPLACE 0x2 +#define STENCILOP_INCRSAT 0x3 +#define STENCILOP_DECRSAT 0x4 +#define STENCILOP_INCR 0x5 +#define STENCILOP_DECR 0x6 +#define STENCILOP_INVERT 0x7 + +#define LOGICOP_CLEAR 0 +#define LOGICOP_NOR 0x1 +#define LOGICOP_AND_INV 0x2 +#define LOGICOP_COPY_INV 0x3 +#define LOGICOP_AND_RVRSE 0x4 +#define LOGICOP_INV 0x5 +#define LOGICOP_XOR 0x6 +#define LOGICOP_NAND 0x7 +#define LOGICOP_AND 0x8 +#define LOGICOP_EQUIV 0x9 +#define LOGICOP_NOOP 0xa +#define LOGICOP_OR_INV 0xb +#define LOGICOP_COPY 0xc +#define LOGICOP_OR_RVRSE 0xd +#define LOGICOP_OR 0xe +#define LOGICOP_SET 0xf + +#define BLENDFACT_ZERO 0x01 +#define BLENDFACT_ONE 0x02 +#define BLENDFACT_SRC_COLR 0x03 +#define BLENDFACT_INV_SRC_COLR 0x04 +#define BLENDFACT_SRC_ALPHA 0x05 +#define BLENDFACT_INV_SRC_ALPHA 0x06 +#define BLENDFACT_DST_ALPHA 0x07 +#define BLENDFACT_INV_DST_ALPHA 0x08 +#define BLENDFACT_DST_COLR 0x09 +#define BLENDFACT_INV_DST_COLR 0x0a +#define BLENDFACT_SRC_ALPHA_SATURATE 0x0b +#define BLENDFACT_CONST_COLOR 0x0c +#define BLENDFACT_INV_CONST_COLOR 0x0d +#define BLENDFACT_CONST_ALPHA 0x0e +#define BLENDFACT_INV_CONST_ALPHA 0x0f +#define BLENDFACT_MASK 0x0f + +#define MI_BATCH_BUFFER_END (0xA<<23) + + +extern int intel_translate_compare_func(GLenum func); +extern int intel_translate_stencil_op(GLenum op); +extern int intel_translate_blend_factor(GLenum factor); +extern int intel_translate_logic_op(GLenum opcode); + + +/*====================================================================== + * Inline conversion functions. + * These are better-typed than the macros used previously: + */ +static INLINE struct intel_context * +intel_context(GLcontext * ctx) +{ + return (struct intel_context *) ctx; +} + +static INLINE struct intel_texture_object * +intel_texture_object(struct gl_texture_object *obj) +{ + return (struct intel_texture_object *) obj; +} + +static INLINE struct intel_texture_image * +intel_texture_image(struct gl_texture_image *img) +{ + return (struct intel_texture_image *) img; +} + +extern struct intel_renderbuffer *intel_renderbuffer(struct gl_renderbuffer + *rb); + + +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_depthstencil.c b/src/mesa/drivers/dri/i915tex/intel_depthstencil.c new file mode 100644 index 0000000000..d269a85a3c --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_depthstencil.c @@ -0,0 +1,282 @@ +/************************************************************************** + * + * Copyright 2006 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 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 ITS 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. + * + **************************************************************************/ + +#include "glheader.h" +#include "imports.h" +#include "context.h" +#include "depthstencil.h" +#include "fbobject.h" +#include "framebuffer.h" +#include "hash.h" +#include "mtypes.h" +#include "renderbuffer.h" + +#include "intel_context.h" +#include "intel_fbo.h" +#include "intel_depthstencil.h" +#include "intel_regions.h" + + +/** + * The GL_EXT_framebuffer_object allows the user to create their own + * framebuffer objects consisting of color renderbuffers (0 or more), + * depth renderbuffers (0 or 1) and stencil renderbuffers (0 or 1). + * + * The spec considers depth and stencil renderbuffers to be totally independent + * buffers. In reality, most graphics hardware today uses a combined + * depth+stencil buffer (one 32-bit pixel = 24 bits of Z + 8 bits of stencil). + * + * This causes difficulty because the user may create some number of depth + * renderbuffers and some number of stencil renderbuffers and bind them + * together in framebuffers in any combination. + * + * This code manages all that. + * + * 1. Depth renderbuffers are always allocated in hardware as 32bpp + * GL_DEPTH24_STENCIL8 buffers. + * + * 2. Stencil renderbuffers are initially allocated in software as 8bpp + * GL_STENCIL_INDEX8 buffers. + * + * 3. Depth and Stencil renderbuffers use the PairedStencil and PairedDepth + * fields (respectively) to indicate if the buffer's currently paired + * with another stencil or depth buffer (respectively). + * + * 4. When a depth and stencil buffer are initially both attached to the + * current framebuffer, we merge the stencil buffer values into the + * depth buffer (really a depth+stencil buffer). The then hardware uses + * the combined buffer. + * + * 5. Whenever a depth or stencil buffer is reallocated (with + * glRenderbufferStorage) we undo the pairing and copy the stencil values + * from the combined depth/stencil buffer back to the stencil-only buffer. + * + * 6. We also undo the pairing when we find a change in buffer bindings. + * + * 7. If a framebuffer is only using a depth renderbuffer (no stencil), we + * just use the combined depth/stencil buffer and ignore the stencil values. + * + * 8. If a framebuffer is only using a stencil renderbuffer (no depth) we have + * to promote the 8bpp software stencil buffer to a 32bpp hardware + * depth+stencil buffer. + * + */ + + + +static void +map_regions(GLcontext * ctx, + struct intel_renderbuffer *depthRb, + struct intel_renderbuffer *stencilRb) +{ + struct intel_context *intel = intel_context(ctx); + if (depthRb && depthRb->region) { + intel_region_map(intel->intelScreen, depthRb->region); + depthRb->pfMap = depthRb->region->map; + depthRb->pfPitch = depthRb->region->pitch; + } + if (stencilRb && stencilRb->region) { + intel_region_map(intel->intelScreen, stencilRb->region); + stencilRb->pfMap = stencilRb->region->map; + stencilRb->pfPitch = stencilRb->region->pitch; + } +} + +static void +unmap_regions(GLcontext * ctx, + struct intel_renderbuffer *depthRb, + struct intel_renderbuffer *stencilRb) +{ + struct intel_context *intel = intel_context(ctx); + if (depthRb && depthRb->region) { + intel_region_unmap(intel->intelScreen, depthRb->region); + depthRb->pfMap = NULL; + depthRb->pfPitch = 0; + } + if (stencilRb && stencilRb->region) { + intel_region_unmap(intel->intelScreen, stencilRb->region); + stencilRb->pfMap = NULL; + stencilRb->pfPitch = 0; + } +} + + + +/** + * Undo the pairing/interleaving between depth and stencil buffers. + * irb should be a depth/stencil or stencil renderbuffer. + */ +void +intel_unpair_depth_stencil(GLcontext * ctx, struct intel_renderbuffer *irb) +{ + if (irb->PairedStencil) { + /* irb is a depth/stencil buffer */ + struct gl_renderbuffer *stencilRb; + struct intel_renderbuffer *stencilIrb; + + ASSERT(irb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); + + stencilRb = _mesa_lookup_renderbuffer(ctx, irb->PairedStencil); + stencilIrb = intel_renderbuffer(stencilRb); + if (stencilIrb) { + /* need to extract stencil values from the depth buffer */ + ASSERT(stencilIrb->PairedDepth == irb->Base.Name); + map_regions(ctx, irb, stencilIrb); + _mesa_extract_stencil(ctx, &irb->Base, &stencilIrb->Base); + unmap_regions(ctx, irb, stencilIrb); + stencilIrb->PairedDepth = 0; + } + irb->PairedStencil = 0; + } + else if (irb->PairedDepth) { + /* irb is a stencil buffer */ + struct gl_renderbuffer *depthRb; + struct intel_renderbuffer *depthIrb; + + ASSERT(irb->Base._ActualFormat == GL_STENCIL_INDEX8_EXT || + irb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); + + depthRb = _mesa_lookup_renderbuffer(ctx, irb->PairedDepth); + depthIrb = intel_renderbuffer(depthRb); + if (depthIrb) { + /* need to extract stencil values from the depth buffer */ + ASSERT(depthIrb->PairedStencil == irb->Base.Name); + map_regions(ctx, depthIrb, irb); + _mesa_extract_stencil(ctx, &depthIrb->Base, &irb->Base); + unmap_regions(ctx, depthIrb, irb); + depthIrb->PairedStencil = 0; + } + irb->PairedDepth = 0; + } + else { + _mesa_problem(ctx, "Problem in undo_depth_stencil_pairing"); + } + + ASSERT(irb->PairedStencil == 0); + ASSERT(irb->PairedDepth == 0); +} + + +/** + * Examine the depth and stencil renderbuffers which are attached to the + * framebuffer. If both depth and stencil are attached, make sure that the + * renderbuffers are 'paired' (combined). If only depth or only stencil is + * attached, undo any previous pairing. + * + * Must be called if NewState & _NEW_BUFFER (when renderbuffer attachments + * change, for example). + */ +void +intel_validate_paired_depth_stencil(GLcontext * ctx, + struct gl_framebuffer *fb) +{ + struct intel_renderbuffer *depthRb, *stencilRb; + + depthRb = intel_get_renderbuffer(fb, BUFFER_DEPTH); + stencilRb = intel_get_renderbuffer(fb, BUFFER_STENCIL); + + if (depthRb && stencilRb) { + if (depthRb == stencilRb) { + /* Using a user-created combined depth/stencil buffer. + * Nothing to do. + */ + ASSERT(depthRb->Base._BaseFormat == GL_DEPTH_STENCIL_EXT); + ASSERT(depthRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); + } + else { + /* Separate depth/stencil buffers, need to interleave now */ + ASSERT(depthRb->Base._BaseFormat == GL_DEPTH_COMPONENT); + ASSERT(stencilRb->Base._BaseFormat == GL_STENCIL_INDEX); + /* may need to interleave depth/stencil now */ + if (depthRb->PairedStencil == stencilRb->Base.Name) { + /* OK, the depth and stencil buffers are already interleaved */ + ASSERT(stencilRb->PairedDepth == depthRb->Base.Name); + } + else { + /* need to setup new pairing/interleaving */ + if (depthRb->PairedStencil) { + intel_unpair_depth_stencil(ctx, depthRb); + } + if (stencilRb->PairedDepth) { + intel_unpair_depth_stencil(ctx, stencilRb); + } + + ASSERT(depthRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); + ASSERT(stencilRb->Base._ActualFormat == GL_STENCIL_INDEX8_EXT || + stencilRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); + + /* establish new pairing: interleave stencil into depth buffer */ + map_regions(ctx, depthRb, stencilRb); + _mesa_insert_stencil(ctx, &depthRb->Base, &stencilRb->Base); + unmap_regions(ctx, depthRb, stencilRb); + depthRb->PairedStencil = stencilRb->Base.Name; + stencilRb->PairedDepth = depthRb->Base.Name; + } + + } + } + else if (depthRb) { + /* Depth buffer but no stencil buffer. + * We'll use a GL_DEPTH24_STENCIL8 buffer and ignore the stencil bits. + */ + /* can't assert this until storage is allocated: + ASSERT(depthRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); + */ + /* intel_undo any previous pairing */ + if (depthRb->PairedStencil) { + intel_unpair_depth_stencil(ctx, depthRb); + } + } + else if (stencilRb) { + /* Stencil buffer but no depth buffer. + * Since h/w doesn't typically support just 8bpp stencil w/out Z, + * we'll use a GL_DEPTH24_STENCIL8 buffer and ignore the depth bits. + */ + /* undo any previous pairing */ + if (stencilRb->PairedDepth) { + intel_unpair_depth_stencil(ctx, stencilRb); + } + if (stencilRb->Base._ActualFormat == GL_STENCIL_INDEX8_EXT) { + /* promote buffer to GL_DEPTH24_STENCIL8 for hw rendering */ + _mesa_promote_stencil(ctx, &stencilRb->Base); + ASSERT(stencilRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); + } + } + + /* Finally, update the fb->_DepthBuffer and fb->_StencilBuffer fields */ + _mesa_update_depth_buffer(ctx, fb, BUFFER_DEPTH); + if (depthRb && depthRb->PairedStencil) + _mesa_update_stencil_buffer(ctx, fb, BUFFER_DEPTH); + else + _mesa_update_stencil_buffer(ctx, fb, BUFFER_STENCIL); + + + /* The hardware should use fb->Attachment[BUFFER_DEPTH].Renderbuffer + * first, if present, then fb->Attachment[BUFFER_STENCIL].Renderbuffer + * if present. + */ +} diff --git a/src/mesa/drivers/dri/i915tex/intel_depthstencil.h b/src/mesa/drivers/dri/i915tex/intel_depthstencil.h new file mode 100644 index 0000000000..2d3fc48b3a --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_depthstencil.h @@ -0,0 +1,14 @@ + +#ifndef INTEL_DEPTH_STENCIL_H +#define INTEL_DEPTH_STENCIL_H + + +extern void +intel_unpair_depth_stencil(GLcontext * ctx, struct intel_renderbuffer *irb); + +extern void +intel_validate_paired_depth_stencil(GLcontext * ctx, + struct gl_framebuffer *fb); + + +#endif /* INTEL_DEPTH_STENCIL_H */ diff --git a/src/mesa/drivers/dri/i915tex/intel_fbo.c b/src/mesa/drivers/dri/i915tex/intel_fbo.c new file mode 100644 index 0000000000..ab0e569bd9 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_fbo.c @@ -0,0 +1,622 @@ +/************************************************************************** + * + * Copyright 2006 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 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 ITS 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. + * + **************************************************************************/ + + +#include "imports.h" +#include "mtypes.h" +#include "fbobject.h" +#include "framebuffer.h" +#include "renderbuffer.h" +#include "context.h" +#include "texformat.h" +#include "texrender.h" + +#include "intel_context.h" +#include "intel_buffers.h" +#include "intel_depthstencil.h" +#include "intel_fbo.h" +#include "intel_mipmap_tree.h" +#include "intel_regions.h" +#include "intel_span.h" + + +#define FILE_DEBUG_FLAG DEBUG_FBO + +#define INTEL_RB_CLASS 0x12345678 + + +/* XXX FBO: move this to intel_context.h (inlined) */ +/** + * Return a gl_renderbuffer ptr casted to intel_renderbuffer. + * NULL will be returned if the rb isn't really an intel_renderbuffer. + * This is determiend by checking the ClassID. + */ +struct intel_renderbuffer * +intel_renderbuffer(struct gl_renderbuffer *rb) +{ + struct intel_renderbuffer *irb = (struct intel_renderbuffer *) rb; + if (irb && irb->Base.ClassID == INTEL_RB_CLASS) { + /*_mesa_warning(NULL, "Returning non-intel Rb\n");*/ + return irb; + } + else + return NULL; +} + + +struct intel_renderbuffer * +intel_get_renderbuffer(struct gl_framebuffer *fb, GLuint attIndex) +{ + return intel_renderbuffer(fb->Attachment[attIndex].Renderbuffer); +} + + +struct intel_region * +intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex) +{ + struct intel_renderbuffer *irb + = intel_renderbuffer(fb->Attachment[attIndex].Renderbuffer); + if (irb) + return irb->region; + else + return NULL; +} + + + +/** + * Create a new framebuffer object. + */ +static struct gl_framebuffer * +intel_new_framebuffer(GLcontext * ctx, GLuint name) +{ + /* there's no intel_framebuffer at this time, just use Mesa's class */ + return _mesa_new_framebuffer(ctx, name); +} + + +static void +intel_delete_renderbuffer(struct gl_renderbuffer *rb) +{ + GET_CURRENT_CONTEXT(ctx); + struct intel_context *intel = intel_context(ctx); + struct intel_renderbuffer *irb = intel_renderbuffer(rb); + + ASSERT(irb); + + if (irb->PairedStencil || irb->PairedDepth) { + intel_unpair_depth_stencil(ctx, irb); + } + + if (intel && irb->region) { + intel_region_release(&irb->region); + } + + _mesa_free(irb); +} + + + +/** + * Return a pointer to a specific pixel in a renderbuffer. + */ +static void * +intel_get_pointer(GLcontext * ctx, struct gl_renderbuffer *rb, + GLint x, GLint y) +{ + /* By returning NULL we force all software rendering to go through + * the span routines. + */ + return NULL; +} + + + +/** + * Called via glRenderbufferStorageEXT() to set the format and allocate + * storage for a user-created renderbuffer. + */ +static GLboolean +intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, GLuint height) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_renderbuffer *irb = intel_renderbuffer(rb); + GLboolean softwareBuffer = GL_FALSE; + int cpp; + + ASSERT(rb->Name != 0); + + switch (internalFormat) { + case GL_R3_G3_B2: + case GL_RGB4: + case GL_RGB5: + rb->_ActualFormat = GL_RGB5; + rb->DataType = GL_UNSIGNED_BYTE; + rb->RedBits = 5; + rb->GreenBits = 6; + rb->BlueBits = 5; + cpp = 2; + break; + case GL_RGB: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + case GL_RGBA: + case GL_RGBA2: + case GL_RGBA4: + case GL_RGB5_A1: + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + rb->_ActualFormat = GL_RGBA8; + rb->DataType = GL_UNSIGNED_BYTE; + rb->RedBits = 8; + rb->GreenBits = 8; + rb->BlueBits = 8; + rb->AlphaBits = 8; + cpp = 4; + break; + case GL_STENCIL_INDEX: + case GL_STENCIL_INDEX1_EXT: + case GL_STENCIL_INDEX4_EXT: + case GL_STENCIL_INDEX8_EXT: + case GL_STENCIL_INDEX16_EXT: + /* alloc a depth+stencil buffer */ + rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT; + rb->DataType = GL_UNSIGNED_INT_24_8_EXT; + rb->StencilBits = 8; + cpp = 4; + break; + case GL_DEPTH_COMPONENT16: + rb->_ActualFormat = GL_DEPTH_COMPONENT16; + rb->DataType = GL_UNSIGNED_SHORT; + rb->DepthBits = 16; + cpp = 2; + break; + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT32: + rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT; + rb->DataType = GL_UNSIGNED_INT_24_8_EXT; + rb->DepthBits = 24; + cpp = 4; + break; + case GL_DEPTH_STENCIL_EXT: + case GL_DEPTH24_STENCIL8_EXT: + rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT; + rb->DataType = GL_UNSIGNED_INT_24_8_EXT; + rb->DepthBits = 24; + rb->StencilBits = 8; + cpp = 4; + break; + default: + _mesa_problem(ctx, + "Unexpected format in intel_alloc_renderbuffer_storage"); + return GL_FALSE; + } + + intelFlush(ctx); + + /* free old region */ + if (irb->region) { + intel_region_release(&irb->region); + } + + /* allocate new memory region/renderbuffer */ + if (softwareBuffer) { + return _mesa_soft_renderbuffer_storage(ctx, rb, internalFormat, + width, height); + } + else { + /* Choose a pitch to match hardware requirements: + */ + GLuint pitch = ((cpp * width + 63) & ~63) / cpp; + + /* alloc hardware renderbuffer */ + DBG("Allocating %d x %d Intel RBO (pitch %d)\n", width, + height, pitch); + + irb->region = intel_region_alloc(intel->intelScreen, cpp, pitch, height); + if (!irb->region) + return GL_FALSE; /* out of memory? */ + + ASSERT(irb->region->buffer); + + rb->Width = width; + rb->Height = height; + + /* This sets the Get/PutRow/Value functions */ + intel_set_span_functions(&irb->Base); + + return GL_TRUE; + } +} + + + +/** + * Called for each hardware renderbuffer when a _window_ is resized. + * Just update fields. + * Not used for user-created renderbuffers! + */ +static GLboolean +intel_alloc_window_storage(GLcontext * ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, GLuint width, GLuint height) +{ + ASSERT(rb->Name == 0); + rb->Width = width; + rb->Height = height; + rb->_ActualFormat = internalFormat; + return GL_TRUE; +} + + +static GLboolean +intel_nop_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, GLuint width, GLuint height) +{ + _mesa_problem(ctx, "intel_op_alloc_storage should never be called."); + return GL_FALSE; +} + + + +/** + * Create a new intel_renderbuffer which corresponds to an on-screen window, + * not a user-created renderbuffer. + * \param width the screen width + * \param height the screen height + */ +struct intel_renderbuffer * +intel_create_renderbuffer(GLenum intFormat, GLsizei width, GLsizei height, + int offset, int pitch, int cpp, void *map) +{ + GET_CURRENT_CONTEXT(ctx); + + struct intel_renderbuffer *irb; + const GLuint name = 0; + + irb = CALLOC_STRUCT(intel_renderbuffer); + if (!irb) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer"); + return NULL; + } + + _mesa_init_renderbuffer(&irb->Base, name); + irb->Base.ClassID = INTEL_RB_CLASS; + + switch (intFormat) { + case GL_RGB5: + irb->Base._ActualFormat = GL_RGB5; + irb->Base._BaseFormat = GL_RGBA; + irb->Base.RedBits = 5; + irb->Base.GreenBits = 6; + irb->Base.BlueBits = 5; + irb->Base.DataType = GL_UNSIGNED_BYTE; + cpp = 2; + break; + case GL_RGBA8: + irb->Base._ActualFormat = GL_RGBA8; + irb->Base._BaseFormat = GL_RGBA; + irb->Base.RedBits = 8; + irb->Base.GreenBits = 8; + irb->Base.BlueBits = 8; + irb->Base.AlphaBits = 8; + irb->Base.DataType = GL_UNSIGNED_BYTE; + cpp = 4; + break; + case GL_STENCIL_INDEX8_EXT: + irb->Base._ActualFormat = GL_STENCIL_INDEX8_EXT; + irb->Base._BaseFormat = GL_STENCIL_INDEX; + irb->Base.StencilBits = 8; + irb->Base.DataType = GL_UNSIGNED_BYTE; + cpp = 1; + break; + case GL_DEPTH_COMPONENT16: + irb->Base._ActualFormat = GL_DEPTH_COMPONENT16; + irb->Base._BaseFormat = GL_DEPTH_COMPONENT; + irb->Base.DepthBits = 16; + irb->Base.DataType = GL_UNSIGNED_SHORT; + cpp = 2; + break; + case GL_DEPTH_COMPONENT24: + irb->Base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; + irb->Base._BaseFormat = GL_DEPTH_COMPONENT; + irb->Base.DepthBits = 24; + irb->Base.DataType = GL_UNSIGNED_INT; + cpp = 4; + break; + case GL_DEPTH24_STENCIL8_EXT: + irb->Base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; + irb->Base._BaseFormat = GL_DEPTH_STENCIL_EXT; + irb->Base.DepthBits = 24; + irb->Base.StencilBits = 8; + irb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT; + cpp = 4; + break; + default: + _mesa_problem(NULL, + "Unexpected intFormat in intel_create_renderbuffer"); + return NULL; + } + + irb->Base.InternalFormat = intFormat; + + /* intel-specific methods */ + irb->Base.Delete = intel_delete_renderbuffer; + irb->Base.AllocStorage = intel_alloc_window_storage; + irb->Base.GetPointer = intel_get_pointer; + /* This sets the Get/PutRow/Value functions */ + intel_set_span_functions(&irb->Base); + + irb->pfMap = map; + irb->pfPitch = pitch / cpp; /* in pixels */ + +#if 00 + irb->region = intel_region_create_static(intel, + DRM_MM_TT, + offset, map, cpp, width, height); +#endif + + return irb; +} + + +/** + * Create a new renderbuffer object. + * Typically called via glBindRenderbufferEXT(). + */ +static struct gl_renderbuffer * +intel_new_renderbuffer(GLcontext * ctx, GLuint name) +{ + /*struct intel_context *intel = intel_context(ctx); */ + struct intel_renderbuffer *irb; + + irb = CALLOC_STRUCT(intel_renderbuffer); + if (!irb) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer"); + return NULL; + } + + _mesa_init_renderbuffer(&irb->Base, name); + irb->Base.ClassID = INTEL_RB_CLASS; + + /* intel-specific methods */ + irb->Base.Delete = intel_delete_renderbuffer; + irb->Base.AllocStorage = intel_alloc_renderbuffer_storage; + irb->Base.GetPointer = intel_get_pointer; + /* span routines set in alloc_storage function */ + + return &irb->Base; +} + + +/** + * Called via glBindFramebufferEXT(). + */ +static void +intel_bind_framebuffer(GLcontext * ctx, GLenum target, + struct gl_framebuffer *fb) +{ + if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) { + intel_draw_buffer(ctx, fb); + /* Integer depth range depends on depth buffer bits */ + ctx->Driver.DepthRange(ctx, ctx->Viewport.Near, ctx->Viewport.Far); + } + else { + /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */ + } +} + + +/** + * Called via glFramebufferRenderbufferEXT(). + */ +static void +intel_framebuffer_renderbuffer(GLcontext * ctx, + struct gl_framebuffer *fb, + GLenum attachment, struct gl_renderbuffer *rb) +{ + DBG("Intel FramebufferRenderbuffer %u %u\n", fb->Name, rb ? rb->Name : 0); + + intelFlush(ctx); + + _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb); + intel_draw_buffer(ctx, fb); +} + + +/** + * When glFramebufferTexture[123]D is called this function sets up the + * gl_renderbuffer wrapp around the texture image. + * This will have the region info needed for hardware rendering. + */ +static struct intel_renderbuffer * +intel_wrap_texture(GLcontext * ctx, struct gl_texture_image *texImage) +{ + const GLuint name = ~0; /* not significant, but distinct for debugging */ + struct intel_renderbuffer *irb; + + /* make an intel_renderbuffer to wrap the texture image */ + irb = CALLOC_STRUCT(intel_renderbuffer); + if (!irb) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture"); + return NULL; + } + + _mesa_init_renderbuffer(&irb->Base, name); + irb->Base.ClassID = INTEL_RB_CLASS; + + if (texImage->TexFormat == &_mesa_texformat_argb8888) { + irb->Base._ActualFormat = GL_RGBA8; + irb->Base._BaseFormat = GL_RGBA; + DBG("Render to RGBA8 texture OK\n"); + } + else if (texImage->TexFormat == &_mesa_texformat_rgb565) { + irb->Base._ActualFormat = GL_RGB5; + irb->Base._BaseFormat = GL_RGB; + DBG("Render to RGB5 texture OK\n"); + } + else if (texImage->TexFormat == &_mesa_texformat_z16) { + irb->Base._ActualFormat = GL_DEPTH_COMPONENT16; + irb->Base._BaseFormat = GL_DEPTH_COMPONENT; + DBG("Render to DEPTH16 texture OK\n"); + } + else { + DBG("Render to texture BAD FORMAT %d\n", + texImage->TexFormat->MesaFormat); + _mesa_free(irb); + return NULL; + } + + irb->Base.InternalFormat = irb->Base._ActualFormat; + irb->Base.Width = texImage->Width; + irb->Base.Height = texImage->Height; + irb->Base.DataType = GL_UNSIGNED_BYTE; /* FBO XXX fix */ + irb->Base.RedBits = texImage->TexFormat->RedBits; + irb->Base.GreenBits = texImage->TexFormat->GreenBits; + irb->Base.BlueBits = texImage->TexFormat->BlueBits; + irb->Base.AlphaBits = texImage->TexFormat->AlphaBits; + irb->Base.DepthBits = texImage->TexFormat->DepthBits; + + irb->Base.Delete = intel_delete_renderbuffer; + irb->Base.AllocStorage = intel_nop_alloc_storage; + intel_set_span_functions(&irb->Base); + + irb->RenderToTexture = GL_TRUE; + + return irb; +} + + +/** + * Called by glFramebufferTexture[123]DEXT() (and other places) to + * prepare for rendering into texture memory. This might be called + * many times to choose different texture levels, cube faces, etc + * before intel_finish_render_texture() is ever called. + */ +static void +intel_render_texture(GLcontext * ctx, + struct gl_framebuffer *fb, + struct gl_renderbuffer_attachment *att) +{ + struct gl_texture_image *newImage + = att->Texture->Image[att->CubeMapFace][att->TextureLevel]; + struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer); + struct intel_texture_image *intel_image; + GLuint imageOffset; + + (void) fb; + + ASSERT(newImage); + + if (!irb) { + irb = intel_wrap_texture(ctx, newImage); + if (irb) { + /* bind the wrapper to the attachment point */ + att->Renderbuffer = &irb->Base; + } + else { + /* fallback to software rendering */ + _mesa_render_texture(ctx, fb, att); + return; + } + } + + DBG("Begin render texture tid %x tex=%u w=%d h=%d refcount=%d\n", + _glthread_GetID(), + att->Texture->Name, newImage->Width, newImage->Height, + irb->Base.RefCount); + + /* point the renderbufer's region to the texture image region */ + intel_image = intel_texture_image(newImage); + if (irb->region != intel_image->mt->region) { + if (irb->region) + intel_region_release(&irb->region); + intel_region_reference(&irb->region, intel_image->mt->region); + } + + /* compute offset of the particular 2D image within the texture region */ + imageOffset = intel_miptree_image_offset(intel_image->mt, + att->CubeMapFace, + att->TextureLevel); + + if (att->Texture->Target == GL_TEXTURE_3D) { + const GLuint *offsets = intel_miptree_depth_offsets(intel_image->mt, + att->TextureLevel); + imageOffset += offsets[att->Zoffset]; + } + + /* store that offset in the region */ + intel_image->mt->region->draw_offset = imageOffset; + + /* update drawing region, etc */ + intel_draw_buffer(ctx, fb); +} + + +/** + * Called by Mesa when rendering to a texture is done. + */ +static void +intel_finish_render_texture(GLcontext * ctx, + struct gl_renderbuffer_attachment *att) +{ + struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer); + + DBG("End render texture (tid %x) tex %u\n", _glthread_GetID(), att->Texture->Name); + + if (irb) { + /* just release the region */ + intel_region_release(&irb->region); + } + else if (att->Renderbuffer) { + /* software fallback */ + _mesa_finish_render_texture(ctx, att); + /* XXX FBO: Need to unmap the buffer (or in intelSpanRenderStart???) */ + } +} + + +/** + * Do one-time context initializations related to GL_EXT_framebuffer_object. + * Hook in device driver functions. + */ +void +intel_fbo_init(struct intel_context *intel) +{ + intel->ctx.Driver.NewFramebuffer = intel_new_framebuffer; + intel->ctx.Driver.NewRenderbuffer = intel_new_renderbuffer; + intel->ctx.Driver.BindFramebuffer = intel_bind_framebuffer; + intel->ctx.Driver.FramebufferRenderbuffer = intel_framebuffer_renderbuffer; + intel->ctx.Driver.RenderTexture = intel_render_texture; + intel->ctx.Driver.FinishRenderTexture = intel_finish_render_texture; +} diff --git a/src/mesa/drivers/dri/i915tex/intel_fbo.h b/src/mesa/drivers/dri/i915tex/intel_fbo.h new file mode 100644 index 0000000000..221f09b39a --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_fbo.h @@ -0,0 +1,80 @@ +/************************************************************************** + * + * Copyright 2006 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 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 ITS 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. + * + **************************************************************************/ + +#ifndef INTEL_FBO_H +#define INTEL_FBO_H + + +struct intel_context; +struct intel_region; + + +/** + * Intel renderbuffer, derived from gl_renderbuffer. + * Note: The PairedDepth and PairedStencil fields use renderbuffer IDs, + * not pointers because in some circumstances a deleted renderbuffer could + * result in a dangling pointer here. + */ +struct intel_renderbuffer +{ + struct gl_renderbuffer Base; + struct intel_region *region; + void *pfMap; /* possibly paged flipped map pointer */ + GLuint pfPitch; /* possibly paged flipped pitch */ + GLboolean RenderToTexture; /* RTT? */ + + GLuint PairedDepth; /**< only used if this is a depth renderbuffer */ + GLuint PairedStencil; /**< only used if this is a stencil renderbuffer */ +}; + + +extern struct intel_renderbuffer *intel_create_renderbuffer(GLenum intFormat, + GLsizei width, + GLsizei height, + int offset, + int pitch, + int cpp, + void *map); + + +extern void intel_fbo_init(struct intel_context *intel); + + +/* XXX make inline or macro */ +extern struct intel_renderbuffer *intel_get_renderbuffer(struct gl_framebuffer + *fb, + GLuint attIndex); + + +/* XXX make inline or macro */ +extern struct intel_region *intel_get_rb_region(struct gl_framebuffer *fb, + GLuint attIndex); + + + + +#endif /* INTEL_FBO_H */ diff --git a/src/mesa/drivers/dri/i915tex/intel_ioctl.c b/src/mesa/drivers/dri/i915tex/intel_ioctl.c new file mode 100644 index 0000000000..3250c6b3a9 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_ioctl.c @@ -0,0 +1,138 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + + +#include +#include +#include +#include + +#include "mtypes.h" +#include "context.h" +#include "swrast/swrast.h" + +#include "intel_context.h" +#include "intel_ioctl.h" +#include "intel_batchbuffer.h" +#include "intel_blit.h" +#include "intel_regions.h" +#include "drm.h" + +#define FILE_DEBUG_FLAG DEBUG_IOCTL + +int +intelEmitIrqLocked(struct intel_context *intel) +{ + drmI830IrqEmit ie; + int ret, seq; + + assert(((*(int *) intel->driHwLock) & ~DRM_LOCK_CONT) == + (DRM_LOCK_HELD | intel->hHWContext)); + + ie.irq_seq = &seq; + + ret = drmCommandWriteRead(intel->driFd, DRM_I830_IRQ_EMIT, + &ie, sizeof(ie)); + if (ret) { + fprintf(stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret); + exit(1); + } + + DBG("%s --> %d\n", __FUNCTION__, seq); + + return seq; +} + +void +intelWaitIrq(struct intel_context *intel, int seq) +{ + int ret; + + DBG("%s %d\n", __FUNCTION__, seq); + + intel->iw.irq_seq = seq; + + do { + ret = + drmCommandWrite(intel->driFd, DRM_I830_IRQ_WAIT, &intel->iw, + sizeof(intel->iw)); + } while (ret == -EAGAIN || ret == -EINTR); + + if (ret) { + fprintf(stderr, "%s: drmI830IrqWait: %d\n", __FUNCTION__, ret); + exit(1); + } +} + + +void +intel_batch_ioctl(struct intel_context *intel, + GLuint start_offset, + GLuint used, + GLboolean ignore_cliprects, GLboolean allow_unlock) +{ + drmI830BatchBuffer batch; + + assert(intel->locked); + assert(used); + + DBG("%s used %d offset %x..%x ignore_cliprects %d\n", + __FUNCTION__, + used, start_offset, start_offset + used, ignore_cliprects); + + /* Throw away non-effective packets. Won't work once we have + * hardware contexts which would preserve statechanges beyond a + * single buffer. + */ + + + + batch.start = start_offset; + batch.used = used; + batch.cliprects = intel->pClipRects; + batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects; + batch.DR1 = 0; + batch.DR4 = ((((GLuint) intel->drawX) & 0xffff) | + (((GLuint) intel->drawY) << 16)); + + DBG("%s: 0x%x..0x%x DR4: %x cliprects: %d\n", + __FUNCTION__, + batch.start, + batch.start + batch.used * 4, batch.DR4, batch.num_cliprects); + + if (drmCommandWrite(intel->driFd, DRM_I830_BATCHBUFFER, &batch, + sizeof(batch))) { + fprintf(stderr, "DRM_I830_BATCHBUFFER: %d\n", -errno); + UNLOCK_HARDWARE(intel); + exit(1); + } + + /* FIXME: use hardware contexts to avoid 'losing' hardware after + * each buffer flush. + */ + intel->vtbl.lost_hardware(intel); +} diff --git a/src/mesa/drivers/dri/i915tex/intel_ioctl.h b/src/mesa/drivers/dri/i915tex/intel_ioctl.h new file mode 100644 index 0000000000..e8d07de893 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_ioctl.h @@ -0,0 +1,40 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#ifndef INTEL_IOCTL_H +#define INTEL_IOCTL_H + +#include "intel_context.h" + +void intelWaitIrq(struct intel_context *intel, int seq); +int intelEmitIrqLocked(struct intel_context *intel); + +void intel_batch_ioctl(struct intel_context *intel, + GLuint start_offset, + GLuint used, + GLboolean ignore_cliprects, GLboolean allow_unlock); +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c new file mode 100644 index 0000000000..2ebe3ae14e --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c @@ -0,0 +1,341 @@ +/************************************************************************** + * + * Copyright 2006 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 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 ITS 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. + * + **************************************************************************/ + +#include "intel_context.h" +#include "intel_mipmap_tree.h" +#include "intel_regions.h" +#include "enums.h" + +#define FILE_DEBUG_FLAG DEBUG_MIPTREE + +static GLenum +target_to_target(GLenum target) +{ + switch (target) { + case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: + return GL_TEXTURE_CUBE_MAP_ARB; + default: + return target; + } +} + +struct intel_mipmap_tree * +intel_miptree_create(struct intel_context *intel, + GLenum target, + GLenum internal_format, + GLuint first_level, + GLuint last_level, + GLuint width0, + GLuint height0, + GLuint depth0, GLuint cpp, GLboolean compressed) +{ + GLboolean ok; + struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1); + + DBG("%s target %s format %s level %d..%d\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(target), + _mesa_lookup_enum_by_nr(internal_format), first_level, last_level); + + mt->target = target_to_target(target); + mt->internal_format = internal_format; + mt->first_level = first_level; + mt->last_level = last_level; + mt->width0 = width0; + mt->height0 = height0; + mt->depth0 = depth0; + mt->cpp = compressed ? 2 : cpp; + mt->compressed = compressed; + mt->refcount = 1; + + switch (intel->intelScreen->deviceID) { + case PCI_CHIP_I945_G: + case PCI_CHIP_I945_GM: + ok = i945_miptree_layout(mt); + break; + case PCI_CHIP_I915_G: + case PCI_CHIP_I915_GM: + case PCI_CHIP_I830_M: + case PCI_CHIP_I855_GM: + case PCI_CHIP_I865_G: + default: + /* All the i830 chips and the i915 use this layout: + */ + ok = i915_miptree_layout(mt); + break; + } + + if (ok) + mt->region = intel_region_alloc(intel->intelScreen, + mt->cpp, mt->pitch, mt->total_height); + + if (!mt->region) { + free(mt); + return NULL; + } + + return mt; +} + + +void +intel_miptree_reference(struct intel_mipmap_tree **dst, + struct intel_mipmap_tree *src) +{ + src->refcount++; + *dst = src; + DBG("%s %p refcount now %d\n", __FUNCTION__, src, src->refcount); +} + +void +intel_miptree_release(struct intel_context *intel, + struct intel_mipmap_tree **mt) +{ + if (!*mt) + return; + + DBG("%s %p refcount will be %d\n", __FUNCTION__, *mt, (*mt)->refcount - 1); + if (--(*mt)->refcount <= 0) { + GLuint i; + + DBG("%s deleting %p\n", __FUNCTION__, *mt); + + intel_region_release(&((*mt)->region)); + + for (i = 0; i < MAX_TEXTURE_LEVELS; i++) + if ((*mt)->level[i].image_offset) + free((*mt)->level[i].image_offset); + + free(*mt); + } + *mt = NULL; +} + + + + +/* Can the image be pulled into a unified mipmap tree. This mirrors + * the completeness test in a lot of ways. + * + * Not sure whether I want to pass gl_texture_image here. + */ +GLboolean +intel_miptree_match_image(struct intel_mipmap_tree *mt, + struct gl_texture_image *image, + GLuint face, GLuint level) +{ + /* Images with borders are never pulled into mipmap trees. + */ + if (image->Border) + return GL_FALSE; + + if (image->InternalFormat != mt->internal_format || + image->IsCompressed != mt->compressed) + return GL_FALSE; + + /* Test image dimensions against the base level image adjusted for + * minification. This will also catch images not present in the + * tree, changed targets, etc. + */ + if (image->Width != mt->level[level].width || + image->Height != mt->level[level].height || + image->Depth != mt->level[level].depth) + return GL_FALSE; + + return GL_TRUE; +} + + +void +intel_miptree_set_level_info(struct intel_mipmap_tree *mt, + GLuint level, + GLuint nr_images, + GLuint x, GLuint y, GLuint w, GLuint h, GLuint d) +{ + + mt->level[level].width = w; + mt->level[level].height = h; + mt->level[level].depth = d; + mt->level[level].level_offset = (x + y * mt->pitch) * mt->cpp; + mt->level[level].nr_images = nr_images; + + DBG("%s level %d size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__, + level, w, h, d, x, y, mt->level[level].level_offset); + + /* Not sure when this would happen, but anyway: + */ + if (mt->level[level].image_offset) { + free(mt->level[level].image_offset); + mt->level[level].image_offset = NULL; + } + + assert(nr_images); + + mt->level[level].image_offset = malloc(nr_images * sizeof(GLuint)); + mt->level[level].image_offset[0] = 0; +} + + + +void +intel_miptree_set_image_offset(struct intel_mipmap_tree *mt, + GLuint level, GLuint img, GLuint x, GLuint y) +{ + if (img == 0 && level == 0) + assert(x == 0 && y == 0); + + assert(img < mt->level[level].nr_images); + + mt->level[level].image_offset[img] = (x + y * mt->pitch); + + DBG("%s level %d img %d pos %d,%d image_offset %x\n", + __FUNCTION__, level, img, x, y, mt->level[level].image_offset[img]); +} + + +/* Although we use the image_offset[] array to store relative offsets + * to cube faces, Mesa doesn't know anything about this and expects + * each cube face to be treated as a separate image. + * + * These functions present that view to mesa: + */ +const GLuint * +intel_miptree_depth_offsets(struct intel_mipmap_tree *mt, GLuint level) +{ + static const GLuint zero = 0; + + if (mt->target != GL_TEXTURE_3D || mt->level[level].nr_images == 1) + return &zero; + else + return mt->level[level].image_offset; +} + + +GLuint +intel_miptree_image_offset(struct intel_mipmap_tree * mt, + GLuint face, GLuint level) +{ + if (mt->target == GL_TEXTURE_CUBE_MAP_ARB) + return (mt->level[level].level_offset + + mt->level[level].image_offset[face] * mt->cpp); + else + return mt->level[level].level_offset; +} + + + +/** + * Map a teximage in a mipmap tree. + * \param row_stride returns row stride in bytes + * \param image_stride returns image stride in bytes (for 3D textures). + * \return address of mapping + */ +GLubyte * +intel_miptree_image_map(struct intel_context * intel, + struct intel_mipmap_tree * mt, + GLuint face, + GLuint level, + GLuint * row_stride, GLuint * image_offsets) +{ + DBG("%s \n", __FUNCTION__); + + if (row_stride) + *row_stride = mt->pitch * mt->cpp; + + if (image_offsets) + memcpy(image_offsets, mt->level[level].image_offset, + mt->level[level].depth * sizeof(GLuint)); + + return (intel_region_map(intel->intelScreen, mt->region) + + intel_miptree_image_offset(mt, face, level)); +} + +void +intel_miptree_image_unmap(struct intel_context *intel, + struct intel_mipmap_tree *mt) +{ + DBG("%s\n", __FUNCTION__); + intel_region_unmap(intel->intelScreen, mt->region); +} + + + +/* Upload data for a particular image. + */ +void +intel_miptree_image_data(struct intel_context *intel, + struct intel_mipmap_tree *dst, + GLuint face, + GLuint level, + void *src, + GLuint src_row_pitch, GLuint src_image_pitch) +{ + GLuint depth = dst->level[level].depth; + GLuint dst_offset = intel_miptree_image_offset(dst, face, level); + const GLuint *dst_depth_offset = intel_miptree_depth_offsets(dst, level); + GLuint i; + + DBG("%s\n", __FUNCTION__); + for (i = 0; i < depth; i++) { + intel_region_data(intel->intelScreen, dst->region, dst_offset + dst_depth_offset[i], 0, 0, src, src_row_pitch, 0, 0, /* source x,y */ + dst->level[level].width, dst->level[level].height); + + src += src_image_pitch; + } +} + +/* Copy mipmap image between trees + */ +void +intel_miptree_image_copy(struct intel_context *intel, + struct intel_mipmap_tree *dst, + GLuint face, GLuint level, + struct intel_mipmap_tree *src) +{ + GLuint width = src->level[level].width; + GLuint height = src->level[level].height; + GLuint depth = src->level[level].depth; + GLuint dst_offset = intel_miptree_image_offset(dst, face, level); + GLuint src_offset = intel_miptree_image_offset(src, face, level); + const GLuint *dst_depth_offset = intel_miptree_depth_offsets(dst, level); + const GLuint *src_depth_offset = intel_miptree_depth_offsets(src, level); + GLuint i; + + for (i = 0; i < depth; i++) { + intel_region_copy(intel->intelScreen, + dst->region, dst_offset + dst_depth_offset[i], + 0, + 0, + src->region, src_offset + src_depth_offset[i], + 0, 0, width, height); + } + +} diff --git a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.h b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.h new file mode 100644 index 0000000000..e6dd5bb600 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.h @@ -0,0 +1,198 @@ +/************************************************************************** + * + * Copyright 2006 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 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 ITS 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. + * + **************************************************************************/ + +#ifndef INTEL_MIPMAP_TREE_H +#define INTEL_MIPMAP_TREE_H + +#include "intel_regions.h" + +/* A layer on top of the intel_regions code which adds: + * + * - Code to size and layout a region to hold a set of mipmaps. + * - Query to determine if a new image fits in an existing tree. + * - More refcounting + * - maybe able to remove refcounting from intel_region? + * - ? + * + * The fixed mipmap layout of intel hardware where one offset + * specifies the position of all images in a mipmap hierachy + * complicates the implementation of GL texture image commands, + * compared to hardware where each image is specified with an + * independent offset. + * + * In an ideal world, each texture object would be associated with a + * single bufmgr buffer or 2d intel_region, and all the images within + * the texture object would slot into the tree as they arrive. The + * reality can be a little messier, as images can arrive from the user + * with sizes that don't fit in the existing tree, or in an order + * where the tree layout cannot be guessed immediately. + * + * This structure encodes an idealized mipmap tree. The GL image + * commands build these where possible, otherwise store the images in + * temporary system buffers. + */ + + +/** + * Describes the location of each texture image within a texture region. + */ +struct intel_mipmap_level +{ + GLuint level_offset; + GLuint width; + GLuint height; + GLuint depth; + GLuint nr_images; + + /* Explicitly store the offset of each image for each cube face or + * depth value. Pretty much have to accept that hardware formats + * are going to be so diverse that there is no unified way to + * compute the offsets of depth/cube images within a mipmap level, + * so have to store them as a lookup table: + */ + GLuint *image_offset; +}; + +struct intel_mipmap_tree +{ + /* Effectively the key: + */ + GLenum target; + GLenum internal_format; + + GLuint first_level; + GLuint last_level; + + GLuint width0, height0, depth0; /**< Level zero image dimensions */ + GLuint cpp; + GLboolean compressed; + + /* Derived from the above: + */ + GLuint pitch; + GLuint depth_pitch; /* per-image on i945? */ + GLuint total_height; + + /* Includes image offset tables: + */ + struct intel_mipmap_level level[MAX_TEXTURE_LEVELS]; + + /* The data is held here: + */ + struct intel_region *region; + + /* These are also refcounted: + */ + GLuint refcount; +}; + + + +struct intel_mipmap_tree *intel_miptree_create(struct intel_context *intel, + GLenum target, + GLenum internal_format, + GLuint first_level, + GLuint last_level, + GLuint width0, + GLuint height0, + GLuint depth0, + GLuint cpp, + GLboolean compressed); + +void intel_miptree_reference(struct intel_mipmap_tree **dst, + struct intel_mipmap_tree *src); + +void intel_miptree_release(struct intel_context *intel, + struct intel_mipmap_tree **mt); + +/* Check if an image fits an existing mipmap tree layout + */ +GLboolean intel_miptree_match_image(struct intel_mipmap_tree *mt, + struct gl_texture_image *image, + GLuint face, GLuint level); + +/* Return a pointer to an image within a tree. Return image stride as + * well. + */ +GLubyte *intel_miptree_image_map(struct intel_context *intel, + struct intel_mipmap_tree *mt, + GLuint face, + GLuint level, + GLuint * row_stride, GLuint * image_stride); + +void intel_miptree_image_unmap(struct intel_context *intel, + struct intel_mipmap_tree *mt); + + +/* Return the linear offset of an image relative to the start of the + * tree: + */ +GLuint intel_miptree_image_offset(struct intel_mipmap_tree *mt, + GLuint face, GLuint level); + +/* Return pointers to each 2d slice within an image. Indexed by depth + * value. + */ +const GLuint *intel_miptree_depth_offsets(struct intel_mipmap_tree *mt, + GLuint level); + + +void intel_miptree_set_level_info(struct intel_mipmap_tree *mt, + GLuint level, + GLuint nr_images, + GLuint x, GLuint y, + GLuint w, GLuint h, GLuint d); + +void intel_miptree_set_image_offset(struct intel_mipmap_tree *mt, + GLuint level, + GLuint img, GLuint x, GLuint y); + + +/* Upload an image into a tree + */ +void intel_miptree_image_data(struct intel_context *intel, + struct intel_mipmap_tree *dst, + GLuint face, + GLuint level, + void *src, + GLuint src_row_pitch, GLuint src_image_pitch); + +/* Copy an image between two trees + */ +void intel_miptree_image_copy(struct intel_context *intel, + struct intel_mipmap_tree *dst, + GLuint face, GLuint level, + struct intel_mipmap_tree *src); + +/* i915_mipmap_tree.c: + */ +GLboolean i915_miptree_layout(struct intel_mipmap_tree *mt); +GLboolean i945_miptree_layout(struct intel_mipmap_tree *mt); + + + +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel.c b/src/mesa/drivers/dri/i915tex/intel_pixel.c new file mode 100644 index 0000000000..4fe128deea --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_pixel.c @@ -0,0 +1,119 @@ +/************************************************************************** + * + * Copyright 2006 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 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 portionsalloc + * 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 ITS 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. + * + **************************************************************************/ + +#include "enums.h" +#include "state.h" +#include "swrast/swrast.h" + +#include "intel_context.h" +#include "intel_pixel.h" +#include "intel_regions.h" + + +/** + * Check if any fragment operations are in effect which might effect + * glDraw/CopyPixels. + */ +GLboolean +intel_check_blit_fragment_ops(GLcontext * ctx) +{ + if (ctx->NewState) + _mesa_update_state(ctx); + + /* XXX Note: Scissor could be done with the blitter: + */ + return !(ctx->_ImageTransferState || + ctx->Color.AlphaEnabled || + ctx->Depth.Test || + ctx->Fog.Enabled || + ctx->Scissor.Enabled || + ctx->Stencil.Enabled || + !ctx->Color.ColorMask[0] || + !ctx->Color.ColorMask[1] || + !ctx->Color.ColorMask[2] || + !ctx->Color.ColorMask[3] || + ctx->Color.ColorLogicOpEnabled || + ctx->Texture._EnabledUnits || ctx->FragmentProgram._Enabled); +} + + +GLboolean +intel_check_meta_tex_fragment_ops(GLcontext * ctx) +{ + if (ctx->NewState) + _mesa_update_state(ctx); + + /* Some of _ImageTransferState (scale, bias) could be done with + * fragment programs on i915. + */ + return !(ctx->_ImageTransferState || ctx->Fog.Enabled || /* not done yet */ + ctx->Texture._EnabledUnits || ctx->FragmentProgram._Enabled); +} + +/* The intel_region struct doesn't really do enough to capture the + * format of the pixels in the region. For now this code assumes that + * the region is a display surface and hence is either ARGB8888 or + * RGB565. + * XXX FBO: If we'd pass in the intel_renderbuffer instead of region, we'd + * know the buffer's pixel format. + * + * \param format as given to glDraw/ReadPixels + * \param type as given to glDraw/ReadPixels + */ +GLboolean +intel_check_blit_format(struct intel_region * region, + GLenum format, GLenum type) +{ + if (region->cpp == 4 && + (type == GL_UNSIGNED_INT_8_8_8_8_REV || + type == GL_UNSIGNED_BYTE) && format == GL_BGRA) { + return GL_TRUE; + } + + if (region->cpp == 2 && + type == GL_UNSIGNED_SHORT_5_6_5_REV && format == GL_BGR) { + return GL_TRUE; + } + + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s: bad format for blit (cpp %d, type %s format %s)\n", + __FUNCTION__, region->cpp, + _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format)); + + return GL_FALSE; +} + + +void +intelInitPixelFuncs(struct dd_function_table *functions) +{ + functions->Accum = _swrast_Accum; + functions->Bitmap = _swrast_Bitmap; + functions->CopyPixels = intelCopyPixels; + functions->ReadPixels = intelReadPixels; + functions->DrawPixels = intelDrawPixels; +} diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel.h b/src/mesa/drivers/dri/i915tex/intel_pixel.h new file mode 100644 index 0000000000..a6fcf90ce0 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_pixel.h @@ -0,0 +1,63 @@ +/************************************************************************** + * + * Copyright 2006 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 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 ITS 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. + * + **************************************************************************/ + +#ifndef INTEL_PIXEL_H +#define INTEL_PIXEL_H + +#include "mtypes.h" + +void intelInitPixelFuncs(struct dd_function_table *functions); + +GLboolean intel_check_blit_fragment_ops(GLcontext * ctx); + +GLboolean intel_check_meta_tex_fragment_ops(GLcontext * ctx); + +GLboolean intel_check_blit_format(struct intel_region *region, + GLenum format, GLenum type); + + +void intelReadPixels(GLcontext * ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, + GLvoid * pixels); + +void intelDrawPixels(GLcontext * ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, + GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid * pixels); + +void intelCopyPixels(GLcontext * ctx, + GLint srcx, GLint srcy, + GLsizei width, GLsizei height, + GLint destx, GLint desty, GLenum type); + +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel_bitmap.c b/src/mesa/drivers/dri/i915tex/intel_pixel_bitmap.c new file mode 100644 index 0000000000..65bf338589 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_pixel_bitmap.c @@ -0,0 +1,350 @@ +/************************************************************************** + * + * Copyright 2006 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 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 portionsalloc + * 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 ITS 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. + * + **************************************************************************/ + +#include "glheader.h" +#include "enums.h" +#include "image.h" +#include "colormac.h" +#include "mtypes.h" +#include "macros.h" +#include "bufferobj.h" +#include "swrast/swrast.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_ioctl.h" +#include "intel_batchbuffer.h" +#include "intel_blit.h" +#include "intel_regions.h" +#include "intel_buffer_objects.h" + + + +#define FILE_DEBUG_FLAG DEBUG_PIXEL + + +/* Unlike the other intel_pixel_* functions, the expectation here is + * that the incoming data is not in a PBO. With the XY_TEXT blit + * method, there's no benefit haveing it in a PBO, but we could + * implement a path based on XY_MONO_SRC_COPY_BLIT which might benefit + * PBO bitmaps. I think they are probably pretty rare though - I + * wonder if Xgl uses them? + */ +static const GLubyte *map_pbo( GLcontext *ctx, + GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap ) +{ + GLubyte *buf; + + if (!_mesa_validate_pbo_access(2, unpack, width, height, 1, + GL_COLOR_INDEX, GL_BITMAP, + (GLvoid *) bitmap)) { + _mesa_error(ctx, GL_INVALID_OPERATION,"glBitmap(invalid PBO access)"); + return NULL; + } + + buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, + GL_READ_ONLY_ARB, + unpack->BufferObj); + if (!buf) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glBitmap(PBO is mapped)"); + return NULL; + } + + return ADD_POINTERS(buf, bitmap); +} + +static GLboolean test_bit( const GLubyte *src, + GLuint bit ) +{ + return (src[bit/8] & (1<<(bit % 8))) ? 1 : 0; +} + +static void set_bit( GLubyte *dest, + GLuint bit ) +{ + dest[bit/8] |= 1 << (bit % 8); +} + +static int align(int x, int align) +{ + return (x + align - 1) & ~(align - 1); +} + +/* Extract a rectangle's worth of data from the bitmap. Called + * per-cliprect. + */ +static GLuint get_bitmap_rect(GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap, + GLuint x, GLuint y, + GLuint w, GLuint h, + GLubyte *dest, + GLuint row_align, + GLboolean invert) +{ + GLuint src_offset = (x + unpack->SkipPixels) & 0x7; + GLuint mask = unpack->LsbFirst ? 0 : 7; + GLuint bit = 0; + GLint row, col; + GLint first, last; + GLint incr; + GLuint count = 0; + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s %d,%d %dx%d bitmap %dx%d skip %d src_offset %d mask %d\n", + __FUNCTION__, x,y,w,h,width,height,unpack->SkipPixels, src_offset, mask); + + if (invert) { + first = h-1; + last = 0; + incr = -1; + } + else { + first = 0; + last = h-1; + incr = 1; + } + + /* Require that dest be pre-zero'd. + */ + for (row = first; row != (last+incr); row += incr) { + const GLubyte *rowsrc = _mesa_image_address2d(unpack, bitmap, + width, height, + GL_COLOR_INDEX, GL_BITMAP, + y + row, x); + + for (col = 0; col < w; col++, bit++) { + if (test_bit(rowsrc, (col + src_offset) ^ mask)) { + set_bit(dest, bit ^ 7); + count++; + } + } + + if (row_align) + bit = (bit + row_align - 1) & ~(row_align - 1); + } + + return count; +} + + + + +/* + * Render a bitmap. + */ +static GLboolean +do_blit_bitmap( GLcontext *ctx, + GLint dstx, GLint dsty, + GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap ) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_region *dst = intel_drawbuf_region(intel); + + union { + GLuint ui; + GLubyte ub[4]; + } color; + + + if (unpack->BufferObj->Name) { + bitmap = map_pbo(ctx, width, height, unpack, bitmap); + if (bitmap == NULL) + return GL_TRUE; /* even though this is an error, we're done */ + } + + UNCLAMPED_FLOAT_TO_CHAN(color.ub[0], ctx->Current.RasterColor[2]); + UNCLAMPED_FLOAT_TO_CHAN(color.ub[1], ctx->Current.RasterColor[1]); + UNCLAMPED_FLOAT_TO_CHAN(color.ub[2], ctx->Current.RasterColor[0]); + UNCLAMPED_FLOAT_TO_CHAN(color.ub[3], ctx->Current.RasterColor[3]); + + /* Does zoom apply to bitmaps? + */ + if (!intel_check_blit_fragment_ops(ctx) || + ctx->Pixel.ZoomX != 1.0F || + ctx->Pixel.ZoomY != 1.0F) + return GL_FALSE; + + LOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) { + __DRIdrawablePrivate *dPriv = intel->driDrawable; + drm_clip_rect_t *box = dPriv->pClipRects; + drm_clip_rect_t dest_rect; + GLint nbox = dPriv->numClipRects; + GLint srcx = 0, srcy = 0; + GLint orig_screen_x1, orig_screen_y2; + GLuint i; + + + orig_screen_x1 = dPriv->x + dstx; + orig_screen_y2 = dPriv->y + (dPriv->h - dsty); + + /* Do scissoring in GL coordinates: + */ +x if (ctx->Scissor.Enabled) + { + GLint x = ctx->Scissor.X; + GLint y = ctx->Scissor.Y; + GLuint w = ctx->Scissor.Width; + GLuint h = ctx->Scissor.Height; + + if (!_mesa_clip_to_region(x, y, x+w-1, y+h-1, &dstx, &dsty, &width, &height)) + goto out; + } + + /* Convert from GL to hardware coordinates: + */ + dsty = dPriv->y + (dPriv->h - dsty - height); + dstx = dPriv->x + dstx; + + dest_rect.x1 = dstx; + dest_rect.y1 = dsty; + dest_rect.x2 = dstx + width; + dest_rect.y2 = dsty + height; + + for (i = 0; i < nbox; i++) { + drm_clip_rect_t rect; + int box_w, box_h; + GLint px, py; + GLuint stipple[32]; + + if (!intel_intersect_cliprects(&rect, &dest_rect, &box[i])) + continue; + + /* Now go back to GL coordinates to figure out what subset of + * the bitmap we are uploading for this cliprect: + */ + box_w = rect.x2 - rect.x1; + box_h = rect.y2 - rect.y1; + srcx = rect.x1 - orig_screen_x1; + srcy = orig_screen_y2 - rect.y2; + + +#define DY 32 +#define DX 32 + + /* Then, finally, chop it all into chunks that can be + * digested by hardware: + */ + for (py = 0; py < box_h; py += DY) { + for (px = 0; px < box_w; px += DX) { + int h = MIN2(DY, box_h - py); + int w = MIN2(DX, box_w - px); + GLuint sz = align(align(w,8) * h, 64)/8; + + assert(sz <= sizeof(stipple)); + memset(stipple, 0, sz); + + /* May need to adjust this when padding has been introduced in + * sz above: + */ + if (get_bitmap_rect(width, height, unpack, + bitmap, + srcx + px, srcy + py, w, h, + (GLubyte *)stipple, + 8, + GL_TRUE) == 0) + continue; + + /* + */ + intelEmitImmediateColorExpandBlit( intel, + dst->cpp, + (GLubyte *)stipple, + sz, + color.ui, + dst->pitch, + dst->buffer, + 0, + dst->tiled, + rect.x1 + px, + rect.y2 - (py + h), + w, h); + } + } + } + intel->need_flush = GL_TRUE; + out: + intel_batchbuffer_flush(intel->batch); + } + UNLOCK_HARDWARE(intel); + + + if (unpack->BufferObj->Name) { + /* done with PBO so unmap it now */ + ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, + unpack->BufferObj); + } + + return GL_TRUE; +} + + + + + +/* There are a large number of possible ways to implement bitmap on + * this hardware, most of them have some sort of drawback. Here are a + * few that spring to mind: + * + * Blit: + * - XY_MONO_SRC_BLT_CMD + * - use XY_SETUP_CLIP_BLT for cliprect clipping. + * - XY_TEXT_BLT + * - XY_TEXT_IMMEDIATE_BLT + * - blit per cliprect, subject to maximum immediate data size. + * - XY_COLOR_BLT + * - per pixel or run of pixels + * - XY_PIXEL_BLT + * - good for sparse bitmaps + * + * 3D engine: + * - Point per pixel + * - Translate bitmap to an alpha texture and render as a quad + * - Chop bitmap up into 32x32 squares and render w/polygon stipple. + */ +void +intelBitmap(GLcontext * ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte * pixels) +{ + if (do_blit_bitmap(ctx, x, y, width, height, + unpack, pixels)) + return; + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s: fallback to swrast\n", __FUNCTION__); + + _swrast_Bitmap(ctx, x, y, width, height, unpack, pixels); +} diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel_copy.c b/src/mesa/drivers/dri/i915tex/intel_pixel_copy.c new file mode 100644 index 0000000000..5eb021f008 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_pixel_copy.c @@ -0,0 +1,380 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#include "glheader.h" +#include "enums.h" +#include "image.h" +#include "state.h" +#include "mtypes.h" +#include "macros.h" +#include "swrast/swrast.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_ioctl.h" +#include "intel_batchbuffer.h" +#include "intel_buffers.h" +#include "intel_blit.h" +#include "intel_regions.h" +#include "intel_tris.h" +#include "intel_pixel.h" + +#define FILE_DEBUG_FLAG DEBUG_PIXEL + +static struct intel_region * +copypix_src_region(struct intel_context *intel, GLenum type) +{ + switch (type) { + case GL_COLOR: + return intel_readbuf_region(intel); + case GL_DEPTH: + /* Don't think this is really possible execpt at 16bpp, when we have no stencil. + */ + if (intel->intelScreen->depth_region && + intel->intelScreen->depth_region->cpp == 2) + return intel->intelScreen->depth_region; + case GL_STENCIL: + /* Don't think this is really possible. + */ + break; + case GL_DEPTH_STENCIL_EXT: + /* Does it matter whether it is stencil/depth or depth/stencil? + */ + return intel->intelScreen->depth_region; + default: + break; + } + + return NULL; +} + + +/** + * Check if any fragment operations are in effect which might effect + * glCopyPixels. Differs from intel_check_blit_fragment_ops in that + * we allow Scissor. + */ +static GLboolean +intel_check_copypixel_blit_fragment_ops(GLcontext * ctx) +{ + if (ctx->NewState) + _mesa_update_state(ctx); + + /* Could do logicop with the blitter: + */ + return !(ctx->_ImageTransferState || + ctx->Color.AlphaEnabled || + ctx->Depth.Test || + ctx->Fog.Enabled || + ctx->Stencil.Enabled || + !ctx->Color.ColorMask[0] || + !ctx->Color.ColorMask[1] || + !ctx->Color.ColorMask[2] || + !ctx->Color.ColorMask[3] || + ctx->Color.ColorLogicOpEnabled || + ctx->Texture._EnabledUnits || + ctx->FragmentProgram._Enabled); +} + +/* Doesn't work for overlapping regions. Could do a double copy or + * just fallback. + */ +static GLboolean +do_texture_copypixels(GLcontext * ctx, + GLint srcx, GLint srcy, + GLsizei width, GLsizei height, + GLint dstx, GLint dsty, GLenum type) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_region *dst = intel_drawbuf_region(intel); + struct intel_region *src = copypix_src_region(intel, type); + GLenum src_format; + GLenum src_type; + + DBG("%s %d,%d %dx%d --> %d,%d\n", __FUNCTION__, + srcx, srcy, width, height, dstx, dsty); + + if (!src || !dst || type != GL_COLOR) + return GL_FALSE; + + /* Can't handle overlapping regions. Don't have sufficient control + * over rasterization to pull it off in-place. Punt on these for + * now. + * + * XXX: do a copy to a temporary. + */ + if (src->buffer == dst->buffer) { + drm_clip_rect_t srcbox; + drm_clip_rect_t dstbox; + drm_clip_rect_t tmp; + + srcbox.x1 = srcx; + srcbox.y1 = srcy; + srcbox.x2 = srcx + width; + srcbox.y2 = srcy + height; + + dstbox.x1 = dstx; + dstbox.y1 = dsty; + dstbox.x2 = dstx + width * ctx->Pixel.ZoomX; + dstbox.y2 = dsty + height * ctx->Pixel.ZoomY; + + DBG("src %d,%d %d,%d\n", srcbox.x1, srcbox.y1, srcbox.x2, srcbox.y2); + DBG("dst %d,%d %d,%d (%dx%d) (%f,%f)\n", dstbox.x1, dstbox.y1, dstbox.x2, dstbox.y2, + width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY); + + if (intel_intersect_cliprects(&tmp, &srcbox, &dstbox)) { + DBG("%s: regions overlap\n", __FUNCTION__); + return GL_FALSE; + } + } + + intelFlush(&intel->ctx); + + intel->vtbl.install_meta_state(intel); + + /* Is this true? Also will need to turn depth testing on according + * to state: + */ + intel->vtbl.meta_no_stencil_write(intel); + intel->vtbl.meta_no_depth_write(intel); + + /* Set the 3d engine to draw into the destination region: + */ + intel->vtbl.meta_draw_region(intel, dst, intel->intelScreen->depth_region); + + intel->vtbl.meta_import_pixel_state(intel); + + if (src->cpp == 2) { + src_format = GL_RGB; + src_type = GL_UNSIGNED_SHORT_5_6_5; + } + else { + src_format = GL_BGRA; + src_type = GL_UNSIGNED_BYTE; + } + + /* Set the frontbuffer up as a large rectangular texture. + */ + if (!intel->vtbl.meta_tex_rect_source(intel, src->buffer, 0, + src->pitch, + src->height, src_format, src_type)) { + intel->vtbl.leave_meta_state(intel); + return GL_FALSE; + } + + + intel->vtbl.meta_texture_blend_replace(intel); + + LOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) { + __DRIdrawablePrivate *dPriv = intel->driDrawable; + + + srcy = dPriv->h - srcy - height; /* convert from gl to hardware coords */ + + srcx += dPriv->x; + srcy += dPriv->y; + + /* Clip against the source region. This is the only source + * clipping we do. XXX: Just set the texcord wrap mode to clamp + * or similar. + * + */ + if (0) { + GLint orig_x = srcx; + GLint orig_y = srcy; + + if (!_mesa_clip_to_region(0, 0, src->pitch, src->height, + &srcx, &srcy, &width, &height)) + goto out; + + dstx += srcx - orig_x; + dsty += (srcy - orig_y) * ctx->Pixel.ZoomY; + } + + /* Just use the regular cliprect mechanism... Does this need to + * even hold the lock??? + */ + intel_meta_draw_quad(intel, + dstx, + dstx + width * ctx->Pixel.ZoomX, + dPriv->h - (dsty + height * ctx->Pixel.ZoomY), + dPriv->h - (dsty), 0, /* XXX: what z value? */ + 0x00ff00ff, + srcx, srcx + width, srcy, srcy + height); + + out: + intel->vtbl.leave_meta_state(intel); + intel_batchbuffer_flush(intel->batch); + } + UNLOCK_HARDWARE(intel); + + DBG("%s: success\n", __FUNCTION__); + return GL_TRUE; +} + + + + + +/** + * CopyPixels with the blitter. Don't support zooming, pixel transfer, etc. + */ +static GLboolean +do_blit_copypixels(GLcontext * ctx, + GLint srcx, GLint srcy, + GLsizei width, GLsizei height, + GLint dstx, GLint dsty, GLenum type) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_region *dst = intel_drawbuf_region(intel); + struct intel_region *src = copypix_src_region(intel, type); + + /* Copypixels can be more than a straight copy. Ensure all the + * extra operations are disabled: + */ + if (!intel_check_copypixel_blit_fragment_ops(ctx) || + ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F) + return GL_FALSE; + + if (!src || !dst) + return GL_FALSE; + + + + intelFlush(&intel->ctx); + + LOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) { + __DRIdrawablePrivate *dPriv = intel->driDrawable; + drm_clip_rect_t *box = dPriv->pClipRects; + drm_clip_rect_t dest_rect; + GLint nbox = dPriv->numClipRects; + GLint delta_x = 0; + GLint delta_y = 0; + GLuint i; + + /* Do scissoring in GL coordinates: + */ + if (ctx->Scissor.Enabled) + { + GLint x = ctx->Scissor.X; + GLint y = ctx->Scissor.Y; + GLuint w = ctx->Scissor.Width; + GLuint h = ctx->Scissor.Height; + GLint dx = dstx - srcx; + GLint dy = dsty - srcy; + + if (!_mesa_clip_to_region(x, y, x+w-1, y+h-1, &dstx, &dsty, &width, &height)) + goto out; + + srcx = dstx - dx; + srcy = dsty - dy; + } + + /* Convert from GL to hardware coordinates: + */ + dsty = dPriv->h - dsty - height; + srcy = dPriv->h - srcy - height; + dstx += dPriv->x; + dsty += dPriv->y; + srcx += dPriv->x; + srcy += dPriv->y; + + /* Clip against the source region. This is the only source + * clipping we do. Dst is clipped with cliprects below. + */ + { + delta_x = srcx - dstx; + delta_y = srcy - dsty; + + if (!_mesa_clip_to_region(0, 0, src->pitch, src->height, + &srcx, &srcy, &width, &height)) + goto out; + + dstx = srcx - delta_x; + dsty = srcy - delta_y; + } + + dest_rect.x1 = dstx; + dest_rect.y1 = dsty; + dest_rect.x2 = dstx + width; + dest_rect.y2 = dsty + height; + + /* Could do slightly more clipping: Eg, take the intersection of + * the existing set of cliprects and those cliprects translated + * by delta_x, delta_y: + * + * This code will not overwrite other windows, but will + * introduce garbage when copying from obscured window regions. + */ + for (i = 0; i < nbox; i++) { + drm_clip_rect_t rect; + + if (!intel_intersect_cliprects(&rect, &dest_rect, &box[i])) + continue; + + + intelEmitCopyBlit(intel, dst->cpp, + src->pitch, src->buffer, 0, + dst->pitch, dst->buffer, 0, + rect.x1 + delta_x, rect.y1 + delta_y, /* srcx, srcy */ + rect.x1, rect.y1, /* dstx, dsty */ + rect.x2 - rect.x1, rect.y2 - rect.y1); + } + + out: + intel_batchbuffer_flush(intel->batch); + } + UNLOCK_HARDWARE(intel); + + DBG("%s: success\n", __FUNCTION__); + return GL_TRUE; +} + + +void +intelCopyPixels(GLcontext * ctx, + GLint srcx, GLint srcy, + GLsizei width, GLsizei height, + GLint destx, GLint desty, GLenum type) +{ + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (do_blit_copypixels(ctx, srcx, srcy, width, height, destx, desty, type)) + return; + + if (do_texture_copypixels(ctx, srcx, srcy, width, height, destx, desty, type)) + return; + + DBG("fallback to _swrast_CopyPixels\n"); + + _swrast_CopyPixels(ctx, srcx, srcy, width, height, destx, desty, type); +} diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c b/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c new file mode 100644 index 0000000000..616101aef9 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c @@ -0,0 +1,365 @@ +/************************************************************************** + * + * Copyright 2006 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 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 portionsalloc + * 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 ITS 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. + * + **************************************************************************/ + +#include "glheader.h" +#include "enums.h" +#include "image.h" +#include "mtypes.h" +#include "macros.h" +#include "bufferobj.h" +#include "swrast/swrast.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_ioctl.h" +#include "intel_batchbuffer.h" +#include "intel_blit.h" +#include "intel_buffers.h" +#include "intel_regions.h" +#include "intel_pixel.h" +#include "intel_buffer_objects.h" +#include "intel_tris.h" + + + +static GLboolean +do_texture_drawpixels(GLcontext * ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid * pixels) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_region *dst = intel_drawbuf_region(intel); + struct intel_buffer_object *src = intel_buffer_object(unpack->BufferObj); + GLuint rowLength = unpack->RowLength ? unpack->RowLength : width; + GLuint src_offset; + + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + intelFlush(&intel->ctx); + intel->vtbl.render_start(intel); + intel->vtbl.emit_state(intel); + + if (!dst) + return GL_FALSE; + + if (src) { + if (!_mesa_validate_pbo_access(2, unpack, width, height, 1, + format, type, pixels)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels"); + return GL_TRUE; + } + } + else { + /* PBO only for now: + */ +/* _mesa_printf("%s - not PBO\n", __FUNCTION__); */ + return GL_FALSE; + } + + /* There are a couple of things we can't do yet, one of which is + * set the correct state for pixel operations when GL texturing is + * enabled. That's a pretty rare state and probably not worth the + * effort. A completely device-independent version of this may do + * more. + * + * Similarly, we make no attempt to merge metaops processing with + * an enabled fragment program, though it would certainly be + * possible. + */ + if (!intel_check_meta_tex_fragment_ops(ctx)) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - bad GL fragment state for metaops texture\n", + __FUNCTION__); + return GL_FALSE; + } + + intel->vtbl.install_meta_state(intel); + + + /* Is this true? Also will need to turn depth testing on according + * to state: + */ + intel->vtbl.meta_no_stencil_write(intel); + intel->vtbl.meta_no_depth_write(intel); + + /* Set the 3d engine to draw into the destination region: + */ + intel->vtbl.meta_draw_region(intel, dst, intel->intelScreen->depth_region); + + intel->vtbl.meta_import_pixel_state(intel); + + src_offset = (GLuint) _mesa_image_address(2, unpack, pixels, width, height, + format, type, 0, 0, 0); + + + /* Setup the pbo up as a rectangular texture, if possible. + * + * TODO: This is almost always possible if the i915 fragment + * program is adjusted to correctly swizzle the sampled colors. + * The major exception is any 24bit texture, like RGB888, for which + * there is no hardware support. + */ + if (!intel->vtbl.meta_tex_rect_source(intel, src->buffer, src_offset, + rowLength, height, format, type)) { + intel->vtbl.leave_meta_state(intel); + return GL_FALSE; + } + + intel->vtbl.meta_texture_blend_replace(intel); + + + LOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) { + __DRIdrawablePrivate *dPriv = intel->driDrawable; + GLint srcx, srcy; + GLint dstx, dsty; + + dstx = x; + dsty = dPriv->h - (y + height); + + srcx = 0; /* skiprows/pixels already done */ + srcy = 0; + + if (0) { + const GLint orig_x = dstx; + const GLint orig_y = dsty; + + if (!_mesa_clip_to_region(0, 0, dst->pitch, dst->height, + &dstx, &dsty, &width, &height)) + goto out; + + srcx += dstx - orig_x; + srcy += dsty - orig_y; + } + + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("draw %d,%d %dx%d\n", dstx, dsty, width, height); + + /* Must use the regular cliprect mechanism in order to get the + * drawing origin set correctly. Otherwise scissor state is in + * incorrect coordinate space. Does this even need to hold the + * lock??? + */ + intel_meta_draw_quad(intel, + dstx, dstx + width * ctx->Pixel.ZoomX, + dPriv->h - (y + height * ctx->Pixel.ZoomY), + dPriv->h - (y), + -ctx->Current.RasterPos[2] * .5, + 0x00ff00ff, + srcx, srcx + width, srcy + height, srcy); + out: + intel->vtbl.leave_meta_state(intel); + intel_batchbuffer_flush(intel->batch); + } + UNLOCK_HARDWARE(intel); + return GL_TRUE; +} + + + + + +/* Pros: + * - no waiting for idle before updating framebuffer. + * + * Cons: + * - if upload is by memcpy, this may actually be slower than fallback path. + * - uploads the whole image even if destination is clipped + * + * Need to benchmark. + * + * Given the questions about performance, implement for pbo's only. + * This path is definitely a win if the pbo is already in agp. If it + * turns out otherwise, we can add the code necessary to upload client + * data to agp space before performing the blit. (Though it may turn + * out to be better/simpler just to use the texture engine). + */ +static GLboolean +do_blit_drawpixels(GLcontext * ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid * pixels) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_region *dest = intel_drawbuf_region(intel); + struct intel_buffer_object *src = intel_buffer_object(unpack->BufferObj); + GLuint src_offset; + GLuint rowLength; + struct _DriFenceObject *fence = NULL; + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s\n", __FUNCTION__); + + + if (!dest) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - no dest\n", __FUNCTION__); + return GL_FALSE; + } + + if (src) { + /* This validation should be done by core mesa: + */ + if (!_mesa_validate_pbo_access(2, unpack, width, height, 1, + format, type, pixels)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels"); + return GL_TRUE; + } + } + else { + /* PBO only for now: + */ + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - not PBO\n", __FUNCTION__); + return GL_FALSE; + } + + if (!intel_check_blit_format(dest, format, type)) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - bad format for blit\n", __FUNCTION__); + return GL_FALSE; + } + + if (!intel_check_meta_tex_fragment_ops(ctx)) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - bad GL fragment state for meta tex\n", + __FUNCTION__); + return GL_FALSE; + } + + if (ctx->Pixel.ZoomX != 1.0F) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - bad PixelZoomX for blit\n", __FUNCTION__); + return GL_FALSE; + } + + + if (unpack->RowLength > 0) + rowLength = unpack->RowLength; + else + rowLength = width; + + if (ctx->Pixel.ZoomY == -1.0F) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - bad PixelZoomY for blit\n", __FUNCTION__); + return GL_FALSE; /* later */ + y -= height; + } + else if (ctx->Pixel.ZoomY == 1.0F) { + rowLength = -rowLength; + } + else { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - bad PixelZoomY for blit\n", __FUNCTION__); + return GL_FALSE; + } + + src_offset = (GLuint) _mesa_image_address(2, unpack, pixels, width, height, + format, type, 0, 0, 0); + + intelFlush(&intel->ctx); + LOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) { + __DRIdrawablePrivate *dPriv = intel->driDrawable; + int nbox = dPriv->numClipRects; + drm_clip_rect_t *box = dPriv->pClipRects; + drm_clip_rect_t rect; + drm_clip_rect_t dest_rect; + struct _DriBufferObject *src_buffer = + intel_bufferobj_buffer(intel, src, INTEL_READ); + int i; + + dest_rect.x1 = dPriv->x + x; + dest_rect.y1 = dPriv->y + dPriv->h - (y + height); + dest_rect.x2 = dest_rect.x1 + width; + dest_rect.y2 = dest_rect.y1 + height; + + for (i = 0; i < nbox; i++) { + if (!intel_intersect_cliprects(&rect, &dest_rect, &box[i])) + continue; + + intelEmitCopyBlit(intel, + dest->cpp, + rowLength, + src_buffer, src_offset, + dest->pitch, + dest->buffer, 0, + rect.x1 - dest_rect.x1, + rect.y2 - dest_rect.y2, + rect.x1, + rect.y1, rect.x2 - rect.x1, rect.y2 - rect.y1); + } + fence = intel_batchbuffer_flush(intel->batch); + driFenceReference(fence); + } + UNLOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) + driFenceFinish(fence, DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW, GL_FALSE); + + driFenceUnReference(fence); + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - DONE\n", __FUNCTION__); + + return GL_TRUE; +} + + + +void +intelDrawPixels(GLcontext * ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, + GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid * pixels) +{ + if (do_blit_drawpixels(ctx, x, y, width, height, format, type, + unpack, pixels)) + return; + + if (do_texture_drawpixels(ctx, x, y, width, height, format, type, + unpack, pixels)) + return; + + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s: fallback to swrast\n", __FUNCTION__); + + _swrast_DrawPixels(ctx, x, y, width, height, format, type, unpack, pixels); +} diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel_read.c b/src/mesa/drivers/dri/i915tex/intel_pixel_read.c new file mode 100644 index 0000000000..c1cc65674d --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_pixel_read.c @@ -0,0 +1,317 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#include "glheader.h" +#include "enums.h" +#include "mtypes.h" +#include "macros.h" +#include "image.h" +#include "bufferobj.h" +#include "swrast/swrast.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_ioctl.h" +#include "intel_batchbuffer.h" +#include "intel_blit.h" +#include "intel_buffers.h" +#include "intel_regions.h" +#include "intel_pixel.h" +#include "intel_buffer_objects.h" + +/* For many applications, the new ability to pull the source buffers + * back out of the GTT and then do the packing/conversion operations + * in software will be as much of an improvement as trying to get the + * blitter and/or texture engine to do the work. + * + * This step is gated on private backbuffers. + * + * Obviously the frontbuffer can't be pulled back, so that is either + * an argument for blit/texture readpixels, or for blitting to a + * temporary and then pulling that back. + * + * When the destination is a pbo, however, it's not clear if it is + * ever going to be pulled to main memory (though the access param + * will be a good hint). So it sounds like we do want to be able to + * choose between blit/texture implementation on the gpu and pullback + * and cpu-based copying. + * + * Unless you can magically turn client memory into a PBO for the + * duration of this call, there will be a cpu-based copying step in + * any case. + */ + + +static GLboolean +do_texture_readpixels(GLcontext * ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, + struct intel_region *dest_region) +{ +#if 0 + struct intel_context *intel = intel_context(ctx); + intelScreenPrivate *screen = intel->intelScreen; + GLint pitch = pack->RowLength ? pack->RowLength : width; + __DRIdrawablePrivate *dPriv = intel->driDrawable; + int textureFormat; + GLenum glTextureFormat; + int destFormat, depthFormat, destPitch; + drm_clip_rect_t tmp; + + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + + if (ctx->_ImageTransferState || + pack->SwapBytes || pack->LsbFirst || !pack->Invert) { + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s: check_color failed\n", __FUNCTION__); + return GL_FALSE; + } + + intel->vtbl.meta_texrect_source(intel, intel_readbuf_region(intel)); + + if (!intel->vtbl.meta_render_dest(intel, dest_region, type, format)) { + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s: couldn't set dest %s/%s\n", + __FUNCTION__, + _mesa_lookup_enum_by_nr(type), + _mesa_lookup_enum_by_nr(format)); + return GL_FALSE; + } + + LOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) { + intel->vtbl.install_meta_state(intel); + intel->vtbl.meta_no_depth_write(intel); + intel->vtbl.meta_no_stencil_write(intel); + + if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) { + UNLOCK_HARDWARE(intel); + SET_STATE(i830, state); + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__); + return GL_TRUE; + } + + y = dPriv->h - y - height; + x += dPriv->x; + y += dPriv->y; + + + /* Set the frontbuffer up as a large rectangular texture. + */ + intel->vtbl.meta_tex_rect_source(intel, src_region, textureFormat); + + + intel->vtbl.meta_texture_blend_replace(i830, glTextureFormat); + + + /* Set the 3d engine to draw into the destination region: + */ + + intel->vtbl.meta_draw_region(intel, dest_region); + intel->vtbl.meta_draw_format(intel, destFormat, depthFormat); /* ?? */ + + + /* Draw a single quad, no cliprects: + */ + intel->vtbl.meta_disable_cliprects(intel); + + intel->vtbl.draw_quad(intel, + 0, width, 0, height, + 0x00ff00ff, x, x + width, y, y + height); + + intel->vtbl.leave_meta_state(intel); + } + UNLOCK_HARDWARE(intel); + + intel_region_wait_fence(ctx, dest_region); /* required by GL */ + return GL_TRUE; +#endif + + return GL_FALSE; +} + + + + +static GLboolean +do_blit_readpixels(GLcontext * ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, GLvoid * pixels) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_region *src = intel_readbuf_region(intel); + struct intel_buffer_object *dst = intel_buffer_object(pack->BufferObj); + GLuint dst_offset; + GLuint rowLength; + struct _DriFenceObject *fence = NULL; + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s\n", __FUNCTION__); + + if (!src) + return GL_FALSE; + + if (dst) { + /* XXX This validation should be done by core mesa: + */ + if (!_mesa_validate_pbo_access(2, pack, width, height, 1, + format, type, pixels)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels"); + return GL_TRUE; + } + } + else { + /* PBO only for now: + */ + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - not PBO\n", __FUNCTION__); + return GL_FALSE; + } + + + if (ctx->_ImageTransferState || + !intel_check_blit_format(src, format, type)) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - bad format for blit\n", __FUNCTION__); + return GL_FALSE; + } + + if (pack->Alignment != 1 || pack->SwapBytes || pack->LsbFirst) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s: bad packing params\n", __FUNCTION__); + return GL_FALSE; + } + + if (pack->RowLength > 0) + rowLength = pack->RowLength; + else + rowLength = width; + + if (pack->Invert) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s: MESA_PACK_INVERT not done yet\n", __FUNCTION__); + return GL_FALSE; + } + else { + rowLength = -rowLength; + } + + /* XXX 64-bit cast? */ + dst_offset = (GLuint) _mesa_image_address(2, pack, pixels, width, height, + format, type, 0, 0, 0); + + + /* Although the blits go on the command buffer, need to do this and + * fire with lock held to guarentee cliprects are correct. + */ + intelFlush(&intel->ctx); + LOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) { + GLboolean all = (width * height * src->cpp == dst->Base.Size && + x == 0 && dst_offset == 0); + + struct _DriBufferObject *dst_buffer = + intel_bufferobj_buffer(intel, dst, all ? INTEL_WRITE_FULL : + INTEL_WRITE_PART); + __DRIdrawablePrivate *dPriv = intel->driDrawable; + int nbox = dPriv->numClipRects; + drm_clip_rect_t *box = dPriv->pClipRects; + drm_clip_rect_t rect; + drm_clip_rect_t src_rect; + int i; + + src_rect.x1 = dPriv->x + x; + src_rect.y1 = dPriv->y + dPriv->h - (y + height); + src_rect.x2 = src_rect.x1 + width; + src_rect.y2 = src_rect.y1 + height; + + + + for (i = 0; i < nbox; i++) { + if (!intel_intersect_cliprects(&rect, &src_rect, &box[i])) + continue; + + intelEmitCopyBlit(intel, + src->cpp, + src->pitch, src->buffer, 0, + rowLength, + dst_buffer, dst_offset, + rect.x1, + rect.y1, + rect.x1 - src_rect.x1, + rect.y2 - src_rect.y2, + rect.x2 - rect.x1, rect.y2 - rect.y1); + } + + fence = intel_batchbuffer_flush(intel->batch); + driFenceReference(fence); + + } + UNLOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) + driFenceFinish(fence, DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW, + GL_FALSE); + + driFenceUnReference(fence); + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - DONE\n", __FUNCTION__); + + return GL_TRUE; +} + +void +intelReadPixels(GLcontext * ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, GLvoid * pixels) +{ + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + intelFlush(ctx); + + if (do_blit_readpixels + (ctx, x, y, width, height, format, type, pack, pixels)) + return; + + if (do_texture_readpixels + (ctx, x, y, width, height, format, type, pack, pixels)) + return; + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s: fallback to swrast\n", __FUNCTION__); + + _swrast_ReadPixels(ctx, x, y, width, height, format, type, pack, pixels); +} diff --git a/src/mesa/drivers/dri/i915tex/intel_reg.h b/src/mesa/drivers/dri/i915tex/intel_reg.h new file mode 100644 index 0000000000..1ec153266c --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_reg.h @@ -0,0 +1,84 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + + +#ifndef _INTEL_REG_H_ +#define _INTEL_REG_H_ + + + +#define CMD_3D (0x3<<29) + + +#define _3DPRIMITIVE ((0x3<<29)|(0x1f<<24)) +#define PRIM_INDIRECT (1<<23) +#define PRIM_INLINE (0<<23) +#define PRIM_INDIRECT_SEQUENTIAL (0<<17) +#define PRIM_INDIRECT_ELTS (1<<17) + +#define PRIM3D_TRILIST (0x0<<18) +#define PRIM3D_TRISTRIP (0x1<<18) +#define PRIM3D_TRISTRIP_RVRSE (0x2<<18) +#define PRIM3D_TRIFAN (0x3<<18) +#define PRIM3D_POLY (0x4<<18) +#define PRIM3D_LINELIST (0x5<<18) +#define PRIM3D_LINESTRIP (0x6<<18) +#define PRIM3D_RECTLIST (0x7<<18) +#define PRIM3D_POINTLIST (0x8<<18) +#define PRIM3D_DIB (0x9<<18) +#define PRIM3D_MASK (0x1f<<18) + +#define I915PACKCOLOR4444(r,g,b,a) \ + ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) + +#define I915PACKCOLOR1555(r,g,b,a) \ + ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ + ((a) ? 0x8000 : 0)) + +#define I915PACKCOLOR565(r,g,b) \ + ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) + +#define I915PACKCOLOR8888(r,g,b,a) \ + ((a<<24) | (r<<16) | (g<<8) | b) + + + + +#define BR00_BITBLT_CLIENT 0x40000000 +#define BR00_OP_COLOR_BLT 0x10000000 +#define BR00_OP_SRC_COPY_BLT 0x10C00000 +#define BR13_SOLID_PATTERN 0x80000000 + +#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4) +#define XY_COLOR_BLT_WRITE_ALPHA (1<<21) +#define XY_COLOR_BLT_WRITE_RGB (1<<20) + +#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) +#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) +#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) + +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_regions.c b/src/mesa/drivers/dri/i915tex/intel_regions.c new file mode 100644 index 0000000000..064a34cda8 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_regions.c @@ -0,0 +1,466 @@ +/************************************************************************** + * + * Copyright 2006 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 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 ITS 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. + * + **************************************************************************/ + +/* Provide additional functionality on top of bufmgr buffers: + * - 2d semantics and blit operations + * - refcounting of buffers for multiple images in a buffer. + * - refcounting of buffer mappings. + * - some logic for moving the buffers to the best memory pools for + * given operations. + * + * Most of this is to make it easier to implement the fixed-layout + * mipmap tree required by intel hardware in the face of GL's + * programming interface where each image can be specifed in random + * order and it isn't clear what layout the tree should have until the + * last moment. + */ + +#include "intel_context.h" +#include "intel_regions.h" +#include "intel_blit.h" +#include "intel_buffer_objects.h" +#include "dri_bufmgr.h" +#include "intel_batchbuffer.h" + +#define FILE_DEBUG_FLAG DEBUG_REGION + +void +intel_region_idle(intelScreenPrivate *intelScreen, struct intel_region *region) +{ + DBG("%s\n", __FUNCTION__); + if (region && region->buffer) + driBOWaitIdle(region->buffer, GL_FALSE); +} + +/* XXX: Thread safety? + */ +GLubyte * +intel_region_map(intelScreenPrivate *intelScreen, struct intel_region *region) +{ + DBG("%s\n", __FUNCTION__); + if (!region->map_refcount++) { + if (region->pbo) + intel_region_cow(intelScreen, region); + + region->map = driBOMap(region->buffer, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); + } + + return region->map; +} + +void +intel_region_unmap(intelScreenPrivate *intelScreen, struct intel_region *region) +{ + DBG("%s\n", __FUNCTION__); + if (!--region->map_refcount) { + driBOUnmap(region->buffer); + region->map = NULL; + } +} + +#undef TEST_CACHED_TEXTURES + +struct intel_region * +intel_region_alloc(intelScreenPrivate *intelScreen, + GLuint cpp, GLuint pitch, GLuint height) +{ + struct intel_region *region = calloc(sizeof(*region), 1); + + DBG("%s\n", __FUNCTION__); + + region->cpp = cpp; + region->pitch = pitch; + region->height = height; /* needed? */ + region->refcount = 1; + + driGenBuffers(intelScreen->regionPool, + "region", 1, ®ion->buffer, 64, +#ifdef TEST_CACHED_TEXTURES + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_BIND_CACHED | + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, +#else + 0, +#endif + 0); + driBOData(region->buffer, pitch * cpp * height, NULL, 0); + return region; +} + +void +intel_region_reference(struct intel_region **dst, struct intel_region *src) +{ + assert(*dst == NULL); + if (src) { + src->refcount++; + *dst = src; + } +} + +void +intel_region_release(struct intel_region **region) +{ + if (!*region) + return; + + DBG("%s %d\n", __FUNCTION__, (*region)->refcount - 1); + + ASSERT((*region)->refcount > 0); + (*region)->refcount--; + + if ((*region)->refcount == 0) { + assert((*region)->map_refcount == 0); + + if ((*region)->pbo) + (*region)->pbo->region = NULL; + (*region)->pbo = NULL; + driBOUnReference((*region)->buffer); + free(*region); + } + *region = NULL; +} + + +struct intel_region * +intel_region_create_static(intelScreenPrivate *intelScreen, + GLuint mem_type, + GLuint offset, + void *virtual, + GLuint cpp, GLuint pitch, GLuint height) +{ + struct intel_region *region = calloc(sizeof(*region), 1); + DBG("%s\n", __FUNCTION__); + + region->cpp = cpp; + region->pitch = pitch; + region->height = height; /* needed? */ + region->refcount = 1; + + /* + * We use a "shared" buffer type to indicate buffers created and + * shared by others. + */ + + driGenBuffers(intelScreen->staticPool, "static region", 1, + ®ion->buffer, 64, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_NO_MOVE | + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); + driBOSetStatic(region->buffer, offset, pitch * cpp * height, virtual, 0); + + return region; +} + + + +void +intel_region_update_static(intelScreenPrivate *intelScreen, + struct intel_region *region, + GLuint mem_type, + GLuint offset, + void *virtual, + GLuint cpp, GLuint pitch, GLuint height) +{ + DBG("%s\n", __FUNCTION__); + + region->cpp = cpp; + region->pitch = pitch; + region->height = height; /* needed? */ + + /* + * We use a "shared" buffer type to indicate buffers created and + * shared by others. + */ + + driDeleteBuffers(1, ®ion->buffer); + driGenBuffers(intelScreen->staticPool, "static region", 1, + ®ion->buffer, 64, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_NO_MOVE | + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); + driBOSetStatic(region->buffer, offset, pitch * cpp * height, virtual, 0); + +} + + + +/* + * XXX Move this into core Mesa? + */ +static void +_mesa_copy_rect(GLubyte * dst, + GLuint cpp, + GLuint dst_pitch, + GLuint dst_x, + GLuint dst_y, + GLuint width, + GLuint height, + GLubyte * src, GLuint src_pitch, GLuint src_x, GLuint src_y) +{ + GLuint i; + + dst_pitch *= cpp; + src_pitch *= cpp; + dst += dst_x * cpp; + src += src_x * cpp; + dst += dst_y * dst_pitch; + src += src_y * dst_pitch; + width *= cpp; + + if (width == dst_pitch && width == src_pitch) + memcpy(dst, src, height * width); + else { + for (i = 0; i < height; i++) { + memcpy(dst, src, width); + dst += dst_pitch; + src += src_pitch; + } + } +} + + +/* Upload data to a rectangular sub-region. Lots of choices how to do this: + * + * - memcpy by span to current destination + * - upload data as new buffer and blit + * + * Currently always memcpy. + */ +void +intel_region_data(intelScreenPrivate *intelScreen, + struct intel_region *dst, + GLuint dst_offset, + GLuint dstx, GLuint dsty, + void *src, GLuint src_pitch, + GLuint srcx, GLuint srcy, GLuint width, GLuint height) +{ + struct intel_context *intel = intelScreenContext(intelScreen); + + DBG("%s\n", __FUNCTION__); + + if (intel == NULL) + return; + + if (dst->pbo) { + if (dstx == 0 && + dsty == 0 && width == dst->pitch && height == dst->height) + intel_region_release_pbo(intelScreen, dst); + else + intel_region_cow(intelScreen, dst); + } + + + LOCK_HARDWARE(intel); + + _mesa_copy_rect(intel_region_map(intelScreen, dst) + dst_offset, + dst->cpp, + dst->pitch, + dstx, dsty, width, height, src, src_pitch, srcx, srcy); + + intel_region_unmap(intelScreen, dst); + + UNLOCK_HARDWARE(intel); + +} + +/* Copy rectangular sub-regions. Need better logic about when to + * push buffers into AGP - will currently do so whenever possible. + */ +void +intel_region_copy(intelScreenPrivate *intelScreen, + struct intel_region *dst, + GLuint dst_offset, + GLuint dstx, GLuint dsty, + struct intel_region *src, + GLuint src_offset, + GLuint srcx, GLuint srcy, GLuint width, GLuint height) +{ + struct intel_context *intel = intelScreenContext(intelScreen); + + DBG("%s\n", __FUNCTION__); + + if (intel == NULL) + return; + + if (dst->pbo) { + if (dstx == 0 && + dsty == 0 && width == dst->pitch && height == dst->height) + intel_region_release_pbo(intelScreen, dst); + else + intel_region_cow(intelScreen, dst); + } + + assert(src->cpp == dst->cpp); + + intelEmitCopyBlit(intel, + dst->cpp, + src->pitch, src->buffer, src_offset, + dst->pitch, dst->buffer, dst_offset, + srcx, srcy, dstx, dsty, width, height); +} + +/* Fill a rectangular sub-region. Need better logic about when to + * push buffers into AGP - will currently do so whenever possible. + */ +void +intel_region_fill(intelScreenPrivate *intelScreen, + struct intel_region *dst, + GLuint dst_offset, + GLuint dstx, GLuint dsty, + GLuint width, GLuint height, GLuint color) +{ + struct intel_context *intel = intelScreenContext(intelScreen); + + DBG("%s\n", __FUNCTION__); + + if (intel == NULL) + return; + + if (dst->pbo) { + if (dstx == 0 && + dsty == 0 && width == dst->pitch && height == dst->height) + intel_region_release_pbo(intelScreen, dst); + else + intel_region_cow(intelScreen, dst); + } + + intelEmitFillBlit(intel, + dst->cpp, + dst->pitch, dst->buffer, dst_offset, + dstx, dsty, width, height, color); +} + +/* Attach to a pbo, discarding our data. Effectively zero-copy upload + * the pbo's data. + */ +void +intel_region_attach_pbo(intelScreenPrivate *intelScreen, + struct intel_region *region, + struct intel_buffer_object *pbo) +{ + if (region->pbo == pbo) + return; + + /* If there is already a pbo attached, break the cow tie now. + * Don't call intel_region_release_pbo() as that would + * unnecessarily allocate a new buffer we would have to immediately + * discard. + */ + if (region->pbo) { + region->pbo->region = NULL; + region->pbo = NULL; + } + + if (region->buffer) { + driDeleteBuffers(1, ®ion->buffer); + region->buffer = NULL; + } + + region->pbo = pbo; + region->pbo->region = region; + region->buffer = driBOReference(pbo->buffer); +} + + +/* Break the COW tie to the pbo. The pbo gets to keep the data. + */ +void +intel_region_release_pbo(intelScreenPrivate *intelScreen, + struct intel_region *region) +{ + assert(region->buffer == region->pbo->buffer); + region->pbo->region = NULL; + region->pbo = NULL; + driBOUnReference(region->buffer); + region->buffer = NULL; + + driGenBuffers(intelScreen->regionPool, + "region", 1, ®ion->buffer, 64, 0, 0); + driBOData(region->buffer, + region->cpp * region->pitch * region->height, NULL, 0); +} + +/* Break the COW tie to the pbo. Both the pbo and the region end up + * with a copy of the data. + */ +void +intel_region_cow(intelScreenPrivate *intelScreen, struct intel_region *region) +{ + struct intel_context *intel = intelScreenContext(intelScreen); + struct intel_buffer_object *pbo = region->pbo; + + if (intel == NULL) + return; + + intel_region_release_pbo(intelScreen, region); + + assert(region->cpp * region->pitch * region->height == pbo->Base.Size); + + DBG("%s (%d bytes)\n", __FUNCTION__, pbo->Base.Size); + + /* Now blit from the texture buffer to the new buffer: + */ + + intel_batchbuffer_flush(intel->batch); + + if (!intel->locked) { + LOCK_HARDWARE(intel); + intelEmitCopyBlit(intel, + region->cpp, + region->pitch, + region->buffer, 0, + region->pitch, + pbo->buffer, 0, + 0, 0, 0, 0, region->pitch, region->height); + + intel_batchbuffer_flush(intel->batch); + UNLOCK_HARDWARE(intel); + } + else { + intelEmitCopyBlit(intel, + region->cpp, + region->pitch, + region->buffer, 0, + region->pitch, + pbo->buffer, 0, + 0, 0, 0, 0, region->pitch, region->height); + + intel_batchbuffer_flush(intel->batch); + } +} + +struct _DriBufferObject * +intel_region_buffer(intelScreenPrivate *intelScreen, + struct intel_region *region, GLuint flag) +{ + if (region->pbo) { + if (flag == INTEL_WRITE_PART) + intel_region_cow(intelScreen, region); + else if (flag == INTEL_WRITE_FULL) + intel_region_release_pbo(intelScreen, region); + } + + return region->buffer; +} diff --git a/src/mesa/drivers/dri/i915tex/intel_regions.h b/src/mesa/drivers/dri/i915tex/intel_regions.h new file mode 100644 index 0000000000..1415bace69 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_regions.h @@ -0,0 +1,141 @@ +/************************************************************************** + * + * Copyright 2006 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 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 ITS 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. + * + **************************************************************************/ + +#ifndef INTEL_REGIONS_H +#define INTEL_REGIONS_H + +#include "mtypes.h" +#include "intel_screen.h" + +struct intel_context; +struct intel_buffer_object; + +/** + * A layer on top of the bufmgr buffers that adds a few useful things: + * + * - Refcounting for local buffer references. + * - Refcounting for buffer maps + * - Buffer dimensions - pitch and height. + * - Blitter commands for copying 2D regions between buffers. (really???) + */ +struct intel_region +{ + struct _DriBufferObject *buffer; /**< buffer manager's buffer ID */ + GLuint refcount; /**< Reference count for region */ + GLuint cpp; /**< bytes per pixel */ + GLuint pitch; /**< in pixels */ + GLuint height; /**< in pixels */ + GLubyte *map; /**< only non-NULL when region is actually mapped */ + GLuint map_refcount; /**< Reference count for mapping */ + + GLuint draw_offset; /**< Offset of drawing address within the region */ + + struct intel_buffer_object *pbo; /* zero-copy uploads */ +}; + + +/* Allocate a refcounted region. Pointers to regions should only be + * copied by calling intel_reference_region(). + */ +struct intel_region *intel_region_alloc(intelScreenPrivate *intelScreen, + GLuint cpp, + GLuint pitch, GLuint height); + +void intel_region_reference(struct intel_region **dst, + struct intel_region *src); + +void intel_region_release(struct intel_region **ib); + +extern struct intel_region +*intel_region_create_static(intelScreenPrivate *intelScreen, + GLuint mem_type, + GLuint offset, + void *virtual, + GLuint cpp, + GLuint pitch, GLuint height); +extern void +intel_region_update_static(intelScreenPrivate *intelScreen, + struct intel_region *region, + GLuint mem_type, + GLuint offset, + void *virtual, + GLuint cpp, GLuint pitch, GLuint height); + + +void intel_region_idle(intelScreenPrivate *intelScreen, + struct intel_region *ib); + +/* Map/unmap regions. This is refcounted also: + */ +GLubyte *intel_region_map(intelScreenPrivate *intelScreen, + struct intel_region *ib); + +void intel_region_unmap(intelScreenPrivate *intelScreen, struct intel_region *ib); + + +/* Upload data to a rectangular sub-region + */ +void intel_region_data(intelScreenPrivate *intelScreen, + struct intel_region *dest, + GLuint dest_offset, + GLuint destx, GLuint desty, + void *src, GLuint src_stride, + GLuint srcx, GLuint srcy, GLuint width, GLuint height); + +/* Copy rectangular sub-regions + */ +void intel_region_copy(intelScreenPrivate *intelScreen, + struct intel_region *dest, + GLuint dest_offset, + GLuint destx, GLuint desty, + struct intel_region *src, + GLuint src_offset, + GLuint srcx, GLuint srcy, GLuint width, GLuint height); + +/* Fill a rectangular sub-region + */ +void intel_region_fill(intelScreenPrivate *intelScreen, + struct intel_region *dest, + GLuint dest_offset, + GLuint destx, GLuint desty, + GLuint width, GLuint height, GLuint color); + +/* Helpers for zerocopy uploads, particularly texture image uploads: + */ +void intel_region_attach_pbo(intelScreenPrivate *intelScreen, + struct intel_region *region, + struct intel_buffer_object *pbo); +void intel_region_release_pbo(intelScreenPrivate *intelScreen, + struct intel_region *region); +void intel_region_cow(intelScreenPrivate *intelScreen, + struct intel_region *region); + +struct _DriBufferObject *intel_region_buffer(intelScreenPrivate *intelScreen, + struct intel_region *region, + GLuint flag); + +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_render.c b/src/mesa/drivers/dri/i915tex/intel_render.c new file mode 100644 index 0000000000..f9fa55051e --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_render.c @@ -0,0 +1,242 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +/* + * Render unclipped vertex buffers by emitting vertices directly to + * dma buffers. Use strip/fan hardware acceleration where possible. + * + */ +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "imports.h" +#include "mtypes.h" +#include "enums.h" + +#include "tnl/t_context.h" +#include "tnl/t_vertex.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_tris.h" +#include "intel_batchbuffer.h" +#include "intel_reg.h" + +/* + * Render unclipped vertex buffers by emitting vertices directly to + * dma buffers. Use strip/fan hardware primitives where possible. + * Try to simulate missing primitives with indexed vertices. + */ +#define HAVE_POINTS 0 /* Has it, but can't use because subpixel has to + * be adjusted for points on the INTEL/I845G + */ +#define HAVE_LINES 1 +#define HAVE_LINE_STRIPS 1 +#define HAVE_TRIANGLES 1 +#define HAVE_TRI_STRIPS 1 +#define HAVE_TRI_STRIP_1 0 /* has it, template can't use it yet */ +#define HAVE_TRI_FANS 1 +#define HAVE_POLYGONS 1 +#define HAVE_QUADS 0 +#define HAVE_QUAD_STRIPS 0 + +#define HAVE_ELTS 0 + +static GLuint hw_prim[GL_POLYGON + 1] = { + 0, + PRIM3D_LINELIST, + PRIM3D_LINESTRIP, + PRIM3D_LINESTRIP, + PRIM3D_TRILIST, + PRIM3D_TRISTRIP, + PRIM3D_TRIFAN, + 0, + 0, + PRIM3D_POLY +}; + +static const GLenum reduced_prim[GL_POLYGON + 1] = { + GL_POINTS, + GL_LINES, + GL_LINES, + GL_LINES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES +}; + +static const int scale_prim[GL_POLYGON + 1] = { + 0, /* fallback case */ + 1, + 2, + 2, + 1, + 3, + 3, + 0, /* fallback case */ + 0, /* fallback case */ + 3 +}; + + +static void +intelDmaPrimitive(struct intel_context *intel, GLenum prim) +{ + if (0) + fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(prim)); + INTEL_FIREVERTICES(intel); + intel->vtbl.reduced_primitive_state(intel, reduced_prim[prim]); + intelStartInlinePrimitive(intel, hw_prim[prim], INTEL_BATCH_CLIPRECTS); +} + + +#define LOCAL_VARS struct intel_context *intel = intel_context(ctx) +#define INIT( prim ) \ +do { \ + intelDmaPrimitive( intel, prim ); \ +} while (0) + +#define FLUSH() INTEL_FIREVERTICES(intel) + +#define GET_SUBSEQUENT_VB_MAX_VERTS() \ + ((intel->batch->size - 1500) / (intel->vertex_size*4)) +#define GET_CURRENT_VB_MAX_VERTS() GET_SUBSEQUENT_VB_MAX_VERTS() + +#define ALLOC_VERTS( nr ) \ + intelExtendInlinePrimitive( intel, (nr) * intel->vertex_size ) + +#define EMIT_VERTS( ctx, j, nr, buf ) \ + _tnl_emit_vertices_to_buffer(ctx, j, (j)+(nr), buf ) + +#define TAG(x) intel_##x +#include "tnl_dd/t_dd_dmatmp.h" + + +/**********************************************************************/ +/* Render pipeline stage */ +/**********************************************************************/ + +/* Heuristic to choose between the two render paths: + */ +static GLboolean +choose_render(struct intel_context *intel, struct vertex_buffer *VB) +{ + int vertsz = intel->vertex_size; + int cost_render = 0; + int cost_fallback = 0; + int nr_prims = 0; + int nr_rprims = 0; + int nr_rverts = 0; + int rprim = intel->reduced_primitive; + int i = 0; + + for (i = 0; i < VB->PrimitiveCount; i++) { + GLuint prim = VB->Primitive[i].mode; + GLuint length = VB->Primitive[i].count; + + if (!length) + continue; + + nr_prims++; + nr_rverts += length * scale_prim[prim & PRIM_MODE_MASK]; + + if (reduced_prim[prim & PRIM_MODE_MASK] != rprim) { + nr_rprims++; + rprim = reduced_prim[prim & PRIM_MODE_MASK]; + } + } + + /* One point for each generated primitive: + */ + cost_render = nr_prims; + cost_fallback = nr_rprims; + + /* One point for every 1024 dwords (4k) of dma: + */ + cost_render += (vertsz * i) / 1024; + cost_fallback += (vertsz * nr_rverts) / 1024; + + if (0) + fprintf(stderr, "cost render: %d fallback: %d\n", + cost_render, cost_fallback); + + if (cost_render > cost_fallback) + return GL_FALSE; + + return GL_TRUE; +} + + +static GLboolean +intel_run_render(GLcontext * ctx, struct tnl_pipeline_stage *stage) +{ + struct intel_context *intel = intel_context(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint i; + + /* Don't handle clipping or indexed vertices. + */ + if (intel->RenderIndex != 0 || + !intel_validate_render(ctx, VB) || !choose_render(intel, VB)) { + return GL_TRUE; + } + + tnl->clipspace.new_inputs |= VERT_BIT_POS; + + tnl->Driver.Render.Start(ctx); + + for (i = 0; i < VB->PrimitiveCount; i++) { + GLuint prim = VB->Primitive[i].mode; + GLuint start = VB->Primitive[i].start; + GLuint length = VB->Primitive[i].count; + + if (!length) + continue; + + intel_render_tab_verts[prim & PRIM_MODE_MASK] (ctx, start, + start + length, prim); + } + + tnl->Driver.Render.Finish(ctx); + + INTEL_FIREVERTICES(intel); + + return GL_FALSE; /* finished the pipe */ +} + +const struct tnl_pipeline_stage _intel_render_stage = { + "intel render", + NULL, + NULL, + NULL, + NULL, + intel_run_render /* run */ +}; diff --git a/src/mesa/drivers/dri/i915tex/intel_rotate.c b/src/mesa/drivers/dri/i915tex/intel_rotate.c new file mode 100644 index 0000000000..12d98c4ad2 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_rotate.c @@ -0,0 +1,237 @@ + +/** + * Routines for simple 2D->2D transformations for rotated, flipped screens. + * + * XXX This code is not intel-specific. Move it into a common/utility + * someday. + */ + +#include "intel_rotate.h" + +#define MIN2(A, B) ( ((A) < (B)) ? (A) : (B) ) + +#define ABS(A) ( ((A) < 0) ? -(A) : (A) ) + + +void +matrix23Set(struct matrix23 *m, + int m00, int m01, int m02, int m10, int m11, int m12) +{ + m->m00 = m00; + m->m01 = m01; + m->m02 = m02; + m->m10 = m10; + m->m11 = m11; + m->m12 = m12; +} + + +/* + * Transform (x,y) coordinate by the given matrix. + */ +void +matrix23TransformCoordf(const struct matrix23 *m, float *x, float *y) +{ + const float x0 = *x; + const float y0 = *y; + + *x = m->m00 * x0 + m->m01 * y0 + m->m02; + *y = m->m10 * x0 + m->m11 * y0 + m->m12; +} + + +void +matrix23TransformCoordi(const struct matrix23 *m, int *x, int *y) +{ + const int x0 = *x; + const int y0 = *y; + + *x = m->m00 * x0 + m->m01 * y0 + m->m02; + *y = m->m10 * x0 + m->m11 * y0 + m->m12; +} + + +/* + * Transform a width and height by the given matrix. + * XXX this could be optimized quite a bit. + */ +void +matrix23TransformDistance(const struct matrix23 *m, int *xDist, int *yDist) +{ + int x0 = 0, y0 = 0; + int x1 = *xDist, y1 = 0; + int x2 = 0, y2 = *yDist; + matrix23TransformCoordi(m, &x0, &y0); + matrix23TransformCoordi(m, &x1, &y1); + matrix23TransformCoordi(m, &x2, &y2); + + *xDist = (x1 - x0) + (x2 - x0); + *yDist = (y1 - y0) + (y2 - y0); + + if (*xDist < 0) + *xDist = -*xDist; + if (*yDist < 0) + *yDist = -*yDist; +} + + +/** + * Transform the rect defined by (x, y, w, h) by m. + */ +void +matrix23TransformRect(const struct matrix23 *m, int *x, int *y, int *w, + int *h) +{ + int x0 = *x, y0 = *y; + int x1 = *x + *w, y1 = *y; + int x2 = *x + *w, y2 = *y + *h; + int x3 = *x, y3 = *y + *h; + matrix23TransformCoordi(m, &x0, &y0); + matrix23TransformCoordi(m, &x1, &y1); + matrix23TransformCoordi(m, &x2, &y2); + matrix23TransformCoordi(m, &x3, &y3); + *w = ABS(x1 - x0) + ABS(x2 - x1); + /**w = ABS(*w);*/ + *h = ABS(y1 - y0) + ABS(y2 - y1); + /**h = ABS(*h);*/ + *x = MIN2(x0, x1); + *x = MIN2(*x, x2); + *y = MIN2(y0, y1); + *y = MIN2(*y, y2); +} + + +/* + * Make rotation matrix for width X height screen. + */ +void +matrix23Rotate(struct matrix23 *m, int width, int height, int angle) +{ + switch (angle) { + case 0: + matrix23Set(m, 1, 0, 0, 0, 1, 0); + break; + case 90: + matrix23Set(m, 0, 1, 0, -1, 0, width); + break; + case 180: + matrix23Set(m, -1, 0, width, 0, -1, height); + break; + case 270: + matrix23Set(m, 0, -1, height, 1, 0, 0); + break; + default: + /*abort() */ ; + } +} + + +/* + * Make flip/reflection matrix for width X height screen. + */ +void +matrix23Flip(struct matrix23 *m, int width, int height, int xflip, int yflip) +{ + if (xflip) { + m->m00 = -1; + m->m01 = 0; + m->m02 = width - 1; + } + else { + m->m00 = 1; + m->m01 = 0; + m->m02 = 0; + } + if (yflip) { + m->m10 = 0; + m->m11 = -1; + m->m12 = height - 1; + } + else { + m->m10 = 0; + m->m11 = 1; + m->m12 = 0; + } +} + + +/* + * result = a * b + */ +void +matrix23Multiply(struct matrix23 *result, + const struct matrix23 *a, const struct matrix23 *b) +{ + result->m00 = a->m00 * b->m00 + a->m01 * b->m10; + result->m01 = a->m00 * b->m01 + a->m01 * b->m11; + result->m02 = a->m00 * b->m02 + a->m01 * b->m12 + a->m02; + + result->m10 = a->m10 * b->m00 + a->m11 * b->m10; + result->m11 = a->m10 * b->m01 + a->m11 * b->m11; + result->m12 = a->m10 * b->m02 + a->m11 * b->m12 + a->m12; +} + + +#if 000 + +#include + +int +main(int argc, char *argv[]) +{ + int width = 500, height = 400; + int rot; + int fx = 0, fy = 0; /* flip x and/or y ? */ + int coords[4][2]; + + /* four corner coords to test with */ + coords[0][0] = 0; + coords[0][1] = 0; + coords[1][0] = width - 1; + coords[1][1] = 0; + coords[2][0] = width - 1; + coords[2][1] = height - 1; + coords[3][0] = 0; + coords[3][1] = height - 1; + + + for (rot = 0; rot < 360; rot += 90) { + struct matrix23 rotate, flip, m; + int i; + + printf("Rot %d, xFlip %d, yFlip %d:\n", rot, fx, fy); + + /* make transformation matrix 'm' */ + matrix23Rotate(&rotate, width, height, rot); + matrix23Flip(&flip, width, height, fx, fy); + matrix23Multiply(&m, &rotate, &flip); + + /* xform four coords */ + for (i = 0; i < 4; i++) { + int x = coords[i][0]; + int y = coords[i][1]; + matrix23TransformCoordi(&m, &x, &y); + printf(" %d, %d -> %d %d\n", coords[i][0], coords[i][1], x, y); + } + + /* xform width, height */ + { + int x = width; + int y = height; + matrix23TransformDistance(&m, &x, &y); + printf(" %d x %d -> %d x %d\n", width, height, x, y); + } + + /* xform rect */ + { + int x = 50, y = 10, w = 200, h = 100; + matrix23TransformRect(&m, &x, &y, &w, &h); + printf(" %d,%d %d x %d -> %d, %d %d x %d\n", 50, 10, 200, 100, + x, y, w, h); + } + + } + + return 0; +} +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_rotate.h b/src/mesa/drivers/dri/i915tex/intel_rotate.h new file mode 100644 index 0000000000..9c8802ca47 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_rotate.h @@ -0,0 +1,39 @@ +#ifndef INTEL_ROTATE_H +#define INTEL_ROTATE_H 1 + +struct matrix23 +{ + int m00, m01, m02; + int m10, m11, m12; +}; + + + +extern void +matrix23Set(struct matrix23 *m, + int m00, int m01, int m02, int m10, int m11, int m12); + +extern void matrix23TransformCoordi(const struct matrix23 *m, int *x, int *y); + +extern void +matrix23TransformCoordf(const struct matrix23 *m, float *x, float *y); + +extern void +matrix23TransformDistance(const struct matrix23 *m, int *xDist, int *yDist); + +extern void +matrix23TransformRect(const struct matrix23 *m, + int *x, int *y, int *w, int *h); + +extern void +matrix23Rotate(struct matrix23 *m, int width, int height, int angle); + +extern void +matrix23Flip(struct matrix23 *m, int width, int height, int xflip, int yflip); + +extern void +matrix23Multiply(struct matrix23 *result, + const struct matrix23 *a, const struct matrix23 *b); + + +#endif /* INTEL_ROTATE_H */ diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c new file mode 100644 index 0000000000..9bbfabbb8c --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_screen.c @@ -0,0 +1,864 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#include "glheader.h" +#include "context.h" +#include "framebuffer.h" +#include "matrix.h" +#include "renderbuffer.h" +#include "simple_list.h" +#include "utils.h" +#include "vblank.h" +#include "xmlpool.h" + + +#include "intel_screen.h" + +#include "intel_buffers.h" +#include "intel_tex.h" +#include "intel_span.h" +#include "intel_tris.h" +#include "intel_ioctl.h" +#include "intel_fbo.h" + +#include "i830_dri.h" +#include "dri_bufpool.h" +#include "intel_regions.h" +#include "intel_batchbuffer.h" + +PUBLIC const char __driConfigOptions[] = + DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE + DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) + DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) + DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY + DRI_CONF_FORCE_S3TC_ENABLE(false) + DRI_CONF_ALLOW_LARGE_TEXTURES(1) + DRI_CONF_SECTION_END DRI_CONF_END; + const GLuint __driNConfigOptions = 4; + +#ifdef USE_NEW_INTERFACE + static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; +#endif /*USE_NEW_INTERFACE */ + + extern const struct dri_extension card_extensions[]; + +/** + * Map all the memory regions described by the screen. + * \return GL_TRUE if success, GL_FALSE if error. + */ +GLboolean +intelMapScreenRegions(__DRIscreenPrivate * sPriv) +{ + intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; + + if (intelScreen->front.handle) { + if (drmMap(sPriv->fd, + intelScreen->front.handle, + intelScreen->front.size, + (drmAddress *) & intelScreen->front.map) != 0) { + _mesa_problem(NULL, "drmMap(frontbuffer) failed!"); + return GL_FALSE; + } + } + else { + _mesa_warning(NULL, "no front buffer handle in intelMapScreenRegions!"); + } + + if (0) + _mesa_printf("Back 0x%08x ", intelScreen->back.handle); + if (drmMap(sPriv->fd, + intelScreen->back.handle, + intelScreen->back.size, + (drmAddress *) & intelScreen->back.map) != 0) { + intelUnmapScreenRegions(intelScreen); + return GL_FALSE; + } + + if (0) + _mesa_printf("Depth 0x%08x ", intelScreen->depth.handle); + if (drmMap(sPriv->fd, + intelScreen->depth.handle, + intelScreen->depth.size, + (drmAddress *) & intelScreen->depth.map) != 0) { + intelUnmapScreenRegions(intelScreen); + return GL_FALSE; + } + +#if 0 + _mesa_printf("TEX 0x%08x ", intelScreen->tex.handle); + if (drmMap(sPriv->fd, + intelScreen->tex.handle, + intelScreen->tex.size, + (drmAddress *) & intelScreen->tex.map) != 0) { + intelUnmapScreenRegions(intelScreen); + return GL_FALSE; + } +#endif + if (0) + printf("Mappings: front: %p back: %p depth: %p tex: %p\n", + intelScreen->front.map, + intelScreen->back.map, + intelScreen->depth.map, intelScreen->tex.map); + return GL_TRUE; +} + + +static struct intel_region * +intel_recreate_static(intelScreenPrivate *intelScreen, + struct intel_region *region, + GLuint mem_type, + GLuint offset, + void *virtual, + GLuint cpp, GLuint pitch, GLuint height) +{ + if (region) { + intel_region_update_static(intelScreen, region, mem_type, offset, + virtual, cpp, pitch, height); + } else { + region = intel_region_create_static(intelScreen, mem_type, offset, + virtual, cpp, pitch, height); + } + return region; +} + + +/* Create intel_region structs to describe the static front,back,depth + * buffers created by the xserver. + * + * Although FBO's mean we now no longer use these as render targets in + * all circumstances, they won't go away until the back and depth + * buffers become private, and the front and rotated buffers will + * remain even then. + * + * Note that these don't allocate video memory, just describe + * allocations alread made by the X server. + */ +static void +intel_recreate_static_regions(intelScreenPrivate *intelScreen) +{ + intelScreen->front_region = + intel_recreate_static(intelScreen, + intelScreen->front_region, + DRM_BO_FLAG_MEM_TT, + intelScreen->front.offset, + intelScreen->front.map, + intelScreen->cpp, + intelScreen->front.pitch / intelScreen->cpp, + intelScreen->height); + + intelScreen->rotated_region = + intel_recreate_static(intelScreen, + intelScreen->rotated_region, + DRM_BO_FLAG_MEM_TT, + intelScreen->rotated.offset, + intelScreen->rotated.map, + intelScreen->cpp, + intelScreen->rotated.pitch / + intelScreen->cpp, intelScreen->height); + + + intelScreen->back_region = + intel_recreate_static(intelScreen, + intelScreen->back_region, + DRM_BO_FLAG_MEM_TT, + intelScreen->back.offset, + intelScreen->back.map, + intelScreen->cpp, + intelScreen->back.pitch / intelScreen->cpp, + intelScreen->height); + + /* Still assuming front.cpp == depth.cpp + */ + intelScreen->depth_region = + intel_recreate_static(intelScreen, + intelScreen->depth_region, + DRM_BO_FLAG_MEM_TT, + intelScreen->depth.offset, + intelScreen->depth.map, + intelScreen->cpp, + intelScreen->depth.pitch / intelScreen->cpp, + intelScreen->height); +} + +/** + * Use the information in the sarea to update the screen parameters + * related to screen rotation. Needs to be called locked. + */ +void +intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea) +{ + intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; + + intelUnmapScreenRegions(intelScreen); + intelUpdateScreenFromSAREA(intelScreen, sarea); + if (!intelMapScreenRegions(sPriv)) { + fprintf(stderr, "ERROR Remapping screen regions!!!\n"); + } + intel_recreate_static_regions(intelScreen); +} + + +void +intelUnmapScreenRegions(intelScreenPrivate * intelScreen) +{ +#define REALLY_UNMAP 1 + if (intelScreen->front.map) { +#if REALLY_UNMAP + if (drmUnmap(intelScreen->front.map, intelScreen->front.size) != 0) + printf("drmUnmap front failed!\n"); +#endif + intelScreen->front.map = NULL; + } + if (intelScreen->back.map) { +#if REALLY_UNMAP + if (drmUnmap(intelScreen->back.map, intelScreen->back.size) != 0) + printf("drmUnmap back failed!\n"); +#endif + intelScreen->back.map = NULL; + } + if (intelScreen->depth.map) { +#if REALLY_UNMAP + drmUnmap(intelScreen->depth.map, intelScreen->depth.size); + intelScreen->depth.map = NULL; +#endif + } + if (intelScreen->tex.map) { +#if REALLY_UNMAP + drmUnmap(intelScreen->tex.map, intelScreen->tex.size); + intelScreen->tex.map = NULL; +#endif + } +} + + +static void +intelPrintDRIInfo(intelScreenPrivate * intelScreen, + __DRIscreenPrivate * sPriv, I830DRIPtr gDRIPriv) +{ + fprintf(stderr, "*** Front size: 0x%x offset: 0x%x pitch: %d\n", + intelScreen->front.size, intelScreen->front.offset, + intelScreen->front.pitch); + fprintf(stderr, "*** Back size: 0x%x offset: 0x%x pitch: %d\n", + intelScreen->back.size, intelScreen->back.offset, + intelScreen->back.pitch); + fprintf(stderr, "*** Depth size: 0x%x offset: 0x%x pitch: %d\n", + intelScreen->depth.size, intelScreen->depth.offset, + intelScreen->depth.pitch); + fprintf(stderr, "*** Rotated size: 0x%x offset: 0x%x pitch: %d\n", + intelScreen->rotated.size, intelScreen->rotated.offset, + intelScreen->rotated.pitch); + fprintf(stderr, "*** Texture size: 0x%x offset: 0x%x\n", + intelScreen->tex.size, intelScreen->tex.offset); + fprintf(stderr, "*** Memory : 0x%x\n", gDRIPriv->mem); +} + + +static void +intelPrintSAREA(const drmI830Sarea * sarea) +{ + fprintf(stderr, "SAREA: sarea width %d height %d\n", sarea->width, + sarea->height); + fprintf(stderr, "SAREA: pitch: %d\n", sarea->pitch); + fprintf(stderr, + "SAREA: front offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->front_offset, sarea->front_size, + (unsigned) sarea->front_handle); + fprintf(stderr, + "SAREA: back offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->back_offset, sarea->back_size, + (unsigned) sarea->back_handle); + fprintf(stderr, "SAREA: depth offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->depth_offset, sarea->depth_size, + (unsigned) sarea->depth_handle); + fprintf(stderr, "SAREA: tex offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->tex_offset, sarea->tex_size, (unsigned) sarea->tex_handle); + fprintf(stderr, "SAREA: rotation: %d\n", sarea->rotation); + fprintf(stderr, + "SAREA: rotated offset: 0x%08x size: 0x%x\n", + sarea->rotated_offset, sarea->rotated_size); + fprintf(stderr, "SAREA: rotated pitch: %d\n", sarea->rotated_pitch); +} + + +/** + * A number of the screen parameters are obtained/computed from + * information in the SAREA. This function updates those parameters. + */ +void +intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen, + drmI830Sarea * sarea) +{ + intelScreen->width = sarea->width; + intelScreen->height = sarea->height; + + intelScreen->front.offset = sarea->front_offset; + intelScreen->front.pitch = sarea->pitch * intelScreen->cpp; + intelScreen->front.handle = sarea->front_handle; + intelScreen->front.size = sarea->front_size; + + intelScreen->back.offset = sarea->back_offset; + intelScreen->back.pitch = sarea->pitch * intelScreen->cpp; + intelScreen->back.handle = sarea->back_handle; + intelScreen->back.size = sarea->back_size; + + intelScreen->depth.offset = sarea->depth_offset; + intelScreen->depth.pitch = sarea->pitch * intelScreen->cpp; + intelScreen->depth.handle = sarea->depth_handle; + intelScreen->depth.size = sarea->depth_size; + + intelScreen->tex.offset = sarea->tex_offset; + intelScreen->logTextureGranularity = sarea->log_tex_granularity; + intelScreen->tex.handle = sarea->tex_handle; + intelScreen->tex.size = sarea->tex_size; + + intelScreen->rotated.offset = sarea->rotated_offset; + intelScreen->rotated.pitch = sarea->rotated_pitch * intelScreen->cpp; + intelScreen->rotated.size = sarea->rotated_size; + intelScreen->current_rotation = sarea->rotation; + matrix23Rotate(&intelScreen->rotMatrix, + sarea->width, sarea->height, sarea->rotation); + intelScreen->rotatedWidth = sarea->virtualX; + intelScreen->rotatedHeight = sarea->virtualY; + + if (0) + intelPrintSAREA(sarea); +} + + +static GLboolean +intelInitDriver(__DRIscreenPrivate * sPriv) +{ + intelScreenPrivate *intelScreen; + I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv; + drmI830Sarea *sarea; + unsigned batchPoolSize = 1024*1024; + + PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = + (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface-> + getProcAddress("glxEnableExtension")); + void *const psc = sPriv->psc->screenConfigs; + + if (sPriv->devPrivSize != sizeof(I830DRIRec)) { + fprintf(stderr, + "\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n"); + return GL_FALSE; + } + + /* Allocate the private area */ + intelScreen = (intelScreenPrivate *) CALLOC(sizeof(intelScreenPrivate)); + if (!intelScreen) { + fprintf(stderr, "\nERROR! Allocating private area failed\n"); + return GL_FALSE; + } + /* parse information in __driConfigOptions */ + driParseOptionInfo(&intelScreen->optionCache, + __driConfigOptions, __driNConfigOptions); + + intelScreen->driScrnPriv = sPriv; + sPriv->private = (void *) intelScreen; + intelScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset; + sarea = (drmI830Sarea *) + (((GLubyte *) sPriv->pSAREA) + intelScreen->sarea_priv_offset); + + intelScreen->maxBatchSize = BATCH_SZ; + intelScreen->deviceID = gDRIPriv->deviceID; + if (intelScreen->deviceID == PCI_CHIP_I865_G) + intelScreen->maxBatchSize = 4096; + batchPoolSize /= intelScreen->maxBatchSize; + + intelScreen->mem = gDRIPriv->mem; + intelScreen->cpp = gDRIPriv->cpp; + + switch (gDRIPriv->bitsPerPixel) { + case 16: + intelScreen->fbFormat = DV_PF_565; + break; + case 32: + intelScreen->fbFormat = DV_PF_8888; + break; + default: + exit(1); + break; + } + + intelUpdateScreenFromSAREA(intelScreen, sarea); + + if (!intelMapScreenRegions(sPriv)) { + fprintf(stderr, "\nERROR! mapping regions\n"); + _mesa_free(intelScreen); + sPriv->private = NULL; + return GL_FALSE; + } + +#if 0 + + /* + * FIXME: Remove this code and its references. + */ + + intelScreen->tex.offset = gDRIPriv->textureOffset; + intelScreen->logTextureGranularity = gDRIPriv->logTextureGranularity; + intelScreen->tex.handle = gDRIPriv->textures; + intelScreen->tex.size = gDRIPriv->textureSize; + +#else + intelScreen->tex.offset = 0; + intelScreen->logTextureGranularity = 0; + intelScreen->tex.handle = 0; + intelScreen->tex.size = 0; +#endif + + intelScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset; + + if (0) + intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv); + + intelScreen->drmMinor = sPriv->drmMinor; + + /* Determine if IRQs are active? */ + { + int ret; + drmI830GetParam gp; + + gp.param = I830_PARAM_IRQ_ACTIVE; + gp.value = &intelScreen->irq_active; + + ret = drmCommandWriteRead(sPriv->fd, DRM_I830_GETPARAM, + &gp, sizeof(gp)); + if (ret) { + fprintf(stderr, "drmI830GetParam: %d\n", ret); + return GL_FALSE; + } + } + + /* Determine if batchbuffers are allowed */ + { + int ret; + drmI830GetParam gp; + + gp.param = I830_PARAM_ALLOW_BATCHBUFFER; + gp.value = &intelScreen->allow_batchbuffer; + + ret = drmCommandWriteRead(sPriv->fd, DRM_I830_GETPARAM, + &gp, sizeof(gp)); + if (ret) { + fprintf(stderr, "drmI830GetParam: (%d) %d\n", gp.param, ret); + return GL_FALSE; + } + } + + if (glx_enable_extension != NULL) { + (*glx_enable_extension) (psc, "GLX_SGI_swap_control"); + (*glx_enable_extension) (psc, "GLX_SGI_video_sync"); + (*glx_enable_extension) (psc, "GLX_MESA_swap_control"); + (*glx_enable_extension) (psc, "GLX_MESA_swap_frame_usage"); + (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); + } + + intelScreen->regionPool = driDRMPoolInit(sPriv->fd); + + if (!intelScreen->regionPool) + return GL_FALSE; + + intelScreen->staticPool = driDRMStaticPoolInit(sPriv->fd); + + if (!intelScreen->staticPool) + return GL_FALSE; + + intelScreen->texPool = intelScreen->regionPool; + + intelScreen->batchPool = driBatchPoolInit(sPriv->fd, + DRM_BO_FLAG_EXE | + DRM_BO_FLAG_MEM_TT | + DRM_BO_FLAG_MEM_LOCAL, + intelScreen->maxBatchSize, + batchPoolSize, 5); + if (!intelScreen->batchPool) { + fprintf(stderr, "Failed to initialize batch pool - possible incorrect agpgart installed\n"); + return GL_FALSE; + } + + intel_recreate_static_regions(intelScreen); + + return GL_TRUE; +} + + +static void +intelDestroyScreen(__DRIscreenPrivate * sPriv) +{ + intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; + + intelUnmapScreenRegions(intelScreen); + + driPoolTakeDown(intelScreen->regionPool); + driPoolTakeDown(intelScreen->staticPool); + driPoolTakeDown(intelScreen->batchPool); + FREE(intelScreen); + sPriv->private = NULL; +} + + +/** + * This is called when we need to set up GL rendering to a new X window. + */ +static GLboolean +intelCreateBuffer(__DRIscreenPrivate * driScrnPriv, + __DRIdrawablePrivate * driDrawPriv, + const __GLcontextModes * mesaVis, GLboolean isPixmap) +{ + intelScreenPrivate *screen = (intelScreenPrivate *) driScrnPriv->private; + + if (isPixmap) { + return GL_FALSE; /* not implemented */ + } + else { + GLboolean swStencil = (mesaVis->stencilBits > 0 && + mesaVis->depthBits != 24); + GLenum rgbFormat = (mesaVis->redBits == 5 ? GL_RGB5 : GL_RGBA8); + + struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis); + + /* setup the hardware-based renderbuffers */ + { + struct intel_renderbuffer *frontRb + = intel_create_renderbuffer(rgbFormat, + screen->width, screen->height, + screen->front.offset, + screen->front.pitch, + screen->cpp, + screen->front.map); + intel_set_span_functions(&frontRb->Base); + _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base); + } + + if (mesaVis->doubleBufferMode) { + struct intel_renderbuffer *backRb + = intel_create_renderbuffer(rgbFormat, + screen->width, screen->height, + screen->back.offset, + screen->back.pitch, + screen->cpp, + screen->back.map); + intel_set_span_functions(&backRb->Base); + _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base); + } + + if (mesaVis->depthBits == 24 && mesaVis->stencilBits == 8) { + /* combined depth/stencil buffer */ + struct intel_renderbuffer *depthStencilRb + = intel_create_renderbuffer(GL_DEPTH24_STENCIL8_EXT, + screen->width, screen->height, + screen->depth.offset, + screen->depth.pitch, + screen->cpp, /* 4! */ + screen->depth.map); + intel_set_span_functions(&depthStencilRb->Base); + /* note: bind RB to two attachment points */ + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthStencilRb->Base); + _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &depthStencilRb->Base); + } + else if (mesaVis->depthBits == 16) { + /* just 16-bit depth buffer, no hw stencil */ + struct intel_renderbuffer *depthRb + = intel_create_renderbuffer(GL_DEPTH_COMPONENT16, + screen->width, screen->height, + screen->depth.offset, + screen->depth.pitch, + screen->cpp, /* 2! */ + screen->depth.map); + intel_set_span_functions(&depthRb->Base); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base); + } + + /* now add any/all software-based renderbuffers we may need */ + _mesa_add_soft_renderbuffers(fb, GL_FALSE, /* never sw color */ + GL_FALSE, /* never sw depth */ + swStencil, mesaVis->accumRedBits > 0, GL_FALSE, /* never sw alpha */ + GL_FALSE /* never sw aux */ ); + driDrawPriv->driverPrivate = (void *) fb; + + return (driDrawPriv->driverPrivate != NULL); + } +} + +static void +intelDestroyBuffer(__DRIdrawablePrivate * driDrawPriv) +{ + _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); +} + + +/** + * Get information about previous buffer swaps. + */ +static int +intelGetSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo) +{ + struct intel_context *intel; + + if ((dPriv == NULL) || (dPriv->driContextPriv == NULL) + || (dPriv->driContextPriv->driverPrivate == NULL) + || (sInfo == NULL)) { + return -1; + } + + intel = dPriv->driContextPriv->driverPrivate; + sInfo->swap_count = intel->swap_count; + sInfo->swap_ust = intel->swap_ust; + sInfo->swap_missed_count = intel->swap_missed_count; + + sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0) + ? driCalculateSwapUsage(dPriv, 0, intel->swap_missed_ust) + : 0.0; + + return 0; +} + + +/* There are probably better ways to do this, such as an + * init-designated function to register chipids and createcontext + * functions. + */ +extern GLboolean i830CreateContext(const __GLcontextModes * mesaVis, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate); + +extern GLboolean i915CreateContext(const __GLcontextModes * mesaVis, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate); + + + + +static GLboolean +intelCreateContext(const __GLcontextModes * mesaVis, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate) +{ + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; + + switch (intelScreen->deviceID) { + /* Don't deal with i830 until texture work complete: + */ + case PCI_CHIP_845_G: + case PCI_CHIP_I830_M: + case PCI_CHIP_I855_GM: + case PCI_CHIP_I865_G: + return i830CreateContext(mesaVis, driContextPriv, sharedContextPrivate); + + case PCI_CHIP_I915_G: + case PCI_CHIP_I915_GM: + case PCI_CHIP_I945_G: + case PCI_CHIP_I945_GM: + return i915CreateContext(mesaVis, driContextPriv, sharedContextPrivate); + + default: + fprintf(stderr, "Unrecognized deviceID %x\n", intelScreen->deviceID); + return GL_FALSE; + } +} + + +static const struct __DriverAPIRec intelAPI = { + .InitDriver = intelInitDriver, + .DestroyScreen = intelDestroyScreen, + .CreateContext = intelCreateContext, + .DestroyContext = intelDestroyContext, + .CreateBuffer = intelCreateBuffer, + .DestroyBuffer = intelDestroyBuffer, + .SwapBuffers = intelSwapBuffers, + .MakeCurrent = intelMakeCurrent, + .UnbindContext = intelUnbindContext, + .GetSwapInfo = intelGetSwapInfo, + .GetMSC = driGetMSC32, + .WaitForMSC = driWaitForMSC32, + .WaitForSBC = NULL, + .SwapBuffersMSC = NULL, + .CopySubBuffer = intelCopySubBuffer +}; + + +static __GLcontextModes * +intelFillInModes(unsigned pixel_bits, unsigned depth_bits, + unsigned stencil_bits, GLboolean have_back_buffer) +{ + __GLcontextModes *modes; + __GLcontextModes *m; + unsigned num_modes; + unsigned depth_buffer_factor; + unsigned back_buffer_factor; + GLenum fb_format; + GLenum fb_type; + + /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't + * support pageflipping at all. + */ + static const GLenum back_buffer_modes[] = { + GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML + }; + + u_int8_t depth_bits_array[3]; + u_int8_t stencil_bits_array[3]; + + + depth_bits_array[0] = 0; + depth_bits_array[1] = depth_bits; + depth_bits_array[2] = depth_bits; + + /* Just like with the accumulation buffer, always provide some modes + * with a stencil buffer. It will be a sw fallback, but some apps won't + * care about that. + */ + stencil_bits_array[0] = 0; + stencil_bits_array[1] = 0; + stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits; + + depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1; + back_buffer_factor = (have_back_buffer) ? 3 : 1; + + num_modes = depth_buffer_factor * back_buffer_factor * 4; + + if (pixel_bits == 16) { + fb_format = GL_RGB; + fb_type = GL_UNSIGNED_SHORT_5_6_5; + } + else { + fb_format = GL_BGRA; + fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; + } + + modes = + (*dri_interface->createContextModes) (num_modes, + sizeof(__GLcontextModes)); + m = modes; + if (!driFillInModes(&m, fb_format, fb_type, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor, GLX_TRUE_COLOR)) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + __LINE__); + return NULL; + } + if (!driFillInModes(&m, fb_format, fb_type, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor, GLX_DIRECT_COLOR)) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + __LINE__); + return NULL; + } + + /* Mark the visual as slow if there are "fake" stencil bits. + */ + for (m = modes; m != NULL; m = m->next) { + if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) { + m->visualRating = GLX_SLOW_CONFIG; + } + } + + return modes; +} + + +/** + * This is the bootstrap function for the driver. libGL supplies all of the + * requisite information about the system, and the driver initializes itself. + * This routine also fills in the linked list pointed to by \c driver_modes + * with the \c __GLcontextModes that the driver can support for windows or + * pbuffers. + * + * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on + * failure. + */ +PUBLIC void * +__driCreateNewScreen_20050727(__DRInativeDisplay * dpy, int scrn, + __DRIscreen * psc, + const __GLcontextModes * modes, + const __DRIversion * ddx_version, + const __DRIversion * dri_version, + const __DRIversion * drm_version, + const __DRIframebuffer * frame_buffer, + drmAddress pSAREA, int fd, + int internal_api_version, + const __DRIinterfaceMethods * interface, + __GLcontextModes ** driver_modes) +{ + __DRIscreenPrivate *psp; + static const __DRIversion ddx_expected = { 1, 5, 0 }; + static const __DRIversion dri_expected = { 4, 0, 0 }; + static const __DRIversion drm_expected = { 1, 7, 0 }; + + dri_interface = interface; + + if (!driCheckDriDdxDrmVersions2("i915", + dri_version, &dri_expected, + ddx_version, &ddx_expected, + drm_version, &drm_expected)) { + return NULL; + } + + psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, + ddx_version, dri_version, drm_version, + frame_buffer, pSAREA, fd, + internal_api_version, &intelAPI); + if (psp != NULL) { + I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; + *driver_modes = intelFillInModes(dri_priv->cpp * 8, + (dri_priv->cpp == 2) ? 16 : 24, + (dri_priv->cpp == 2) ? 0 : 8, 1); + + /* Calling driInitExtensions here, with a NULL context pointer, does not actually + * enable the extensions. It just makes sure that all the dispatch offsets for all + * the extensions that *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is called, but we can't + * enable the extensions until we have a context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions(NULL, card_extensions, GL_FALSE); + } + + return (void *) psp; +} + +struct intel_context *intelScreenContext(intelScreenPrivate *intelScreen) +{ + /* + * This should probably change to have the screen allocate a dummy + * context at screen creation. For now just use the current context. + */ + + GET_CURRENT_CONTEXT(ctx); + if (ctx == NULL) { + _mesa_problem(NULL, "No current context in intelScreenContext\n"); + return NULL; + } + return intel_context(ctx); +} + diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.h b/src/mesa/drivers/dri/i915tex/intel_screen.h new file mode 100644 index 0000000000..17698773f3 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_screen.h @@ -0,0 +1,132 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#ifndef _INTEL_INIT_H_ +#define _INTEL_INIT_H_ + +#include +#include "dri_util.h" +#include "intel_rotate.h" +#include "i830_common.h" +#include "xmlconfig.h" +#include "dri_bufpool.h" + +/* XXX: change name or eliminate to avoid conflict with "struct + * intel_region"!!! + */ +typedef struct +{ + drm_handle_t handle; + drmSize size; /* region size in bytes */ + char *map; /* memory map */ + int offset; /* from start of video mem, in bytes */ + int pitch; /* row stride, in bytes */ +} intelRegion; + +typedef struct +{ + intelRegion front; + intelRegion back; + intelRegion rotated; + intelRegion depth; + intelRegion tex; + + struct intel_region *front_region; + struct intel_region *back_region; + struct intel_region *depth_region; + struct intel_region *rotated_region; + + int deviceID; + int width; + int height; + int mem; /* unused */ + + int cpp; /* for front and back buffers */ +/* int bitsPerPixel; */ + int fbFormat; /* XXX FBO: this is obsolete - remove after i830 updates */ + + int logTextureGranularity; + + __DRIscreenPrivate *driScrnPriv; + unsigned int sarea_priv_offset; + + int drmMinor; + + int irq_active; + int allow_batchbuffer; + + struct matrix23 rotMatrix; + + int current_rotation; /* 0, 90, 180 or 270 */ + int rotatedWidth, rotatedHeight; + + /** + * Configuration cache with default values for all contexts + */ + driOptionCache optionCache; + struct _DriBufferPool *batchPool; + struct _DriBufferPool *texPool; + struct _DriBufferPool *regionPool; + struct _DriBufferPool *staticPool; + unsigned int maxBatchSize; +} intelScreenPrivate; + + + +extern GLboolean intelMapScreenRegions(__DRIscreenPrivate * sPriv); + +extern void intelUnmapScreenRegions(intelScreenPrivate * intelScreen); + +extern void +intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen, + drmI830Sarea * sarea); + +extern void intelDestroyContext(__DRIcontextPrivate * driContextPriv); + +extern GLboolean intelUnbindContext(__DRIcontextPrivate * driContextPriv); + +extern GLboolean +intelMakeCurrent(__DRIcontextPrivate * driContextPriv, + __DRIdrawablePrivate * driDrawPriv, + __DRIdrawablePrivate * driReadPriv); + +extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); + +extern void +intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h); + +extern struct _DriBufferPool *driBatchPoolInit(int fd, unsigned flags, + unsigned long bufSize, + unsigned numBufs, + unsigned checkDelayed); + +extern struct intel_context *intelScreenContext(intelScreenPrivate *intelScreen); + +extern void +intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea); + +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_span.c b/src/mesa/drivers/dri/i915tex/intel_span.c new file mode 100644 index 0000000000..ab0874e4fd --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_span.c @@ -0,0 +1,409 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#include "glheader.h" +#include "macros.h" +#include "mtypes.h" +#include "colormac.h" + +#include "intel_fbo.h" +#include "intel_screen.h" +#include "intel_span.h" +#include "intel_regions.h" +#include "intel_ioctl.h" +#include "intel_tex.h" + +#include "swrast/swrast.h" + +/* + break intelWriteRGBASpan_ARGB8888 +*/ + +#undef DBG +#define DBG 0 + +#define LOCAL_VARS \ + struct intel_context *intel = intel_context(ctx); \ + struct intel_renderbuffer *irb = intel_renderbuffer(rb); \ + const GLint yScale = irb->RenderToTexture ? 1 : -1; \ + const GLint yBias = irb->RenderToTexture ? 0 : irb->Base.Height - 1; \ + GLubyte *buf = (GLubyte *) irb->pfMap \ + + (intel->drawY * irb->pfPitch + intel->drawX) * irb->region->cpp;\ + GLuint p; \ + assert(irb->pfMap);\ + (void) p; + +/* XXX FBO: this is identical to the macro in spantmp2.h except we get + * the cliprect info from the context, not the driDrawable. + * Move this into spantmp2.h someday. + */ +#define HW_CLIPLOOP() \ + do { \ + int _nc = intel->numClipRects; \ + while ( _nc-- ) { \ + int minx = intel->pClipRects[_nc].x1 - intel->drawX; \ + int miny = intel->pClipRects[_nc].y1 - intel->drawY; \ + int maxx = intel->pClipRects[_nc].x2 - intel->drawX; \ + int maxy = intel->pClipRects[_nc].y2 - intel->drawY; + + + + +#define Y_FLIP(_y) ((_y) * yScale + yBias) + +#define HW_LOCK() + +#define HW_UNLOCK() + +/* 16 bit, RGB565 color spanline and pixel functions + */ +#define SPANTMP_PIXEL_FMT GL_RGB +#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5 + +#define TAG(x) intel##x##_RGB565 +#define TAG2(x,y) intel##x##_RGB565##y +#define GET_PTR(X,Y) (buf + ((Y) * irb->pfPitch + (X)) * 2) +#include "spantmp2.h" + +/* 32 bit, ARGB8888 color spanline and pixel functions + */ +#define SPANTMP_PIXEL_FMT GL_BGRA +#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV + +#define TAG(x) intel##x##_ARGB8888 +#define TAG2(x,y) intel##x##_ARGB8888##y +#define GET_PTR(X,Y) (buf + ((Y) * irb->pfPitch + (X)) * 4) +#include "spantmp2.h" + + +#define LOCAL_DEPTH_VARS \ + struct intel_context *intel = intel_context(ctx); \ + struct intel_renderbuffer *irb = intel_renderbuffer(rb); \ + const GLuint pitch = irb->pfPitch/***XXX region->pitch*/; /* in pixels */ \ + const GLint yScale = irb->RenderToTexture ? 1 : -1; \ + const GLint yBias = irb->RenderToTexture ? 0 : irb->Base.Height - 1; \ + char *buf = (char *) irb->pfMap/*XXX use region->map*/ + \ + (intel->drawY * pitch + intel->drawX) * irb->region->cpp; + + +#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS + +/** + ** 16-bit depthbuffer functions. + **/ +#define WRITE_DEPTH( _x, _y, d ) \ + ((GLushort *)buf)[(_x) + (_y) * pitch] = d; + +#define READ_DEPTH( d, _x, _y ) \ + d = ((GLushort *)buf)[(_x) + (_y) * pitch]; + + +#define TAG(x) intel##x##_z16 +#include "depthtmp.h" + + +/** + ** 24/8-bit interleaved depth/stencil functions + ** Note: we're actually reading back combined depth+stencil values. + ** The wrappers in main/depthstencil.c are used to extract the depth + ** and stencil values. + **/ +/* Change ZZZS -> SZZZ */ +#define WRITE_DEPTH( _x, _y, d ) { \ + GLuint tmp = ((d) >> 8) | ((d) << 24); \ + ((GLuint *)buf)[(_x) + (_y) * pitch] = tmp; \ +} + +/* Change SZZZ -> ZZZS */ +#define READ_DEPTH( d, _x, _y ) { \ + GLuint tmp = ((GLuint *)buf)[(_x) + (_y) * pitch]; \ + d = (tmp << 8) | (tmp >> 24); \ +} + +#define TAG(x) intel##x##_z24_s8 +#include "depthtmp.h" + + +/** + ** 8-bit stencil function (XXX FBO: This is obsolete) + **/ +#define WRITE_STENCIL( _x, _y, d ) { \ + GLuint tmp = ((GLuint *)buf)[(_x) + (_y) * pitch]; \ + tmp &= 0xffffff; \ + tmp |= ((d) << 24); \ + ((GLuint *) buf)[(_x) + (_y) * pitch] = tmp; \ +} + +#define READ_STENCIL( d, _x, _y ) \ + d = ((GLuint *)buf)[(_x) + (_y) * pitch] >> 24; + +#define TAG(x) intel##x##_z24_s8 +#include "stenciltmp.h" + + + +/** + * Map or unmap all the renderbuffers which we may need during + * software rendering. + * XXX in the future, we could probably convey extra information to + * reduce the number of mappings needed. I.e. if doing a glReadPixels + * from the depth buffer, we really only need one mapping. + * + * XXX Rewrite this function someday. + * We can probably just loop over all the renderbuffer attachments, + * map/unmap all of them, and not worry about the _ColorDrawBuffers + * _ColorReadBuffer, _DepthBuffer or _StencilBuffer fields. + */ +static void +intel_map_unmap_buffers(struct intel_context *intel, GLboolean map) +{ + GLcontext *ctx = &intel->ctx; + GLuint i, j; + struct intel_renderbuffer *irb; + + /* color draw buffers */ + for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { + for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers[i]; j++) { + struct gl_renderbuffer *rb = + ctx->DrawBuffer->_ColorDrawBuffers[i][j]; + irb = intel_renderbuffer(rb); + if (irb) { + /* this is a user-created intel_renderbuffer */ + if (irb->region) { + if (map) + intel_region_map(intel->intelScreen, irb->region); + else + intel_region_unmap(intel->intelScreen, irb->region); + } + irb->pfMap = irb->region->map; + irb->pfPitch = irb->region->pitch; + } + } + } + + /* check for render to textures */ + for (i = 0; i < BUFFER_COUNT; i++) { + struct gl_renderbuffer_attachment *att = + ctx->DrawBuffer->Attachment + i; + struct gl_texture_object *tex = att->Texture; + if (tex) { + /* render to texture */ + ASSERT(att->Renderbuffer); + if (map) { + struct gl_texture_image *texImg; + texImg = tex->Image[att->CubeMapFace][att->TextureLevel]; + intel_tex_map_images(intel, intel_texture_object(tex)); + } + else { + intel_tex_unmap_images(intel, intel_texture_object(tex)); + } + } + } + + /* color read buffers */ + irb = intel_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer); + if (irb && irb->region) { + if (map) + intel_region_map(intel->intelScreen, irb->region); + else + intel_region_unmap(intel->intelScreen, irb->region); + irb->pfMap = irb->region->map; + irb->pfPitch = irb->region->pitch; + } + + /* Account for front/back color page flipping. + * The span routines use the pfMap and pfPitch fields which will + * swap the front/back region map/pitch if we're page flipped. + * Do this after mapping, above, so the map field is valid. + */ +#if 0 + if (map && ctx->DrawBuffer->Name == 0) { + struct intel_renderbuffer *irbFront + = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_FRONT_LEFT); + struct intel_renderbuffer *irbBack + = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_BACK_LEFT); + if (irbBack) { + /* double buffered */ + if (intel->sarea->pf_current_page == 0) { + irbFront->pfMap = irbFront->region->map; + irbFront->pfPitch = irbFront->region->pitch; + irbBack->pfMap = irbBack->region->map; + irbBack->pfPitch = irbBack->region->pitch; + } + else { + irbFront->pfMap = irbBack->region->map; + irbFront->pfPitch = irbBack->region->pitch; + irbBack->pfMap = irbFront->region->map; + irbBack->pfPitch = irbFront->region->pitch; + } + } + } +#endif + + /* depth buffer (Note wrapper!) */ + if (ctx->DrawBuffer->_DepthBuffer) { + irb = intel_renderbuffer(ctx->DrawBuffer->_DepthBuffer->Wrapped); + if (irb && irb->region && irb->Base.Name != 0) { + if (map) { + intel_region_map(intel->intelScreen, irb->region); + irb->pfMap = irb->region->map; + irb->pfPitch = irb->region->pitch; + } + else { + intel_region_unmap(intel->intelScreen, irb->region); + irb->pfMap = NULL; + irb->pfPitch = 0; + } + } + } + + /* stencil buffer (Note wrapper!) */ + if (ctx->DrawBuffer->_StencilBuffer) { + irb = intel_renderbuffer(ctx->DrawBuffer->_StencilBuffer->Wrapped); + if (irb && irb->region && irb->Base.Name != 0) { + if (map) { + intel_region_map(intel->intelScreen, irb->region); + irb->pfMap = irb->region->map; + irb->pfPitch = irb->region->pitch; + } + else { + intel_region_unmap(intel->intelScreen, irb->region); + irb->pfMap = NULL; + irb->pfPitch = 0; + } + } + } +} + + + +/** + * Prepare for softare rendering. Map current read/draw framebuffers' + * renderbuffes and all currently bound texture objects. + * + * Old note: Moved locking out to get reasonable span performance. + */ +void +intelSpanRenderStart(GLcontext * ctx) +{ + struct intel_context *intel = intel_context(ctx); + GLuint i; + + intelFinish(&intel->ctx); + LOCK_HARDWARE(intel); + +#if 0 + /* Just map the framebuffer and all textures. Bufmgr code will + * take care of waiting on the necessary fences: + */ + intel_region_map(intel->intelScreen, intel->front_region); + intel_region_map(intel->intelScreen, intel->back_region); + intel_region_map(intel->intelScreen, intel->intelScreen->depth_region); +#endif + + for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { + if (ctx->Texture.Unit[i]._ReallyEnabled) { + struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current; + intel_tex_map_images(intel, intel_texture_object(texObj)); + } + } + + intel_map_unmap_buffers(intel, GL_TRUE); +} + +/** + * Called when done softare rendering. Unmap the buffers we mapped in + * the above function. + */ +void +intelSpanRenderFinish(GLcontext * ctx) +{ + struct intel_context *intel = intel_context(ctx); + GLuint i; + + _swrast_flush(ctx); + + /* Now unmap the framebuffer: + */ +#if 0 + intel_region_unmap(intel, intel->front_region); + intel_region_unmap(intel, intel->back_region); + intel_region_unmap(intel, intel->intelScreen->depth_region); +#endif + + for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { + if (ctx->Texture.Unit[i]._ReallyEnabled) { + struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current; + intel_tex_unmap_images(intel, intel_texture_object(texObj)); + } + } + + intel_map_unmap_buffers(intel, GL_FALSE); + + UNLOCK_HARDWARE(intel); +} + + +void +intelInitSpanFuncs(GLcontext * ctx) +{ + struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx); + swdd->SpanRenderStart = intelSpanRenderStart; + swdd->SpanRenderFinish = intelSpanRenderFinish; +} + + +/** + * Plug in appropriate span read/write functions for the given renderbuffer. + * These are used for the software fallbacks. + */ +void +intel_set_span_functions(struct gl_renderbuffer *rb) +{ + if (rb->_ActualFormat == GL_RGB5) { + /* 565 RGB */ + intelInitPointers_RGB565(rb); + } + else if (rb->_ActualFormat == GL_RGBA8) { + /* 8888 RGBA */ + intelInitPointers_ARGB8888(rb); + } + else if (rb->_ActualFormat == GL_DEPTH_COMPONENT16) { + intelInitDepthPointers_z16(rb); + } + else if (rb->_ActualFormat == GL_DEPTH_COMPONENT24 || /* XXX FBO remove */ + rb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT) { + intelInitDepthPointers_z24_s8(rb); + } + else if (rb->_ActualFormat == GL_STENCIL_INDEX8_EXT) { /* XXX FBO remove */ + intelInitStencilPointers_z24_s8(rb); + } + else { + _mesa_problem(NULL, + "Unexpected _ActualFormat in intelSetSpanFunctions"); + } +} diff --git a/src/mesa/drivers/dri/i915tex/intel_span.h b/src/mesa/drivers/dri/i915tex/intel_span.h new file mode 100644 index 0000000000..5201f6d6c6 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_span.h @@ -0,0 +1,38 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#ifndef _INTEL_SPAN_H +#define _INTEL_SPAN_H + +extern void intelInitSpanFuncs(GLcontext * ctx); + +extern void intelSpanRenderFinish(GLcontext * ctx); +extern void intelSpanRenderStart(GLcontext * ctx); + +extern void intel_set_span_functions(struct gl_renderbuffer *rb); + +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_state.c b/src/mesa/drivers/dri/i915tex/intel_state.c new file mode 100644 index 0000000000..f85d8ef835 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_state.c @@ -0,0 +1,363 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + + +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "enums.h" +#include "colormac.h" +#include "dd.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_fbo.h" +#include "intel_regions.h" +#include "swrast/swrast.h" + +int +intel_translate_compare_func(GLenum func) +{ + switch (func) { + case GL_NEVER: + return COMPAREFUNC_NEVER; + case GL_LESS: + return COMPAREFUNC_LESS; + case GL_LEQUAL: + return COMPAREFUNC_LEQUAL; + case GL_GREATER: + return COMPAREFUNC_GREATER; + case GL_GEQUAL: + return COMPAREFUNC_GEQUAL; + case GL_NOTEQUAL: + return COMPAREFUNC_NOTEQUAL; + case GL_EQUAL: + return COMPAREFUNC_EQUAL; + case GL_ALWAYS: + return COMPAREFUNC_ALWAYS; + } + + fprintf(stderr, "Unknown value in %s: %x\n", __FUNCTION__, func); + return COMPAREFUNC_ALWAYS; +} + +int +intel_translate_stencil_op(GLenum op) +{ + switch (op) { + case GL_KEEP: + return STENCILOP_KEEP; + case GL_ZERO: + return STENCILOP_ZERO; + case GL_REPLACE: + return STENCILOP_REPLACE; + case GL_INCR: + return STENCILOP_INCRSAT; + case GL_DECR: + return STENCILOP_DECRSAT; + case GL_INCR_WRAP: + return STENCILOP_INCR; + case GL_DECR_WRAP: + return STENCILOP_DECR; + case GL_INVERT: + return STENCILOP_INVERT; + default: + return STENCILOP_ZERO; + } +} + +int +intel_translate_blend_factor(GLenum factor) +{ + switch (factor) { + case GL_ZERO: + return BLENDFACT_ZERO; + case GL_SRC_ALPHA: + return BLENDFACT_SRC_ALPHA; + case GL_ONE: + return BLENDFACT_ONE; + case GL_SRC_COLOR: + return BLENDFACT_SRC_COLR; + case GL_ONE_MINUS_SRC_COLOR: + return BLENDFACT_INV_SRC_COLR; + case GL_DST_COLOR: + return BLENDFACT_DST_COLR; + case GL_ONE_MINUS_DST_COLOR: + return BLENDFACT_INV_DST_COLR; + case GL_ONE_MINUS_SRC_ALPHA: + return BLENDFACT_INV_SRC_ALPHA; + case GL_DST_ALPHA: + return BLENDFACT_DST_ALPHA; + case GL_ONE_MINUS_DST_ALPHA: + return BLENDFACT_INV_DST_ALPHA; + case GL_SRC_ALPHA_SATURATE: + return BLENDFACT_SRC_ALPHA_SATURATE; + case GL_CONSTANT_COLOR: + return BLENDFACT_CONST_COLOR; + case GL_ONE_MINUS_CONSTANT_COLOR: + return BLENDFACT_INV_CONST_COLOR; + case GL_CONSTANT_ALPHA: + return BLENDFACT_CONST_ALPHA; + case GL_ONE_MINUS_CONSTANT_ALPHA: + return BLENDFACT_INV_CONST_ALPHA; + } + + fprintf(stderr, "Unknown value in %s: %x\n", __FUNCTION__, factor); + return BLENDFACT_ZERO; +} + +int +intel_translate_logic_op(GLenum opcode) +{ + switch (opcode) { + case GL_CLEAR: + return LOGICOP_CLEAR; + case GL_AND: + return LOGICOP_AND; + case GL_AND_REVERSE: + return LOGICOP_AND_RVRSE; + case GL_COPY: + return LOGICOP_COPY; + case GL_COPY_INVERTED: + return LOGICOP_COPY_INV; + case GL_AND_INVERTED: + return LOGICOP_AND_INV; + case GL_NOOP: + return LOGICOP_NOOP; + case GL_XOR: + return LOGICOP_XOR; + case GL_OR: + return LOGICOP_OR; + case GL_OR_INVERTED: + return LOGICOP_OR_INV; + case GL_NOR: + return LOGICOP_NOR; + case GL_EQUIV: + return LOGICOP_EQUIV; + case GL_INVERT: + return LOGICOP_INV; + case GL_OR_REVERSE: + return LOGICOP_OR_RVRSE; + case GL_NAND: + return LOGICOP_NAND; + case GL_SET: + return LOGICOP_SET; + default: + return LOGICOP_SET; + } +} + + +static void +intelClearColor(GLcontext * ctx, const GLfloat color[4]) +{ + struct intel_context *intel = intel_context(ctx); + GLubyte clear[4]; + + CLAMPED_FLOAT_TO_UBYTE(clear[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(clear[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(clear[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(clear[3], color[3]); + + /* compute both 32 and 16-bit clear values */ + intel->ClearColor8888 = INTEL_PACKCOLOR8888(clear[0], clear[1], + clear[2], clear[3]); + intel->ClearColor565 = INTEL_PACKCOLOR565(clear[0], clear[1], clear[2]); +} + + +/** + * Update the viewport transformation matrix. Depends on: + * - viewport pos/size + * - depthrange + * - window pos/size or FBO size + */ +static void +intelCalcViewport(GLcontext * ctx) +{ + struct intel_context *intel = intel_context(ctx); + const GLfloat *v = ctx->Viewport._WindowMap.m; + const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF; + GLfloat *m = intel->ViewportMatrix.m; + GLfloat yScale, yBias; + + if (ctx->DrawBuffer->Name) { + /* User created FBO */ + struct intel_renderbuffer *irb + = intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]); + if (irb && !irb->RenderToTexture) { + /* y=0=top */ + yScale = -1.0; + yBias = irb->Base.Height; + } + else { + /* y=0=bottom */ + yScale = 1.0; + yBias = 0.0; + } + } + else { + /* window buffer, y=0=top */ + yScale = -1.0; + yBias = (intel->driDrawable) ? intel->driDrawable->h : 0.0F; + } + + m[MAT_SX] = v[MAT_SX]; + m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X; + + m[MAT_SY] = v[MAT_SY] * yScale; + m[MAT_TY] = v[MAT_TY] * yScale + yBias + SUBPIXEL_Y; + + m[MAT_SZ] = v[MAT_SZ] * depthScale; + m[MAT_TZ] = v[MAT_TZ] * depthScale; +} + +static void +intelViewport(GLcontext * ctx, + GLint x, GLint y, GLsizei width, GLsizei height) +{ + intelCalcViewport(ctx); +} + +static void +intelDepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval) +{ + intelCalcViewport(ctx); +} + +/* Fallback to swrast for select and feedback. + */ +static void +intelRenderMode(GLcontext * ctx, GLenum mode) +{ + struct intel_context *intel = intel_context(ctx); + FALLBACK(intel, INTEL_FALLBACK_RENDERMODE, (mode != GL_RENDER)); +} + + +void +intelInitStateFuncs(struct dd_function_table *functions) +{ + functions->RenderMode = intelRenderMode; + functions->Viewport = intelViewport; + functions->DepthRange = intelDepthRange; + functions->ClearColor = intelClearColor; +} + + + + +void +intelInitState(GLcontext * ctx) +{ + /* Mesa should do this for us: + */ + ctx->Driver.AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef); + + ctx->Driver.BlendColor(ctx, ctx->Color.BlendColor); + + ctx->Driver.BlendEquationSeparate(ctx, + ctx->Color.BlendEquationRGB, + ctx->Color.BlendEquationA); + + ctx->Driver.BlendFuncSeparate(ctx, + ctx->Color.BlendSrcRGB, + ctx->Color.BlendDstRGB, + ctx->Color.BlendSrcA, ctx->Color.BlendDstA); + + ctx->Driver.ColorMask(ctx, + ctx->Color.ColorMask[RCOMP], + ctx->Color.ColorMask[GCOMP], + ctx->Color.ColorMask[BCOMP], + ctx->Color.ColorMask[ACOMP]); + + ctx->Driver.CullFace(ctx, ctx->Polygon.CullFaceMode); + ctx->Driver.DepthFunc(ctx, ctx->Depth.Func); + ctx->Driver.DepthMask(ctx, ctx->Depth.Mask); + + ctx->Driver.Enable(ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled); + ctx->Driver.Enable(ctx, GL_BLEND, ctx->Color.BlendEnabled); + ctx->Driver.Enable(ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled); + ctx->Driver.Enable(ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled); + ctx->Driver.Enable(ctx, GL_CULL_FACE, ctx->Polygon.CullFlag); + ctx->Driver.Enable(ctx, GL_DEPTH_TEST, ctx->Depth.Test); + ctx->Driver.Enable(ctx, GL_DITHER, ctx->Color.DitherFlag); + ctx->Driver.Enable(ctx, GL_FOG, ctx->Fog.Enabled); + ctx->Driver.Enable(ctx, GL_LIGHTING, ctx->Light.Enabled); + ctx->Driver.Enable(ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag); + ctx->Driver.Enable(ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag); + ctx->Driver.Enable(ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled); + ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); + ctx->Driver.Enable(ctx, GL_TEXTURE_1D, GL_FALSE); + ctx->Driver.Enable(ctx, GL_TEXTURE_2D, GL_FALSE); + ctx->Driver.Enable(ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE); + ctx->Driver.Enable(ctx, GL_TEXTURE_3D, GL_FALSE); + ctx->Driver.Enable(ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE); + + ctx->Driver.Fogfv(ctx, GL_FOG_COLOR, ctx->Fog.Color); + ctx->Driver.Fogfv(ctx, GL_FOG_MODE, 0); + ctx->Driver.Fogfv(ctx, GL_FOG_DENSITY, &ctx->Fog.Density); + ctx->Driver.Fogfv(ctx, GL_FOG_START, &ctx->Fog.Start); + ctx->Driver.Fogfv(ctx, GL_FOG_END, &ctx->Fog.End); + + ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace); + + { + GLfloat f = (GLfloat) ctx->Light.Model.ColorControl; + ctx->Driver.LightModelfv(ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f); + } + + ctx->Driver.LineWidth(ctx, ctx->Line.Width); + ctx->Driver.LogicOpcode(ctx, ctx->Color.LogicOp); + ctx->Driver.PointSize(ctx, ctx->Point.Size); + ctx->Driver.PolygonStipple(ctx, (const GLubyte *) ctx->PolygonStipple); + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); + ctx->Driver.ShadeModel(ctx, ctx->Light.ShadeModel); + ctx->Driver.StencilFuncSeparate(ctx, GL_FRONT, + ctx->Stencil.Function[0], + ctx->Stencil.Ref[0], + ctx->Stencil.ValueMask[0]); + ctx->Driver.StencilFuncSeparate(ctx, GL_BACK, + ctx->Stencil.Function[1], + ctx->Stencil.Ref[1], + ctx->Stencil.ValueMask[1]); + ctx->Driver.StencilMaskSeparate(ctx, GL_FRONT, ctx->Stencil.WriteMask[0]); + ctx->Driver.StencilMaskSeparate(ctx, GL_BACK, ctx->Stencil.WriteMask[1]); + ctx->Driver.StencilOpSeparate(ctx, GL_FRONT, + ctx->Stencil.FailFunc[0], + ctx->Stencil.ZFailFunc[0], + ctx->Stencil.ZPassFunc[0]); + ctx->Driver.StencilOpSeparate(ctx, GL_BACK, + ctx->Stencil.FailFunc[1], + ctx->Stencil.ZFailFunc[1], + ctx->Stencil.ZPassFunc[1]); + + + /* XXX this isn't really needed */ + ctx->Driver.DrawBuffer(ctx, ctx->Color.DrawBuffer[0]); +} diff --git a/src/mesa/drivers/dri/i915tex/intel_structs.h b/src/mesa/drivers/dri/i915tex/intel_structs.h new file mode 100644 index 0000000000..522e3bd92c --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_structs.h @@ -0,0 +1,132 @@ +#ifndef INTEL_STRUCTS_H +#define INTEL_STRUCTS_H + +struct br0 { + GLuint length:8; + GLuint pad0:3; + GLuint dst_tiled:1; + GLuint pad1:8; + GLuint write_rgb:1; + GLuint write_alpha:1; + GLuint opcode:7; + GLuint client:3; +}; + + +struct br13 { + GLint dest_pitch:16; + GLuint rop:8; + GLuint color_depth:2; + GLuint pad1:3; + GLuint mono_source_transparency:1; + GLuint clipping_enable:1; + GLuint pad0:1; +}; + + + +/* This is an attempt to move some of the 2D interaction in this + * driver to using structs for packets rather than a bunch of #defines + * and dwords. + */ +struct xy_color_blit { + struct br0 br0; + struct br13 br13; + + struct { + GLuint dest_x1:16; + GLuint dest_y1:16; + } dw2; + + struct { + GLuint dest_x2:16; + GLuint dest_y2:16; + } dw3; + + GLuint dest_base_addr; + GLuint color; +}; + +struct xy_src_copy_blit { + struct br0 br0; + struct br13 br13; + + struct { + GLuint dest_x1:16; + GLuint dest_y1:16; + } dw2; + + struct { + GLuint dest_x2:16; + GLuint dest_y2:16; + } dw3; + + GLuint dest_base_addr; + + struct { + GLuint src_x1:16; + GLuint src_y1:16; + } dw5; + + struct { + GLint src_pitch:16; + GLuint pad:16; + } dw6; + + GLuint src_base_addr; +}; + +struct xy_setup_blit { + struct br0 br0; + struct br13 br13; + + struct { + GLuint clip_x1:16; + GLuint clip_y1:16; + } dw2; + + struct { + GLuint clip_x2:16; + GLuint clip_y2:16; + } dw3; + + GLuint dest_base_addr; + GLuint background_color; + GLuint foreground_color; + GLuint pattern_base_addr; +}; + + +struct xy_text_immediate_blit { + struct { + GLuint length:8; + GLuint pad2:3; + GLuint dst_tiled:1; + GLuint pad1:4; + GLuint byte_packed:1; + GLuint pad0:5; + GLuint opcode:7; + GLuint client:3; + } dw0; + + struct { + GLuint dest_x1:16; + GLuint dest_y1:16; + } dw1; + + struct { + GLuint dest_x2:16; + GLuint dest_y2:16; + } dw2; + + /* Src bitmap data follows as inline dwords. + */ +}; + + +#define CLIENT_2D 0x2 +#define OPCODE_XY_SETUP_BLT 0x1 +#define OPCODE_XY_COLOR_BLT 0x50 +#define OPCODE_XY_TEXT_IMMEDIATE_BLT 0x31 + +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_tex.c b/src/mesa/drivers/dri/i915tex/intel_tex.c new file mode 100644 index 0000000000..51875ab292 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_tex.c @@ -0,0 +1,182 @@ +#include "texobj.h" +#include "intel_context.h" +#include "intel_mipmap_tree.h" +#include "intel_tex.h" + +#define FILE_DEBUG_FLAG DEBUG_TEXTURE + +static GLboolean +intelIsTextureResident(GLcontext * ctx, struct gl_texture_object *texObj) +{ +#if 0 + struct intel_context *intel = intel_context(ctx); + struct intel_texture_object *intelObj = intel_texture_object(texObj); + + return + intelObj->mt && + intelObj->mt->region && + intel_is_region_resident(intel, intelObj->mt->region); +#endif + return 1; +} + + + +static struct gl_texture_image * +intelNewTextureImage(GLcontext * ctx) +{ + DBG("%s\n", __FUNCTION__); + (void) ctx; + return (struct gl_texture_image *) CALLOC_STRUCT(intel_texture_image); +} + + +static struct gl_texture_object * +intelNewTextureObject(GLcontext * ctx, GLuint name, GLenum target) +{ + struct intel_texture_object *obj = CALLOC_STRUCT(intel_texture_object); + + DBG("%s\n", __FUNCTION__); + _mesa_initialize_texture_object(&obj->base, name, target); + + return &obj->base; +} + +static void +intelDeleteTextureObject(GLcontext *ctx, + struct gl_texture_object *texObj) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_texture_object *intelObj = intel_texture_object(texObj); + + if (intelObj->mt) + intel_miptree_release(intel, &intelObj->mt); + + _mesa_delete_texture_object(ctx, texObj); +} + + +static void +intelFreeTextureImageData(GLcontext * ctx, struct gl_texture_image *texImage) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_texture_image *intelImage = intel_texture_image(texImage); + + DBG("%s\n", __FUNCTION__); + + if (intelImage->mt) { + intel_miptree_release(intel, &intelImage->mt); + } + + if (texImage->Data) { + free(texImage->Data); + texImage->Data = NULL; + } +} + + +#ifndef __x86_64__ +static unsigned +fastrdtsc(void) +{ + unsigned eax; + __asm__ volatile ("\t" + "pushl %%ebx\n\t" + "cpuid\n\t" ".byte 0x0f, 0x31\n\t" + "popl %%ebx\n":"=a" (eax) + :"0"(0) + :"ecx", "edx", "cc"); + + return eax; +} +#else +static unsigned +fastrdtsc(void) +{ + unsigned eax; + __asm__ volatile ("\t" "cpuid\n\t" ".byte 0x0f, 0x31\n\t":"=a" (eax) + :"0"(0) + :"ecx", "edx", "ebx", "cc"); + + return eax; +} +#endif + +static unsigned +time_diff(unsigned t, unsigned t2) +{ + return ((t < t2) ? t2 - t : 0xFFFFFFFFU - (t - t2 - 1)); +} + + +/* The system memcpy (at least on ubuntu 5.10) has problems copying + * to agp (writecombined) memory from a source which isn't 64-byte + * aligned - there is a 4x performance falloff. + * + * The x86 __memcpy is immune to this but is slightly slower + * (10%-ish) than the system memcpy. + * + * The sse_memcpy seems to have a slight cliff at 64/32 bytes, but + * isn't much faster than x86_memcpy for agp copies. + * + * TODO: switch dynamically. + */ +static void * +do_memcpy(void *dest, const void *src, size_t n) +{ + if ((((unsigned) src) & 63) || (((unsigned) dest) & 63)) { + return __memcpy(dest, src, n); + } + else + return memcpy(dest, src, n); +} + + +static void * +timed_memcpy(void *dest, const void *src, size_t n) +{ + void *ret; + unsigned t1, t2; + double rate; + + if ((((unsigned) src) & 63) || (((unsigned) dest) & 63)) + _mesa_printf("Warning - non-aligned texture copy!\n"); + + t1 = fastrdtsc(); + ret = do_memcpy(dest, src, n); + t2 = fastrdtsc(); + + rate = time_diff(t1, t2); + rate /= (double) n; + _mesa_printf("timed_memcpy: %u %u --> %f clocks/byte\n", t1, t2, rate); + return ret; +} + + +void +intelInitTextureFuncs(struct dd_function_table *functions) +{ + functions->ChooseTextureFormat = intelChooseTextureFormat; + functions->TexImage1D = intelTexImage1D; + functions->TexImage2D = intelTexImage2D; + functions->TexImage3D = intelTexImage3D; + functions->TexSubImage1D = intelTexSubImage1D; + functions->TexSubImage2D = intelTexSubImage2D; + functions->TexSubImage3D = intelTexSubImage3D; + functions->CopyTexImage1D = intelCopyTexImage1D; + functions->CopyTexImage2D = intelCopyTexImage2D; + functions->CopyTexSubImage1D = intelCopyTexSubImage1D; + functions->CopyTexSubImage2D = intelCopyTexSubImage2D; + functions->GetTexImage = intelGetTexImage; + functions->NewTextureObject = intelNewTextureObject; + functions->NewTextureImage = intelNewTextureImage; + functions->DeleteTexture = intelDeleteTextureObject; + functions->FreeTexImageData = intelFreeTextureImageData; + functions->UpdateTexturePalette = 0; + functions->IsTextureResident = intelIsTextureResident; + + if (INTEL_DEBUG & DEBUG_BUFMGR) + functions->TextureMemCpy = timed_memcpy; + else + functions->TextureMemCpy = do_memcpy; +} diff --git a/src/mesa/drivers/dri/i915tex/intel_tex.h b/src/mesa/drivers/dri/i915tex/intel_tex.h new file mode 100644 index 0000000000..2f3d4ec2d1 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_tex.h @@ -0,0 +1,134 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#ifndef INTELTEX_INC +#define INTELTEX_INC + +#include "mtypes.h" +#include "intel_context.h" +#include "texmem.h" + + +void intelInitTextureFuncs(struct dd_function_table *functions); + +const struct gl_texture_format *intelChooseTextureFormat(GLcontext * ctx, + GLint internalFormat, + GLenum format, + GLenum type); + + +void intelTexImage3D(GLcontext * ctx, + GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint depth, + GLint border, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +void intelTexSubImage3D(GLcontext * ctx, + GLenum target, + GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +void intelTexImage2D(GLcontext * ctx, + GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +void intelTexSubImage2D(GLcontext * ctx, + GLenum target, + GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +void intelTexImage1D(GLcontext * ctx, + GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint border, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +void intelTexSubImage1D(GLcontext * ctx, + GLenum target, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +void intelCopyTexImage1D(GLcontext * ctx, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLint border); + +void intelCopyTexImage2D(GLcontext * ctx, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLsizei height, + GLint border); + +void intelCopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, GLsizei width); + +void intelCopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, GLsizei width, GLsizei height); + +void intelGetTexImage(GLcontext * ctx, GLenum target, GLint level, + GLenum format, GLenum type, GLvoid * pixels, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +GLuint intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit); + +void intel_tex_map_images(struct intel_context *intel, + struct intel_texture_object *intelObj); + +void intel_tex_unmap_images(struct intel_context *intel, + struct intel_texture_object *intelObj); + +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_copy.c b/src/mesa/drivers/dri/i915tex/intel_tex_copy.c new file mode 100644 index 0000000000..88b62e781c --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_tex_copy.c @@ -0,0 +1,301 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#include "mtypes.h" +#include "enums.h" +#include "image.h" +#include "teximage.h" +#include "swrast/swrast.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_batchbuffer.h" +#include "intel_buffers.h" +#include "intel_mipmap_tree.h" +#include "intel_regions.h" +#include "intel_fbo.h" +#include "intel_tex.h" +#include "intel_blit.h" +#include "intel_pixel.h" + +#define FILE_DEBUG_FLAG DEBUG_TEXTURE + +/** + * Get the intel_region which is the source for any glCopyTex[Sub]Image call. + * + * Do the best we can using the blitter. A future project is to use + * the texture engine and fragment programs for these copies. + */ +static const struct intel_region * +get_teximage_source(struct intel_context *intel, GLenum internalFormat) +{ + struct intel_renderbuffer *irb; + + DBG("%s %s\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(internalFormat)); + + switch (internalFormat) { + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT16_ARB: + irb = intel_get_renderbuffer(intel->ctx.ReadBuffer, BUFFER_DEPTH); + if (irb && irb->region && irb->region->cpp == 2) + return irb->region; + return NULL; + case GL_DEPTH24_STENCIL8_EXT: + case GL_DEPTH_STENCIL_EXT: + irb = intel_get_renderbuffer(intel->ctx.ReadBuffer, BUFFER_DEPTH); + if (irb && irb->region && irb->region->cpp == 4) + return irb->region; + return NULL; + case GL_RGBA: + case GL_RGBA8: + return intel_readbuf_region(intel); + case GL_RGB: + if (intel->intelScreen->cpp == 2) + return intel_readbuf_region(intel); + return NULL; + default: + return NULL; + } +} + + +static GLboolean +do_copy_texsubimage(struct intel_context *intel, + struct intel_texture_image *intelImage, + GLenum internalFormat, + GLint dstx, GLint dsty, + GLint x, GLint y, GLsizei width, GLsizei height) +{ + GLcontext *ctx = &intel->ctx; + const struct intel_region *src = + get_teximage_source(intel, internalFormat); + + if (!intelImage->mt || !src) { + DBG("%s fail %p %p\n", __FUNCTION__, intelImage->mt, src); + return GL_FALSE; + } + + intelFlush(ctx); + LOCK_HARDWARE(intel); + { + GLuint image_offset = intel_miptree_image_offset(intelImage->mt, + intelImage->face, + intelImage->level); + const GLint orig_x = x; + const GLint orig_y = y; + const struct gl_framebuffer *fb = ctx->DrawBuffer; + + if (_mesa_clip_to_region(fb->_Xmin, fb->_Ymin, fb->_Xmax, fb->_Ymax, + &x, &y, &width, &height)) { + /* Update dst for clipped src. Need to also clip the source rect. + */ + dstx += x - orig_x; + dsty += y - orig_y; + + if (ctx->ReadBuffer->Name == 0) { + /* reading from a window, adjust x, y */ + __DRIdrawablePrivate *dPriv = intel->driDrawable; + GLuint window_y; + /* window_y = position of window on screen if y=0=bottom */ + window_y = intel->intelScreen->height - (dPriv->y + dPriv->h); + y = window_y + y; + x += dPriv->x; + } + else { + /* reading from a FBO */ + /* invert Y */ + y = ctx->ReadBuffer->Height - y - 1; + } + + + /* A bit of fiddling to get the blitter to work with -ve + * pitches. But we get a nice inverted blit this way, so it's + * worth it: + */ + intelEmitCopyBlit(intel, + intelImage->mt->cpp, + -src->pitch, + src->buffer, + src->height * src->pitch * src->cpp, + intelImage->mt->pitch, + intelImage->mt->region->buffer, + image_offset, + x, y + height, dstx, dsty, width, height); + + intel_batchbuffer_flush(intel->batch); + } + } + + + UNLOCK_HARDWARE(intel); + +#if 0 + /* GL_SGIS_generate_mipmap -- this can be accelerated now. + * XXX Add a ctx->Driver.GenerateMipmaps() function? + */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + intel_generate_mipmap(ctx, target, + &ctx->Texture.Unit[ctx->Texture.CurrentUnit], + texObj); + } +#endif + + return GL_TRUE; +} + + + + + +void +intelCopyTexImage1D(GLcontext * ctx, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLint border) +{ + struct gl_texture_unit *texUnit = + &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + struct gl_texture_object *texObj = + _mesa_select_tex_object(ctx, texUnit, target); + struct gl_texture_image *texImage = + _mesa_select_tex_image(ctx, texObj, target, level); + + if (border) + goto fail; + + /* Setup or redefine the texture object, mipmap tree and texture + * image. Don't populate yet. + */ + ctx->Driver.TexImage1D(ctx, target, level, internalFormat, + width, border, + GL_RGBA, CHAN_TYPE, NULL, + &ctx->DefaultPacking, texObj, texImage); + + if (!do_copy_texsubimage(intel_context(ctx), + intel_texture_image(texImage), + internalFormat, 0, 0, x, y, width, 1)) + goto fail; + + return; + + fail: + _swrast_copy_teximage1d(ctx, target, level, internalFormat, x, y, + width, border); +} + +void +intelCopyTexImage2D(GLcontext * ctx, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLsizei height, + GLint border) +{ + struct gl_texture_unit *texUnit = + &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + struct gl_texture_object *texObj = + _mesa_select_tex_object(ctx, texUnit, target); + struct gl_texture_image *texImage = + _mesa_select_tex_image(ctx, texObj, target, level); + + if (border) + goto fail; + + /* Setup or redefine the texture object, mipmap tree and texture + * image. Don't populate yet. + */ + ctx->Driver.TexImage2D(ctx, target, level, internalFormat, + width, height, border, + GL_RGBA, CHAN_TYPE, NULL, + &ctx->DefaultPacking, texObj, texImage); + + + if (!do_copy_texsubimage(intel_context(ctx), + intel_texture_image(texImage), + internalFormat, 0, 0, x, y, width, height)) + goto fail; + + return; + + fail: + _swrast_copy_teximage2d(ctx, target, level, internalFormat, x, y, + width, height, border); +} + + +void +intelCopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, GLsizei width) +{ + struct gl_texture_unit *texUnit = + &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + struct gl_texture_object *texObj = + _mesa_select_tex_object(ctx, texUnit, target); + struct gl_texture_image *texImage = + _mesa_select_tex_image(ctx, texObj, target, level); + GLenum internalFormat = texImage->InternalFormat; + + /* XXX need to check as in above function? */ + + /* Need to check texture is compatible with source format. + */ + + if (!do_copy_texsubimage(intel_context(ctx), + intel_texture_image(texImage), + internalFormat, xoffset, 0, x, y, width, 1)) { + _swrast_copy_texsubimage1d(ctx, target, level, xoffset, x, y, width); + } +} + + + +void +intelCopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, GLsizei width, GLsizei height) +{ + struct gl_texture_unit *texUnit = + &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + struct gl_texture_object *texObj = + _mesa_select_tex_object(ctx, texUnit, target); + struct gl_texture_image *texImage = + _mesa_select_tex_image(ctx, texObj, target, level); + GLenum internalFormat = texImage->InternalFormat; + + + /* Need to check texture is compatible with source format. + */ + + if (!do_copy_texsubimage(intel_context(ctx), + intel_texture_image(texImage), + internalFormat, + xoffset, yoffset, x, y, width, height)) { + + DBG("%s - fallback to swrast\n", __FUNCTION__); + + _swrast_copy_texsubimage2d(ctx, target, level, + xoffset, yoffset, x, y, width, height); + } +} diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_format.c b/src/mesa/drivers/dri/i915tex/intel_tex_format.c new file mode 100644 index 0000000000..d7612dcbaa --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_tex_format.c @@ -0,0 +1,146 @@ +#include "intel_context.h" +#include "intel_tex.h" +#include "texformat.h" +#include "enums.h" + +/* It works out that this function is fine for all the supported + * hardware. However, there is still a need to map the formats onto + * hardware descriptors. + */ +/* Note that the i915 can actually support many more formats than + * these if we take the step of simply swizzling the colors + * immediately after sampling... + */ +const struct gl_texture_format * +intelChooseTextureFormat(GLcontext * ctx, GLint internalFormat, + GLenum format, GLenum type) +{ + struct intel_context *intel = intel_context(ctx); + const GLboolean do32bpt = (intel->intelScreen->cpp == 4); + + switch (internalFormat) { + case 4: + case GL_RGBA: + case GL_COMPRESSED_RGBA: + if (format == GL_BGRA) { + if (type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_INT_8_8_8_8_REV) { + return &_mesa_texformat_argb8888; + } + else if (type == GL_UNSIGNED_SHORT_4_4_4_4_REV) { + return &_mesa_texformat_argb4444; + } + else if (type == GL_UNSIGNED_SHORT_1_5_5_5_REV) { + return &_mesa_texformat_argb1555; + } + } + return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444; + + case 3: + case GL_RGB: + case GL_COMPRESSED_RGB: + if (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5) { + return &_mesa_texformat_rgb565; + } + return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565; + + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444; + + case GL_RGBA4: + case GL_RGBA2: + return &_mesa_texformat_argb4444; + + case GL_RGB5_A1: + return &_mesa_texformat_argb1555; + + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return &_mesa_texformat_argb8888; + + case GL_RGB5: + case GL_RGB4: + case GL_R3_G3_B2: + return &_mesa_texformat_rgb565; + + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + case GL_COMPRESSED_ALPHA: + return &_mesa_texformat_a8; + + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + case GL_COMPRESSED_LUMINANCE: + return &_mesa_texformat_l8; + + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + case GL_COMPRESSED_LUMINANCE_ALPHA: + return &_mesa_texformat_al88; + + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + case GL_COMPRESSED_INTENSITY: + return &_mesa_texformat_i8; + + case GL_YCBCR_MESA: + if (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE) + return &_mesa_texformat_ycbcr; + else + return &_mesa_texformat_ycbcr_rev; + + case GL_COMPRESSED_RGB_FXT1_3DFX: + return &_mesa_texformat_rgb_fxt1; + case GL_COMPRESSED_RGBA_FXT1_3DFX: + return &_mesa_texformat_rgba_fxt1; + + case GL_RGB_S3TC: + case GL_RGB4_S3TC: + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + return &_mesa_texformat_rgb_dxt1; + + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return &_mesa_texformat_rgba_dxt1; + + case GL_RGBA_S3TC: + case GL_RGBA4_S3TC: + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + return &_mesa_texformat_rgba_dxt3; + + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + return &_mesa_texformat_rgba_dxt5; + + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT16: + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT32: + return &_mesa_texformat_z16; + + default: + fprintf(stderr, "unexpected texture format %s in %s\n", + _mesa_lookup_enum_by_nr(internalFormat), __FUNCTION__); + return NULL; + } + + return NULL; /* never get here */ +} diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_image.c b/src/mesa/drivers/dri/i915tex/intel_tex_image.c new file mode 100644 index 0000000000..48c2f35d3b --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_tex_image.c @@ -0,0 +1,626 @@ + +#include +#include + +#include "glheader.h" +#include "macros.h" +#include "mtypes.h" +#include "enums.h" +#include "colortab.h" +#include "convolve.h" +#include "context.h" +#include "simple_list.h" +#include "texcompress.h" +#include "texformat.h" +#include "texobj.h" +#include "texstore.h" + +#include "intel_context.h" +#include "intel_mipmap_tree.h" +#include "intel_buffer_objects.h" +#include "intel_batchbuffer.h" +#include "intel_tex.h" +#include "intel_ioctl.h" +#include "intel_blit.h" + +#define FILE_DEBUG_FLAG DEBUG_TEXTURE + +/* Functions to store texture images. Where possible, mipmap_tree's + * will be created or further instantiated with image data, otherwise + * images will be stored in malloc'd memory. A validation step is + * required to pull those images into a mipmap tree, or otherwise + * decide a fallback is required. + */ + + +static int +logbase2(int n) +{ + GLint i = 1; + GLint log2 = 0; + + while (n > i) { + i *= 2; + log2++; + } + + return log2; +} + + +/* Otherwise, store it in memory if (Border != 0) or (any dimension == + * 1). + * + * Otherwise, if max_level >= level >= min_level, create tree with + * space for textures from min_level down to max_level. + * + * Otherwise, create tree with space for textures from (level + * 0)..(1x1). Consider pruning this tree at a validation if the + * saving is worth it. + */ +static void +guess_and_alloc_mipmap_tree(struct intel_context *intel, + struct intel_texture_object *intelObj, + struct intel_texture_image *intelImage) +{ + GLuint firstLevel; + GLuint lastLevel; + GLuint width = intelImage->base.Width; + GLuint height = intelImage->base.Height; + GLuint depth = intelImage->base.Depth; + GLuint l2width, l2height, l2depth; + GLuint i; + + DBG("%s\n", __FUNCTION__); + + if (intelImage->base.Border) + return; + + if (intelImage->level > intelObj->base.BaseLevel && + (intelImage->base.Width == 1 || + (intelObj->base.Target != GL_TEXTURE_1D && + intelImage->base.Height == 1) || + (intelObj->base.Target == GL_TEXTURE_3D && + intelImage->base.Depth == 1))) + return; + + /* If this image disrespects BaseLevel, allocate from level zero. + * Usually BaseLevel == 0, so it's unlikely to happen. + */ + if (intelImage->level < intelObj->base.BaseLevel) + firstLevel = 0; + else + firstLevel = intelObj->base.BaseLevel; + + + /* Figure out image dimensions at start level. + */ + for (i = intelImage->level; i > firstLevel; i--) { + width <<= 1; + if (height != 1) + height <<= 1; + if (depth != 1) + depth <<= 1; + } + + /* Guess a reasonable value for lastLevel. This is probably going + * to be wrong fairly often and might mean that we have to look at + * resizable buffers, or require that buffers implement lazy + * pagetable arrangements. + */ + if ((intelObj->base.MinFilter == GL_NEAREST || + intelObj->base.MinFilter == GL_LINEAR) && + intelImage->level == firstLevel) { + lastLevel = firstLevel; + } + else { + l2width = logbase2(width); + l2height = logbase2(height); + l2depth = logbase2(depth); + lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth); + } + + assert(!intelObj->mt); + intelObj->mt = intel_miptree_create(intel, + intelObj->base.Target, + intelImage->base.InternalFormat, + firstLevel, + lastLevel, + width, + height, + depth, + intelImage->base.TexFormat->TexelBytes, + intelImage->base.IsCompressed); + + DBG("%s - success\n", __FUNCTION__); +} + + + + +static GLuint +target_to_face(GLenum target) +{ + switch (target) { + case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: + return ((GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X); + default: + return 0; + } +} + +/* There are actually quite a few combinations this will work for, + * more than what I've listed here. + */ +static GLboolean +check_pbo_format(GLint internalFormat, + GLenum format, GLenum type, + const struct gl_texture_format *mesa_format) +{ + switch (internalFormat) { + case 4: + case GL_RGBA: + return (format == GL_BGRA && + (type == GL_UNSIGNED_BYTE || + type == GL_UNSIGNED_INT_8_8_8_8_REV) && + mesa_format == &_mesa_texformat_argb8888); + case 3: + case GL_RGB: + return (format == GL_RGB && + type == GL_UNSIGNED_SHORT_5_6_5 && + mesa_format == &_mesa_texformat_rgb565); + case GL_YCBCR_MESA: + return (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE); + default: + return GL_FALSE; + } +} + + +/* XXX: Do this for TexSubImage also: + */ +static GLboolean +try_pbo_upload(struct intel_context *intel, + struct intel_texture_image *intelImage, + const struct gl_pixelstore_attrib *unpack, + GLint internalFormat, + GLint width, GLint height, + GLenum format, GLenum type, const void *pixels) +{ + struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj); + GLuint src_offset, src_stride; + GLuint dst_offset, dst_stride; + + if (!pbo || + intel->ctx._ImageTransferState || + unpack->SkipPixels || unpack->SkipRows) { + _mesa_printf("%s: failure 1\n", __FUNCTION__); + return GL_FALSE; + } + + src_offset = (GLuint) pixels; + + if (unpack->RowLength > 0) + src_stride = unpack->RowLength; + else + src_stride = width; + + dst_offset = intel_miptree_image_offset(intelImage->mt, + intelImage->face, + intelImage->level); + + dst_stride = intelImage->mt->pitch; + + intelFlush(&intel->ctx); + LOCK_HARDWARE(intel); + { + struct _DriBufferObject *src_buffer = + intel_bufferobj_buffer(intel, pbo, INTEL_READ); + struct _DriBufferObject *dst_buffer = + intel_region_buffer(intel->intelScreen, intelImage->mt->region, + INTEL_WRITE_FULL); + + + intelEmitCopyBlit(intel, + intelImage->mt->cpp, + src_stride, src_buffer, src_offset, + dst_stride, dst_buffer, dst_offset, + 0, 0, 0, 0, width, height); + + intel_batchbuffer_flush(intel->batch); + } + UNLOCK_HARDWARE(intel); + + return GL_TRUE; +} + + + +static GLboolean +try_pbo_zcopy(struct intel_context *intel, + struct intel_texture_image *intelImage, + const struct gl_pixelstore_attrib *unpack, + GLint internalFormat, + GLint width, GLint height, + GLenum format, GLenum type, const void *pixels) +{ + struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj); + GLuint src_offset, src_stride; + GLuint dst_offset, dst_stride; + + if (!pbo || + intel->ctx._ImageTransferState || + unpack->SkipPixels || unpack->SkipRows) { + _mesa_printf("%s: failure 1\n", __FUNCTION__); + return GL_FALSE; + } + + src_offset = (GLuint) pixels; + + if (unpack->RowLength > 0) + src_stride = unpack->RowLength; + else + src_stride = width; + + dst_offset = intel_miptree_image_offset(intelImage->mt, + intelImage->face, + intelImage->level); + + dst_stride = intelImage->mt->pitch; + + if (src_stride != dst_stride || dst_offset != 0 || src_offset != 0) { + _mesa_printf("%s: failure 2\n", __FUNCTION__); + return GL_FALSE; + } + + intel_region_attach_pbo(intel->intelScreen, intelImage->mt->region, pbo); + + return GL_TRUE; +} + + + + + + +static void +intelTexImage(GLcontext * ctx, + GLint dims, + GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint depth, + GLint border, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *unpack, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_texture_object *intelObj = intel_texture_object(texObj); + struct intel_texture_image *intelImage = intel_texture_image(texImage); + GLint postConvWidth = width; + GLint postConvHeight = height; + GLint texelBytes, sizeInBytes; + GLuint dstRowStride; + + + DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(target), level, width, height, depth, border); + + intelFlush(ctx); + + intelImage->face = target_to_face(target); + intelImage->level = level; + + if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { + _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth, + &postConvHeight); + } + + /* choose the texture format */ + texImage->TexFormat = intelChooseTextureFormat(ctx, internalFormat, + format, type); + + assert(texImage->TexFormat); + + switch (dims) { + case 1: + texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D; + texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df; + break; + case 2: + texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D; + texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df; + break; + case 3: + texImage->FetchTexelc = texImage->TexFormat->FetchTexel3D; + texImage->FetchTexelf = texImage->TexFormat->FetchTexel3Df; + break; + default: + assert(0); + break; + } + + texelBytes = texImage->TexFormat->TexelBytes; + + + /* Minimum pitch of 32 bytes */ + if (postConvWidth * texelBytes < 32) { + postConvWidth = 32 / texelBytes; + texImage->RowStride = postConvWidth; + } + + assert(texImage->RowStride == postConvWidth); + + /* Release the reference to a potentially orphaned buffer. + * Release any old malloced memory. + */ + if (intelImage->mt) { + intel_miptree_release(intel, &intelImage->mt); + assert(!texImage->Data); + } + else if (texImage->Data) { + _mesa_align_free(texImage->Data); + } + + /* If this is the only texture image in the tree, could call + * bmBufferData with NULL data to free the old block and avoid + * waiting on any outstanding fences. + */ + if (intelObj->mt && + intelObj->mt->first_level == level && + intelObj->mt->last_level == level && + intelObj->mt->target != GL_TEXTURE_CUBE_MAP_ARB && + !intel_miptree_match_image(intelObj->mt, &intelImage->base, + intelImage->face, intelImage->level)) { + + DBG("release it\n"); + intel_miptree_release(intel, &intelObj->mt); + assert(!intelObj->mt); + } + + if (!intelObj->mt) { + guess_and_alloc_mipmap_tree(intel, intelObj, intelImage); + if (!intelObj->mt) { + DBG("guess_and_alloc_mipmap_tree: failed\n"); + } + } + + + assert(!intelImage->mt); + + if (intelObj->mt && + intel_miptree_match_image(intelObj->mt, &intelImage->base, + intelImage->face, intelImage->level)) { + + intel_miptree_reference(&intelImage->mt, intelObj->mt); + assert(intelImage->mt); + } + + if (!intelImage->mt) + DBG("XXX: Image did not fit into tree - storing in local memory!\n"); + + /* PBO fastpaths: + */ + if (dims <= 2 && + intelImage->mt && + intel_buffer_object(unpack->BufferObj) && + check_pbo_format(internalFormat, format, + type, intelImage->base.TexFormat)) { + + DBG("trying pbo upload\n"); + + /* Attempt to texture directly from PBO data (zero copy upload). + * + * Currently disable as it can lead to worse as well as better + * performance (in particular when intel_region_cow() is + * required). + */ + if (intelObj->mt == intelImage->mt && + intelObj->mt->first_level == level && + intelObj->mt->last_level == level) { + + if (try_pbo_zcopy(intel, intelImage, unpack, + internalFormat, + width, height, format, type, pixels)) { + + DBG("pbo zcopy upload succeeded\n"); + return; + } + } + + + /* Otherwise, attempt to use the blitter for PBO image uploads. + */ + if (try_pbo_upload(intel, intelImage, unpack, + internalFormat, + width, height, format, type, pixels)) { + DBG("pbo upload succeeded\n"); + return; + } + + DBG("pbo upload failed\n"); + } + + + + /* intelCopyTexImage calls this function with pixels == NULL, with + * the expectation that the mipmap tree will be set up but nothing + * more will be done. This is where those calls return: + */ + pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1, + format, type, + pixels, unpack, "glTexImage"); + if (!pixels) + return; + + + if (intelImage->mt) + intel_region_idle(intel->intelScreen, intelImage->mt->region); + + LOCK_HARDWARE(intel); + + if (intelImage->mt) { + texImage->Data = intel_miptree_image_map(intel, + intelImage->mt, + intelImage->face, + intelImage->level, + &dstRowStride, + intelImage->base.ImageOffsets); + } + else { + /* Allocate regular memory and store the image there temporarily. */ + if (texImage->IsCompressed) { + sizeInBytes = texImage->CompressedSize; + dstRowStride = + _mesa_compressed_row_stride(texImage->InternalFormat, width); + assert(dims != 3); + } + else { + dstRowStride = postConvWidth * texelBytes; + sizeInBytes = depth * dstRowStride * postConvHeight; + } + + texImage->Data = malloc(sizeInBytes); + } + + DBG("Upload image %dx%dx%d row_len %x " + "pitch %x\n", + width, height, depth, width * texelBytes, dstRowStride); + + /* Copy data. Would like to know when it's ok for us to eg. use + * the blitter to copy. Or, use the hardware to do the format + * conversion and copy: + */ + if (!texImage->TexFormat->StoreImage(ctx, dims, + texImage->_BaseFormat, + texImage->TexFormat, + texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */ + dstRowStride, + texImage->ImageOffsets, + width, height, depth, + format, type, pixels, unpack)) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); + } + + _mesa_unmap_teximage_pbo(ctx, unpack); + + if (intelImage->mt) { + intel_miptree_image_unmap(intel, intelImage->mt); + texImage->Data = NULL; + } + + UNLOCK_HARDWARE(intel); + +#if 0 + /* GL_SGIS_generate_mipmap -- this can be accelerated now. + */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + intel_generate_mipmap(ctx, target, + &ctx->Texture.Unit[ctx->Texture.CurrentUnit], + texObj); + } +#endif +} + +void +intelTexImage3D(GLcontext * ctx, + GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint depth, + GLint border, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *unpack, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + intelTexImage(ctx, 3, target, level, + internalFormat, width, height, depth, border, + format, type, pixels, unpack, texObj, texImage); +} + + +void +intelTexImage2D(GLcontext * ctx, + GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *unpack, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + intelTexImage(ctx, 2, target, level, + internalFormat, width, height, 1, border, + format, type, pixels, unpack, texObj, texImage); +} + +void +intelTexImage1D(GLcontext * ctx, + GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint border, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *unpack, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + intelTexImage(ctx, 1, target, level, + internalFormat, width, 1, 1, border, + format, type, pixels, unpack, texObj, texImage); +} + + + +/** + * Need to map texture image into memory before copying image data, + * then unmap it. + */ +void +intelGetTexImage(GLcontext * ctx, GLenum target, GLint level, + GLenum format, GLenum type, GLvoid * pixels, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_texture_image *intelImage = intel_texture_image(texImage); + + /* Map */ + if (intelImage->mt) { + /* Image is stored in hardware format in a buffer managed by the + * kernel. Need to explicitly map and unmap it. + */ + intelImage->base.Data = + intel_miptree_image_map(intel, + intelImage->mt, + intelImage->face, + intelImage->level, + &intelImage->base.RowStride, + intelImage->base.ImageOffsets); + } + else { + /* Otherwise, the image should actually be stored in + * intelImage->base.Data. This is pretty confusing for + * everybody, I'd much prefer to separate the two functions of + * texImage->Data - storage for texture images in main memory + * and access (ie mappings) of images. In other words, we'd + * create a new texImage->Map field and leave Data simply for + * storage. + */ + assert(intelImage->base.Data); + } + + _mesa_get_teximage(ctx, target, level, format, type, pixels, + texObj, texImage); + + /* Unmap */ + if (intelImage->mt) { + intel_miptree_image_unmap(intel, intelImage->mt); + intelImage->base.Data = NULL; + } +} diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_subimage.c b/src/mesa/drivers/dri/i915tex/intel_tex_subimage.c new file mode 100644 index 0000000000..25a2dca685 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_tex_subimage.c @@ -0,0 +1,183 @@ + +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#include "mtypes.h" +#include "texobj.h" +#include "texstore.h" +#include "enums.h" + +#include "intel_context.h" +#include "intel_tex.h" +#include "intel_mipmap_tree.h" + +#define FILE_DEBUG_FLAG DEBUG_TEXTURE + +static void +intelTexSubimage(GLcontext * ctx, + GLint dims, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint width, GLint height, GLint depth, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_texture_image *intelImage = intel_texture_image(texImage); + GLuint dstImageStride; + GLuint dstRowStride; + + DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(target), + level, xoffset, yoffset, width, height); + + intelFlush(ctx); + + pixels = + _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, format, + type, pixels, packing, "glTexSubImage2D"); + if (!pixels) + return; + + if (intelImage->mt) + intel_region_idle(intel->intelScreen, intelImage->mt->region); + + LOCK_HARDWARE(intel); + + /* Map buffer if necessary. Need to lock to prevent other contexts + * from uploading the buffer under us. + */ + if (intelImage->mt) + texImage->Data = intel_miptree_image_map(intel, + intelImage->mt, + intelImage->face, + intelImage->level, + &dstRowStride, + &dstImageStride); + + assert(dstRowStride); + + if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat, + texImage->TexFormat, + texImage->Data, + xoffset, yoffset, zoffset, + dstRowStride, + texImage->ImageOffsets, + width, height, depth, + format, type, pixels, packing)) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage"); + } + +#if 0 + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + _mesa_generate_mipmap(ctx, target, + &ctx->Texture.Unit[ctx->Texture.CurrentUnit], + texObj); + } +#endif + + _mesa_unmap_teximage_pbo(ctx, packing); + + if (intelImage->mt) { + intel_miptree_image_unmap(intel, intelImage->mt); + texImage->Data = NULL; + } + + UNLOCK_HARDWARE(intel); +} + + + + + +void +intelTexSubImage3D(GLcontext * ctx, + GLenum target, + GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + + intelTexSubimage(ctx, 3, + target, level, + xoffset, yoffset, zoffset, + width, height, depth, + format, type, pixels, packing, texObj, texImage); + +} + + + +void +intelTexSubImage2D(GLcontext * ctx, + GLenum target, + GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + + intelTexSubimage(ctx, 2, + target, level, + xoffset, yoffset, 0, + width, height, 1, + format, type, pixels, packing, texObj, texImage); + +} + + +void +intelTexSubImage1D(GLcontext * ctx, + GLenum target, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + intelTexSubimage(ctx, 1, + target, level, + xoffset, 0, 0, + width, 1, 1, + format, type, pixels, packing, texObj, texImage); + +} diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_validate.c b/src/mesa/drivers/dri/i915tex/intel_tex_validate.c new file mode 100644 index 0000000000..e273716b09 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_tex_validate.c @@ -0,0 +1,252 @@ +#include "mtypes.h" +#include "macros.h" + +#include "intel_context.h" +#include "intel_mipmap_tree.h" +#include "intel_tex.h" + +#define FILE_DEBUG_FLAG DEBUG_TEXTURE + +/** + * Compute which mipmap levels that really need to be sent to the hardware. + * This depends on the base image size, GL_TEXTURE_MIN_LOD, + * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL. + */ +static void +intel_calculate_first_last_level(struct intel_texture_object *intelObj) +{ + struct gl_texture_object *tObj = &intelObj->base; + const struct gl_texture_image *const baseImage = + tObj->Image[0][tObj->BaseLevel]; + + /* These must be signed values. MinLod and MaxLod can be negative numbers, + * and having firstLevel and lastLevel as signed prevents the need for + * extra sign checks. + */ + int firstLevel; + int lastLevel; + + /* Yes, this looks overly complicated, but it's all needed. + */ + switch (tObj->Target) { + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + case GL_TEXTURE_CUBE_MAP: + if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) { + /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL. + */ + firstLevel = lastLevel = tObj->BaseLevel; + } + else { + firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5); + firstLevel = MAX2(firstLevel, tObj->BaseLevel); + lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5); + lastLevel = MAX2(lastLevel, tObj->BaseLevel); + lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2); + lastLevel = MIN2(lastLevel, tObj->MaxLevel); + lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */ + } + break; + case GL_TEXTURE_RECTANGLE_NV: + case GL_TEXTURE_4D_SGIS: + firstLevel = lastLevel = 0; + break; + default: + return; + } + + /* save these values */ + intelObj->firstLevel = firstLevel; + intelObj->lastLevel = lastLevel; +} + +static void +copy_image_data_to_tree(struct intel_context *intel, + struct intel_texture_object *intelObj, + struct intel_texture_image *intelImage) +{ + if (intelImage->mt) { + /* Copy potentially with the blitter: + */ + intel_miptree_image_copy(intel, + intelObj->mt, + intelImage->face, + intelImage->level, intelImage->mt); + + intel_miptree_release(intel, &intelImage->mt); + } + else { + assert(intelImage->base.Data != NULL); + + /* More straightforward upload. + */ + intel_miptree_image_data(intel, + intelObj->mt, + intelImage->face, + intelImage->level, + intelImage->base.Data, + intelImage->base.RowStride, + intelImage->base.RowStride * + intelImage->base.Height); + _mesa_align_free(intelImage->base.Data); + intelImage->base.Data = NULL; + } + + intel_miptree_reference(&intelImage->mt, intelObj->mt); +} + + +/* + */ +GLuint +intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) +{ + struct gl_texture_object *tObj = intel->ctx.Texture.Unit[unit]._Current; + struct intel_texture_object *intelObj = intel_texture_object(tObj); + + GLuint face, i; + GLuint nr_faces = 0; + struct intel_texture_image *firstImage; + + /* We know/require this is true by now: + */ + assert(intelObj->base.Complete); + + /* What levels must the tree include at a minimum? + */ + intel_calculate_first_last_level(intelObj); + firstImage = + intel_texture_image(intelObj->base.Image[0][intelObj->firstLevel]); + + /* Fallback case: + */ + if (firstImage->base.Border) { + if (intelObj->mt) { + intel_miptree_release(intel, &intelObj->mt); + } + return GL_FALSE; + } + + + /* If both firstImage and intelObj have a tree which can contain + * all active images, favour firstImage. Note that because of the + * completeness requirement, we know that the image dimensions + * will match. + */ + if (firstImage->mt && + firstImage->mt != intelObj->mt && + firstImage->mt->first_level <= intelObj->firstLevel && + firstImage->mt->last_level >= intelObj->lastLevel) { + + if (intelObj->mt) + intel_miptree_release(intel, &intelObj->mt); + + intel_miptree_reference(&intelObj->mt, firstImage->mt); + } + + /* Check tree can hold all active levels. Check tree matches + * target, imageFormat, etc. + * + * XXX: For some layouts (eg i945?), the test might have to be + * first_level == firstLevel, as the tree isn't valid except at the + * original start level. Hope to get around this by + * programming minLod, maxLod, baseLevel into the hardware and + * leaving the tree alone. + */ + if (intelObj->mt && + ((intelObj->mt->first_level > intelObj->firstLevel) || + (intelObj->mt->last_level < intelObj->lastLevel) || + (intelObj->mt->internal_format != firstImage->base.InternalFormat))) { + intel_miptree_release(intel, &intelObj->mt); + } + + + /* May need to create a new tree: + */ + if (!intelObj->mt) { + intelObj->mt = intel_miptree_create(intel, + intelObj->base.Target, + firstImage->base.InternalFormat, + intelObj->firstLevel, + intelObj->lastLevel, + firstImage->base.Width, + firstImage->base.Height, + firstImage->base.Depth, + firstImage->base.TexFormat-> + TexelBytes, + firstImage->base.IsCompressed); + } + + /* Pull in any images not in the object's tree: + */ + nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; + for (face = 0; face < nr_faces; face++) { + for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++) { + struct intel_texture_image *intelImage = + intel_texture_image(intelObj->base.Image[face][i]); + + /* Need to import images in main memory or held in other trees. + */ + if (intelObj->mt != intelImage->mt) { + copy_image_data_to_tree(intel, intelObj, intelImage); + } + } + } + + return GL_TRUE; +} + + + +void +intel_tex_map_images(struct intel_context *intel, + struct intel_texture_object *intelObj) +{ + GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; + GLuint face, i; + + DBG("%s\n", __FUNCTION__); + + for (face = 0; face < nr_faces; face++) { + for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++) { + struct intel_texture_image *intelImage = + intel_texture_image(intelObj->base.Image[face][i]); + + if (intelImage->mt) { + intelImage->base.Data = + intel_miptree_image_map(intel, + intelImage->mt, + intelImage->face, + intelImage->level, + &intelImage->base.RowStride, + intelImage->base.ImageOffsets); + /* convert stride to texels, not bytes */ + intelImage->base.RowStride /= intelImage->mt->cpp; +/* intelImage->base.ImageStride /= intelImage->mt->cpp; */ + } + } + } +} + + + +void +intel_tex_unmap_images(struct intel_context *intel, + struct intel_texture_object *intelObj) +{ + GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; + GLuint face, i; + + for (face = 0; face < nr_faces; face++) { + for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++) { + struct intel_texture_image *intelImage = + intel_texture_image(intelObj->base.Image[face][i]); + + if (intelImage->mt) { + intel_miptree_image_unmap(intel, intelImage->mt); + intelImage->base.Data = NULL; + } + } + } +} diff --git a/src/mesa/drivers/dri/i915tex/intel_tris.c b/src/mesa/drivers/dri/i915tex/intel_tris.c new file mode 100644 index 0000000000..1ba49d8f6e --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_tris.c @@ -0,0 +1,1149 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "enums.h" +#include "texobj.h" +#include "state.h" +#include "dd.h" + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" +#include "tnl/t_vertex.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_tris.h" +#include "intel_batchbuffer.h" +#include "intel_reg.h" +#include "intel_span.h" +#include "intel_tex.h" + +static void intelRenderPrimitive(GLcontext * ctx, GLenum prim); +static void intelRasterPrimitive(GLcontext * ctx, GLenum rprim, + GLuint hwprim); + +/* + */ +static void +intel_flush_inline_primitive(struct intel_context *intel) +{ + GLuint used = intel->batch->ptr - intel->prim.start_ptr; + + assert(intel->prim.primitive != ~0); + +/* _mesa_printf("/\n"); */ + + if (used < 8) + goto do_discard; + + *(int *) intel->prim.start_ptr = (_3DPRIMITIVE | + intel->prim.primitive | (used / 4 - 2)); + + goto finished; + + do_discard: + intel->batch->ptr -= used; + + finished: + intel->prim.primitive = ~0; + intel->prim.start_ptr = 0; + intel->prim.flush = 0; +} + + +/* Emit a primitive referencing vertices in a vertex buffer. + */ +void +intelStartInlinePrimitive(struct intel_context *intel, + GLuint prim, GLuint batch_flags) +{ + BATCH_LOCALS; + + intel->vtbl.emit_state(intel); + + /* Need to make sure at the very least that we don't wrap + * batchbuffers in BEGIN_BATCH below, otherwise the primitive will + * be emitted to a batchbuffer missing the required full-state + * preamble. + */ + if (intel_batchbuffer_space(intel->batch) < 100) { + intel_batchbuffer_flush(intel->batch); + intel->vtbl.emit_state(intel); + } + +/* _mesa_printf("%s *", __progname); */ + + /* Emit a slot which will be filled with the inline primitive + * command later. + */ + BEGIN_BATCH(2, batch_flags); + OUT_BATCH(0); + + intel->prim.start_ptr = intel->batch->ptr; + intel->prim.primitive = prim; + intel->prim.flush = intel_flush_inline_primitive; + + OUT_BATCH(0); + ADVANCE_BATCH(); + +/* _mesa_printf(">"); */ +} + + +void +intelWrapInlinePrimitive(struct intel_context *intel) +{ + GLuint prim = intel->prim.primitive; + GLuint batchflags = intel->batch->flags; + + intel_flush_inline_primitive(intel); + intel_batchbuffer_flush(intel->batch); + intelStartInlinePrimitive(intel, prim, batchflags); /* ??? */ +} + +GLuint * +intelExtendInlinePrimitive(struct intel_context *intel, GLuint dwords) +{ + GLuint sz = dwords * sizeof(GLuint); + GLuint *ptr; + + assert(intel->prim.flush == intel_flush_inline_primitive); + + if (intel_batchbuffer_space(intel->batch) < sz) + intelWrapInlinePrimitive(intel); + +/* _mesa_printf("."); */ + + intel->vtbl.assert_not_dirty(intel); + + ptr = (GLuint *) intel->batch->ptr; + intel->batch->ptr += sz; + + return ptr; +} + + + +/*********************************************************************** + * Emit primitives as inline vertices * + ***********************************************************************/ + +#ifdef __i386__ +#define COPY_DWORDS( j, vb, vertsize, v ) \ +do { \ + int __tmp; \ + __asm__ __volatile__( "rep ; movsl" \ + : "=%c" (j), "=D" (vb), "=S" (__tmp) \ + : "0" (vertsize), \ + "D" ((long)vb), \ + "S" ((long)v) ); \ +} while (0) +#else +#define COPY_DWORDS( j, vb, vertsize, v ) \ +do { \ + for ( j = 0 ; j < vertsize ; j++ ) { \ + vb[j] = ((GLuint *)v)[j]; \ + } \ + vb += vertsize; \ +} while (0) +#endif + +static void +intel_draw_quad(struct intel_context *intel, + intelVertexPtr v0, + intelVertexPtr v1, intelVertexPtr v2, intelVertexPtr v3) +{ + GLuint vertsize = intel->vertex_size; + GLuint *vb = intelExtendInlinePrimitive(intel, 6 * vertsize); + int j; + + COPY_DWORDS(j, vb, vertsize, v0); + COPY_DWORDS(j, vb, vertsize, v1); + + /* If smooth shading, draw like a trifan which gives better + * rasterization. Otherwise draw as two triangles with provoking + * vertex in third position as required for flat shading. + */ + if (intel->ctx.Light.ShadeModel == GL_FLAT) { + COPY_DWORDS(j, vb, vertsize, v3); + COPY_DWORDS(j, vb, vertsize, v1); + } + else { + COPY_DWORDS(j, vb, vertsize, v2); + COPY_DWORDS(j, vb, vertsize, v0); + } + + COPY_DWORDS(j, vb, vertsize, v2); + COPY_DWORDS(j, vb, vertsize, v3); +} + +static void +intel_draw_triangle(struct intel_context *intel, + intelVertexPtr v0, intelVertexPtr v1, intelVertexPtr v2) +{ + GLuint vertsize = intel->vertex_size; + GLuint *vb = intelExtendInlinePrimitive(intel, 3 * vertsize); + int j; + + COPY_DWORDS(j, vb, vertsize, v0); + COPY_DWORDS(j, vb, vertsize, v1); + COPY_DWORDS(j, vb, vertsize, v2); +} + + +static void +intel_draw_line(struct intel_context *intel, + intelVertexPtr v0, intelVertexPtr v1) +{ + GLuint vertsize = intel->vertex_size; + GLuint *vb = intelExtendInlinePrimitive(intel, 2 * vertsize); + int j; + + COPY_DWORDS(j, vb, vertsize, v0); + COPY_DWORDS(j, vb, vertsize, v1); +} + + +static void +intel_draw_point(struct intel_context *intel, intelVertexPtr v0) +{ + GLuint vertsize = intel->vertex_size; + GLuint *vb = intelExtendInlinePrimitive(intel, vertsize); + int j; + + /* Adjust for sub pixel position -- still required for conform. */ + *(float *) &vb[0] = v0->v.x - 0.125; + *(float *) &vb[1] = v0->v.y - 0.125; + for (j = 2; j < vertsize; j++) + vb[j] = v0->ui[j]; +} + + + +/*********************************************************************** + * Fixup for ARB_point_parameters * + ***********************************************************************/ + +/* Currently not working - VERT_ATTRIB_POINTSIZE isn't correctly + * represented in the fragment program InputsRead field. + */ +static void +intel_atten_point(struct intel_context *intel, intelVertexPtr v0) +{ + GLcontext *ctx = &intel->ctx; + GLfloat psz[4], col[4], restore_psz, restore_alpha; + + _tnl_get_attr(ctx, v0, _TNL_ATTRIB_POINTSIZE, psz); + _tnl_get_attr(ctx, v0, _TNL_ATTRIB_COLOR0, col); + + restore_psz = psz[0]; + restore_alpha = col[3]; + + if (psz[0] >= ctx->Point.Threshold) { + psz[0] = MIN2(psz[0], ctx->Point.MaxSize); + } + else { + GLfloat dsize = psz[0] / ctx->Point.Threshold; + psz[0] = MAX2(ctx->Point.Threshold, ctx->Point.MinSize); + col[3] *= dsize * dsize; + } + + if (psz[0] < 1.0) + psz[0] = 1.0; + + if (restore_psz != psz[0] || restore_alpha != col[3]) { + _tnl_set_attr(ctx, v0, _TNL_ATTRIB_POINTSIZE, psz); + _tnl_set_attr(ctx, v0, _TNL_ATTRIB_COLOR0, col); + + intel_draw_point(intel, v0); + + psz[0] = restore_psz; + col[3] = restore_alpha; + + _tnl_set_attr(ctx, v0, _TNL_ATTRIB_POINTSIZE, psz); + _tnl_set_attr(ctx, v0, _TNL_ATTRIB_COLOR0, col); + } + else + intel_draw_point(intel, v0); +} + + + + + +/*********************************************************************** + * Fixup for I915 WPOS texture coordinate * + ***********************************************************************/ + + + +static void +intel_wpos_triangle(struct intel_context *intel, + intelVertexPtr v0, intelVertexPtr v1, intelVertexPtr v2) +{ + GLuint offset = intel->wpos_offset; + GLuint size = intel->wpos_size; + + __memcpy(((char *) v0) + offset, v0, size); + __memcpy(((char *) v1) + offset, v1, size); + __memcpy(((char *) v2) + offset, v2, size); + + intel_draw_triangle(intel, v0, v1, v2); +} + + +static void +intel_wpos_line(struct intel_context *intel, + intelVertexPtr v0, intelVertexPtr v1) +{ + GLuint offset = intel->wpos_offset; + GLuint size = intel->wpos_size; + + __memcpy(((char *) v0) + offset, v0, size); + __memcpy(((char *) v1) + offset, v1, size); + + intel_draw_line(intel, v0, v1); +} + + +static void +intel_wpos_point(struct intel_context *intel, intelVertexPtr v0) +{ + GLuint offset = intel->wpos_offset; + GLuint size = intel->wpos_size; + + __memcpy(((char *) v0) + offset, v0, size); + + intel_draw_point(intel, v0); +} + + + + + + +/*********************************************************************** + * Macros for t_dd_tritmp.h to draw basic primitives * + ***********************************************************************/ + +#define TRI( a, b, c ) \ +do { \ + if (DO_FALLBACK) \ + intel->draw_tri( intel, a, b, c ); \ + else \ + intel_draw_triangle( intel, a, b, c ); \ +} while (0) + +#define QUAD( a, b, c, d ) \ +do { \ + if (DO_FALLBACK) { \ + intel->draw_tri( intel, a, b, d ); \ + intel->draw_tri( intel, b, c, d ); \ + } else \ + intel_draw_quad( intel, a, b, c, d ); \ +} while (0) + +#define LINE( v0, v1 ) \ +do { \ + if (DO_FALLBACK) \ + intel->draw_line( intel, v0, v1 ); \ + else \ + intel_draw_line( intel, v0, v1 ); \ +} while (0) + +#define POINT( v0 ) \ +do { \ + if (DO_FALLBACK) \ + intel->draw_point( intel, v0 ); \ + else \ + intel_draw_point( intel, v0 ); \ +} while (0) + + +/*********************************************************************** + * Build render functions from dd templates * + ***********************************************************************/ + +#define INTEL_OFFSET_BIT 0x01 +#define INTEL_TWOSIDE_BIT 0x02 +#define INTEL_UNFILLED_BIT 0x04 +#define INTEL_FALLBACK_BIT 0x08 +#define INTEL_MAX_TRIFUNC 0x10 + + +static struct +{ + tnl_points_func points; + tnl_line_func line; + tnl_triangle_func triangle; + tnl_quad_func quad; +} rast_tab[INTEL_MAX_TRIFUNC]; + + +#define DO_FALLBACK (IND & INTEL_FALLBACK_BIT) +#define DO_OFFSET (IND & INTEL_OFFSET_BIT) +#define DO_UNFILLED (IND & INTEL_UNFILLED_BIT) +#define DO_TWOSIDE (IND & INTEL_TWOSIDE_BIT) +#define DO_FLAT 0 +#define DO_TRI 1 +#define DO_QUAD 1 +#define DO_LINE 1 +#define DO_POINTS 1 +#define DO_FULL_QUAD 1 + +#define HAVE_RGBA 1 +#define HAVE_SPEC 1 +#define HAVE_BACK_COLORS 0 +#define HAVE_HW_FLATSHADE 1 +#define VERTEX intelVertex +#define TAB rast_tab + +/* Only used to pull back colors into vertices (ie, we know color is + * floating point). + */ +#define INTEL_COLOR( dst, src ) \ +do { \ + UNCLAMPED_FLOAT_TO_UBYTE((dst)[0], (src)[2]); \ + UNCLAMPED_FLOAT_TO_UBYTE((dst)[1], (src)[1]); \ + UNCLAMPED_FLOAT_TO_UBYTE((dst)[2], (src)[0]); \ + UNCLAMPED_FLOAT_TO_UBYTE((dst)[3], (src)[3]); \ +} while (0) + +#define INTEL_SPEC( dst, src ) \ +do { \ + UNCLAMPED_FLOAT_TO_UBYTE((dst)[0], (src)[2]); \ + UNCLAMPED_FLOAT_TO_UBYTE((dst)[1], (src)[1]); \ + UNCLAMPED_FLOAT_TO_UBYTE((dst)[2], (src)[0]); \ +} while (0) + + +#define DEPTH_SCALE intel->polygon_offset_scale +#define UNFILLED_TRI unfilled_tri +#define UNFILLED_QUAD unfilled_quad +#define VERT_X(_v) _v->v.x +#define VERT_Y(_v) _v->v.y +#define VERT_Z(_v) _v->v.z +#define AREA_IS_CCW( a ) (a > 0) +#define GET_VERTEX(e) (intel->verts + (e * intel->vertex_size * sizeof(GLuint))) + +#define VERT_SET_RGBA( v, c ) if (coloroffset) INTEL_COLOR( v->ub4[coloroffset], c ) +#define VERT_COPY_RGBA( v0, v1 ) if (coloroffset) v0->ui[coloroffset] = v1->ui[coloroffset] +#define VERT_SAVE_RGBA( idx ) if (coloroffset) color[idx] = v[idx]->ui[coloroffset] +#define VERT_RESTORE_RGBA( idx ) if (coloroffset) v[idx]->ui[coloroffset] = color[idx] + +#define VERT_SET_SPEC( v, c ) if (specoffset) INTEL_SPEC( v->ub4[specoffset], c ) +#define VERT_COPY_SPEC( v0, v1 ) if (specoffset) COPY_3V(v0->ub4[specoffset], v1->ub4[specoffset]) +#define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->ui[specoffset] +#define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx] + +#define LOCAL_VARS(n) \ + struct intel_context *intel = intel_context(ctx); \ + GLuint color[n], spec[n]; \ + GLuint coloroffset = intel->coloroffset; \ + GLboolean specoffset = intel->specoffset; \ + (void) color; (void) spec; (void) coloroffset; (void) specoffset; + + +/*********************************************************************** + * Helpers for rendering unfilled primitives * + ***********************************************************************/ + +static const GLuint hw_prim[GL_POLYGON + 1] = { + PRIM3D_POINTLIST, + PRIM3D_LINELIST, + PRIM3D_LINELIST, + PRIM3D_LINELIST, + PRIM3D_TRILIST, + PRIM3D_TRILIST, + PRIM3D_TRILIST, + PRIM3D_TRILIST, + PRIM3D_TRILIST, + PRIM3D_TRILIST +}; + +#define RASTERIZE(x) intelRasterPrimitive( ctx, x, hw_prim[x] ) +#define RENDER_PRIMITIVE intel->render_primitive +#define TAG(x) x +#define IND INTEL_FALLBACK_BIT +#include "tnl_dd/t_dd_unfilled.h" +#undef IND + +/*********************************************************************** + * Generate GL render functions * + ***********************************************************************/ + +#define IND (0) +#define TAG(x) x +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_OFFSET_BIT) +#define TAG(x) x##_offset +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_TWOSIDE_BIT) +#define TAG(x) x##_twoside +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT) +#define TAG(x) x##_twoside_offset +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_UNFILLED_BIT) +#define TAG(x) x##_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT) +#define TAG(x) x##_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_TWOSIDE_BIT|INTEL_UNFILLED_BIT) +#define TAG(x) x##_twoside_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT) +#define TAG(x) x##_twoside_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_FALLBACK_BIT) +#define TAG(x) x##_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_OFFSET_BIT|INTEL_FALLBACK_BIT) +#define TAG(x) x##_offset_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_TWOSIDE_BIT|INTEL_FALLBACK_BIT) +#define TAG(x) x##_twoside_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT|INTEL_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_UNFILLED_BIT|INTEL_FALLBACK_BIT) +#define TAG(x) x##_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT|INTEL_FALLBACK_BIT) +#define TAG(x) x##_offset_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_TWOSIDE_BIT|INTEL_UNFILLED_BIT|INTEL_FALLBACK_BIT) +#define TAG(x) x##_twoside_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT| \ + INTEL_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + + +static void +init_rast_tab(void) +{ + init(); + init_offset(); + init_twoside(); + init_twoside_offset(); + init_unfilled(); + init_offset_unfilled(); + init_twoside_unfilled(); + init_twoside_offset_unfilled(); + init_fallback(); + init_offset_fallback(); + init_twoside_fallback(); + init_twoside_offset_fallback(); + init_unfilled_fallback(); + init_offset_unfilled_fallback(); + init_twoside_unfilled_fallback(); + init_twoside_offset_unfilled_fallback(); +} + + +/*********************************************************************** + * Rasterization fallback helpers * + ***********************************************************************/ + + +/* This code is hit only when a mix of accelerated and unaccelerated + * primitives are being drawn, and only for the unaccelerated + * primitives. + */ +static void +intel_fallback_tri(struct intel_context *intel, + intelVertex * v0, intelVertex * v1, intelVertex * v2) +{ + GLcontext *ctx = &intel->ctx; + SWvertex v[3]; + + if (0) + fprintf(stderr, "\n%s\n", __FUNCTION__); + + INTEL_FIREVERTICES(intel); + + _swsetup_Translate(ctx, v0, &v[0]); + _swsetup_Translate(ctx, v1, &v[1]); + _swsetup_Translate(ctx, v2, &v[2]); + intelSpanRenderStart(ctx); + _swrast_Triangle(ctx, &v[0], &v[1], &v[2]); + intelSpanRenderFinish(ctx); +} + + +static void +intel_fallback_line(struct intel_context *intel, + intelVertex * v0, intelVertex * v1) +{ + GLcontext *ctx = &intel->ctx; + SWvertex v[2]; + + if (0) + fprintf(stderr, "\n%s\n", __FUNCTION__); + + INTEL_FIREVERTICES(intel); + + _swsetup_Translate(ctx, v0, &v[0]); + _swsetup_Translate(ctx, v1, &v[1]); + intelSpanRenderStart(ctx); + _swrast_Line(ctx, &v[0], &v[1]); + intelSpanRenderFinish(ctx); +} + +static void +intel_fallback_point(struct intel_context *intel, + intelVertex * v0) +{ + GLcontext *ctx = &intel->ctx; + SWvertex v[1]; + + if (0) + fprintf(stderr, "\n%s\n", __FUNCTION__); + + INTEL_FIREVERTICES(intel); + + _swsetup_Translate(ctx, v0, &v[0]); + intelSpanRenderStart(ctx); + _swrast_Point(ctx, &v[0]); + intelSpanRenderFinish(ctx); +} + + +/**********************************************************************/ +/* Render unclipped begin/end objects */ +/**********************************************************************/ + +#define IND 0 +#define V(x) (intelVertex *)(vertptr + ((x)*vertsize*sizeof(GLuint))) +#define RENDER_POINTS( start, count ) \ + for ( ; start < count ; start++) POINT( V(ELT(start)) ); +#define RENDER_LINE( v0, v1 ) LINE( V(v0), V(v1) ) +#define RENDER_TRI( v0, v1, v2 ) TRI( V(v0), V(v1), V(v2) ) +#define RENDER_QUAD( v0, v1, v2, v3 ) QUAD( V(v0), V(v1), V(v2), V(v3) ) +#define INIT(x) intelRenderPrimitive( ctx, x ) +#undef LOCAL_VARS +#define LOCAL_VARS \ + struct intel_context *intel = intel_context(ctx); \ + GLubyte *vertptr = (GLubyte *)intel->verts; \ + const GLuint vertsize = intel->vertex_size; \ + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ + (void) elt; +#define RESET_STIPPLE +#define RESET_OCCLUSION +#define PRESERVE_VB_DEFS +#define ELT(x) x +#define TAG(x) intel_##x##_verts +#include "tnl/t_vb_rendertmp.h" +#undef ELT +#undef TAG +#define TAG(x) intel_##x##_elts +#define ELT(x) elt[x] +#include "tnl/t_vb_rendertmp.h" + +/**********************************************************************/ +/* Render clipped primitives */ +/**********************************************************************/ + + + +static void +intelRenderClippedPoly(GLcontext * ctx, const GLuint * elts, GLuint n) +{ + struct intel_context *intel = intel_context(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLuint prim = intel->render_primitive; + + /* Render the new vertices as an unclipped polygon. + */ + { + GLuint *tmp = VB->Elts; + VB->Elts = (GLuint *) elts; + tnl->Driver.Render.PrimTabElts[GL_POLYGON] (ctx, 0, n, + PRIM_BEGIN | PRIM_END); + VB->Elts = tmp; + } + + /* Restore the render primitive + */ + if (prim != GL_POLYGON) + tnl->Driver.Render.PrimitiveNotify(ctx, prim); +} + +static void +intelRenderClippedLine(GLcontext * ctx, GLuint ii, GLuint jj) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + tnl->Driver.Render.Line(ctx, ii, jj); +} + +static void +intelFastRenderClippedPoly(GLcontext * ctx, const GLuint * elts, GLuint n) +{ + struct intel_context *intel = intel_context(ctx); + const GLuint vertsize = intel->vertex_size; + GLuint *vb = intelExtendInlinePrimitive(intel, (n - 2) * 3 * vertsize); + GLubyte *vertptr = (GLubyte *) intel->verts; + const GLuint *start = (const GLuint *) V(elts[0]); + int i, j; + + for (i = 2; i < n; i++) { + COPY_DWORDS(j, vb, vertsize, V(elts[i - 1])); + COPY_DWORDS(j, vb, vertsize, V(elts[i])); + COPY_DWORDS(j, vb, vertsize, start); + } +} + +/**********************************************************************/ +/* Choose render functions */ +/**********************************************************************/ + + + + +#define ANY_FALLBACK_FLAGS (DD_LINE_STIPPLE | DD_TRI_STIPPLE | DD_POINT_ATTEN | DD_POINT_SMOOTH | DD_TRI_SMOOTH) +#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE | DD_TRI_OFFSET | DD_TRI_UNFILLED) + +void +intelChooseRenderState(GLcontext * ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct intel_context *intel = intel_context(ctx); + GLuint flags = ctx->_TriangleCaps; + const struct gl_fragment_program *fprog = ctx->FragmentProgram._Current; + GLboolean have_wpos = (fprog && (fprog->Base.InputsRead & FRAG_BIT_WPOS)); + GLuint index = 0; + + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "\n%s\n", __FUNCTION__); + + if ((flags & (ANY_FALLBACK_FLAGS | ANY_RASTER_FLAGS)) || have_wpos) { + + if (flags & ANY_RASTER_FLAGS) { + if (flags & DD_TRI_LIGHT_TWOSIDE) + index |= INTEL_TWOSIDE_BIT; + if (flags & DD_TRI_OFFSET) + index |= INTEL_OFFSET_BIT; + if (flags & DD_TRI_UNFILLED) + index |= INTEL_UNFILLED_BIT; + } + + if (have_wpos) { + intel->draw_point = intel_wpos_point; + intel->draw_line = intel_wpos_line; + intel->draw_tri = intel_wpos_triangle; + + /* Make sure these get called: + */ + index |= INTEL_FALLBACK_BIT; + } + else { + intel->draw_point = intel_draw_point; + intel->draw_line = intel_draw_line; + intel->draw_tri = intel_draw_triangle; + } + + /* Hook in fallbacks for specific primitives. + */ + if (flags & ANY_FALLBACK_FLAGS) { + if (flags & DD_LINE_STIPPLE) + intel->draw_line = intel_fallback_line; + + if ((flags & DD_TRI_STIPPLE) && !intel->hw_stipple) + intel->draw_tri = intel_fallback_tri; + + if (flags & DD_TRI_SMOOTH) { + if (intel->strict_conformance) + intel->draw_tri = intel_fallback_tri; + } + + if (flags & DD_POINT_ATTEN) { + if (0) + intel->draw_point = intel_atten_point; + else + intel->draw_point = intel_fallback_point; + } + + if (flags & DD_POINT_SMOOTH) { + if (intel->strict_conformance) + intel->draw_point = intel_fallback_point; + } + + index |= INTEL_FALLBACK_BIT; + } + } + + if (intel->RenderIndex != index) { + intel->RenderIndex = index; + + tnl->Driver.Render.Points = rast_tab[index].points; + tnl->Driver.Render.Line = rast_tab[index].line; + tnl->Driver.Render.Triangle = rast_tab[index].triangle; + tnl->Driver.Render.Quad = rast_tab[index].quad; + + if (index == 0) { + tnl->Driver.Render.PrimTabVerts = intel_render_tab_verts; + tnl->Driver.Render.PrimTabElts = intel_render_tab_elts; + tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */ + tnl->Driver.Render.ClippedPolygon = intelFastRenderClippedPoly; + } + else { + tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; + tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; + tnl->Driver.Render.ClippedLine = intelRenderClippedLine; + tnl->Driver.Render.ClippedPolygon = intelRenderClippedPoly; + } + } +} + +static const GLenum reduced_prim[GL_POLYGON + 1] = { + GL_POINTS, + GL_LINES, + GL_LINES, + GL_LINES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES +}; + + +/**********************************************************************/ +/* High level hooks for t_vb_render.c */ +/**********************************************************************/ + + + + +static void +intelRunPipeline(GLcontext * ctx) +{ + struct intel_context *intel = intel_context(ctx); + + _mesa_lock_context_textures(ctx); + + if (ctx->NewState) + _mesa_update_state_locked(ctx); + + if (intel->NewGLState) { + if (intel->NewGLState & _NEW_TEXTURE) { + intel->vtbl.update_texture_state(intel); + } + + if (!intel->Fallback) { + if (intel->NewGLState & _INTEL_NEW_RENDERSTATE) + intelChooseRenderState(ctx); + } + + intel->NewGLState = 0; + } + + _tnl_run_pipeline(ctx); + + _mesa_unlock_context_textures(ctx); +} + +static void +intelRenderStart(GLcontext * ctx) +{ + struct intel_context *intel = intel_context(ctx); + + intel->vtbl.render_start(intel_context(ctx)); + intel->vtbl.emit_state(intel); +} + +static void +intelRenderFinish(GLcontext * ctx) +{ + struct intel_context *intel = intel_context(ctx); + + if (intel->RenderIndex & INTEL_FALLBACK_BIT) + _swrast_flush(ctx); + + INTEL_FIREVERTICES(intel); +} + + + + + /* System to flush dma and emit state changes based on the rasterized + * primitive. + */ +static void +intelRasterPrimitive(GLcontext * ctx, GLenum rprim, GLuint hwprim) +{ + struct intel_context *intel = intel_context(ctx); + + if (0) + fprintf(stderr, "%s %s %x\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(rprim), hwprim); + + intel->vtbl.reduced_primitive_state(intel, rprim); + + /* Start a new primitive. Arrange to have it flushed later on. + */ + if (hwprim != intel->prim.primitive) { + INTEL_FIREVERTICES(intel); + + intelStartInlinePrimitive(intel, hwprim, INTEL_BATCH_CLIPRECTS); + } +} + + + /* + */ +static void +intelRenderPrimitive(GLcontext * ctx, GLenum prim) +{ + struct intel_context *intel = intel_context(ctx); + + if (0) + fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(prim)); + + /* Let some clipping routines know which primitive they're dealing + * with. + */ + intel->render_primitive = prim; + + /* Shortcircuit this when called from t_dd_rendertmp.h for unfilled + * triangles. The rasterized primitive will always be reset by + * lower level functions in that case, potentially pingponging the + * state: + */ + if (reduced_prim[prim] == GL_TRIANGLES && + (ctx->_TriangleCaps & DD_TRI_UNFILLED)) + return; + + /* Set some primitive-dependent state and Start? a new primitive. + */ + intelRasterPrimitive(ctx, reduced_prim[prim], hw_prim[prim]); +} + + + /**********************************************************************/ + /* Transition to/from hardware rasterization. */ + /**********************************************************************/ + +static char *fallbackStrings[] = { + [0] = "Draw buffer", + [1] = "Read buffer", + [2] = "Depth buffer", + [3] = "Stencil buffer", + [4] = "User disable", + [5] = "Render mode", + + [12] = "Texture", + [13] = "Color mask", + [14] = "Stencil", + [15] = "Stipple", + [16] = "Program", + [17] = "Logic op", + [18] = "Smooth polygon", + [19] = "Smooth point", +}; + + +static char * +getFallbackString(GLuint bit) +{ + int i = 0; + while (bit > 1) { + i++; + bit >>= 1; + } + return fallbackStrings[i]; +} + + + +void +intelFallback(struct intel_context *intel, GLuint bit, GLboolean mode) +{ + GLcontext *ctx = &intel->ctx; + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint oldfallback = intel->Fallback; + + if (mode) { + intel->Fallback |= bit; + if (oldfallback == 0) { + intelFlush(ctx); + if (INTEL_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "ENTER FALLBACK %x: %s\n", + bit, getFallbackString(bit)); + _swsetup_Wakeup(ctx); + intel->RenderIndex = ~0; + } + } + else { + intel->Fallback &= ~bit; + if (oldfallback == bit) { + _swrast_flush(ctx); + if (INTEL_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "LEAVE FALLBACK %s\n", getFallbackString(bit)); + tnl->Driver.Render.Start = intelRenderStart; + tnl->Driver.Render.PrimitiveNotify = intelRenderPrimitive; + tnl->Driver.Render.Finish = intelRenderFinish; + tnl->Driver.Render.BuildVertices = _tnl_build_vertices; + tnl->Driver.Render.CopyPV = _tnl_copy_pv; + tnl->Driver.Render.Interp = _tnl_interp; + + _tnl_invalidate_vertex_state(ctx, ~0); + _tnl_invalidate_vertices(ctx, ~0); + _tnl_install_attrs(ctx, + intel->vertex_attrs, + intel->vertex_attr_count, + intel->ViewportMatrix.m, 0); + + intel->NewGLState |= _INTEL_NEW_RENDERSTATE; + } + } +} + +union fi +{ + GLfloat f; + GLint i; +}; + + +/**********************************************************************/ +/* Used only with the metaops callbacks. */ +/**********************************************************************/ +void +intel_meta_draw_poly(struct intel_context *intel, + GLuint n, + GLfloat xy[][2], + GLfloat z, GLuint color, GLfloat tex[][2]) +{ + union fi *vb; + GLint i; + + /* All 3d primitives should be emitted with INTEL_BATCH_CLIPRECTS, + * otherwise the drawing origin (DR4) might not be set correctly. + */ + intelStartInlinePrimitive(intel, PRIM3D_TRIFAN, INTEL_BATCH_CLIPRECTS); + vb = (union fi *) intelExtendInlinePrimitive(intel, n * 6); + + for (i = 0; i < n; i++) { + vb[0].f = xy[i][0]; + vb[1].f = xy[i][1]; + vb[2].f = z; + vb[3].i = color; + vb[4].f = tex[i][0]; + vb[5].f = tex[i][1]; + vb += 6; + } + + INTEL_FIREVERTICES(intel); +} + +void +intel_meta_draw_quad(struct intel_context *intel, + GLfloat x0, GLfloat x1, + GLfloat y0, GLfloat y1, + GLfloat z, + GLuint color, + GLfloat s0, GLfloat s1, GLfloat t0, GLfloat t1) +{ + GLfloat xy[4][2]; + GLfloat tex[4][2]; + + xy[0][0] = x0; + xy[0][1] = y0; + xy[1][0] = x1; + xy[1][1] = y0; + xy[2][0] = x1; + xy[2][1] = y1; + xy[3][0] = x0; + xy[3][1] = y1; + + tex[0][0] = s0; + tex[0][1] = t0; + tex[1][0] = s1; + tex[1][1] = t0; + tex[2][0] = s1; + tex[2][1] = t1; + tex[3][0] = s0; + tex[3][1] = t1; + + intel_meta_draw_poly(intel, 4, xy, z, color, tex); +} + + + +/**********************************************************************/ +/* Initialization. */ +/**********************************************************************/ + + +void +intelInitTriFuncs(GLcontext * ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + static int firsttime = 1; + + if (firsttime) { + init_rast_tab(); + firsttime = 0; + } + + tnl->Driver.RunPipeline = intelRunPipeline; + tnl->Driver.Render.Start = intelRenderStart; + tnl->Driver.Render.Finish = intelRenderFinish; + tnl->Driver.Render.PrimitiveNotify = intelRenderPrimitive; + tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple; + tnl->Driver.Render.BuildVertices = _tnl_build_vertices; + tnl->Driver.Render.CopyPV = _tnl_copy_pv; + tnl->Driver.Render.Interp = _tnl_interp; +} diff --git a/src/mesa/drivers/dri/i915tex/intel_tris.h b/src/mesa/drivers/dri/i915tex/intel_tris.h new file mode 100644 index 0000000000..b7bae8cd3b --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_tris.h @@ -0,0 +1,69 @@ +/************************************************************************** + * + * Copyright 2003 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 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 ITS 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. + * + **************************************************************************/ + +#ifndef INTELTRIS_INC +#define INTELTRIS_INC + +#include "mtypes.h" + + + +#define _INTEL_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE | \ + _DD_NEW_TRI_UNFILLED | \ + _DD_NEW_TRI_LIGHT_TWOSIDE | \ + _DD_NEW_TRI_OFFSET | \ + _DD_NEW_TRI_STIPPLE | \ + _NEW_PROGRAM | \ + _NEW_POLYGONSTIPPLE) + +extern void intelInitTriFuncs(GLcontext * ctx); + +extern void intelChooseRenderState(GLcontext * ctx); + +extern void intelStartInlinePrimitive(struct intel_context *intel, + GLuint prim, GLuint flags); +extern void intelWrapInlinePrimitive(struct intel_context *intel); + +GLuint *intelExtendInlinePrimitive(struct intel_context *intel, + GLuint dwords); + + +void intel_meta_draw_quad(struct intel_context *intel, + GLfloat x0, GLfloat x1, + GLfloat y0, GLfloat y1, + GLfloat z, + GLuint color, + GLfloat s0, GLfloat s1, GLfloat t0, GLfloat t1); + +void intel_meta_draw_poly(struct intel_context *intel, + GLuint n, + GLfloat xy[][2], + GLfloat z, GLuint color, GLfloat tex[][2]); + + + +#endif diff --git a/src/mesa/drivers/dri/i915tex/server/i830_common.h b/src/mesa/drivers/dri/i915tex/server/i830_common.h new file mode 100644 index 0000000000..fb6ceaa52d --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/server/i830_common.h @@ -0,0 +1,212 @@ +/************************************************************************** + +Copyright 2001 VA Linux Systems Inc., Fremont, California. +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 +ATI, VA LINUX SYSTEMS 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. + +**************************************************************************/ + +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_common.h,v 1.1 2002/09/11 00:29:32 dawes Exp $ */ + +#ifndef _I830_COMMON_H_ +#define _I830_COMMON_H_ + + +#define I830_NR_TEX_REGIONS 255 /* maximum due to use of chars for next/prev */ +#define I830_LOG_MIN_TEX_REGION_SIZE 14 + + +/* Driver specific DRM command indices + * NOTE: these are not OS specific, but they are driver specific + */ +#define DRM_I830_INIT 0x00 +#define DRM_I830_FLUSH 0x01 +#define DRM_I830_FLIP 0x02 +#define DRM_I830_BATCHBUFFER 0x03 +#define DRM_I830_IRQ_EMIT 0x04 +#define DRM_I830_IRQ_WAIT 0x05 +#define DRM_I830_GETPARAM 0x06 +#define DRM_I830_SETPARAM 0x07 +#define DRM_I830_ALLOC 0x08 +#define DRM_I830_FREE 0x09 +#define DRM_I830_INIT_HEAP 0x0a +#define DRM_I830_CMDBUFFER 0x0b +#define DRM_I830_DESTROY_HEAP 0x0c + +typedef struct { + enum { + I830_INIT_DMA = 0x01, + I830_CLEANUP_DMA = 0x02, + I830_RESUME_DMA = 0x03 + } func; + unsigned int mmio_offset; + int sarea_priv_offset; + unsigned int ring_start; + unsigned int ring_end; + unsigned int ring_size; + unsigned int front_offset; + unsigned int back_offset; + unsigned int depth_offset; + unsigned int w; + unsigned int h; + unsigned int pitch; + unsigned int pitch_bits; + unsigned int back_pitch; + unsigned int depth_pitch; + unsigned int cpp; + unsigned int chipset; +} drmI830Init; + +typedef struct { + drmTextureRegion texList[I830_NR_TEX_REGIONS+1]; + int last_upload; /* last time texture was uploaded */ + int last_enqueue; /* last time a buffer was enqueued */ + int last_dispatch; /* age of the most recently dispatched buffer */ + int ctxOwner; /* last context to upload state */ + int texAge; + int pf_enabled; /* is pageflipping allowed? */ + int pf_active; + int pf_current_page; /* which buffer is being displayed? */ + int perf_boxes; /* performance boxes to be displayed */ + int width, height; /* screen size in pixels */ + + drm_handle_t front_handle; + int front_offset; + int front_size; + + drm_handle_t back_handle; + int back_offset; + int back_size; + + drm_handle_t depth_handle; + int depth_offset; + int depth_size; + + drm_handle_t tex_handle; + int tex_offset; + int tex_size; + int log_tex_granularity; + int pitch; + int rotation; /* 0, 90, 180 or 270 */ + int rotated_offset; + int rotated_size; + int rotated_pitch; + int virtualX, virtualY; + + unsigned int front_tiled; + unsigned int back_tiled; + unsigned int depth_tiled; + unsigned int rotated_tiled; + unsigned int rotated2_tiled; + + int pipeA_x; + int pipeA_y; + int pipeA_w; + int pipeA_h; + int pipeB_x; + int pipeB_y; + int pipeB_w; + int pipeB_h; +} drmI830Sarea; + +/* Flags for perf_boxes + */ +#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */ +#define I830_BOX_FLIP 0x2 /* populated by kernel */ +#define I830_BOX_WAIT 0x4 /* populated by kernel & client */ +#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */ +#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */ + + +typedef struct { + int start; /* agp offset */ + int used; /* nr bytes in use */ + int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ + int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/ + int num_cliprects; /* mulitpass with multiple cliprects? */ + drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */ +} drmI830BatchBuffer; + +typedef struct { + char *buf; /* agp offset */ + int sz; /* nr bytes in use */ + int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ + int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/ + int num_cliprects; /* mulitpass with multiple cliprects? */ + drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */ +} drmI830CmdBuffer; + +typedef struct { + int *irq_seq; +} drmI830IrqEmit; + +typedef struct { + int irq_seq; +} drmI830IrqWait; + +typedef struct { + int param; + int *value; +} drmI830GetParam; + +#define I830_PARAM_IRQ_ACTIVE 1 +#define I830_PARAM_ALLOW_BATCHBUFFER 2 + +typedef struct { + int param; + int value; +} drmI830SetParam; + +#define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1 +#define I830_SETPARAM_TEX_LRU_LOG_GRANULARITY 2 +#define I830_SETPARAM_ALLOW_BATCHBUFFER 3 + + +/* A memory manager for regions of shared memory: + */ +#define I830_MEM_REGION_AGP 1 + +typedef struct { + int region; + int alignment; + int size; + int *region_offset; /* offset from start of fb or agp */ +} drmI830MemAlloc; + +typedef struct { + int region; + int region_offset; +} drmI830MemFree; + +typedef struct { + int region; + int size; + int start; +} drmI830MemInitHeap; + +typedef struct { + int region; +} drmI830MemDestroyHeap; + + +#endif /* _I830_DRM_H_ */ diff --git a/src/mesa/drivers/dri/i915tex/server/i830_dri.h b/src/mesa/drivers/dri/i915tex/server/i830_dri.h new file mode 100644 index 0000000000..6c9a709021 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/server/i830_dri.h @@ -0,0 +1,73 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.h,v 1.4 2002/10/30 12:52:18 alanh Exp $ */ + +#ifndef _I830_DRI_H +#define _I830_DRI_H + +#include "xf86drm.h" +#include "i830_common.h" + +#define I830_MAX_DRAWABLES 256 + +#define I830_MAJOR_VERSION 1 +#define I830_MINOR_VERSION 3 +#define I830_PATCHLEVEL 0 + +#define I830_REG_SIZE 0x80000 + +typedef struct _I830DRIRec { + drm_handle_t regs; + drmSize regsSize; + + drmSize backbufferSize; + drm_handle_t backbuffer; + + drmSize depthbufferSize; + drm_handle_t depthbuffer; + + drmSize rotatedSize; + drm_handle_t rotatedbuffer; + + drm_handle_t textures; + int textureSize; + + drm_handle_t agp_buffers; + drmSize agp_buf_size; + + int deviceID; + int width; + int height; + int mem; + int cpp; + int bitsPerPixel; + + int fbOffset; + int fbStride; + + int backOffset; + int backPitch; + + int depthOffset; + int depthPitch; + + int rotatedOffset; + int rotatedPitch; + + int logTextureGranularity; + int textureOffset; + + int irq; + int sarea_priv_offset; +} I830DRIRec, *I830DRIPtr; + +typedef struct { + /* Nothing here yet */ + int dummy; +} I830ConfigPrivRec, *I830ConfigPrivPtr; + +typedef struct { + /* Nothing here yet */ + int dummy; +} I830DRIContextRec, *I830DRIContextPtr; + + +#endif diff --git a/src/mesa/drivers/dri/i915tex/server/intel.h b/src/mesa/drivers/dri/i915tex/server/intel.h new file mode 100644 index 0000000000..d7858a20c8 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/server/intel.h @@ -0,0 +1,328 @@ +#ifndef _INTEL_H_ +#define _INTEL_H_ + +#include "xf86drm.h" /* drm_handle_t, etc */ + +/* Intel */ +#ifndef PCI_CHIP_I810 +#define PCI_CHIP_I810 0x7121 +#define PCI_CHIP_I810_DC100 0x7123 +#define PCI_CHIP_I810_E 0x7125 +#define PCI_CHIP_I815 0x1132 +#define PCI_CHIP_I810_BRIDGE 0x7120 +#define PCI_CHIP_I810_DC100_BRIDGE 0x7122 +#define PCI_CHIP_I810_E_BRIDGE 0x7124 +#define PCI_CHIP_I815_BRIDGE 0x1130 +#endif + +#define PCI_CHIP_845_G 0x2562 +#define PCI_CHIP_I830_M 0x3577 + +#ifndef PCI_CHIP_I855_GM +#define PCI_CHIP_I855_GM 0x3582 +#define PCI_CHIP_I855_GM_BRIDGE 0x3580 +#endif + +#ifndef PCI_CHIP_I865_G +#define PCI_CHIP_I865_G 0x2572 +#define PCI_CHIP_I865_G_BRIDGE 0x2570 +#endif + +#ifndef PCI_CHIP_I915_G +#define PCI_CHIP_I915_G 0x2582 +#define PCI_CHIP_I915_G_BRIDGE 0x2580 +#endif + +#ifndef PCI_CHIP_I915_GM +#define PCI_CHIP_I915_GM 0x2592 +#define PCI_CHIP_I915_GM_BRIDGE 0x2590 +#endif + +#ifndef PCI_CHIP_E7221_G +#define PCI_CHIP_E7221_G 0x258A +/* Same as I915_G_BRIDGE */ +#define PCI_CHIP_E7221_G_BRIDGE 0x2580 +#endif + +#ifndef PCI_CHIP_I945_G +#define PCI_CHIP_I945_G 0x2772 +#define PCI_CHIP_I945_G_BRIDGE 0x2770 +#endif + +#ifndef PCI_CHIP_I945_GM +#define PCI_CHIP_I945_GM 0x27A2 +#define PCI_CHIP_I945_GM_BRIDGE 0x27A0 +#endif + +#define IS_I810(pI810) (pI810->Chipset == PCI_CHIP_I810 || \ + pI810->Chipset == PCI_CHIP_I810_DC100 || \ + pI810->Chipset == PCI_CHIP_I810_E) +#define IS_I815(pI810) (pI810->Chipset == PCI_CHIP_I815) +#define IS_I830(pI810) (pI810->Chipset == PCI_CHIP_I830_M) +#define IS_845G(pI810) (pI810->Chipset == PCI_CHIP_845_G) +#define IS_I85X(pI810) (pI810->Chipset == PCI_CHIP_I855_GM) +#define IS_I852(pI810) (pI810->Chipset == PCI_CHIP_I855_GM && (pI810->variant == I852_GM || pI810->variant == I852_GME)) +#define IS_I855(pI810) (pI810->Chipset == PCI_CHIP_I855_GM && (pI810->variant == I855_GM || pI810->variant == I855_GME)) +#define IS_I865G(pI810) (pI810->Chipset == PCI_CHIP_I865_G) + +#define IS_I915G(pI810) (pI810->Chipset == PCI_CHIP_I915_G || pI810->Chipset == PCI_CHIP_E7221_G) +#define IS_I915GM(pI810) (pI810->Chipset == PCI_CHIP_I915_GM) +#define IS_I945G(pI810) (pI810->Chipset == PCI_CHIP_I945_G) +#define IS_I945GM(pI810) (pI810->Chipset == PCI_CHIP_I945_GM) +#define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810)) + +#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810)) + +#define I830_GMCH_CTRL 0x52 + + +#define I830_GMCH_GMS_MASK 0x70 +#define I830_GMCH_GMS_DISABLED 0x00 +#define I830_GMCH_GMS_LOCAL 0x10 +#define I830_GMCH_GMS_STOLEN_512 0x20 +#define I830_GMCH_GMS_STOLEN_1024 0x30 +#define I830_GMCH_GMS_STOLEN_8192 0x40 + +#define I855_GMCH_GMS_MASK (0x7 << 4) +#define I855_GMCH_GMS_DISABLED 0x00 +#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) +#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4) +#define I855_GMCH_GMS_STOLEN_8M (0x3 << 4) +#define I855_GMCH_GMS_STOLEN_16M (0x4 << 4) +#define I855_GMCH_GMS_STOLEN_32M (0x5 << 4) +#define I915G_GMCH_GMS_STOLEN_48M (0x6 << 4) +#define I915G_GMCH_GMS_STOLEN_64M (0x7 << 4) + +typedef unsigned char Bool; +#define TRUE 1 +#define FALSE 0 + +#define PIPE_NONE 0<<0 +#define PIPE_CRT 1<<0 +#define PIPE_TV 1<<1 +#define PIPE_DFP 1<<2 +#define PIPE_LFP 1<<3 +#define PIPE_CRT2 1<<4 +#define PIPE_TV2 1<<5 +#define PIPE_DFP2 1<<6 +#define PIPE_LFP2 1<<7 + +typedef struct _I830MemPool *I830MemPoolPtr; +typedef struct _I830MemRange *I830MemRangePtr; +typedef struct _I830MemRange { + long Start; + long End; + long Size; + unsigned long Physical; + unsigned long Offset; /* Offset of AGP-allocated portion */ + unsigned long Alignment; + drm_handle_t Key; + unsigned long Pitch; // add pitch + I830MemPoolPtr Pool; +} I830MemRange; + +typedef struct _I830MemPool { + I830MemRange Total; + I830MemRange Free; + I830MemRange Fixed; + I830MemRange Allocated; +} I830MemPool; + +typedef struct { + int tail_mask; + I830MemRange mem; + unsigned char *virtual_start; + int head; + int tail; + int space; +} I830RingBuffer; + +typedef struct _I830Rec { + unsigned char *MMIOBase; + unsigned char *FbBase; + int cpp; + + unsigned int bios_version; + + /* These are set in PreInit and never changed. */ + long FbMapSize; + long TotalVideoRam; + I830MemRange StolenMemory; /* pre-allocated memory */ + long BIOSMemorySize; /* min stolen pool size */ + int BIOSMemSizeLoc; + + /* These change according to what has been allocated. */ + long FreeMemory; + I830MemRange MemoryAperture; + I830MemPool StolenPool; + long allocatedMemory; + + /* Regions allocated either from the above pools, or from agpgart. */ + /* for single and dual head configurations */ + I830MemRange FrontBuffer; + I830MemRange FrontBuffer2; + I830MemRange Scratch; + I830MemRange Scratch2; + + I830RingBuffer *LpRing; + + I830MemRange BackBuffer; + I830MemRange DepthBuffer; + I830MemRange TexMem; + int TexGranularity; + I830MemRange ContextMem; + int drmMinor; + Bool have3DWindows; + + Bool NeedRingBufferLow; + Bool allowPageFlip; + Bool disableTiling; + + int Chipset; + unsigned long LinearAddr; + unsigned long MMIOAddr; + + drmSize registerSize; /**< \brief MMIO register map size */ + drm_handle_t registerHandle; /**< \brief MMIO register map handle */ + // IOADDRESS ioBase; + int irq; /**< \brief IRQ number */ + int GttBound; + + drm_handle_t ring_map; + unsigned int Fence[8]; + +} I830Rec; + +/* + * 12288 is set as the maximum, chosen because it is enough for + * 1920x1440@32bpp with a 2048 pixel line pitch with some to spare. + */ +#define I830_MAXIMUM_VBIOS_MEM 12288 +#define I830_DEFAULT_VIDEOMEM_2D (MB(32) / 1024) +#define I830_DEFAULT_VIDEOMEM_3D (MB(64) / 1024) + +/* Flags for memory allocation function */ +#define FROM_ANYWHERE 0x00000000 +#define FROM_POOL_ONLY 0x00000001 +#define FROM_NEW_ONLY 0x00000002 +#define FROM_MASK 0x0000000f + +#define ALLOCATE_AT_TOP 0x00000010 +#define ALLOCATE_AT_BOTTOM 0x00000020 +#define FORCE_GAPS 0x00000040 + +#define NEED_PHYSICAL_ADDR 0x00000100 +#define ALIGN_BOTH_ENDS 0x00000200 +#define FORCE_LOW 0x00000400 + +#define ALLOC_NO_TILING 0x00001000 +#define ALLOC_INITIAL 0x00002000 + +#define ALLOCATE_DRY_RUN 0x80000000 + +/* Chipset registers for VIDEO BIOS memory RW access */ +#define _855_DRAM_RW_CONTROL 0x58 +#define _845_DRAM_RW_CONTROL 0x90 +#define DRAM_WRITE 0x33330000 + +#define KB(x) ((x) * 1024) +#define MB(x) ((x) * KB(1024)) + +#define GTT_PAGE_SIZE KB(4) +#define ROUND_TO(x, y) (((x) + (y) - 1) / (y) * (y)) +#define ROUND_DOWN_TO(x, y) ((x) / (y) * (y)) +#define ROUND_TO_PAGE(x) ROUND_TO((x), GTT_PAGE_SIZE) +#define ROUND_TO_MB(x) ROUND_TO((x), MB(1)) +#define PRIMARY_RINGBUFFER_SIZE KB(128) + + +/* Ring buffer registers, p277, overview p19 + */ +#define LP_RING 0x2030 +#define HP_RING 0x2040 + +#define RING_TAIL 0x00 +#define TAIL_ADDR 0x000FFFF8 +#define I830_TAIL_MASK 0x001FFFF8 + +#define RING_HEAD 0x04 +#define HEAD_WRAP_COUNT 0xFFE00000 +#define HEAD_WRAP_ONE 0x00200000 +#define HEAD_ADDR 0x001FFFFC +#define I830_HEAD_MASK 0x001FFFFC + +#define RING_START 0x08 +#define START_ADDR 0x03FFFFF8 +#define I830_RING_START_MASK 0xFFFFF000 + +#define RING_LEN 0x0C +#define RING_NR_PAGES 0x001FF000 +#define I830_RING_NR_PAGES 0x001FF000 +#define RING_REPORT_MASK 0x00000006 +#define RING_REPORT_64K 0x00000002 +#define RING_REPORT_128K 0x00000004 +#define RING_NO_REPORT 0x00000000 +#define RING_VALID_MASK 0x00000001 +#define RING_VALID 0x00000001 +#define RING_INVALID 0x00000000 + + +/* Fence/Tiling ranges [0..7] + */ +#define FENCE 0x2000 +#define FENCE_NR 8 + +#define I915G_FENCE_START_MASK 0x0ff00000 + +#define I830_FENCE_START_MASK 0x07f80000 + +#define FENCE_START_MASK 0x03F80000 +#define FENCE_X_MAJOR 0x00000000 +#define FENCE_Y_MAJOR 0x00001000 +#define FENCE_SIZE_MASK 0x00000700 +#define FENCE_SIZE_512K 0x00000000 +#define FENCE_SIZE_1M 0x00000100 +#define FENCE_SIZE_2M 0x00000200 +#define FENCE_SIZE_4M 0x00000300 +#define FENCE_SIZE_8M 0x00000400 +#define FENCE_SIZE_16M 0x00000500 +#define FENCE_SIZE_32M 0x00000600 +#define FENCE_SIZE_64M 0x00000700 +#define I915G_FENCE_SIZE_1M 0x00000000 +#define I915G_FENCE_SIZE_2M 0x00000100 +#define I915G_FENCE_SIZE_4M 0x00000200 +#define I915G_FENCE_SIZE_8M 0x00000300 +#define I915G_FENCE_SIZE_16M 0x00000400 +#define I915G_FENCE_SIZE_32M 0x00000500 +#define I915G_FENCE_SIZE_64M 0x00000600 +#define I915G_FENCE_SIZE_128M 0x00000700 +#define FENCE_PITCH_1 0x00000000 +#define FENCE_PITCH_2 0x00000010 +#define FENCE_PITCH_4 0x00000020 +#define FENCE_PITCH_8 0x00000030 +#define FENCE_PITCH_16 0x00000040 +#define FENCE_PITCH_32 0x00000050 +#define FENCE_PITCH_64 0x00000060 +#define FENCE_VALID 0x00000001 + +#include + +# define MMIO_IN8(base, offset) \ + *(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) +# define MMIO_IN32(base, offset) \ + read_MMIO_LE32(base, offset) +# define MMIO_OUT8(base, offset, val) \ + *(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) = (val) +# define MMIO_OUT32(base, offset, val) \ + *(volatile unsigned int *)(void *)(((unsigned char*)(base)) + (offset)) = CPU_TO_LE32(val) + + + /* Memory mapped register access macros */ +#define INREG8(addr) MMIO_IN8(MMIO, addr) +#define INREG(addr) MMIO_IN32(MMIO, addr) +#define OUTREG8(addr, val) MMIO_OUT8(MMIO, addr, val) +#define OUTREG(addr, val) MMIO_OUT32(MMIO, addr, val) + +#define DSPABASE 0x70184 + +#endif diff --git a/src/mesa/drivers/dri/i915tex/server/intel_dri.c b/src/mesa/drivers/dri/i915tex/server/intel_dri.c new file mode 100644 index 0000000000..169fdbece3 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/server/intel_dri.c @@ -0,0 +1,1282 @@ +/** + * \file server/intel_dri.c + * \brief File to perform the device-specific initialization tasks typically + * done in the X server. + * + * Here they are converted to run in the client (or perhaps a standalone + * process), and to work with the frame buffer device rather than the X + * server infrastructure. + * + * Copyright (C) 2006 Dave Airlie (airlied@linux.ie) + + 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, 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 THE COPYRIGHT HOLDERS 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. +*/ + +#include +#include +#include +#include +#include + +#include "driver.h" +#include "drm.h" + +#include "intel.h" +#include "i830_dri.h" + +#include "memops.h" +#include "pciaccess.h" + +static size_t drm_page_size; +static int nextTile = 0; +#define xf86DrvMsg(...) do {} while(0) + +static const int pitches[] = { + 128 * 8, + 128 * 16, + 128 * 32, + 128 * 64, + 0 +}; + +static Bool I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea); + +static unsigned long +GetBestTileAlignment(unsigned long size) +{ + unsigned long i; + + for (i = KB(512); i < size; i <<= 1) + ; + + if (i > MB(64)) + i = MB(64); + + return i; +} + +static void SetFenceRegs(const DRIDriverContext *ctx, I830Rec *pI830) +{ + int i; + unsigned char *MMIO = ctx->MMIOAddress; + + for (i = 0; i < 8; i++) { + OUTREG(FENCE + i * 4, pI830->Fence[i]); + // if (I810_DEBUG & DEBUG_VERBOSE_VGA) + fprintf(stderr,"Fence Register : %x\n", pI830->Fence[i]); + } +} + +/* Tiled memory is good... really, really good... + * + * Need to make it less likely that we miss out on this - probably + * need to move the frontbuffer away from the 'guarenteed' alignment + * of the first memory segment, or perhaps allocate a discontigous + * framebuffer to get more alignment 'sweet spots'. + */ +static void +SetFence(const DRIDriverContext *ctx, I830Rec *pI830, + int nr, unsigned int start, unsigned int pitch, + unsigned int size) +{ + unsigned int val; + unsigned int fence_mask = 0; + unsigned int fence_pitch; + + if (nr < 0 || nr > 7) { + fprintf(stderr, + "SetFence: fence %d out of range\n",nr); + return; + } + + pI830->Fence[nr] = 0; + + if (IS_I9XX(pI830)) + fence_mask = ~I915G_FENCE_START_MASK; + else + fence_mask = ~I830_FENCE_START_MASK; + + if (start & fence_mask) { + fprintf(stderr, + "SetFence: %d: start (0x%08x) is not %s aligned\n", + nr, start, (IS_I9XX(pI830)) ? "1MB" : "512k"); + return; + } + + if (start % size) { + fprintf(stderr, + "SetFence: %d: start (0x%08x) is not size (%dk) aligned\n", + nr, start, size / 1024); + return; + } + + if (pitch & 127) { + fprintf(stderr, + "SetFence: %d: pitch (%d) not a multiple of 128 bytes\n", + nr, pitch); + return; + } + + val = (start | FENCE_X_MAJOR | FENCE_VALID); + + if (IS_I9XX(pI830)) { + switch (size) { + case MB(1): + val |= I915G_FENCE_SIZE_1M; + break; + case MB(2): + val |= I915G_FENCE_SIZE_2M; + break; + case MB(4): + val |= I915G_FENCE_SIZE_4M; + break; + case MB(8): + val |= I915G_FENCE_SIZE_8M; + break; + case MB(16): + val |= I915G_FENCE_SIZE_16M; + break; + case MB(32): + val |= I915G_FENCE_SIZE_32M; + break; + case MB(64): + val |= I915G_FENCE_SIZE_64M; + break; + default: + fprintf(stderr, + "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); + return; + } + } else { + switch (size) { + case KB(512): + val |= FENCE_SIZE_512K; + break; + case MB(1): + val |= FENCE_SIZE_1M; + break; + case MB(2): + val |= FENCE_SIZE_2M; + break; + case MB(4): + val |= FENCE_SIZE_4M; + break; + case MB(8): + val |= FENCE_SIZE_8M; + break; + case MB(16): + val |= FENCE_SIZE_16M; + break; + case MB(32): + val |= FENCE_SIZE_32M; + break; + case MB(64): + val |= FENCE_SIZE_64M; + break; + default: + fprintf(stderr, + "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); + return; + } + } + + if (IS_I9XX(pI830)) + fence_pitch = pitch / 512; + else + fence_pitch = pitch / 128; + + switch (fence_pitch) { + case 1: + val |= FENCE_PITCH_1; + break; + case 2: + val |= FENCE_PITCH_2; + break; + case 4: + val |= FENCE_PITCH_4; + break; + case 8: + val |= FENCE_PITCH_8; + break; + case 16: + val |= FENCE_PITCH_16; + break; + case 32: + val |= FENCE_PITCH_32; + break; + case 64: + val |= FENCE_PITCH_64; + break; + default: + fprintf(stderr, + "SetFence: %d: illegal pitch (%d)\n", nr, pitch); + return; + } + + pI830->Fence[nr] = val; +} + +static Bool +MakeTiles(const DRIDriverContext *ctx, I830Rec *pI830, I830MemRange *pMem) +{ + int pitch, ntiles, i; + + pitch = pMem->Pitch * ctx->cpp; + /* + * Simply try to break the region up into at most four pieces of size + * equal to the alignment. + */ + ntiles = ROUND_TO(pMem->Size, pMem->Alignment) / pMem->Alignment; + if (ntiles >= 4) { + return FALSE; + } + + for (i = 0; i < ntiles; i++, nextTile++) { + SetFence(ctx, pI830, nextTile, pMem->Start + i * pMem->Alignment, + pitch, pMem->Alignment); + } + return TRUE; +} + +static void I830SetupMemoryTiling(const DRIDriverContext *ctx, I830Rec *pI830) +{ + int i; + + /* Clear out */ + for (i = 0; i < 8; i++) + pI830->Fence[i] = 0; + + nextTile = 0; + + if (pI830->BackBuffer.Alignment >= KB(512)) { + if (MakeTiles(ctx, pI830, &(pI830->BackBuffer))) { + fprintf(stderr, + "Activating tiled memory for the back buffer.\n"); + } else { + fprintf(stderr, + "MakeTiles failed for the back buffer.\n"); + pI830->allowPageFlip = FALSE; + } + } + + if (pI830->DepthBuffer.Alignment >= KB(512)) { + if (MakeTiles(ctx, pI830, &(pI830->DepthBuffer))) { + fprintf(stderr, + "Activating tiled memory for the depth buffer.\n"); + } else { + fprintf(stderr, + "MakeTiles failed for the depth buffer.\n"); + } + } + + return; +} + +static int I830DetectMemory(const DRIDriverContext *ctx, I830Rec *pI830) +{ + struct pci_device host_bridge; + uint32_t gmch_ctrl; + int memsize = 0; + int range; + + memset(&host_bridge, 0, sizeof(host_bridge)); + + pci_device_cfg_read_u32(&host_bridge, &gmch_ctrl, I830_GMCH_CTRL); + + /* We need to reduce the stolen size, by the GTT and the popup. + * The GTT varying according the the FbMapSize and the popup is 4KB */ + range = (ctx->shared.fbSize / (1024*1024)) + 4; + + if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) { + switch (gmch_ctrl & I830_GMCH_GMS_MASK) { + case I855_GMCH_GMS_STOLEN_1M: + memsize = MB(1) - KB(range); + break; + case I855_GMCH_GMS_STOLEN_4M: + memsize = MB(4) - KB(range); + break; + case I855_GMCH_GMS_STOLEN_8M: + memsize = MB(8) - KB(range); + break; + case I855_GMCH_GMS_STOLEN_16M: + memsize = MB(16) - KB(range); + break; + case I855_GMCH_GMS_STOLEN_32M: + memsize = MB(32) - KB(range); + break; + case I915G_GMCH_GMS_STOLEN_48M: + if (IS_I9XX(pI830)) + memsize = MB(48) - KB(range); + break; + case I915G_GMCH_GMS_STOLEN_64M: + if (IS_I9XX(pI830)) + memsize = MB(64) - KB(range); + break; + } + } else { + switch (gmch_ctrl & I830_GMCH_GMS_MASK) { + case I830_GMCH_GMS_STOLEN_512: + memsize = KB(512) - KB(range); + break; + case I830_GMCH_GMS_STOLEN_1024: + memsize = MB(1) - KB(range); + break; + case I830_GMCH_GMS_STOLEN_8192: + memsize = MB(8) - KB(range); + break; + case I830_GMCH_GMS_LOCAL: + memsize = 0; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Local memory found, but won't be used.\n"); + break; + } + } + if (memsize > 0) { + fprintf(stderr, + "detected %d kB stolen memory.\n", memsize / 1024); + } else { + fprintf(stderr, + "no video memory detected.\n"); + } + return memsize; +} + +static int AgpInit(const DRIDriverContext *ctx, I830Rec *info) +{ + unsigned long mode = 0x4; + + if (drmAgpAcquire(ctx->drmFD) < 0) { + fprintf(stderr, "[gart] AGP not available\n"); + return 0; + } + + if (drmAgpEnable(ctx->drmFD, mode) < 0) { + fprintf(stderr, "[gart] AGP not enabled\n"); + drmAgpRelease(ctx->drmFD); + return 0; + } + else + fprintf(stderr, "[gart] AGP enabled at %dx\n", ctx->agpmode); + + return 1; +} + +/* + * Allocate memory from the given pool. Grow the pool if needed and if + * possible. + */ +static unsigned long +AllocFromPool(const DRIDriverContext *ctx, I830Rec *pI830, + I830MemRange *result, I830MemPool *pool, + long size, unsigned long alignment, int flags) +{ + long needed, start, end; + + if (!result || !pool || !size) + return 0; + + /* Calculate how much space is needed. */ + if (alignment <= GTT_PAGE_SIZE) + needed = size; + else { + start = ROUND_TO(pool->Free.Start, alignment); + end = ROUND_TO(start + size, alignment); + needed = end - pool->Free.Start; + } + if (needed > pool->Free.Size) { + return 0; + } + + result->Start = ROUND_TO(pool->Free.Start, alignment); + pool->Free.Start += needed; + result->End = pool->Free.Start; + + pool->Free.Size = pool->Free.End - pool->Free.Start; + result->Size = result->End - result->Start; + result->Pool = pool; + result->Alignment = alignment; + return needed; +} + +static unsigned long AllocFromAGP(const DRIDriverContext *ctx, I830Rec *pI830, long size, unsigned long alignment, I830MemRange *result) +{ + unsigned long start, end; + unsigned long newApStart, newApEnd; + int ret; + if (!result || !size) + return 0; + + if (!alignment) + alignment = 4; + + start = ROUND_TO(pI830->MemoryAperture.Start, alignment); + end = ROUND_TO(start + size, alignment); + newApStart = end; + newApEnd = pI830->MemoryAperture.End; + + ret=drmAgpAlloc(ctx->drmFD, size, 0, &(result->Physical), (drm_handle_t *)&(result->Key)); + + if (ret) + { + fprintf(stderr,"drmAgpAlloc failed %d\n", ret); + return 0; + } + pI830->allocatedMemory += size; + pI830->MemoryAperture.Start = newApStart; + pI830->MemoryAperture.End = newApEnd; + pI830->MemoryAperture.Size = newApEnd - newApStart; + // pI830->FreeMemory -= size; + result->Start = start; + result->End = start + size; + result->Size = size; + result->Offset = start; + result->Alignment = alignment; + result->Pool = NULL; + + return size; +} + +unsigned long +I830AllocVidMem(const DRIDriverContext *ctx, I830Rec *pI830, I830MemRange *result, I830MemPool *pool, long size, unsigned long alignment, int flags) +{ + int ret; + + if (!result) + return 0; + + /* Make sure these are initialised. */ + result->Size = 0; + result->Key = -1; + + if (!size) { + return 0; + } + + if (pool->Free.Size < size) + return AllocFromAGP(ctx, pI830, size, alignment, result); + else + { + ret = AllocFromPool(ctx, pI830, result, pool, size, alignment, flags); + + if (ret==0) + return AllocFromAGP(ctx, pI830, size, alignment, result); + return ret; + } +} + +static Bool BindAgpRange(const DRIDriverContext *ctx, I830MemRange *mem) +{ + if (!mem) + return FALSE; + + if (mem->Key == -1) + return TRUE; + + return !drmAgpBind(ctx->drmFD, mem->Key, mem->Offset); +} + +/* simple memory allocation routines needed */ +/* put ring buffer in low memory */ +/* need to allocate front, back, depth buffers aligned correctly, + allocate ring buffer, +*/ + +/* */ +static Bool +I830AllocateMemory(const DRIDriverContext *ctx, I830Rec *pI830) +{ + unsigned long size, ret; + unsigned long lines, lineSize, align; + + /* allocate ring buffer */ + memset(pI830->LpRing, 0, sizeof(I830RingBuffer)); + pI830->LpRing->mem.Key = -1; + + size = PRIMARY_RINGBUFFER_SIZE; + + ret = I830AllocVidMem(ctx, pI830, &pI830->LpRing->mem, &pI830->StolenPool, size, 0x1000, 0); + + if (ret != size) + { + fprintf(stderr,"unable to allocate ring buffer %ld\n", ret); + return FALSE; + } + + pI830->LpRing->tail_mask = pI830->LpRing->mem.Size - 1; + + + /* allocate front buffer */ + memset(&(pI830->FrontBuffer), 0, sizeof(pI830->FrontBuffer)); + pI830->FrontBuffer.Key = -1; + pI830->FrontBuffer.Pitch = ctx->shared.virtualWidth; + + align = KB(512); + + lineSize = ctx->shared.virtualWidth * ctx->cpp; + lines = (ctx->shared.virtualHeight + 15) / 16 * 16; + size = lineSize * lines; + size = ROUND_TO_PAGE(size); + + align = GetBestTileAlignment(size); + + ret = I830AllocVidMem(ctx, pI830, &pI830->FrontBuffer, &pI830->StolenPool, size, align, 0); + if (ret < size) + { + fprintf(stderr,"unable to allocate front buffer %ld\n", ret); + return FALSE; + } + + memset(&(pI830->BackBuffer), 0, sizeof(pI830->BackBuffer)); + pI830->BackBuffer.Key = -1; + pI830->BackBuffer.Pitch = ctx->shared.virtualWidth; + + ret = I830AllocVidMem(ctx, pI830, &pI830->BackBuffer, &pI830->StolenPool, size, align, 0); + if (ret < size) + { + fprintf(stderr,"unable to allocate back buffer %ld\n", ret); + return FALSE; + } + + memset(&(pI830->DepthBuffer), 0, sizeof(pI830->DepthBuffer)); + pI830->DepthBuffer.Key = -1; + pI830->DepthBuffer.Pitch = ctx->shared.virtualWidth; + + ret = I830AllocVidMem(ctx, pI830, &pI830->DepthBuffer, &pI830->StolenPool, size, align, 0); + if (ret < size) + { + fprintf(stderr,"unable to allocate depth buffer %ld\n", ret); + return FALSE; + } + + memset(&(pI830->ContextMem), 0, sizeof(pI830->ContextMem)); + pI830->ContextMem.Key = -1; + size = KB(32); + + ret = I830AllocVidMem(ctx, pI830, &pI830->ContextMem, &pI830->StolenPool, size, align, 0); + if (ret < size) + { + fprintf(stderr,"unable to allocate context buffer %ld\n", ret); + return FALSE; + } + + memset(&(pI830->TexMem), 0, sizeof(pI830->TexMem)); + pI830->TexMem.Key = -1; + + size = 32768 * 1024; + ret = AllocFromAGP(ctx, pI830, size, align, &pI830->TexMem); + if (ret < size) + { + fprintf(stderr,"unable to allocate texture memory %ld\n", ret); + return FALSE; + } + + return TRUE; +} + +static Bool +I830BindMemory(const DRIDriverContext *ctx, I830Rec *pI830) +{ + if (!BindAgpRange(ctx, &pI830->LpRing->mem)) + return FALSE; + if (!BindAgpRange(ctx, &pI830->FrontBuffer)) + return FALSE; + if (!BindAgpRange(ctx, &pI830->BackBuffer)) + return FALSE; + if (!BindAgpRange(ctx, &pI830->DepthBuffer)) + return FALSE; + if (!BindAgpRange(ctx, &pI830->ContextMem)) + return FALSE; + if (!BindAgpRange(ctx, &pI830->TexMem)) + return FALSE; + + return TRUE; +} + +static Bool +I830CleanupDma(const DRIDriverContext *ctx) +{ + drmI830Init info; + + memset(&info, 0, sizeof(drmI830Init)); + info.func = I830_CLEANUP_DMA; + + if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT, + &info, sizeof(drmI830Init))) { + fprintf(stderr, "I830 Dma Cleanup Failed\n"); + return FALSE; + } + + return TRUE; +} + +static Bool +I830InitDma(const DRIDriverContext *ctx, I830Rec *pI830) +{ + I830RingBuffer *ring = pI830->LpRing; + drmI830Init info; + + memset(&info, 0, sizeof(drmI830Init)); + info.func = I830_INIT_DMA; + + info.ring_start = ring->mem.Start + pI830->LinearAddr; + info.ring_end = ring->mem.End + pI830->LinearAddr; + info.ring_size = ring->mem.Size; + + info.mmio_offset = (unsigned int)ctx->MMIOStart; + + info.sarea_priv_offset = sizeof(drm_sarea_t); + + info.front_offset = pI830->FrontBuffer.Start; + info.back_offset = pI830->BackBuffer.Start; + info.depth_offset = pI830->DepthBuffer.Start; + info.w = ctx->shared.virtualWidth; + info.h = ctx->shared.virtualHeight; + info.pitch = ctx->shared.virtualWidth; + info.back_pitch = pI830->BackBuffer.Pitch; + info.depth_pitch = pI830->DepthBuffer.Pitch; + info.cpp = ctx->cpp; + + if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT, + &info, sizeof(drmI830Init))) { + fprintf(stderr, + "I830 Dma Initialization Failed\n"); + return FALSE; + } + + return TRUE; +} + +static int I830CheckDRMVersion( const DRIDriverContext *ctx, + I830Rec *pI830 ) +{ + drmVersionPtr version; + + version = drmGetVersion(ctx->drmFD); + + if (version) { + int req_minor, req_patch; + + req_minor = 4; + req_patch = 0; + + if (version->version_major != 1 || + version->version_minor < req_minor || + (version->version_minor == req_minor && + version->version_patchlevel < req_patch)) { + /* Incompatible drm version */ + fprintf(stderr, + "[dri] I830DRIScreenInit failed because of a version " + "mismatch.\n" + "[dri] i915.o kernel module version is %d.%d.%d " + "but version 1.%d.%d or newer is needed.\n" + "[dri] Disabling DRI.\n", + version->version_major, + version->version_minor, + version->version_patchlevel, + req_minor, + req_patch); + drmFreeVersion(version); + return 0; + } + + pI830->drmMinor = version->version_minor; + drmFreeVersion(version); + } + return 1; +} + +static void +I830SetRingRegs(const DRIDriverContext *ctx, I830Rec *pI830) +{ + unsigned int itemp; + unsigned char *MMIO = ctx->MMIOAddress; + + OUTREG(LP_RING + RING_LEN, 0); + OUTREG(LP_RING + RING_TAIL, 0); + OUTREG(LP_RING + RING_HEAD, 0); + + if ((long)(pI830->LpRing->mem.Start & I830_RING_START_MASK) != + pI830->LpRing->mem.Start) { + fprintf(stderr, + "I830SetRingRegs: Ring buffer start (%lx) violates its " + "mask (%x)\n", pI830->LpRing->mem.Start, I830_RING_START_MASK); + } + /* Don't care about the old value. Reserved bits must be zero anyway. */ + itemp = pI830->LpRing->mem.Start & I830_RING_START_MASK; + OUTREG(LP_RING + RING_START, itemp); + + if (((pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES) != + pI830->LpRing->mem.Size - 4096) { + fprintf(stderr, + "I830SetRingRegs: Ring buffer size - 4096 (%lx) violates its " + "mask (%x)\n", pI830->LpRing->mem.Size - 4096, + I830_RING_NR_PAGES); + } + /* Don't care about the old value. Reserved bits must be zero anyway. */ + itemp = (pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES; + itemp |= (RING_NO_REPORT | RING_VALID); + OUTREG(LP_RING + RING_LEN, itemp); + + pI830->LpRing->head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK; + pI830->LpRing->tail = INREG(LP_RING + RING_TAIL); + pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8); + if (pI830->LpRing->space < 0) + pI830->LpRing->space += pI830->LpRing->mem.Size; + + SetFenceRegs(ctx, pI830); + + /* RESET THE DISPLAY PIPE TO POINT TO THE FRONTBUFFER - hacky + hacky hacky */ + OUTREG(DSPABASE, pI830->FrontBuffer.Start + pI830->LinearAddr); + +} + +static Bool +I830SetParam(const DRIDriverContext *ctx, int param, int value) +{ + drmI830SetParam sp; + + memset(&sp, 0, sizeof(sp)); + sp.param = param; + sp.value = value; + + if (drmCommandWrite(ctx->drmFD, DRM_I830_SETPARAM, &sp, sizeof(sp))) { + fprintf(stderr, "I830 SetParam Failed\n"); + return FALSE; + } + + return TRUE; +} + +static Bool +I830DRIMapScreenRegions(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) +{ + fprintf(stderr, + "[drm] Mapping front buffer\n"); + + if (drmAddMap(ctx->drmFD, + (drm_handle_t)(sarea->front_offset + pI830->LinearAddr), + sarea->front_size, + DRM_FRAME_BUFFER, /*DRM_AGP,*/ + 0, + &sarea->front_handle) < 0) { + fprintf(stderr, + "[drm] drmAddMap(front_handle) failed. Disabling DRI\n"); + return FALSE; + } + ctx->shared.hFrameBuffer = sarea->front_handle; + ctx->shared.fbSize = sarea->front_size; + fprintf(stderr, "[drm] Front Buffer = 0x%08x\n", + sarea->front_handle); + + if (drmAddMap(ctx->drmFD, + (drm_handle_t)(sarea->back_offset), + sarea->back_size, DRM_AGP, 0, + &sarea->back_handle) < 0) { + fprintf(stderr, + "[drm] drmAddMap(back_handle) failed. Disabling DRI\n"); + return FALSE; + } + fprintf(stderr, "[drm] Back Buffer = 0x%08x\n", + sarea->back_handle); + + if (drmAddMap(ctx->drmFD, + (drm_handle_t)sarea->depth_offset, + sarea->depth_size, DRM_AGP, 0, + &sarea->depth_handle) < 0) { + fprintf(stderr, + "[drm] drmAddMap(depth_handle) failed. Disabling DRI\n"); + return FALSE; + } + fprintf(stderr, "[drm] Depth Buffer = 0x%08x\n", + sarea->depth_handle); + + if (drmAddMap(ctx->drmFD, + (drm_handle_t)sarea->tex_offset, + sarea->tex_size, DRM_AGP, 0, + &sarea->tex_handle) < 0) { + fprintf(stderr, + "[drm] drmAddMap(tex_handle) failed. Disabling DRI\n"); + return FALSE; + } + fprintf(stderr, "[drm] textures = 0x%08x\n", + sarea->tex_handle); + + return TRUE; +} + + +static void +I830DRIUnmapScreenRegions(const DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) +{ +#if 1 + if (sarea->front_handle) { + drmRmMap(ctx->drmFD, sarea->front_handle); + sarea->front_handle = 0; + } +#endif + if (sarea->back_handle) { + drmRmMap(ctx->drmFD, sarea->back_handle); + sarea->back_handle = 0; + } + if (sarea->depth_handle) { + drmRmMap(ctx->drmFD, sarea->depth_handle); + sarea->depth_handle = 0; + } + if (sarea->tex_handle) { + drmRmMap(ctx->drmFD, sarea->tex_handle); + sarea->tex_handle = 0; + } +} + +static void +I830InitTextureHeap(const DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) +{ + /* Start up the simple memory manager for agp space */ + drmI830MemInitHeap drmHeap; + drmHeap.region = I830_MEM_REGION_AGP; + drmHeap.start = 0; + drmHeap.size = sarea->tex_size; + + if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT_HEAP, + &drmHeap, sizeof(drmHeap))) { + fprintf(stderr, + "[drm] Failed to initialized agp heap manager\n"); + } else { + fprintf(stderr, + "[drm] Initialized kernel agp heap manager, %d\n", + sarea->tex_size); + + I830SetParam(ctx, I830_SETPARAM_TEX_LRU_LOG_GRANULARITY, + sarea->log_tex_granularity); + } +} + +static Bool +I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) +{ + if (drmAddMap(ctx->drmFD, + (drm_handle_t)pI830->LpRing->mem.Start, + pI830->LpRing->mem.Size, DRM_AGP, 0, + &pI830->ring_map) < 0) { + fprintf(stderr, + "[drm] drmAddMap(ring_map) failed. Disabling DRI\n"); + return FALSE; + } + fprintf(stderr, "[drm] ring buffer = 0x%08x\n", + pI830->ring_map); + + if (I830InitDma(ctx, pI830) == FALSE) { + return FALSE; + } + + /* init to zero to be safe */ + + I830DRIMapScreenRegions(ctx, pI830, sarea); + I830InitTextureHeap(ctx, pI830, sarea); + + if (ctx->pciDevice != PCI_CHIP_845_G && + ctx->pciDevice != PCI_CHIP_I830_M) { + I830SetParam(ctx, I830_SETPARAM_USE_MI_BATCHBUFFER_START, 1 ); + } + + /* Okay now initialize the dma engine */ + { + pI830->irq = drmGetInterruptFromBusID(ctx->drmFD, + ctx->pciBus, + ctx->pciDevice, + ctx->pciFunc); + + if (drmCtlInstHandler(ctx->drmFD, pI830->irq)) { + fprintf(stderr, + "[drm] failure adding irq handler\n"); + pI830->irq = 0; + return FALSE; + } + else + fprintf(stderr, + "[drm] dma control initialized, using IRQ %d\n", + pI830->irq); + } + + fprintf(stderr, "[dri] visual configs initialized\n"); + + return TRUE; +} + +static Bool +I830ClearScreen(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) +{ + /* need to drmMap front and back buffers and zero them */ + drmAddress map_addr; + int ret; + + ret = drmMap(ctx->drmFD, + sarea->front_handle, + sarea->front_size, + &map_addr); + + if (ret) + { + fprintf(stderr, "Unable to map front buffer\n"); + return FALSE; + } + + drimemsetio((char *)map_addr, + 0, + sarea->front_size); + drmUnmap(map_addr, sarea->front_size); + + + ret = drmMap(ctx->drmFD, + sarea->back_handle, + sarea->back_size, + &map_addr); + + if (ret) + { + fprintf(stderr, "Unable to map back buffer\n"); + return FALSE; + } + + drimemsetio((char *)map_addr, + 0, + sarea->back_size); + drmUnmap(map_addr, sarea->back_size); + + return TRUE; +} + +static Bool +I830ScreenInit(DRIDriverContext *ctx, I830Rec *pI830) + +{ + I830DRIPtr pI830DRI; + drmI830Sarea *pSAREAPriv; + int err; + + drm_page_size = getpagesize(); + + pI830->registerSize = ctx->MMIOSize; + /* This is a hack for now. We have to have more than a 4k page here + * because of the size of the state. However, the state should be + * in a per-context mapping. This will be added in the Mesa 3.5 port + * of the I830 driver. + */ + ctx->shared.SAREASize = SAREA_MAX; + + /* Note that drmOpen will try to load the kernel module, if needed. */ + ctx->drmFD = drmOpen("i915", NULL ); + if (ctx->drmFD < 0) { + fprintf(stderr, "[drm] drmOpen failed\n"); + return 0; + } + + if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) { + fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n", + ctx->drmFD, ctx->pciBusID, strerror(-err)); + return 0; + } + + if (drmAddMap( ctx->drmFD, + 0, + ctx->shared.SAREASize, + DRM_SHM, + DRM_CONTAINS_LOCK, + &ctx->shared.hSAREA) < 0) + { + fprintf(stderr, "[drm] drmAddMap failed\n"); + return 0; + } + + fprintf(stderr, "[drm] added %d byte SAREA at 0x%08x\n", + ctx->shared.SAREASize, ctx->shared.hSAREA); + + if (drmMap( ctx->drmFD, + ctx->shared.hSAREA, + ctx->shared.SAREASize, + (drmAddressPtr)(&ctx->pSAREA)) < 0) + { + fprintf(stderr, "[drm] drmMap failed\n"); + return 0; + + } + + memset(ctx->pSAREA, 0, ctx->shared.SAREASize); + fprintf(stderr, "[drm] mapped SAREA 0x%08x to %p, size %d\n", + ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize); + + + if (drmAddMap(ctx->drmFD, + ctx->MMIOStart, + ctx->MMIOSize, + DRM_REGISTERS, + DRM_READ_ONLY, + &pI830->registerHandle) < 0) { + fprintf(stderr, "[drm] drmAddMap mmio failed\n"); + return 0; + } + fprintf(stderr, + "[drm] register handle = 0x%08x\n", pI830->registerHandle); + + + if (!I830CheckDRMVersion(ctx, pI830)) { + return FALSE; + } + + /* Create a 'server' context so we can grab the lock for + * initialization ioctls. + */ + if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) { + fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); + return 0; + } + + DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0); + + /* Initialize the SAREA private data structure */ + pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) + + sizeof(drm_sarea_t)); + memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); + + pI830->StolenMemory.Size = I830DetectMemory(ctx, pI830); + pI830->StolenMemory.Start = 0; + pI830->StolenMemory.End = pI830->StolenMemory.Size; + + pI830->MemoryAperture.Start = pI830->StolenMemory.End; + pI830->MemoryAperture.End = KB(40000); + pI830->MemoryAperture.Size = pI830->MemoryAperture.End - pI830->MemoryAperture.Start; + + pI830->StolenPool.Fixed = pI830->StolenMemory; + pI830->StolenPool.Total = pI830->StolenMemory; + pI830->StolenPool.Free = pI830->StolenPool.Total; + pI830->FreeMemory = pI830->StolenPool.Total.Size; + + if (!AgpInit(ctx, pI830)) + return FALSE; + + if (I830AllocateMemory(ctx, pI830) == FALSE) + { + return FALSE; + } + + if (I830BindMemory(ctx, pI830) == FALSE) + { + return FALSE; + } + + pSAREAPriv->front_offset = pI830->FrontBuffer.Start; + pSAREAPriv->front_size = pI830->FrontBuffer.Size; + pSAREAPriv->width = ctx->shared.virtualWidth; + pSAREAPriv->height = ctx->shared.virtualHeight; + pSAREAPriv->pitch = ctx->shared.virtualWidth; + pSAREAPriv->virtualX = ctx->shared.virtualWidth; + pSAREAPriv->virtualY = ctx->shared.virtualHeight; + pSAREAPriv->back_offset = pI830->BackBuffer.Start; + pSAREAPriv->back_size = pI830->BackBuffer.Size; + pSAREAPriv->depth_offset = pI830->DepthBuffer.Start; + pSAREAPriv->depth_size = pI830->DepthBuffer.Size; + pSAREAPriv->tex_offset = pI830->TexMem.Start; + pSAREAPriv->tex_size = pI830->TexMem.Size; + pSAREAPriv->log_tex_granularity = pI830->TexGranularity; + + ctx->driverClientMsg = malloc(sizeof(I830DRIRec)); + ctx->driverClientMsgSize = sizeof(I830DRIRec); + pI830DRI = (I830DRIPtr)ctx->driverClientMsg; + pI830DRI->deviceID = pI830->Chipset; + pI830DRI->regsSize = I830_REG_SIZE; + pI830DRI->width = ctx->shared.virtualWidth; + pI830DRI->height = ctx->shared.virtualHeight; + pI830DRI->mem = ctx->shared.fbSize; + pI830DRI->cpp = ctx->cpp; + pI830DRI->backOffset = pI830->BackBuffer.Start; + pI830DRI->backPitch = pI830->BackBuffer.Pitch; + + pI830DRI->depthOffset = pI830->DepthBuffer.Start; + pI830DRI->depthPitch = pI830->DepthBuffer.Pitch; + + pI830DRI->fbOffset = pI830->FrontBuffer.Start; + pI830DRI->fbStride = pI830->FrontBuffer.Pitch; + + pI830DRI->bitsPerPixel = ctx->bpp; + pI830DRI->sarea_priv_offset = sizeof(drm_sarea_t); + + err = I830DRIDoMappings(ctx, pI830, pSAREAPriv); + if (err == FALSE) + return FALSE; + + I830SetupMemoryTiling(ctx, pI830); + + /* Quick hack to clear the front & back buffers. Could also use + * the clear ioctl to do this, but would need to setup hw state + * first. + */ + I830ClearScreen(ctx, pI830, pSAREAPriv); + + I830SetRingRegs(ctx, pI830); + + return TRUE; +} + + +/** + * \brief Validate the fbdev mode. + * + * \param ctx display handle. + * + * \return one on success, or zero on failure. + * + * Saves some registers and returns 1. + * + * \sa radeonValidateMode(). + */ +static int i830ValidateMode( const DRIDriverContext *ctx ) +{ + return 1; +} + +/** + * \brief Examine mode returned by fbdev. + * + * \param ctx display handle. + * + * \return one on success, or zero on failure. + * + * Restores registers that fbdev has clobbered and returns 1. + * + * \sa i810ValidateMode(). + */ +static int i830PostValidateMode( const DRIDriverContext *ctx ) +{ + I830Rec *pI830 = ctx->driverPrivate; + + I830SetRingRegs(ctx, pI830); + return 1; +} + + +/** + * \brief Initialize the framebuffer device mode + * + * \param ctx display handle. + * + * \return one on success, or zero on failure. + * + * Fills in \p info with some default values and some information from \p ctx + * and then calls I810ScreenInit() for the screen initialization. + * + * Before exiting clears the framebuffer memory accessing it directly. + */ +static int i830InitFBDev( DRIDriverContext *ctx ) +{ + I830Rec *pI830 = calloc(1, sizeof(I830Rec)); + int i; + + { + int dummy = ctx->shared.virtualWidth; + + switch (ctx->bpp / 8) { + case 1: dummy = (ctx->shared.virtualWidth + 127) & ~127; break; + case 2: dummy = (ctx->shared.virtualWidth + 31) & ~31; break; + case 3: + case 4: dummy = (ctx->shared.virtualWidth + 15) & ~15; break; + } + + ctx->shared.virtualWidth = dummy; + ctx->shared.Width = ctx->shared.virtualWidth; + } + + + for (i = 0; pitches[i] != 0; i++) { + if (pitches[i] >= ctx->shared.virtualWidth) { + ctx->shared.virtualWidth = pitches[i]; + break; + } + } + + ctx->driverPrivate = (void *)pI830; + + pI830->LpRing = calloc(1, sizeof(I830RingBuffer)); + pI830->Chipset = ctx->chipset; + pI830->LinearAddr = ctx->FBStart; + + if (!I830ScreenInit( ctx, pI830 )) + return 0; + + + return 1; +} + + +/** + * \brief The screen is being closed, so clean up any state and free any + * resources used by the DRI. + * + * \param ctx display handle. + * + * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver + * private data. + */ +static void i830HaltFBDev( DRIDriverContext *ctx ) +{ + drmI830Sarea *pSAREAPriv; + I830Rec *pI830 = ctx->driverPrivate; + + if (pI830->irq) { + drmCtlUninstHandler(ctx->drmFD); + pI830->irq = 0; } + + I830CleanupDma(ctx); + + pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) + + sizeof(drm_sarea_t)); + + I830DRIUnmapScreenRegions(ctx, pI830, pSAREAPriv); + drmUnmap( ctx->pSAREA, ctx->shared.SAREASize ); + drmClose(ctx->drmFD); + + if (ctx->driverPrivate) { + free(ctx->driverPrivate); + ctx->driverPrivate = 0; + } +} + + +extern void i810NotifyFocus( int ); + +/** + * \brief Exported driver interface for Mini GLX. + * + * \sa DRIDriverRec. + */ +const struct DRIDriverRec __driDriver = { + i830ValidateMode, + i830PostValidateMode, + i830InitFBDev, + i830HaltFBDev, + NULL,//I830EngineShutdown, + NULL, //I830EngineRestore, +#ifndef _EMBEDDED + 0, +#else + i810NotifyFocus, +#endif +}; diff --git a/src/mesa/drivers/dri/i965/intel_blit.c b/src/mesa/drivers/dri/i965/intel_blit.c index e501f5e660..0974f1f80a 100644 --- a/src/mesa/drivers/dri/i965/intel_blit.c +++ b/src/mesa/drivers/dri/i965/intel_blit.c @@ -322,14 +322,14 @@ void intelEmitCopyBlit( struct intel_context *intel, -void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, - GLint cx1, GLint cy1, GLint cw, GLint ch) +void intelClearWithBlit(GLcontext *ctx, GLbitfield flags) { struct intel_context *intel = intel_context( ctx ); intelScreenPrivate *intelScreen = intel->intelScreen; GLuint clear_depth, clear_color; - GLint cx, cy; + GLint cx, cy, cw, ch; GLint cpp = intelScreen->cpp; + GLboolean all; GLint i; struct intel_region *front = intel->front_region; struct intel_region *back = intel->back_region; @@ -376,21 +376,16 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, intelFlush( &intel->ctx ); LOCK_HARDWARE( intel ); { - /* Refresh the cx/y/w/h values as they may have been invalidated - * by a new window position or size picked up when we did - * LOCK_HARDWARE above. The values passed by mesa are not - * reliable. - */ - { - cx = ctx->DrawBuffer->_Xmin; - cy = ctx->DrawBuffer->_Ymin; - ch = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; - cw = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; - } + /* get clear bounds after locking */ + cx = ctx->DrawBuffer->_Xmin; + cy = ctx->DrawBuffer->_Ymin; + ch = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; + cw = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; + all = (cw == ctx->DrawBuffer->Width && ch == ctx->DrawBuffer->Height); /* flip top to bottom */ - cy = intel->driDrawable->h-cy1-ch; - cx = cx1 + intel->drawX; + cy = intel->driDrawable->h - cy - ch; + cx = cx + intel->drawX; cy += intel->drawY; /* adjust for page flipping */ diff --git a/src/mesa/drivers/dri/i965/intel_blit.h b/src/mesa/drivers/dri/i965/intel_blit.h index 71ce830778..b15fb1c2b7 100644 --- a/src/mesa/drivers/dri/i965/intel_blit.h +++ b/src/mesa/drivers/dri/i965/intel_blit.h @@ -35,8 +35,7 @@ struct buffer; extern void intelCopyBuffer( const __DRIdrawablePrivate *dpriv, const drm_clip_rect_t *rect ); -extern void intelClearWithBlit(GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint cx1, GLint cy1, GLint cw, GLint ch); +extern void intelClearWithBlit(GLcontext *ctx, GLbitfield mask); extern void intelEmitCopyBlit( struct intel_context *intel, GLuint cpp, diff --git a/src/mesa/drivers/dri/i965/intel_buffers.c b/src/mesa/drivers/dri/i965/intel_buffers.c index dc5b9c0bc4..d155c039d7 100644 --- a/src/mesa/drivers/dri/i965/intel_buffers.c +++ b/src/mesa/drivers/dri/i965/intel_buffers.c @@ -224,12 +224,11 @@ void intelWindowMoved( struct intel_context *intel ) * machine independent. Maybe we'll get there one day. */ static void intelClearWithTris(struct intel_context *intel, - GLbitfield mask, - GLboolean all, - GLint cx, GLint cy, - GLint cw, GLint ch) + GLbitfield mask) { + GLcontext *ctx = &intel->ctx; drm_clip_rect_t clear; + GLint cx, cy, cw, ch; if (INTEL_DEBUG & DEBUG_DRI) _mesa_printf("%s %x\n", __FUNCTION__, mask); @@ -238,18 +237,11 @@ static void intelClearWithTris(struct intel_context *intel, intel->vtbl.install_meta_state(intel); - /* Refresh the cx/y/w/h values as they may have been invalidated - * by a new window position or size picked up when we did - * LOCK_HARDWARE above. The values passed by mesa are not - * reliable. - */ - { - GLcontext *ctx = &intel->ctx; - cx = ctx->DrawBuffer->_Xmin; - cy = ctx->DrawBuffer->_Ymin; - ch = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; - cw = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; - } + /* Get clear bounds after locking */ + cx = ctx->DrawBuffer->_Xmin; + cy = ctx->DrawBuffer->_Ymin; + cw = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; + ch = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; clear.x1 = cx; clear.y1 = cy; @@ -327,11 +319,7 @@ static void intelClearWithTris(struct intel_context *intel, -static void intelClear(GLcontext *ctx, - GLbitfield mask, - GLboolean all, - GLint cx, GLint cy, - GLint cw, GLint ch) +static void intelClear(GLcontext *ctx, GLbitfield mask) { struct intel_context *intel = intel_context( ctx ); const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); @@ -340,8 +328,7 @@ static void intelClear(GLcontext *ctx, GLbitfield swrast_mask = 0; if (INTEL_DEBUG & DEBUG_DRI) - fprintf(stderr, "%s %x all %d dims %d,%d %dx%d\n", __FUNCTION__, - mask, all, cx, cy, cw, ch); + fprintf(stderr, "%s %x\n", __FUNCTION__, mask); if (mask & BUFFER_BIT_FRONT_LEFT) { @@ -392,13 +379,13 @@ static void intelClear(GLcontext *ctx, intelFlush( ctx ); if (blit_mask) - intelClearWithBlit( ctx, blit_mask, all, cx, cy, cw, ch ); + intelClearWithBlit( ctx, blit_mask ); if (tri_mask) - intelClearWithTris( intel, tri_mask, all, cx, cy, cw, ch); + intelClearWithTris( intel, tri_mask ); if (swrast_mask) - _swrast_Clear( ctx, swrast_mask, all, cx, cy, cw, ch ); + _swrast_Clear( ctx, swrast_mask ); } diff --git a/src/mesa/drivers/dri/mach64/mach64_ioctl.c b/src/mesa/drivers/dri/mach64/mach64_ioctl.c index 30a45ad034..36e7d3c5d3 100644 --- a/src/mesa/drivers/dri/mach64/mach64_ioctl.c +++ b/src/mesa/drivers/dri/mach64/mach64_ioctl.c @@ -665,8 +665,7 @@ void mach64PerformanceBoxesLocked( mach64ContextPtr mmesa ) * Buffer clear */ -static void mach64DDClear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, - GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo ) +static void mach64DDClear( GLcontext *ctx, GLbitfield mask ) { mach64ContextPtr mmesa = MACH64_CONTEXT( ctx ); __DRIdrawablePrivate *dPriv = mmesa->driDrawable; @@ -713,7 +712,7 @@ static void mach64DDClear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, } if ( mask ) - _swrast_Clear( ctx, mask, 0, 0, 0, 0, 0 ); + _swrast_Clear( ctx, mask ); if ( !flags ) return; diff --git a/src/mesa/drivers/dri/mga/mga_xmesa.c b/src/mesa/drivers/dri/mga/mga_xmesa.c index 32cfbc6a1c..f024f73eb6 100644 --- a/src/mesa/drivers/dri/mga/mga_xmesa.c +++ b/src/mesa/drivers/dri/mga/mga_xmesa.c @@ -883,7 +883,6 @@ mgaMakeCurrent(__DRIcontextPrivate *driContextPriv, mmesa->driDrawable = driDrawPriv; mmesa->dirty = ~0; mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK); - mmesa->mesa_drawable = driDrawPriv; } mmesa->driReadable = driReadPriv; diff --git a/src/mesa/drivers/dri/mga/mgacontext.h b/src/mesa/drivers/dri/mga/mgacontext.h index 81348b6c7f..2124006ade 100644 --- a/src/mesa/drivers/dri/mga/mgacontext.h +++ b/src/mesa/drivers/dri/mga/mgacontext.h @@ -303,13 +303,6 @@ struct mga_context_t { __DRIdrawablePrivate *driDrawable; __DRIdrawablePrivate *driReadable; - /** - * Drawable used by Mesa for software fallbacks for reading and - * writing. It is set by Mesa's \c SetBuffer callback, and will always be - * either \c mga_context_t::driDrawable or \c mga_context_t::driReadable. - */ - __DRIdrawablePrivate *mesa_drawable; - __DRIscreenPrivate *driScreen; struct mga_screen_private_s *mgaScreen; drm_mga_sarea_t *sarea; diff --git a/src/mesa/drivers/dri/mga/mgadd.c b/src/mesa/drivers/dri/mga/mgadd.c index faf46f3139..b1d5e0c48f 100644 --- a/src/mesa/drivers/dri/mga/mgadd.c +++ b/src/mesa/drivers/dri/mga/mgadd.c @@ -41,7 +41,7 @@ #include "mga_xmesa.h" #include "utils.h" -#define DRIVER_DATE "20050609" +#define DRIVER_DATE "20061030" /*************************************** @@ -74,24 +74,7 @@ static const GLubyte *mgaGetString( GLcontext *ctx, GLenum name ) } -static void mgaBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height) -{ - GET_CURRENT_CONTEXT(ctx); - mgaContextPtr mmesa = MGA_CONTEXT(ctx); - - /* Need to lock to make sure the driDrawable is uptodate. This - * information is used to resize Mesa's software buffers, so it has - * to be correct. - */ - LOCK_HARDWARE( mmesa ); - *width = mmesa->driDrawable->w; - *height = mmesa->driDrawable->h; - UNLOCK_HARDWARE( mmesa ); -} - - void mgaInitDriverFuncs( struct dd_function_table *functions ) { - functions->GetBufferSize = mgaBufferSize; functions->GetString = mgaGetString; } diff --git a/src/mesa/drivers/dri/mga/mgaioctl.c b/src/mesa/drivers/dri/mga/mgaioctl.c index c9fa9d1294..f8587fc541 100644 --- a/src/mesa/drivers/dri/mga/mgaioctl.c +++ b/src/mesa/drivers/dri/mga/mgaioctl.c @@ -204,8 +204,7 @@ drmBufPtr mga_get_buffer_ioctl( mgaContextPtr mmesa ) static void -mgaClear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, - GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo ) +mgaClear( GLcontext *ctx, GLbitfield mask ) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = mmesa->driDrawable; @@ -334,7 +333,7 @@ mgaClear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, } if (mask) - _swrast_Clear( ctx, mask, 0, 0, 0, 0, 0 ); + _swrast_Clear( ctx, mask ); } diff --git a/src/mesa/drivers/dri/mga/mgaspan.c b/src/mesa/drivers/dri/mga/mgaspan.c index dbc7fc884c..05dcbb8526 100644 --- a/src/mesa/drivers/dri/mga/mgaspan.c +++ b/src/mesa/drivers/dri/mga/mgaspan.c @@ -36,9 +36,9 @@ #define LOCAL_VARS \ mgaContextPtr mmesa = MGA_CONTEXT(ctx); \ - __DRIdrawablePrivate *dPriv = mmesa->mesa_drawable; \ __DRIscreenPrivate *sPriv = mmesa->driScreen; \ driRenderbuffer *drb = (driRenderbuffer *) rb; \ + const __DRIdrawablePrivate *dPriv = drb->dPriv; \ GLuint pitch = drb->pitch; \ GLuint height = dPriv->h; \ char *buf = (char *)(sPriv->pFB + \ @@ -52,9 +52,9 @@ #define LOCAL_DEPTH_VARS \ mgaContextPtr mmesa = MGA_CONTEXT(ctx); \ - __DRIdrawablePrivate *dPriv = mmesa->mesa_drawable; \ __DRIscreenPrivate *sPriv = mmesa->driScreen; \ driRenderbuffer *drb = (driRenderbuffer *) rb; \ + const __DRIdrawablePrivate *dPriv = drb->dPriv; \ GLuint pitch = drb->pitch; \ GLuint height = dPriv->h; \ char *buf = (char *)(sPriv->pFB + \ diff --git a/src/mesa/drivers/dri/mga/mgastate.c b/src/mesa/drivers/dri/mga/mgastate.c index 69f85d62a5..f7e07c330a 100644 --- a/src/mesa/drivers/dri/mga/mgastate.c +++ b/src/mesa/drivers/dri/mga/mgastate.c @@ -744,32 +744,12 @@ static void mgaDDLogicOp( GLcontext *ctx, GLenum opcode ) } -static void mgaXMesaSetFrontClipRects( mgaContextPtr mmesa ) +static void mga_set_cliprects(mgaContextPtr mmesa) { __DRIdrawablePrivate *driDrawable = mmesa->driDrawable; - if (driDrawable->numClipRects == 0) { - static drm_clip_rect_t zeroareacliprect = {0,0,0,0}; - mmesa->numClipRects = 1; - mmesa->pClipRects = &zeroareacliprect; - } else { - mmesa->numClipRects = driDrawable->numClipRects; - mmesa->pClipRects = driDrawable->pClipRects; - } - mmesa->drawX = driDrawable->x; - mmesa->drawY = driDrawable->y; - - mmesa->setup.dstorg = mmesa->drawOffset; - mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_CLIPRECTS; -} - - -static void mgaXMesaSetBackClipRects( mgaContextPtr mmesa ) -{ - __DRIdrawablePrivate *driDrawable = mmesa->driDrawable; - - if (driDrawable->numBackClipRects == 0) - { + if ((mmesa->draw_buffer != MGA_FRONT) + || (driDrawable->numBackClipRects == 0)) { if (driDrawable->numClipRects == 0) { static drm_clip_rect_t zeroareacliprect = {0,0,0,0}; mmesa->numClipRects = 1; @@ -794,25 +774,25 @@ static void mgaXMesaSetBackClipRects( mgaContextPtr mmesa ) void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers ) { - __DRIdrawablePrivate *driDrawable = mmesa->driDrawable; + __DRIdrawablePrivate *const driDrawable = mmesa->driDrawable; + __DRIdrawablePrivate *const driReadable = mmesa->driReadable; drm_mga_sarea_t *sarea = mmesa->sarea; - DRI_VALIDATE_DRAWABLE_INFO(mmesa->driScreen, driDrawable); mmesa->dirty_cliprects = 0; - if (mmesa->draw_buffer == MGA_FRONT) - mgaXMesaSetFrontClipRects( mmesa ); - else - mgaXMesaSetBackClipRects( mmesa ); + driUpdateFramebufferSize(mmesa->glCtx, driDrawable); + if (driDrawable != driReadable) { + driUpdateFramebufferSize(mmesa->glCtx, driReadable); + } + + mga_set_cliprects(mmesa); sarea->req_drawable = driDrawable->draw; sarea->req_draw_buffer = mmesa->draw_buffer; mgaUpdateClipping( mmesa->glCtx ); mgaCalcViewport( mmesa->glCtx ); - - mmesa->dirty |= MGA_UPLOAD_CLIPRECTS; } @@ -828,23 +808,21 @@ static void mgaDDDrawBuffer(GLcontext *ctx, GLenum mode ) switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0] ) { case BUFFER_BIT_FRONT_LEFT: mmesa->setup.dstorg = mmesa->mgaScreen->frontOffset; - mmesa->dirty |= MGA_UPLOAD_CONTEXT; mmesa->draw_buffer = MGA_FRONT; - mgaXMesaSetFrontClipRects( mmesa ); - FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE ); break; case BUFFER_BIT_BACK_LEFT: mmesa->setup.dstorg = mmesa->mgaScreen->backOffset; mmesa->draw_buffer = MGA_BACK; - mmesa->dirty |= MGA_UPLOAD_CONTEXT; - mgaXMesaSetBackClipRects( mmesa ); - FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE ); break; default: /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */ FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_TRUE ); return; } + + mmesa->dirty |= MGA_UPLOAD_CONTEXT; + mga_set_cliprects(mmesa); + FALLBACK(ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE); } diff --git a/src/mesa/drivers/dri/r128/r128_ioctl.c b/src/mesa/drivers/dri/r128/r128_ioctl.c index 7dbb5e5dda..b0dba7d04e 100644 --- a/src/mesa/drivers/dri/r128/r128_ioctl.c +++ b/src/mesa/drivers/dri/r128/r128_ioctl.c @@ -399,8 +399,7 @@ void r128PageFlip( const __DRIdrawablePrivate *dPriv ) * Buffer clear */ -static void r128Clear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, - GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo ) +static void r128Clear( GLcontext *ctx, GLbitfield mask ) { r128ContextPtr rmesa = R128_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = rmesa->driDrawable; @@ -541,7 +540,7 @@ static void r128Clear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, } if ( mask ) - _swrast_Clear( ctx, mask, 0, 0, 0, 0, 0 ); + _swrast_Clear( ctx, mask ); } diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.c b/src/mesa/drivers/dri/r200/r200_ioctl.c index efa0b64ed2..463bd64415 100644 --- a/src/mesa/drivers/dri/r200/r200_ioctl.c +++ b/src/mesa/drivers/dri/r200/r200_ioctl.c @@ -605,8 +605,7 @@ void r200PageFlip( const __DRIdrawablePrivate *dPriv ) /* ================================================================ * Buffer clear */ -static void r200Clear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, - GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo ) +static void r200Clear( GLcontext *ctx, GLbitfield mask ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; @@ -653,7 +652,7 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, if ( mask ) { if (R200_DEBUG & DEBUG_FALLBACKS) fprintf(stderr, "%s: swrast clear, mask: %x\n", __FUNCTION__, mask); - _swrast_Clear( ctx, mask, 0, 0, 0, 0, 0 ); + _swrast_Clear( ctx, mask ); } if ( !flags ) diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c index 2d947dea3a..91ec4f855c 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog.c @@ -82,7 +82,8 @@ static const struct { { "LG2", 1, R300_FPI0_OUTC_REPL_ALPHA, R300_FPI2_OUTA_LG2 }, { "RCP", 1, R300_FPI0_OUTC_REPL_ALPHA, R300_FPI2_OUTA_RCP }, { "RSQ", 1, R300_FPI0_OUTC_REPL_ALPHA, R300_FPI2_OUTA_RSQ }, - { "REPL_ALPHA", 1, R300_FPI0_OUTC_REPL_ALPHA, PFS_INVAL } + { "REPL_ALPHA", 1, R300_FPI0_OUTC_REPL_ALPHA, PFS_INVAL }, + { "CMPH", 3, R300_FPI0_OUTC_CMPH, PFS_INVAL }, }; #define MAKE_SWZ3(x, y, z) (MAKE_SWIZZLE4(SWIZZLE_##x, \ @@ -180,7 +181,7 @@ static const pfs_reg_t undef = { valid: GL_FALSE }; -/* constant zero source */ +/* constant one source */ static const pfs_reg_t pfs_one = { type: REG_TYPE_CONST, index: 0, @@ -189,7 +190,16 @@ static const pfs_reg_t pfs_one = { valid: GL_TRUE }; -/* constant one source */ +/* constant half source */ +static const pfs_reg_t pfs_half = { + type: REG_TYPE_CONST, + index: 0, + v_swz: SWIZZLE_HHH, + s_swz: SWIZZLE_HALF, + valid: GL_TRUE +}; + +/* constant zero source */ static const pfs_reg_t pfs_zero = { type: REG_TYPE_CONST, index: 0, @@ -319,7 +329,6 @@ static pfs_reg_t emit_param4fv(struct r300_fragment_program *rp, return r; } -#if 0 static pfs_reg_t emit_const4fv(struct r300_fragment_program *rp, GLfloat *cp) { pfs_reg_t r = undef; @@ -330,13 +339,11 @@ static pfs_reg_t emit_const4fv(struct r300_fragment_program *rp, GLfloat *cp) ERROR("Out of hw constants!\n"); return r; } - - COPY_4V(rp->constant[r.index], cp); + COPY_4V(rp->constant[r.index], cp); r.valid = GL_TRUE; return r; } -#endif static __inline pfs_reg_t negate(pfs_reg_t r) { @@ -773,13 +780,15 @@ static void emit_tex(struct r300_fragment_program *rp, cs->dest_in_node = 0; } - if (rp->cur_node == 0) rp->first_node_has_tex = 1; + if (rp->cur_node == 0) + rp->first_node_has_tex = 1; - rp->tex.inst[rp->tex.length++] = 0 - | (hwsrc << R300_FPITX_SRC_SHIFT) - | (hwdest << R300_FPITX_DST_SHIFT) - | (unit << R300_FPITX_IMAGE_SHIFT) - | (opcode << R300_FPITX_OPCODE_SHIFT); /* not entirely sure about this */ + rp->tex.inst[rp->tex.length++] = 0 + | (hwsrc << R300_FPITX_SRC_SHIFT) + | (hwdest << R300_FPITX_DST_SHIFT) + | (unit << R300_FPITX_IMAGE_SHIFT) + /* not entirely sure about this */ + | (opcode << R300_FPITX_OPCODE_SHIFT); cs->dest_in_node |= (1 << hwdest); if (coord.type != REG_TYPE_CONST) @@ -884,7 +893,7 @@ static void emit_arith(struct r300_fragment_program *rp, int op, vop = r300_fpop[op].v_op; sop = r300_fpop[op].s_op; - argc = r300_fpop[op].argc; + argc = r300_fpop[op].argc; if ((mask & WRITEMASK_XYZ) || vop == R300_FPI0_OUTC_DP3) emit_vop = GL_TRUE; @@ -1039,7 +1048,9 @@ static GLboolean parse_program(struct r300_fragment_program *rp) const struct prog_instruction *inst = mp->Base.Instructions; struct prog_instruction *fpi; pfs_reg_t src[3], dest, temp; + pfs_reg_t cnst; int flags, mask = 0; + GLfloat cnstv[4] = {0.0, 0.0, 0.0, 0.0}; if (!inst || inst[0].Opcode == OPCODE_END) { ERROR("empty program?\n"); @@ -1179,7 +1190,66 @@ static GLboolean parse_program(struct r300_fragment_program *rp) flags); break; case OPCODE_LIT: - ERROR("LIT not implemented\n"); + /* LIT + * if (s.x < 0) t.x = 0; else t.x = s.x; + * if (s.y < 0) t.y = 0; else t.y = s.y; + * if (s.w > 128.0) t.w = 128.0; else t.w = s.w; + * if (s.w < -128.0) t.w = -128.0; else t.w = s.w; + * r.x = 1.0 + * if (t.x > 0) r.y = pow(t.y, t.w); else r.y = 0; + * Also r.y = 0 if t.y < 0 + * For the t.x > 0 FGLRX use the CMPH opcode which + * change the compare to (t.x + 0.5) > 0.5 we may + * save one instruction by doing CMP -t.x + */ + cnstv[0] = cnstv[1] = cnstv[2] = cnstv[4] = 0.50001; + src[0] = t_src(rp, fpi->SrcReg[0]); + temp = get_temp_reg(rp); + cnst = emit_const4fv(rp, cnstv); + emit_arith(rp, PFS_OP_CMP, temp, + WRITEMASK_X | WRITEMASK_Y, + src[0], pfs_zero, src[0], flags); + emit_arith(rp, PFS_OP_MIN, temp, WRITEMASK_Z, + swizzle(keep(src[0]), W, W, W, W), + cnst, undef, flags); + emit_arith(rp, PFS_OP_LG2, temp, WRITEMASK_W, + swizzle(temp, Y, Y, Y, Y), + undef, undef, flags); + emit_arith(rp, PFS_OP_MAX, temp, WRITEMASK_Z, + temp, negate(cnst), undef, flags); + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_W, + temp, swizzle(temp, Z, Z, Z, Z), + pfs_zero, flags); + emit_arith(rp, PFS_OP_EX2, temp, WRITEMASK_W, + temp, undef, undef, flags); + emit_arith(rp, PFS_OP_MAD, dest, WRITEMASK_Y, + swizzle(keep(temp), X, X, X, X), + pfs_one, pfs_zero, flags); +#if 0 + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, + temp, pfs_one, pfs_half, flags); + emit_arith(rp, PFS_OP_CMPH, temp, WRITEMASK_Z, + swizzle(keep(temp), W, W, W, W), + pfs_zero, swizzle(keep(temp), X, X, X, X), + flags); +#else + emit_arith(rp, PFS_OP_CMP, temp, WRITEMASK_Z, + pfs_zero, + swizzle(keep(temp), W, W, W, W), + negate(swizzle(keep(temp), X, X, X, X)), + flags); +#endif + emit_arith(rp, PFS_OP_CMP, dest, WRITEMASK_Z, + pfs_zero, temp, + negate(swizzle(keep(temp), Y, Y, Y, Y)), + flags); + emit_arith(rp, PFS_OP_MAD, dest, + WRITEMASK_X | WRITEMASK_W, + pfs_one, + pfs_one, + pfs_zero, + flags); + free_temp(rp, temp); break; case OPCODE_LRP: src[0] = t_src(rp, fpi->SrcReg[0]); @@ -1345,7 +1415,7 @@ static GLboolean parse_program(struct r300_fragment_program *rp) return GL_FALSE; } - + return GL_TRUE; } diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.h b/src/mesa/drivers/dri/r300/r300_fragprog.h index e7dbaf973e..4bbaa07e01 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.h +++ b/src/mesa/drivers/dri/r300/r300_fragprog.h @@ -78,7 +78,8 @@ typedef struct r300_fragment_program_swizzle { #define PFS_OP_RCP 9 #define PFS_OP_RSQ 10 #define PFS_OP_REPL_ALPHA 11 -#define MAX_PFS_OP 11 +#define PFS_OP_CMPH 12 +#define MAX_PFS_OP 12 #define PFS_FLAG_SAT (1 << 0) #define PFS_FLAG_ABS (1 << 1) diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c index 7775ca96e4..87276a11ae 100644 --- a/src/mesa/drivers/dri/r300/r300_ioctl.c +++ b/src/mesa/drivers/dri/r300/r300_ioctl.c @@ -477,8 +477,7 @@ static void r300EmitClearState(GLcontext * ctx) /** * Buffer clear */ -static void r300Clear(GLcontext * ctx, GLbitfield mask, GLboolean allFoo, - GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo) +static void r300Clear(GLcontext * ctx, GLbitfield mask) { r300ContextPtr r300 = R300_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable; @@ -520,7 +519,7 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask, GLboolean allFoo, if (RADEON_DEBUG & DEBUG_FALLBACKS) fprintf(stderr, "%s: swrast clear, mask: %x\n", __FUNCTION__, mask); - _swrast_Clear(ctx, mask, 0, 0, 0, 0, 0); + _swrast_Clear(ctx, mask); } swapped = r300->radeon.doPageFlip && (r300->radeon.sarea->pfCurrentPage == 1); diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h index f3d8fa60f5..9f636ec1d2 100644 --- a/src/mesa/drivers/dri/r300/r300_reg.h +++ b/src/mesa/drivers/dri/r300/r300_reg.h @@ -1001,6 +1001,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * - DP4: Use OUTC_DP4, OUTA_DP4 * - DP3: Use OUTC_DP3, OUTA_DP4, appropriate alpha operands * - DPH: Use OUTC_DP4, OUTA_DP4, appropriate alpha operands + * - CMPH: If ARG2 > 0.5, return ARG0, else return ARG1 * - CMP: If ARG2 < 0, return ARG1, else return ARG0 * - FLR: use FRC+MAD * - XPD: use MAD+MAD @@ -1138,6 +1139,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_FPI0_OUTC_DP4 (2 << 23) # define R300_FPI0_OUTC_MIN (4 << 23) # define R300_FPI0_OUTC_MAX (5 << 23) +# define R300_FPI0_OUTC_CMPH (7 << 23) # define R300_FPI0_OUTC_CMP (8 << 23) # define R300_FPI0_OUTC_FRC (9 << 23) # define R300_FPI0_OUTC_REPL_ALPHA (10 << 23) diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 5a98226300..6aff04fd27 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -460,7 +460,6 @@ static void update_depth(GLcontext* ctx) static void r300Enable(GLcontext* ctx, GLenum cap, GLboolean state) { r300ContextPtr r300 = R300_CONTEXT(ctx); - uint32_t newval; if (RADEON_DEBUG & DEBUG_STATE) fprintf(stderr, "%s( %s = %s )\n", __FUNCTION__, diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c index 1d78918a2b..cc356afb23 100644 --- a/src/mesa/drivers/dri/r300/r300_texstate.c +++ b/src/mesa/drivers/dri/r300/r300_texstate.c @@ -171,7 +171,6 @@ static void r300SetTexImages(r300ContextPtr rmesa, GLint i, texelBytes; GLint numLevels; GLint log2Width, log2Height, log2Depth; - const GLuint ui = 1; /* Set the hardware texture format */ diff --git a/src/mesa/drivers/dri/r300/radeon_context.c b/src/mesa/drivers/dri/r300/radeon_context.c index 09321126d6..62a6e1e5f7 100644 --- a/src/mesa/drivers/dri/r300/radeon_context.c +++ b/src/mesa/drivers/dri/r300/radeon_context.c @@ -98,27 +98,11 @@ static const GLubyte *radeonGetString(GLcontext * ctx, GLenum name) } } - -/* Return the width and height of the given buffer. - */ -static void radeonGetBufferSize(GLframebuffer * buffer, - GLuint * width, GLuint * height) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr radeon = RADEON_CONTEXT(ctx); - - LOCK_HARDWARE(radeon); - *width = radeon->dri.drawable->w; - *height = radeon->dri.drawable->h; - UNLOCK_HARDWARE(radeon); -} - - /* Initialize the driver's misc functions. */ static void radeonInitDriverFuncs(struct dd_function_table *functions) { - functions->GetBufferSize = radeonGetBufferSize; + functions->GetBufferSize = NULL; functions->GetString = radeonGetString; } @@ -158,7 +142,8 @@ GLboolean radeonInitContext(radeonContextPtr radeon, /* DRI fields */ radeon->dri.context = driContextPriv; radeon->dri.screen = sPriv; - radeon->dri.drawable = NULL; /* Set by XMesaMakeCurrent */ + radeon->dri.drawable = NULL; + radeon->dri.readable = NULL; radeon->dri.hwContext = driContextPriv->hHWContext; radeon->dri.hwLock = &sPriv->pSAREA->lock; radeon->dri.fd = sPriv->fd; @@ -282,12 +267,15 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, fprintf(stderr, "%s ctx %p\n", __FUNCTION__, radeon->glCtx); - if (radeon->dri.drawable != driDrawPriv) { + if ( (radeon->dri.drawable != driDrawPriv) + || (radeon->dri.readable != driReadPriv) ) { + driDrawableInitVBlank(driDrawPriv, radeon->vblank_flags, &radeon->vbl_seq); radeon->dri.drawable = driDrawPriv; - + radeon->dri.readable = driReadPriv; + r300UpdateWindow(radeon->glCtx); r300UpdateViewportOffset(radeon->glCtx); } diff --git a/src/mesa/drivers/dri/r300/radeon_context.h b/src/mesa/drivers/dri/r300/radeon_context.h index 0ec6466e44..07a0c7cbd6 100644 --- a/src/mesa/drivers/dri/r300/radeon_context.h +++ b/src/mesa/drivers/dri/r300/radeon_context.h @@ -120,7 +120,15 @@ extern void radeonTclFallback(GLcontext * ctx, GLuint bit, GLboolean mode); struct radeon_dri_mirror { __DRIcontextPrivate *context; /* DRI context */ __DRIscreenPrivate *screen; /* DRI screen */ - __DRIdrawablePrivate *drawable; /* DRI drawable bound to this ctx */ + /** + * DRI drawable bound to this context for drawing. + */ + __DRIdrawablePrivate *drawable; + + /** + * DRI drawable bound to this context for reading. + */ + __DRIdrawablePrivate *readable; drm_context_t hwContext; drm_hw_lock_t *hwLock; diff --git a/src/mesa/drivers/dri/r300/radeon_lock.c b/src/mesa/drivers/dri/r300/radeon_lock.c index 0e1e6512db..a00da6c8bc 100644 --- a/src/mesa/drivers/dri/r300/radeon_lock.c +++ b/src/mesa/drivers/dri/r300/radeon_lock.c @@ -75,34 +75,30 @@ static void radeonUpdatePageFlipping(radeonContextPtr radeon) * Called by radeonGetLock() after the lock has been obtained. */ static void r300RegainedLock(radeonContextPtr radeon) -{ - __DRIdrawablePrivate *dPriv = radeon->dri.drawable; +{ int i; + __DRIdrawablePrivate *const drawable = radeon->dri.drawable; r300ContextPtr r300 = (r300ContextPtr)radeon; + drm_radeon_sarea_t *sarea = radeon->sarea; - if (radeon->lastStamp != dPriv->lastStamp) { - _mesa_resize_framebuffer(radeon->glCtx, - (GLframebuffer*)dPriv->driverPrivate, - dPriv->w, dPriv->h); - + if ( radeon->lastStamp != drawable->lastStamp ) { radeonUpdatePageFlipping(radeon); - - if (radeon->glCtx->DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_BACK_LEFT) - radeonSetCliprects(radeon, GL_BACK_LEFT); - else - radeonSetCliprects(radeon, GL_FRONT_LEFT); - + radeonSetCliprects(radeon); #if 1 r300UpdateViewportOffset( radeon->glCtx ); - driUpdateFramebufferSize(radeon->glCtx, dPriv); + driUpdateFramebufferSize(radeon->glCtx, drawable); #else radeonUpdateScissor(radeon->glCtx); #endif - radeon->lastStamp = dPriv->lastStamp; + radeon->lastStamp = drawable->lastStamp; } - for (i = 0; i < r300->nr_heaps; i++) { - DRI_AGE_TEXTURES(r300->texture_heaps[i]); + if (sarea->ctx_owner != radeon->dri.hwContext) { + sarea->ctx_owner = radeon->dri.hwContext; + + for (i = 0; i < r300->nr_heaps; i++) { + DRI_AGE_TEXTURES(r300->texture_heaps[i]); + } } } @@ -116,11 +112,11 @@ static void r300RegainedLock(radeonContextPtr radeon) */ void radeonGetLock(radeonContextPtr radeon, GLuint flags) { - __DRIdrawablePrivate *dPriv = radeon->dri.drawable; + __DRIdrawablePrivate *const drawable = radeon->dri.drawable; + __DRIdrawablePrivate *const readable = radeon->dri.readable; __DRIscreenPrivate *sPriv = radeon->dri.screen; - drm_radeon_sarea_t *sarea = radeon->sarea; - assert (dPriv != NULL); + assert (drawable != NULL); drmGetLock(radeon->dri.fd, radeon->dri.hwContext, flags); @@ -132,10 +128,10 @@ void radeonGetLock(radeonContextPtr radeon, GLuint flags) * Since the hardware state depends on having the latest drawable * clip rects, all state checking must be done _after_ this call. */ - DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); - - if (sarea->ctx_owner != radeon->dri.hwContext) - sarea->ctx_owner = radeon->dri.hwContext; + DRI_VALIDATE_DRAWABLE_INFO( sPriv, drawable ); + if (drawable != readable) { + DRI_VALIDATE_DRAWABLE_INFO( sPriv, readable ); + } if (IS_R300_CLASS(radeon->radeonScreen)) r300RegainedLock(radeon); diff --git a/src/mesa/drivers/dri/r300/radeon_state.c b/src/mesa/drivers/dri/r300/radeon_state.c index 7726c22f42..1b1ec3df3c 100644 --- a/src/mesa/drivers/dri/r300/radeon_state.c +++ b/src/mesa/drivers/dri/r300/radeon_state.c @@ -49,7 +49,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_ioctl.h" #include "radeon_state.h" #include "r300_ioctl.h" - +#include "framebuffer.h" /* ============================================================= * Scissoring @@ -137,7 +137,6 @@ static void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h if (ctx->Scissor.Enabled) { /* We don't pipeline cliprect changes */ r300Flush(ctx); - radeonUpdateScissor(ctx); } } @@ -146,31 +145,46 @@ static void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h /** * Update cliprects and scissors. */ -void radeonSetCliprects(radeonContextPtr radeon, GLenum mode) +void radeonSetCliprects(radeonContextPtr radeon) { - __DRIdrawablePrivate *dPriv = radeon->dri.drawable; - - switch (mode) { - case GL_FRONT_LEFT: - radeon->numClipRects = dPriv->numClipRects; - radeon->pClipRects = dPriv->pClipRects; - break; - case GL_BACK_LEFT: - /* Can't ignore 2d windows if we are page flipping. - */ - if (dPriv->numBackClipRects == 0 || radeon->doPageFlip) { - radeon->numClipRects = dPriv->numClipRects; - radeon->pClipRects = dPriv->pClipRects; + __DRIdrawablePrivate *const drawable = radeon->dri.drawable; + __DRIdrawablePrivate *const readable = radeon->dri.readable; + GLframebuffer *const draw_fb = (GLframebuffer*)drawable->driverPrivate; + GLframebuffer *const read_fb = (GLframebuffer*)readable->driverPrivate; + + if (draw_fb->_ColorDrawBufferMask[0] == BUFFER_BIT_BACK_LEFT) { + /* Can't ignore 2d windows if we are page flipping. */ + if (drawable->numBackClipRects == 0 || radeon->doPageFlip) { + radeon->numClipRects = drawable->numClipRects; + radeon->pClipRects = drawable->pClipRects; } else { - radeon->numClipRects = dPriv->numBackClipRects; - radeon->pClipRects = dPriv->pBackClipRects; + radeon->numClipRects = drawable->numBackClipRects; + radeon->pClipRects = drawable->pBackClipRects; + } + } else { + /* front buffer (or none, or multiple buffers */ + radeon->numClipRects = drawable->numClipRects; + radeon->pClipRects = drawable->pClipRects; + } + + if ((draw_fb->Width != drawable->w) || + (draw_fb->Height != drawable->h)) { + printf("w,h %d %d\n", + radeon->glCtx->DrawBuffer->Width, + radeon->glCtx->DrawBuffer->Height); + + _mesa_resize_framebuffer(radeon->glCtx, draw_fb, + drawable->w, drawable->h); + draw_fb->Initialized = GL_TRUE; + } + + if (drawable != readable) { + if ((read_fb->Width != readable->w) || + (read_fb->Height != readable->h)) { + _mesa_resize_framebuffer(radeon->glCtx, read_fb, + readable->w, readable->h); + read_fb->Initialized = GL_TRUE; } - break; - default: - fprintf(stderr, "bad mode in radeonSetCliprects\n"); - radeon->numClipRects = 0; - radeon->pClipRects = 0; - return; } if (radeon->state.scissor.enabled) diff --git a/src/mesa/drivers/dri/r300/radeon_state.h b/src/mesa/drivers/dri/r300/radeon_state.h index 636bf5d008..c2d041eb4a 100644 --- a/src/mesa/drivers/dri/r300/radeon_state.h +++ b/src/mesa/drivers/dri/r300/radeon_state.h @@ -34,7 +34,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_context.h" extern void radeonRecalcScissorRects(radeonContextPtr radeon); -extern void radeonSetCliprects(radeonContextPtr radeon, GLenum mode); +extern void radeonSetCliprects(radeonContextPtr radeon); extern void radeonUpdateScissor(GLcontext* ctx); extern void radeonEnable(GLcontext* ctx, GLenum cap, GLboolean state); diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c index d9eec622f3..737490fcde 100644 --- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c +++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c @@ -1021,8 +1021,7 @@ void radeonPageFlip( const __DRIdrawablePrivate *dPriv ) */ #define RADEON_MAX_CLEARS 256 -static void radeonClear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, - GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo ) +static void radeonClear( GLcontext *ctx, GLbitfield mask ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; @@ -1071,7 +1070,7 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, if ( mask ) { if (RADEON_DEBUG & DEBUG_FALLBACKS) fprintf(stderr, "%s: swrast clear, mask: %x\n", __FUNCTION__, mask); - _swrast_Clear( ctx, mask, 0, 0, 0, 0, 0 ); + _swrast_Clear( ctx, mask ); } if ( !flags ) diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c index f1a1728eaa..e19202fa44 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.c +++ b/src/mesa/drivers/dri/radeon/radeon_state.c @@ -40,6 +40,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "light.h" #include "state.h" #include "context.h" +#include "framebuffer.h" #include "vbo/vbo.h" #include "tnl/tnl.h" @@ -1659,14 +1660,14 @@ void radeonSetCliprects( radeonContextPtr rmesa ) } if ((draw_fb->Width != drawable->w) || (draw_fb->Height != drawable->h)) { - _mesa_resize_framebuffer(&rmesa->glCtx, draw_fb, + _mesa_resize_framebuffer(rmesa->glCtx, draw_fb, drawable->w, drawable->h); draw_fb->Initialized = GL_TRUE; } if (drawable != readable) { if ((read_fb->Width != readable->w) || (read_fb->Height != readable->h)) { - _mesa_resize_framebuffer(&rmesa->glCtx, read_fb, + _mesa_resize_framebuffer(rmesa->glCtx, read_fb, readable->w, readable->h); read_fb->Initialized = GL_TRUE; } diff --git a/src/mesa/drivers/dri/s3v/s3v_state.c b/src/mesa/drivers/dri/s3v/s3v_state.c index 08ce0f565c..b86b618c11 100644 --- a/src/mesa/drivers/dri/s3v/s3v_state.c +++ b/src/mesa/drivers/dri/s3v/s3v_state.c @@ -73,8 +73,7 @@ static void s3vDDBlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor ) * Buffer clear */ -static void s3vDDClear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, - GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo ) +static void s3vDDClear( GLcontext *ctx, GLbitfield mask ) { s3vContextPtr vmesa = S3V_CONTEXT(ctx); unsigned int _stride; @@ -163,7 +162,7 @@ static void s3vDDClear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, if ( mask ) DEBUG(("still masked ;3(\n")); */ /* yes */ #else - _swrast_Clear( ctx, mask, 0, 0, 0, 0, 0 ); + _swrast_Clear( ctx, mask ); #endif } diff --git a/src/mesa/drivers/dri/savage/savageioctl.c b/src/mesa/drivers/dri/savage/savageioctl.c index 7513a07e85..4eac1fb349 100644 --- a/src/mesa/drivers/dri/savage/savageioctl.c +++ b/src/mesa/drivers/dri/savage/savageioctl.c @@ -327,8 +327,7 @@ static GLuint savageIntersectClipRects(drm_clip_rect_t *dest, } -static void savageDDClear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, - GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo ) +static void savageDDClear( GLcontext *ctx, GLbitfield mask ) { savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); GLuint colorMask, depthMask, clearColor, clearDepth, flags; @@ -426,7 +425,7 @@ static void savageDDClear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, } if (mask) - _swrast_Clear( ctx, mask, 0, 0, 0, 0, 0 ); + _swrast_Clear( ctx, mask ); } /* diff --git a/src/mesa/drivers/dri/sis/sis6326_clear.c b/src/mesa/drivers/dri/sis/sis6326_clear.c index d8f39b31c7..48db19566c 100644 --- a/src/mesa/drivers/dri/sis/sis6326_clear.c +++ b/src/mesa/drivers/dri/sis/sis6326_clear.c @@ -69,8 +69,7 @@ sis6326UpdateZPattern(sisContextPtr smesa, GLclampd z) } void -sis6326DDClear(GLcontext *ctx, GLbitfield mask, GLboolean allFoo, - GLint xFoo, GLint yFoo, GLint widthFoo, GLint heightFoo) +sis6326DDClear(GLcontext *ctx, GLbitfield mask) { sisContextPtr smesa = SIS_CONTEXT(ctx); GLint x1, y1, width1, height1; @@ -110,7 +109,7 @@ sis6326DDClear(GLcontext *ctx, GLbitfield mask, GLboolean allFoo, UNLOCK_HARDWARE(); if (mask != 0) - _swrast_Clear(ctx, mask, 0, 0, 0, 0, 0); + _swrast_Clear(ctx, mask); } diff --git a/src/mesa/drivers/dri/sis/sis_clear.c b/src/mesa/drivers/dri/sis/sis_clear.c index 64b6870871..fb92d06c73 100644 --- a/src/mesa/drivers/dri/sis/sis_clear.c +++ b/src/mesa/drivers/dri/sis/sis_clear.c @@ -95,8 +95,7 @@ sisUpdateZStencilPattern( sisContextPtr smesa, GLclampd z, GLint stencil ) } void -sisDDClear( GLcontext * ctx, GLbitfield mask, GLboolean allFoo, - GLint xFoo, GLint yFoo, GLint widthFoo, GLint heightFoo ) +sisDDClear( GLcontext * ctx, GLbitfield mask ) { sisContextPtr smesa = SIS_CONTEXT(ctx); @@ -145,7 +144,7 @@ sisDDClear( GLcontext * ctx, GLbitfield mask, GLboolean allFoo, UNLOCK_HARDWARE(); if (mask != 0) - _swrast_Clear( ctx, mask, 0, 0, 0, 0, 0); + _swrast_Clear( ctx, mask); } @@ -329,9 +328,7 @@ sis_clear_color_buffer( GLcontext *ctx, GLenum mask, GLint x, GLint y, GLint width, GLint height ) { sisContextPtr smesa = SIS_CONTEXT(ctx); - int count; - GLuint depth = smesa->bytesPerPixel; drm_clip_rect_t *pExtents = NULL; GLint xx, yy; GLint x0, y0, width0, height0; @@ -379,8 +376,6 @@ sis_clear_color_buffer( GLcontext *ctx, GLenum mask, GLint x, GLint y, if (width <= 0 || height <= 0) continue; - int cmd; - mWait3DCmdQueue (8); MMIO(REG_SRC_PITCH, (smesa->bytesPerPixel == 4) ? BLIT_DEPTH_32 : BLIT_DEPTH_16); diff --git a/src/mesa/drivers/dri/sis/sis_screen.c b/src/mesa/drivers/dri/sis/sis_screen.c index 4fd692ec24..8f52cfe098 100644 --- a/src/mesa/drivers/dri/sis/sis_screen.c +++ b/src/mesa/drivers/dri/sis/sis_screen.c @@ -209,7 +209,7 @@ sisCreateBuffer( __DRIscreenPrivate *driScrnPriv, const __GLcontextModes *mesaVis, GLboolean isPixmap ) { - sisScreenPtr screen = (sisScreenPtr) driScrnPriv->private; + /*sisScreenPtr screen = (sisScreenPtr) driScrnPriv->private;*/ struct gl_framebuffer *fb; if (isPixmap) diff --git a/src/mesa/drivers/dri/sis/sis_state.h b/src/mesa/drivers/dri/sis/sis_state.h index 580a522bf3..8f7e2acb92 100644 --- a/src/mesa/drivers/dri/sis/sis_state.h +++ b/src/mesa/drivers/dri/sis/sis_state.h @@ -35,15 +35,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "sis_context.h" /* sis6326_clear.c */ -extern void sis6326DDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint x, GLint y, GLint width, GLint height ); +extern void sis6326DDClear( GLcontext *ctx, GLbitfield mask ); extern void sis6326DDClearColor( GLcontext * ctx, const GLfloat color[4] ); extern void sis6326DDClearDepth( GLcontext * ctx, GLclampd d ); extern void sis6326UpdateZPattern(sisContextPtr smesa, GLclampd z); /* sis_clear.c */ -extern void sisDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint x, GLint y, GLint width, GLint height ); +extern void sisDDClear( GLcontext *ctx, GLbitfield mask ); extern void sisDDClearColor( GLcontext * ctx, const GLfloat color[4] ); extern void sisDDClearDepth( GLcontext * ctx, GLclampd d ); extern void sisDDClearStencil( GLcontext * ctx, GLint s ); diff --git a/src/mesa/drivers/dri/tdfx/tdfx_render.c b/src/mesa/drivers/dri/tdfx/tdfx_render.c index 3301d948e1..f36c97bfeb 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_render.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_render.c @@ -46,9 +46,7 @@ /* Clear the color and/or depth buffers. */ -static void tdfxClear( GLcontext *ctx, - GLbitfield mask, GLboolean all, - GLint xFoo, GLint yFoo, GLint widthFoo, GLint heightFoo) +static void tdfxClear( GLcontext *ctx, GLbitfield mask ) { tdfxContextPtr fxMesa = (tdfxContextPtr) ctx->DriverCtx; GLbitfield softwareMask = mask & (BUFFER_BIT_ACCUM); @@ -312,7 +310,7 @@ static void tdfxClear( GLcontext *ctx, } if (softwareMask) - _swrast_Clear( ctx, softwareMask, 0, 0, 0, 0, 0); + _swrast_Clear(ctx, softwareMask); } diff --git a/src/mesa/drivers/dri/tdfx/tdfx_tex.c b/src/mesa/drivers/dri/tdfx/tdfx_tex.c index 3e6011a2ac..c3fe7bebd3 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_tex.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_tex.c @@ -1404,7 +1404,6 @@ tdfxTexImage2D(GLcontext *ctx, GLenum target, GLint level, GLint mipWidth, mipHeight; tdfxMipMapLevel *mip; struct gl_texture_image *mipImage; - const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; const GLint maxLevels = _mesa_max_texture_levels(ctx, texObj->Target); assert(!texImage->IsCompressed); @@ -1425,7 +1424,7 @@ tdfxTexImage2D(GLcontext *ctx, GLenum target, GLint level, mipWidth, mipHeight, border, format, type, NULL); - mipImage = _mesa_select_tex_image(ctx, texUnit, target, level); + mipImage = _mesa_select_tex_image(ctx, texObj, target, level); mip = TDFX_TEXIMAGE_DATA(mipImage); _mesa_halve2x2_teximage2d(ctx, texImage, @@ -1514,7 +1513,6 @@ tdfxTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, GLint mipWidth, mipHeight; tdfxMipMapLevel *mip; struct gl_texture_image *mipImage; - const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; const GLint maxLevels = _mesa_max_texture_levels(ctx, texObj->Target); assert(!texImage->IsCompressed); @@ -1534,7 +1532,7 @@ tdfxTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, break; } ++level; - mipImage = _mesa_select_tex_image(ctx, texUnit, target, level); + mipImage = _mesa_select_tex_image(ctx, texObj, target, level); mip = TDFX_TEXIMAGE_DATA(mipImage); _mesa_halve2x2_teximage2d(ctx, texImage, diff --git a/src/mesa/drivers/dri/trident/trident_state.c b/src/mesa/drivers/dri/trident/trident_state.c index 6cdf23092a..5303bd422e 100644 --- a/src/mesa/drivers/dri/trident/trident_state.c +++ b/src/mesa/drivers/dri/trident/trident_state.c @@ -150,8 +150,7 @@ void tridentCopyBuffer( const __DRIdrawablePrivate *dPriv ) } -static void tridentDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo) +static void tridentDDClear( GLcontext *ctx, GLbitfield mask ) { tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx); unsigned char *MMIO = tmesa->tridentScreen->mmio.map; @@ -297,7 +296,7 @@ if (flags & DRM_TRIDENT_FRONT) { UNLOCK_HARDWARE(tmesa); if ( mask ) - _swrast_Clear( ctx, mask, 0, 0, 0, 0, 0); + _swrast_Clear( ctx, mask ); } static void tridentDDShadeModel( GLcontext *ctx, GLenum mode ) diff --git a/src/mesa/drivers/dri/unichrome/via_ioctl.c b/src/mesa/drivers/dri/unichrome/via_ioctl.c index 86077bc4d4..dd2e93b286 100644 --- a/src/mesa/drivers/dri/unichrome/via_ioctl.c +++ b/src/mesa/drivers/dri/unichrome/via_ioctl.c @@ -202,8 +202,7 @@ static void viaFillBuffer(struct via_context *vmesa, -static void viaClear(GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo) +static void viaClear(GLcontext *ctx, GLbitfield mask) { struct via_context *vmesa = VIA_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = vmesa->driDrawable; @@ -262,6 +261,7 @@ static void viaClear(GLcontext *ctx, GLbitfield mask, GLboolean all, drm_clip_rect_t *boxes, *tmp_boxes = 0; int nr = 0; GLint cx, cy, cw, ch; + GLboolean all; LOCK_HARDWARE(vmesa); @@ -270,6 +270,7 @@ static void viaClear(GLcontext *ctx, GLbitfield mask, GLboolean all, cy = ctx->DrawBuffer->_Ymin; cw = ctx->DrawBuffer->_Xmax - cx; ch = ctx->DrawBuffer->_Ymax - cy; + all = (cw == ctx->DrawBuffer->Width && ch == ctx->DrawBuffer->Height); /* flip top to bottom */ cy = dPriv->h - cy - ch; @@ -335,7 +336,7 @@ static void viaClear(GLcontext *ctx, GLbitfield mask, GLboolean all, } if (mask) - _swrast_Clear(ctx, mask, 0, 0, 0, 0, 0); + _swrast_Clear(ctx, mask); } diff --git a/src/mesa/drivers/ggi/ggimesa.c b/src/mesa/drivers/ggi/ggimesa.c index 4fbbe61ab8..47d7f2bdb9 100644 --- a/src/mesa/drivers/ggi/ggimesa.c +++ b/src/mesa/drivers/ggi/ggimesa.c @@ -313,10 +313,14 @@ static void gl_ggiSetClearColor(GLcontext *ctx, const GLfloat color[4]) ggi_ctx->clearcolor = col; } -static void gl_ggiClear(GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint x, GLint y, GLint width, GLint height) +static void gl_ggiClear(GLcontext *ctx, GLbitfield mask) { ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx; + int x = ctx->DrawBuffer->_Xmin; + int y = ctx->DrawBuffer->_Ymin; + int w = ctx->DrawBuffer->_Xmax - x; + int h = ctx->DrawBuffer->_Ymax - y; + GLboolean all = (w == ctx->DrawBuffer->Width && h == ctx->DrawBuffer->height) GGIMESADPRINT_CORE("gl_ggiClear() called\n"); @@ -336,7 +340,7 @@ static void gl_ggiClear(GLcontext *ctx, GLbitfield mask, GLboolean all, mask &= ~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT); } - _swrast_Clear(ctx, mask, all, x, y, width, height); + _swrast_Clear(ctx, mask); } diff --git a/src/mesa/drivers/glide/fxdd.c b/src/mesa/drivers/glide/fxdd.c index e218a316aa..f49c3889f6 100644 --- a/src/mesa/drivers/glide/fxdd.c +++ b/src/mesa/drivers/glide/fxdd.c @@ -162,9 +162,7 @@ fxDDClearColor(GLcontext * ctx, const GLfloat color[4]) /* Clear the color and/or depth buffers */ -static void fxDDClear( GLcontext *ctx, - GLbitfield mask, GLboolean all, - GLint x, GLint y, GLint width, GLint height ) +static void fxDDClear( GLcontext *ctx, GLbitfield mask ) { fxMesaContext fxMesa = FX_CONTEXT(ctx); GLbitfield softwareMask = mask & (BUFFER_BIT_ACCUM); @@ -173,8 +171,7 @@ static void fxDDClear( GLcontext *ctx, const FxU8 clearS = (FxU8) (ctx->Stencil.Clear & 0xff); if ( TDFX_DEBUG & MESA_VERBOSE ) { - fprintf( stderr, "fxDDClear( %d, %d, %d, %d )\n", - (int) x, (int) y, (int) width, (int) height ); + fprintf( stderr, "fxDDClear\n"); } /* we can't clear accum buffers nor stereo */ @@ -389,7 +386,7 @@ static void fxDDClear( GLcontext *ctx, grRenderBuffer(fxMesa->currentFB); if (softwareMask) - _swrast_Clear( ctx, softwareMask, all, x, y, width, height ); + _swrast_Clear( ctx, softwareMask ); } diff --git a/src/mesa/drivers/svga/svgamesa15.c b/src/mesa/drivers/svga/svgamesa15.c index 54b6c977a7..ae5104d0c0 100644 --- a/src/mesa/drivers/svga/svgamesa15.c +++ b/src/mesa/drivers/svga/svgamesa15.c @@ -1,4 +1,4 @@ -/* $Id: svgamesa15.c,v 1.11 2002/11/11 18:42:39 brianp Exp $ */ +/* $Id: svgamesa15.c,v 1.11.36.1 2006/11/02 12:02:17 alanh Exp $ */ /* * Mesa 3-D graphics library @@ -66,10 +66,14 @@ void __clear_color15( GLcontext *ctx, const GLfloat color[4] ) /* SVGAMesa->clear_hicolor=(red)<<10 | (green)<<5 | (blue);*/ } -void __clear15( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint x, GLint y, GLint width, GLint height ) +void __clear15( GLcontext *ctx, GLbitfield mask ) { int i, j; + int x = ctx->DrawBuffer->_Xmin; + int y = ctx->DrawBuffer->_Ymin; + int width = ctx->DrawBuffer->_Xmax - x; + int height = ctx->DrawBuffer->_Ymax - y; + GLboolean all = (width == ctx->DrawBuffer->Width && height == ctx->DrawBuffer->height) if (mask & DD_FRONT_LEFT_BIT) { GLshort *shortBuffer=(void *)SVGABuffer.FrontBuffer; @@ -105,7 +109,7 @@ void __clear15( GLcontext *ctx, GLbitfield mask, GLboolean all, } if (mask) - _swrast_Clear( ctx, mask, all, x, y, width, height ); + _swrast_Clear( ctx, mask ); } void __write_rgba_span15( const GLcontext *ctx, GLuint n, GLint x, GLint y, diff --git a/src/mesa/drivers/svga/svgamesa16.c b/src/mesa/drivers/svga/svgamesa16.c index 72ac818329..a59937bfb4 100644 --- a/src/mesa/drivers/svga/svgamesa16.c +++ b/src/mesa/drivers/svga/svgamesa16.c @@ -1,4 +1,4 @@ -/* $Id: svgamesa16.c,v 1.11 2002/11/11 18:42:40 brianp Exp $ */ +/* $Id: svgamesa16.c,v 1.11.36.1 2006/11/02 12:02:17 alanh Exp $ */ /* * Mesa 3-D graphics library @@ -69,10 +69,14 @@ void __clear_color16( GLcontext *ctx, const GLfloat color[4] ) /* SVGAMesa->clear_hicolor=(red)<<11 | (green)<<5 | (blue); */ } -void __clear16( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint x, GLint y, GLint width, GLint height ) +void __clear16( GLcontext *ctx, GLbitfield mask ) { int i,j; + int x = ctx->DrawBuffer->_Xmin; + int y = ctx->DrawBuffer->_Ymin; + int width = ctx->DrawBuffer->_Xmax - x; + int height = ctx->DrawBuffer->_Ymax - y; + GLboolean all = (width == ctx->DrawBuffer->Width && height == ctx->DrawBuffer->height) if (mask & DD_FRONT_LEFT_BIT) { if (all) { @@ -108,7 +112,7 @@ void __clear16( GLcontext *ctx, GLbitfield mask, GLboolean all, } if (mask) - _swrast_Clear( ctx, mask, all, x, y, width, height ); + _swrast_Clear( ctx, mask ); } void __write_rgba_span16( const GLcontext *ctx, GLuint n, GLint x, GLint y, diff --git a/src/mesa/drivers/svga/svgamesa24.c b/src/mesa/drivers/svga/svgamesa24.c index 07491cc67a..dd15bf38db 100644 --- a/src/mesa/drivers/svga/svgamesa24.c +++ b/src/mesa/drivers/svga/svgamesa24.c @@ -1,4 +1,4 @@ -/* $Id: svgamesa24.c,v 1.12 2002/11/11 18:42:41 brianp Exp $ */ +/* $Id: svgamesa24.c,v 1.12.36.1 2006/11/02 12:02:17 alanh Exp $ */ /* * Mesa 3-D graphics library @@ -91,10 +91,14 @@ void __clear_color24( GLcontext *ctx, const GLfloat color[4] ) /* SVGAMesa->clear_truecolor = red<<16 | green<<8 | blue; */ } -void __clear24( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint x, GLint y, GLint width, GLint height ) +void __clear24( GLcontext *ctx, GLbitfield mask ) { int i,j; + int x = ctx->DrawBuffer->_Xmin; + int y = ctx->DrawBuffer->_Ymin; + int width = ctx->DrawBuffer->_Xmax - x; + int height = ctx->DrawBuffer->_Ymax - y; + GLboolean all = (width == ctx->DrawBuffer->Width && height == ctx->DrawBuffer->height) if (mask & DD_FRONT_LEFT_BIT) { if (all) { @@ -140,7 +144,7 @@ void __clear24( GLcontext *ctx, GLbitfield mask, GLboolean all, } if (mask) - _swrast_Clear( ctx, mask, all, x, y, width, height ); + _swrast_Clear( ctx, mask ); } void __write_rgba_span24( const GLcontext *ctx, GLuint n, GLint x, GLint y, diff --git a/src/mesa/drivers/svga/svgamesa32.c b/src/mesa/drivers/svga/svgamesa32.c index 8a366998d6..4da18795d8 100644 --- a/src/mesa/drivers/svga/svgamesa32.c +++ b/src/mesa/drivers/svga/svgamesa32.c @@ -1,4 +1,4 @@ -/* $Id: svgamesa32.c,v 1.12 2002/11/11 18:42:42 brianp Exp $ */ +/* $Id: svgamesa32.c,v 1.12.36.1 2006/11/02 12:02:17 alanh Exp $ */ /* * Mesa 3-D graphics library @@ -85,10 +85,14 @@ void __clear_color32( GLcontext *ctx, const GLfloat color[4] ) SVGAMesa->clear_truecolor = (col[0] << 16) | (col[1] << 8) | col[2]; } -void __clear32( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint x, GLint y, GLint width, GLint height ) +void __clear32( GLcontext *ctx, GLbitfield mask ) { int i,j; + int x = ctx->DrawBuffer->_Xmin; + int y = ctx->DrawBuffer->_Ymin; + int width = ctx->DrawBuffer->_Xmax - x; + int height = ctx->DrawBuffer->_Ymax - y; + GLboolean all = (width == ctx->DrawBuffer->Width && height == ctx->DrawBuffer->height) if (mask & DD_FRONT_LEFT_BIT) { if (all) { @@ -124,7 +128,7 @@ void __clear32( GLcontext *ctx, GLbitfield mask, GLboolean all, } if (mask) - _swrast_Clear( ctx, mask, all, x, y, width, height ); + _swrast_Clear( ctx, mask ); } void __write_rgba_span32( const GLcontext *ctx, GLuint n, GLint x, GLint y, diff --git a/src/mesa/drivers/svga/svgamesa8.c b/src/mesa/drivers/svga/svgamesa8.c index fd880ef85a..4264fcd959 100644 --- a/src/mesa/drivers/svga/svgamesa8.c +++ b/src/mesa/drivers/svga/svgamesa8.c @@ -1,4 +1,4 @@ -/* $Id: svgamesa8.c,v 1.9 2005/05/04 20:11:39 brianp Exp $ */ +/* $Id: svgamesa8.c,v 1.9.10.1 2006/11/02 12:02:17 alanh Exp $ */ /* * Mesa 3-D graphics library @@ -60,10 +60,14 @@ void __clear_index8( GLcontext *ctx, GLuint index ) SVGAMesa->clear_index = index; } -void __clear8( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint x, GLint y, GLint width, GLint height ) +void __clear8( GLcontext *ctx, GLbitfield mask ) { int i,j; + int x = ctx->DrawBuffer->_Xmin; + int y = ctx->DrawBuffer->_Ymin; + int width = ctx->DrawBuffer->_Xmax - x; + int height = ctx->DrawBuffer->_Ymax - y; + GLboolean all = (width == ctx->DrawBuffer->Width && height == ctx->DrawBuffer->height) if (mask & DD_FRONT_LEFT_BIT) { if (all) { @@ -95,7 +99,7 @@ void __clear8( GLcontext *ctx, GLbitfield mask, GLboolean all, } if (mask) - _swrast_Clear( ctx, mask, all, x, y, width, height ); + _swrast_Clear( ctx, mask ); } void __write_ci32_span8( const GLcontext *ctx, struct gl_renderbuffer *rb, diff --git a/src/mesa/drivers/windows/gdi/wmesa.c b/src/mesa/drivers/windows/gdi/wmesa.c index 0dfd7a6b39..8c3229ab14 100644 --- a/src/mesa/drivers/windows/gdi/wmesa.c +++ b/src/mesa/drivers/windows/gdi/wmesa.c @@ -281,11 +281,7 @@ static void clear_color(GLcontext *ctx, const GLfloat color[4]) * Clearing of the other non-color buffers is left to the swrast. */ -static void clear(GLcontext *ctx, - GLbitfield mask, - GLboolean all, - GLint xFoo, GLint yFoo, - GLint widthFoo, GLint heightFoo) +static void clear(GLcontext *ctx, GLbitfield mask) { #define FLIP(Y) (ctx->DrawBuffer->Height - (Y) - 1) const GLint x = ctx->DrawBuffer->_Xmin; @@ -303,7 +299,7 @@ static void clear(GLcontext *ctx, ctx->Color.ColorMask[1] != 0xff || ctx->Color.ColorMask[2] != 0xff || ctx->Color.ColorMask[3] != 0xff) { - _swrast_Clear(ctx, mask, all, x, y, width, height); + _swrast_Clear(ctx, mask); return; } @@ -322,7 +318,8 @@ static void clear(GLcontext *ctx, /* Try for a fast clear - clearing entire buffer with a single * byte value. */ - if (all) { /* entire buffer */ + if (width == ctx->DrawBuffer->Width && + height == ctx->DrawBuffer->Height) { /* entire buffer */ /* Now check for an easy clear value */ switch (bytesPerPixel) { case 1: @@ -435,7 +432,7 @@ static void clear(GLcontext *ctx, /* Call swrast if there is anything left to clear (like DEPTH) */ if (mask) - _swrast_Clear(ctx, mask, all, x, y, width, height); + _swrast_Clear(ctx, mask); #undef FLIP } diff --git a/src/mesa/drivers/x11/xm_dd.c b/src/mesa/drivers/x11/xm_dd.c index 87bd5e4a30..dbac3b8cdb 100644 --- a/src/mesa/drivers/x11/xm_dd.c +++ b/src/mesa/drivers/x11/xm_dd.c @@ -382,9 +382,7 @@ clear_nbit_ximage(GLcontext *ctx, struct xmesa_renderbuffer *xrb, static void -clear_buffers( GLcontext *ctx, GLbitfield mask, - GLboolean all, GLint xFoo, GLint yFoo, - GLint widthFoo, GLint heightFoo ) +clear_buffers(GLcontext *ctx, GLbitfield buffers) { if (ctx->DrawBuffer->Name == 0) { /* this is a window system framebuffer */ @@ -397,33 +395,33 @@ clear_buffers( GLcontext *ctx, GLbitfield mask, /* we can't handle color or index masking */ if (*colorMask == 0xffffffff && ctx->Color.IndexMask == 0xffffffff) { - if (mask & BUFFER_BIT_FRONT_LEFT) { + if (buffers & BUFFER_BIT_FRONT_LEFT) { /* clear front color buffer */ struct gl_renderbuffer *frontRb = ctx->DrawBuffer->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; if (b->frontxrb == xmesa_renderbuffer(frontRb)) { /* renderbuffer is not wrapped - great! */ b->frontxrb->clearFunc(ctx, b->frontxrb, x, y, width, height); - mask &= ~BUFFER_BIT_FRONT_LEFT; + buffers &= ~BUFFER_BIT_FRONT_LEFT; } else { /* we can't directly clear an alpha-wrapped color buffer */ } } - if (mask & BUFFER_BIT_BACK_LEFT) { + if (buffers & BUFFER_BIT_BACK_LEFT) { /* clear back color buffer */ struct gl_renderbuffer *backRb = ctx->DrawBuffer->Attachment[BUFFER_BACK_LEFT].Renderbuffer; if (b->backxrb == xmesa_renderbuffer(backRb)) { /* renderbuffer is not wrapped - great! */ b->backxrb->clearFunc(ctx, b->backxrb, x, y, width, height); - mask &= ~BUFFER_BIT_BACK_LEFT; + buffers &= ~BUFFER_BIT_BACK_LEFT; } } } } - if (mask) - _swrast_Clear( ctx, mask, 0, 0, 0, 0, 0); + if (buffers) + _swrast_Clear(ctx, buffers); } diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index ef970ad9eb..e22edc1bbc 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -337,6 +337,8 @@ _mesa_PushAttrib(GLbitfield mask) if (mask & GL_TEXTURE_BIT) { struct gl_texture_attrib *attr; GLuint u; + + _mesa_lock_context_textures(ctx); /* Bump the texture object reference counts so that they don't * inadvertantly get deleted. */ @@ -362,6 +364,9 @@ _mesa_PushAttrib(GLbitfield mask) _mesa_copy_texture_object(&attr->Unit[u].SavedRect, attr->Unit[u].CurrentRect); } + + _mesa_unlock_context_textures(ctx); + newnode = new_attrib_node( GL_TEXTURE_BIT ); newnode->data = attr; newnode->next = head; diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c index 2710d04454..ece53463b3 100644 --- a/src/mesa/main/buffers.c +++ b/src/mesa/main/buffers.c @@ -141,10 +141,6 @@ _mesa_Clear( GLbitfield mask ) } if (ctx->RenderMode == GL_RENDER) { - const GLint x = ctx->DrawBuffer->_Xmin; - const GLint y = ctx->DrawBuffer->_Ymin; - const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; - const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; GLbitfield bufferMask; /* don't clear depth buffer if depth writing disabled */ @@ -177,8 +173,7 @@ _mesa_Clear( GLbitfield mask ) } ASSERT(ctx->Driver.Clear); - ctx->Driver.Clear( ctx, bufferMask, (GLboolean) !ctx->Scissor.Enabled, - x, y, width, height ); + ctx->Driver.Clear(ctx, bufferMask); } } diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 15b69db595..91f3af3c91 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -735,6 +735,10 @@ alloc_shared_state( GLcontext *ctx ) ss->DefaultCubeMap->RefCount += MAX_TEXTURE_IMAGE_UNITS; ss->DefaultRect->RefCount += MAX_TEXTURE_IMAGE_UNITS; + _glthread_INIT_MUTEX(ss->TexMutex); + ss->TextureStateStamp = 0; + + #if FEATURE_EXT_framebuffer_object ss->FrameBuffers = _mesa_NewHashTable(); if (!ss->FrameBuffers) @@ -1048,6 +1052,7 @@ _mesa_init_constants( GLcontext *ctx ) ctx->Const.VertexProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS; ctx->Const.VertexProgram.MaxEnvParams = MAX_NV_VERTEX_PROGRAM_PARAMS; ctx->Const.VertexProgram.MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS; + ctx->Const.VertexProgram.MaxUniformComponents = MAX_VERTEX_UNIFORM_COMPONENTS; init_natives(&ctx->Const.VertexProgram); #endif #if FEATURE_ARB_fragment_program @@ -1061,6 +1066,7 @@ _mesa_init_constants( GLcontext *ctx ) ctx->Const.FragmentProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS; ctx->Const.FragmentProgram.MaxEnvParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS; ctx->Const.FragmentProgram.MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS; + ctx->Const.FragmentProgram.MaxUniformComponents = MAX_FRAGMENT_UNIFORM_COMPONENTS; init_natives(&ctx->Const.FragmentProgram); #endif ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES; @@ -1087,6 +1093,11 @@ _mesa_init_constants( GLcontext *ctx ) ctx->Const.MaxRenderbufferSize = MAX_WIDTH; #endif +#if FEATURE_ARB_vertex_shader + ctx->Const.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS; + ctx->Const.MaxVaryingFloats = MAX_VARYING_FLOATS; +#endif + /* sanity checks */ ASSERT(ctx->Const.MaxTextureUnits == MIN2(ctx->Const.MaxTextureImageUnits, ctx->Const.MaxTextureCoordUnits)); diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index a1999ac76d..1de2542bee 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -99,39 +99,24 @@ struct dd_function_table { /** * Clear the color/depth/stencil/accum buffer(s). - * - * \param mask a bitmask of the DD_*_BIT values defined above that indicates - * which buffers need to be cleared. - * \param all if true then clear the whole buffer, else clear only the - * region defined by (x, y, width, height). - * - * This function must obey the glColorMask(), glIndexMask() and - * glStencilMask() settings! - * Software Mesa can do masked clears if the device driver can't. + * \param buffers a bitmask of BUFFER_BIT_* flags indicating which + * renderbuffers need to be cleared. */ - void (*Clear)( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint x, GLint y, GLint width, GLint height ); - + void (*Clear)( GLcontext *ctx, GLbitfield buffers ); - /** - * \name For hardware accumulation buffer - */ - /*@{*/ /** * Execute glAccum command. */ void (*Accum)( GLcontext *ctx, GLenum op, GLfloat value ); - /*@}*/ /** - * \name glDraw(), glRead(), glCopyPixels() and glBitmap() functions + * \name Image-related functions */ /*@{*/ /** - * This is called by glDrawPixels(). - * + * Called by glDrawPixels(). * \p unpack describes how to unpack the source image data. */ void (*DrawPixels)( GLcontext *ctx, @@ -150,19 +135,14 @@ struct dd_function_table { GLvoid *dest ); /** - * Do a glCopyPixels(). - * - * This function must respect all rasterization state, glPixelTransfer(), - * glPixelZoom(), etc. + * Called by glCopyPixels(). */ void (*CopyPixels)( GLcontext *ctx, GLint srcx, GLint srcy, GLsizei width, GLsizei height, GLint dstx, GLint dsty, GLenum type ); /** - * This is called by glBitmap(). - * - * Works the same as dd_function_table::DrawPixels, above. + * Called by glBitmap(). */ void (*Bitmap)( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c index 5edf9a7dd6..39f8e26f57 100644 --- a/src/mesa/main/extensions.c +++ b/src/mesa/main/extensions.c @@ -135,6 +135,7 @@ static const struct { { OFF, "GL_ATI_texture_env_combine3", F(ATI_texture_env_combine3)}, { OFF, "GL_ATI_texture_mirror_once", F(ATI_texture_mirror_once)}, { OFF, "GL_ATI_fragment_shader", F(ATI_fragment_shader)}, + { OFF, "GL_ATI_separate_stencil", F(ATI_separate_stencil)}, { OFF, "GL_IBM_multimode_draw_arrays", F(IBM_multimode_draw_arrays) }, { ON, "GL_IBM_rasterpos_clip", F(IBM_rasterpos_clip) }, { OFF, "GL_IBM_texture_mirrored_repeat", F(ARB_texture_mirrored_repeat)}, @@ -222,6 +223,7 @@ _mesa_enable_sw_extensions(GLcontext *ctx) #endif ctx->Extensions.ATI_texture_env_combine3 = GL_TRUE; ctx->Extensions.ATI_texture_mirror_once = GL_TRUE; + ctx->Extensions.ATI_separate_stencil = GL_TRUE; ctx->Extensions.EXT_blend_color = GL_TRUE; ctx->Extensions.EXT_blend_equation_separate = GL_TRUE; ctx->Extensions.EXT_blend_func_separate = GL_TRUE; @@ -249,7 +251,7 @@ _mesa_enable_sw_extensions(GLcontext *ctx) ctx->Extensions.EXT_secondary_color = GL_TRUE; ctx->Extensions.EXT_shared_texture_palette = GL_TRUE; ctx->Extensions.EXT_stencil_wrap = GL_TRUE; - ctx->Extensions.EXT_stencil_two_side = GL_TRUE; + ctx->Extensions.EXT_stencil_two_side = GL_FALSE; /* obsolete */ ctx->Extensions.EXT_texture_env_add = GL_TRUE; ctx->Extensions.EXT_texture_env_combine = GL_TRUE; ctx->Extensions.EXT_texture_env_dot3 = GL_TRUE; @@ -388,7 +390,8 @@ _mesa_enable_2_0_extensions(GLcontext *ctx) #if FEATURE_ARB_shading_language_100 ctx->Extensions.ARB_shading_language_100 = GL_TRUE; #endif - ctx->Extensions.EXT_stencil_two_side = GL_FALSE; /* yes, turn it off */ + ctx->Extensions.ATI_separate_stencil = GL_TRUE; + ctx->Extensions.EXT_stencil_two_side = GL_FALSE; /* obsolete */ #if FEATURE_ARB_vertex_shader ctx->Extensions.ARB_vertex_shader = GL_TRUE; #endif diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index 2ca1014631..cf8de1e0cb 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -979,7 +979,9 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer) } FLUSH_VERTICES(ctx, _NEW_BUFFERS); - + if (ctx->Driver.Flush) { + ctx->Driver.Flush(ctx); + } if (framebuffer) { /* Binding a user-created framebuffer object */ newFb = _mesa_lookup_framebuffer(ctx, framebuffer); @@ -1548,7 +1550,9 @@ _mesa_GenerateMipmapEXT(GLenum target) texObj = _mesa_select_tex_object(ctx, texUnit, target); /* XXX this might not handle cube maps correctly */ + _mesa_lock_texture(ctx, texObj); _mesa_generate_mipmap(ctx, target, texUnit, texObj); + _mesa_unlock_texture(ctx, texObj); } diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index 3dd1aa1873..9f3a8d12cf 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -1863,7 +1863,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) break; case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB: CHECK_EXT1(ARB_fragment_shader, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(MAX_FRAGMENT_UNIFORM_COMPONENTS); + params[0] = INT_TO_BOOLEAN(ctx->Const.FragmentProgram.MaxUniformComponents); break; case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB: CHECK_EXT1(ARB_fragment_shader, "GetBooleanv"); @@ -1871,15 +1871,15 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) break; case GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(MAX_VERTEX_UNIFORM_COMPONENTS); + params[0] = INT_TO_BOOLEAN(ctx->Const.VertexProgram.MaxUniformComponents); break; case GL_MAX_VARYING_FLOATS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(MAX_VARYING_FLOATS); + params[0] = INT_TO_BOOLEAN(ctx->Const.MaxVaryingFloats); break; case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(MAX_VERTEX_TEXTURE_IMAGE_UNITS); + params[0] = INT_TO_BOOLEAN(ctx->Const.MaxVertexTextureImageUnits); break; case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetBooleanv"); @@ -3687,7 +3687,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) break; case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB: CHECK_EXT1(ARB_fragment_shader, "GetFloatv"); - params[0] = (GLfloat)(MAX_FRAGMENT_UNIFORM_COMPONENTS); + params[0] = (GLfloat)(ctx->Const.FragmentProgram.MaxUniformComponents); break; case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB: CHECK_EXT1(ARB_fragment_shader, "GetFloatv"); @@ -3695,15 +3695,15 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) break; case GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetFloatv"); - params[0] = (GLfloat)(MAX_VERTEX_UNIFORM_COMPONENTS); + params[0] = (GLfloat)(ctx->Const.VertexProgram.MaxUniformComponents); break; case GL_MAX_VARYING_FLOATS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetFloatv"); - params[0] = (GLfloat)(MAX_VARYING_FLOATS); + params[0] = (GLfloat)(ctx->Const.MaxVaryingFloats); break; case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetFloatv"); - params[0] = (GLfloat)(MAX_VERTEX_TEXTURE_IMAGE_UNITS); + params[0] = (GLfloat)(ctx->Const.MaxVertexTextureImageUnits); break; case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetFloatv"); @@ -5511,7 +5511,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) break; case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB: CHECK_EXT1(ARB_fragment_shader, "GetIntegerv"); - params[0] = MAX_FRAGMENT_UNIFORM_COMPONENTS; + params[0] = ctx->Const.FragmentProgram.MaxUniformComponents; break; case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB: CHECK_EXT1(ARB_fragment_shader, "GetIntegerv"); @@ -5519,15 +5519,15 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) break; case GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetIntegerv"); - params[0] = MAX_VERTEX_UNIFORM_COMPONENTS; + params[0] = ctx->Const.VertexProgram.MaxUniformComponents; break; case GL_MAX_VARYING_FLOATS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetIntegerv"); - params[0] = MAX_VARYING_FLOATS; + params[0] = ctx->Const.MaxVaryingFloats; break; case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetIntegerv"); - params[0] = MAX_VERTEX_TEXTURE_IMAGE_UNITS; + params[0] = ctx->Const.MaxVertexTextureImageUnits; break; case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetIntegerv"); diff --git a/src/mesa/main/get_gen.py b/src/mesa/main/get_gen.py index ec8a192b31..50ff13d2f9 100644 --- a/src/mesa/main/get_gen.py +++ b/src/mesa/main/get_gen.py @@ -978,17 +978,19 @@ StateVars = [ # GL_ARB_fragment_shader ( "GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB", GLint, - ["MAX_FRAGMENT_UNIFORM_COMPONENTS"], "", ["ARB_fragment_shader"] ), + ["ctx->Const.FragmentProgram.MaxUniformComponents"], "", + ["ARB_fragment_shader"] ), ( "GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB", GLenum, ["ctx->Hint.FragmentShaderDerivative"], "", ["ARB_fragment_shader"] ), # GL_ARB_vertex_shader ( "GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB", GLint, - ["MAX_VERTEX_UNIFORM_COMPONENTS"], "", ["ARB_vertex_shader"] ), + ["ctx->Const.VertexProgram.MaxUniformComponents"], "", + ["ARB_vertex_shader"] ), ( "GL_MAX_VARYING_FLOATS_ARB", GLint, - ["MAX_VARYING_FLOATS"], "", ["ARB_vertex_shader"] ), + ["ctx->Const.MaxVaryingFloats"], "", ["ARB_vertex_shader"] ), ( "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB", GLint, - ["MAX_VERTEX_TEXTURE_IMAGE_UNITS"], "", ["ARB_vertex_shader"] ), + ["ctx->Const.MaxVertexTextureImageUnits"], "", ["ARB_vertex_shader"] ), ( "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB", GLint, ["MAX_COMBINED_TEXTURE_IMAGE_UNITS"], "", ["ARB_vertex_shader"] ) ] diff --git a/src/mesa/main/getstring.c b/src/mesa/main/getstring.c index a68bf9ff74..f2989aaefa 100644 --- a/src/mesa/main/getstring.c +++ b/src/mesa/main/getstring.c @@ -54,7 +54,7 @@ _mesa_GetString( GLenum name ) static const char *version_1_3 = "1.3 Mesa " MESA_VERSION_STRING; static const char *version_1_4 = "1.4 Mesa " MESA_VERSION_STRING; static const char *version_1_5 = "1.5 Mesa " MESA_VERSION_STRING; - static const char *version_2_0 = "1.5 Mesa " MESA_VERSION_STRING;/*XXX FIX*/ + static const char *version_2_0 = "1.5 Mesa " MESA_VERSION_STRING; #if FEATURE_ARB_shading_language_100 static const char *sl_version_110 = "1.10 Mesa " MESA_VERSION_STRING; @@ -111,7 +111,7 @@ _mesa_GetString( GLenum name ) if (ctx->Extensions.ARB_draw_buffers && ctx->Extensions.ARB_point_sprite && ctx->Extensions.ARB_texture_non_power_of_two && - ctx->Extensions.EXT_stencil_two_side) { + ctx->Extensions.ATI_separate_stencil) { return (const GLubyte *) version_2_0; } else { diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c index 604dea34e0..f154bd4651 100644 --- a/src/mesa/main/mipmap.c +++ b/src/mesa/main/mipmap.c @@ -883,7 +883,7 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, GLint border, bytesPerTexel; /* get src image parameters */ - srcImage = _mesa_select_tex_image(ctx, texUnit, target, level); + srcImage = _mesa_select_tex_image(ctx, texObj, target, level); ASSERT(srcImage); srcWidth = srcImage->Width; srcHeight = srcImage->Height; @@ -922,7 +922,7 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, } /* get dest gl_texture_image */ - dstImage = _mesa_get_tex_image(ctx, texUnit, target, level + 1); + dstImage = _mesa_get_tex_image(ctx, texObj, target, level + 1); if (!dstImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); return; diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index bc7c6b8026..1d5eb61e06 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1909,20 +1909,6 @@ struct gl_program_state }; -/** - * Virtual vertex program machine state. - * Only used during program execution (may be moved someday): - */ -struct gl_vertex_program_machine -{ - GLfloat Temporaries[MAX_NV_VERTEX_PROGRAM_TEMPS][4]; - GLfloat Inputs[MAX_NV_VERTEX_PROGRAM_INPUTS][4]; - GLuint InputsSize[MAX_NV_VERTEX_PROGRAM_INPUTS]; - GLfloat Outputs[MAX_NV_VERTEX_PROGRAM_OUTPUTS][4]; - GLint AddressReg[4]; -}; - - /** * Context state for vertex programs. */ @@ -1939,8 +1925,6 @@ struct gl_vertex_program_state GLfloat Parameters[MAX_NV_VERTEX_PROGRAM_PARAMS][4]; /**< Env params */ - struct gl_vertex_program_machine Machine; - /* For GL_NV_vertex_program only: */ GLenum TrackMatrix[MAX_NV_VERTEX_PROGRAM_PARAMS / 4]; GLenum TrackMatrixTransform[MAX_NV_VERTEX_PROGRAM_PARAMS / 4]; @@ -2074,6 +2058,19 @@ struct gl_shared_state struct gl_texture_object *DefaultRect; /*@}*/ + /** + * \name Thread safety and statechange notification for texture + * objects. + * + * \todo Improve the granularity of locking. + */ + /*@{*/ + _glthread_Mutex TexMutex; /**< texobj thread safety */ + GLuint TextureStateStamp; /**< state notification for shared tex */ + /*@}*/ + + + /** * \name Vertex/fragment programs */ @@ -2323,6 +2320,8 @@ struct gl_program_constants GLuint MaxNativeTemps; GLuint MaxNativeAddressRegs; /* vertex program only, for now */ GLuint MaxNativeParameters; + /* For shaders */ + GLuint MaxUniformComponents; }; @@ -2372,6 +2371,9 @@ struct gl_constants /* GL_EXT_framebuffer_object */ GLuint MaxColorAttachments; GLuint MaxRenderbufferSize; + /* GL_ARB_vertex_shader */ + GLuint MaxVertexTextureImageUnits; + GLuint MaxVaryingFloats; }; @@ -2471,6 +2473,7 @@ struct gl_extensions GLboolean ATI_texture_mirror_once; GLboolean ATI_texture_env_combine3; GLboolean ATI_fragment_shader; + GLboolean ATI_separate_stencil; GLboolean IBM_rasterpos_clip; GLboolean IBM_multimode_draw_arrays; GLboolean MESA_pack_invert; @@ -2938,6 +2941,8 @@ struct __GLcontextRec GLboolean _ForceEyeCoords; GLenum _CurrentProgram; /* currently executing program */ + GLuint TextureStateTimestamp; /* detect changes to shared state */ + struct gl_shine_tab *_ShineTable[2]; /**< Active shine tables */ struct gl_shine_tab *_ShineTabList; /**< MRU list of inactive shine tables */ /**@}*/ diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index d57217d9c4..06cf5f8698 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -1003,7 +1003,7 @@ update_color(GLcontext *ctx) * _mesa_update_lighting() and _mesa_update_tnl_spaces(). */ void -_mesa_update_state( GLcontext *ctx ) +_mesa_update_state_locked( GLcontext *ctx ) { GLbitfield new_state = ctx->NewState; @@ -1084,4 +1084,17 @@ _mesa_update_state( GLcontext *ctx ) ctx->Array.NewState = 0; } + +/* This is the usual entrypoint for state updates: + */ +void +_mesa_update_state( GLcontext *ctx ) +{ + _mesa_lock_context_textures(ctx); + _mesa_update_state_locked(ctx); + _mesa_unlock_context_textures(ctx); +} + + + /*@}*/ diff --git a/src/mesa/main/state.h b/src/mesa/main/state.h index 58cfcc4146..5240d4bf93 100644 --- a/src/mesa/main/state.h +++ b/src/mesa/main/state.h @@ -39,5 +39,11 @@ _mesa_init_exec_table(struct _glapi_table *exec); extern void _mesa_update_state( GLcontext *ctx ); +/* As above but can only be called between _mesa_lock_context_textures() and + * _mesa_unlock_context_textures(). + */ +extern void +_mesa_update_state_locked( GLcontext *ctx ); + #endif diff --git a/src/mesa/main/stencil.c b/src/mesa/main/stencil.c index 9992ec9b6e..d6be410e76 100644 --- a/src/mesa/main/stencil.c +++ b/src/mesa/main/stencil.c @@ -115,23 +115,7 @@ _mesa_StencilFunc( GLenum func, GLint ref, GLuint mask ) ref = CLAMP( ref, 0, stencilMax ); - if (ctx->Extensions.EXT_stencil_two_side) { - /* only set active face state */ - const GLint face = ctx->Stencil.ActiveFace; - if (ctx->Stencil.Function[face] == func && - ctx->Stencil.ValueMask[face] == mask && - ctx->Stencil.Ref[face] == ref) - return; - FLUSH_VERTICES(ctx, _NEW_STENCIL); - ctx->Stencil.Function[face] = func; - ctx->Stencil.Ref[face] = ref; - ctx->Stencil.ValueMask[face] = mask; - if (ctx->Driver.StencilFuncSeparate) { - ctx->Driver.StencilFuncSeparate(ctx, face ? GL_BACK : GL_FRONT, - func, ref, mask); - } - } - else { + if (ctx->Extensions.ATI_separate_stencil) { /* set both front and back state */ if (ctx->Stencil.Function[0] == func && ctx->Stencil.Function[1] == func && @@ -149,6 +133,22 @@ _mesa_StencilFunc( GLenum func, GLint ref, GLuint mask ) func, ref, mask); } } + else { + /* only set active face state */ + const GLint face = ctx->Stencil.ActiveFace; + if (ctx->Stencil.Function[face] == func && + ctx->Stencil.ValueMask[face] == mask && + ctx->Stencil.Ref[face] == ref) + return; + FLUSH_VERTICES(ctx, _NEW_STENCIL); + ctx->Stencil.Function[face] = func; + ctx->Stencil.Ref[face] = ref; + ctx->Stencil.ValueMask[face] = mask; + if (ctx->Driver.StencilFuncSeparate) { + ctx->Driver.StencilFuncSeparate(ctx, face ? GL_BACK : GL_FRONT, + func, ref, mask); + } + } } @@ -169,26 +169,26 @@ _mesa_StencilMask( GLuint mask ) GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); - if (ctx->Extensions.EXT_stencil_two_side) { - /* only set active face state */ - const GLint face = ctx->Stencil.ActiveFace; - if (ctx->Stencil.WriteMask[face] == mask) + if (ctx->Extensions.ATI_separate_stencil) { + /* set both front and back state */ + if (ctx->Stencil.WriteMask[0] == mask && + ctx->Stencil.WriteMask[1] == mask) return; FLUSH_VERTICES(ctx, _NEW_STENCIL); - ctx->Stencil.WriteMask[face] = mask; + ctx->Stencil.WriteMask[0] = ctx->Stencil.WriteMask[1] = mask; if (ctx->Driver.StencilMaskSeparate) { - ctx->Driver.StencilMaskSeparate(ctx, face ? GL_BACK : GL_FRONT, mask); + ctx->Driver.StencilMaskSeparate(ctx, GL_FRONT_AND_BACK, mask); } } else { - /* set both front and back state */ - if (ctx->Stencil.WriteMask[0] == mask && - ctx->Stencil.WriteMask[1] == mask) + /* only set active face state */ + const GLint face = ctx->Stencil.ActiveFace; + if (ctx->Stencil.WriteMask[face] == mask) return; FLUSH_VERTICES(ctx, _NEW_STENCIL); - ctx->Stencil.WriteMask[0] = ctx->Stencil.WriteMask[1] = mask; + ctx->Stencil.WriteMask[face] = mask; if (ctx->Driver.StencilMaskSeparate) { - ctx->Driver.StencilMaskSeparate(ctx, GL_FRONT_AND_BACK, mask); + ctx->Driver.StencilMaskSeparate(ctx, face ? GL_BACK : GL_FRONT, mask); } } } @@ -269,23 +269,7 @@ _mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass) return; } - if (ctx->Extensions.EXT_stencil_two_side) { - /* only set active face state */ - const GLint face = ctx->Stencil.ActiveFace; - if (ctx->Stencil.ZFailFunc[face] == zfail && - ctx->Stencil.ZPassFunc[face] == zpass && - ctx->Stencil.FailFunc[face] == fail) - return; - FLUSH_VERTICES(ctx, _NEW_STENCIL); - ctx->Stencil.ZFailFunc[face] = zfail; - ctx->Stencil.ZPassFunc[face] = zpass; - ctx->Stencil.FailFunc[face] = fail; - if (ctx->Driver.StencilOpSeparate) { - ctx->Driver.StencilOpSeparate(ctx, face ? GL_BACK : GL_FRONT, - fail, zfail, zpass); - } - } - else { + if (ctx->Extensions.ATI_separate_stencil) { /* set both front and back state */ if (ctx->Stencil.ZFailFunc[0] == zfail && ctx->Stencil.ZFailFunc[1] == zfail && @@ -303,6 +287,22 @@ _mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass) fail, zfail, zpass); } } + else { + /* only set active face state */ + const GLint face = ctx->Stencil.ActiveFace; + if (ctx->Stencil.ZFailFunc[face] == zfail && + ctx->Stencil.ZPassFunc[face] == zpass && + ctx->Stencil.FailFunc[face] == fail) + return; + FLUSH_VERTICES(ctx, _NEW_STENCIL); + ctx->Stencil.ZFailFunc[face] = zfail; + ctx->Stencil.ZPassFunc[face] = zpass; + ctx->Stencil.FailFunc[face] = fail; + if (ctx->Driver.StencilOpSeparate) { + ctx->Driver.StencilOpSeparate(ctx, face ? GL_BACK : GL_FRONT, + fail, zfail, zpass); + } + } } @@ -406,17 +406,16 @@ _mesa_StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) FLUSH_VERTICES(ctx, _NEW_STENCIL); - if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + if (face != GL_BACK) { ctx->Stencil.FailFunc[0] = fail; ctx->Stencil.ZFailFunc[0] = zfail; ctx->Stencil.ZPassFunc[0] = zpass; } - if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + if (face != GL_FRONT) { ctx->Stencil.FailFunc[1] = fail; ctx->Stencil.ZFailFunc[1] = zfail; ctx->Stencil.ZPassFunc[1] = zpass; } - if (ctx->Driver.StencilOpSeparate) { ctx->Driver.StencilOpSeparate(ctx, face, fail, zfail, zpass); } @@ -465,7 +464,6 @@ _mesa_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) ctx->Stencil.Ref[1] = ref; ctx->Stencil.ValueMask[1] = mask; } - if (ctx->Driver.StencilFuncSeparate) { ctx->Driver.StencilFuncSeparate(ctx, face, func, ref, mask); } @@ -486,13 +484,12 @@ _mesa_StencilMaskSeparate(GLenum face, GLuint mask) FLUSH_VERTICES(ctx, _NEW_STENCIL); - if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + if (face != GL_BACK) { ctx->Stencil.WriteMask[0] = mask; } - if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + if (face != GL_FRONT) { ctx->Stencil.WriteMask[1] = mask; } - if (ctx->Driver.StencilMaskSeparate) { ctx->Driver.StencilMaskSeparate(ctx, face, mask); } diff --git a/src/mesa/main/texcompress_s3tc.c b/src/mesa/main/texcompress_s3tc.c index 65ecaba3a3..c71501c5e6 100644 --- a/src/mesa/main/texcompress_s3tc.c +++ b/src/mesa/main/texcompress_s3tc.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5.1 + * Version: 6.5.2 * * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * @@ -48,6 +48,8 @@ #ifdef __MINGW32__ #define DXTN_LIBNAME "dxtn.dll" +#define RTLD_LAZY 0 +#define RTLD_GLOBAL 0 #elif defined(__DJGPP__) #define DXTN_LIBNAME "dxtn.dxe" #else @@ -104,7 +106,7 @@ _mesa_dlsym(void *handle, const char *fname) { #if USE_EXTERNAL_DXTN_LIB #ifdef __MINGW32__ - return (GenericFunc) GetProcAddress(handle, fname) + return (GenericFunc) GetProcAddress(handle, fname); #elif defined(__DJGPP__) /* need '_' prefix on symbol names */ char fname2[1000]; diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c index 5f798cc7df..c99ff5cdc4 100644 --- a/src/mesa/main/texenvprogram.c +++ b/src/mesa/main/texenvprogram.c @@ -33,7 +33,11 @@ #include "shader/program.h" #include "shader/program_instruction.h" -#define MAX_INSTRUCTIONS 100 +/** + * According to Glean's texCombine test, no more than 21 instructions + * are needed. Allow a few extra just in case. + */ +#define MAX_INSTRUCTIONS 24 #define DISASSEM (MESA_VERBOSE & VERBOSE_DISASSEM) @@ -474,7 +478,7 @@ emit_op(struct texenv_fragment_program *p, GLuint nr = p->program->Base.NumInstructions++; struct prog_instruction *inst = &p->program->Base.Instructions[nr]; - _mesa_init_instruction(inst); + _mesa_init_instructions(inst, 1); inst->Opcode = op; emit_arg( &inst->SrcReg[0], src0 ); @@ -988,9 +992,10 @@ load_texunit_sources( struct texenv_fragment_program *p, int unit ) * current texture env/combine mode. */ static void -create_new_program(struct state_key *key, GLcontext *ctx, +create_new_program(GLcontext *ctx, struct state_key *key, struct gl_fragment_program *program) { + struct prog_instruction instBuffer[MAX_INSTRUCTIONS]; struct texenv_fragment_program p; GLuint unit; struct ureg cf, out; @@ -1000,18 +1005,19 @@ create_new_program(struct state_key *key, GLcontext *ctx, p.state = key; p.program = program; - p.program->Base.Instructions = - (struct prog_instruction*) _mesa_malloc(sizeof(struct prog_instruction) * MAX_INSTRUCTIONS); - p.program->Base.NumInstructions = 0; + /* During code generation, use locally-allocated instruction buffer, + * then alloc dynamic storage below. + */ + p.program->Base.Instructions = instBuffer; p.program->Base.Target = GL_FRAGMENT_PROGRAM_ARB; p.program->NumTexIndirections = 1; /* correct? */ p.program->NumTexInstructions = 0; p.program->NumAluInstructions = 0; p.program->Base.String = 0; p.program->Base.NumInstructions = - p.program->Base.NumTemporaries = - p.program->Base.NumParameters = - p.program->Base.NumAttributes = p.program->Base.NumAddressRegs = 0; + p.program->Base.NumTemporaries = + p.program->Base.NumParameters = + p.program->Base.NumAttributes = p.program->Base.NumAddressRegs = 0; p.program->Base.Parameters = _mesa_new_parameter_list(); p.program->Base.InputsRead = 0; @@ -1088,17 +1094,28 @@ create_new_program(struct state_key *key, GLcontext *ctx, ASSERT(p.program->Base.NumInstructions <= MAX_INSTRUCTIONS); + /* Allocate final instruction array */ + program->Base.Instructions + = _mesa_alloc_instructions(program->Base.NumInstructions); + if (!program->Base.Instructions) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, + "generating tex env program"); + return; + } + _mesa_memcpy(program->Base.Instructions, instBuffer, + sizeof(struct prog_instruction) + * program->Base.NumInstructions); + /* Notify driver the fragment program has (actually) changed. */ - if (ctx->Driver.ProgramStringNotify || DISASSEM) { - if (ctx->Driver.ProgramStringNotify) - ctx->Driver.ProgramStringNotify( ctx, GL_FRAGMENT_PROGRAM_ARB, - &p.program->Base ); - - if (DISASSEM) { - _mesa_print_program(&p.program->Base); - _mesa_printf("\n"); - } + if (ctx->Driver.ProgramStringNotify) { + ctx->Driver.ProgramStringNotify( ctx, GL_FRAGMENT_PROGRAM_ARB, + &p.program->Base ); + } + + if (DISASSEM) { + _mesa_print_program(&p.program->Base); + _mesa_printf("\n"); } } @@ -1225,7 +1242,7 @@ void _mesa_UpdateTexEnvProgram( GLcontext *ctx ) (struct gl_fragment_program *) ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); - create_new_program(&key, ctx, ctx->_TexEnvProgram); + create_new_program(ctx, &key, ctx->_TexEnvProgram); cache_item(&ctx->Texture.env_fp_cache, hash, &key, ctx->_TexEnvProgram); } else { diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index c2ba450cb3..662f697147 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -706,9 +706,12 @@ _mesa_free_texture_image_data(GLcontext *ctx, void _mesa_delete_texture_image( GLcontext *ctx, struct gl_texture_image *texImage ) { - if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } + /* Free texImage->Data and/or any other driver-specific texture + * image storage. + */ + ASSERT(ctx->Driver.FreeTexImageData); + ctx->Driver.FreeTexImageData( ctx, texImage ); + ASSERT(texImage->Data == NULL); if (texImage->ImageOffsets) _mesa_free(texImage->ImageOffsets); @@ -801,24 +804,23 @@ _mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit, * \sa gl_texture_unit. */ struct gl_texture_image * -_mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit, - GLenum target, GLint level) +_mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_object *texObj, + GLenum target, GLint level) { - ASSERT(texUnit); - ASSERT(level < MAX_TEXTURE_LEVELS); + ASSERT(texObj); + + if (level < 0 || level >= MAX_TEXTURE_LEVELS) + return NULL; + switch (target) { case GL_TEXTURE_1D: - return texUnit->Current1D->Image[0][level]; case GL_PROXY_TEXTURE_1D: - return ctx->Texture.Proxy1D->Image[0][level]; case GL_TEXTURE_2D: - return texUnit->Current2D->Image[0][level]; case GL_PROXY_TEXTURE_2D: - return ctx->Texture.Proxy2D->Image[0][level]; case GL_TEXTURE_3D: - return texUnit->Current3D->Image[0][level]; case GL_PROXY_TEXTURE_3D: - return ctx->Texture.Proxy3D->Image[0][level]; + return texObj->Image[0][level]; + case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: @@ -828,33 +830,25 @@ _mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit, if (ctx->Extensions.ARB_texture_cube_map) { GLuint face = ((GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X); - return texUnit->CurrentCubeMap->Image[face][level]; + return texObj->Image[face][level]; } else return NULL; + case GL_PROXY_TEXTURE_CUBE_MAP_ARB: if (ctx->Extensions.ARB_texture_cube_map) - return ctx->Texture.ProxyCubeMap->Image[0][level]; + return texObj->Image[0][level]; else return NULL; + case GL_TEXTURE_RECTANGLE_NV: - if (ctx->Extensions.NV_texture_rectangle) { - ASSERT(level == 0); - return texUnit->CurrentRect->Image[0][level]; - } - else { - return NULL; - } case GL_PROXY_TEXTURE_RECTANGLE_NV: - if (ctx->Extensions.NV_texture_rectangle) { - ASSERT(level == 0); - return ctx->Texture.ProxyRect->Image[0][level]; - } - else { + if (ctx->Extensions.NV_texture_rectangle && level == 0) + return texObj->Image[0][level]; + else return NULL; - } + default: - _mesa_problem(ctx, "bad target in _mesa_select_tex_image()"); return NULL; } } @@ -866,22 +860,25 @@ _mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit, * out of memory. */ struct gl_texture_image * -_mesa_get_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit, +_mesa_get_tex_image(GLcontext *ctx, struct gl_texture_object *texObj, GLenum target, GLint level) { struct gl_texture_image *texImage; - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + + if (!texObj) + return NULL; + + texImage = _mesa_select_tex_image(ctx, texObj, target, level); if (!texImage) { - struct gl_texture_object *texObj; texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture image allocation"); return NULL; } - texObj = _mesa_select_tex_object(ctx, texUnit, target); - ASSERT(texObj); + _mesa_set_tex_image(texObj, target, level, texImage); } + return texImage; } @@ -1584,9 +1581,6 @@ subtexture_error_check( GLcontext *ctx, GLuint dimensions, GLint width, GLint height, GLint depth, GLenum format, GLenum type ) { - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - struct gl_texture_image *destTex; - /* Check target */ if (dimensions == 1) { if (target != GL_TEXTURE_1D) { @@ -1602,8 +1596,7 @@ subtexture_error_check( GLcontext *ctx, GLuint dimensions, return GL_TRUE; } } - else if (ctx->Extensions.NV_texture_rectangle && - target == GL_TEXTURE_RECTANGLE_NV) { + else if (target == GL_TEXTURE_RECTANGLE_NV) { if (!ctx->Extensions.NV_texture_rectangle) { _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" ); return GL_TRUE; @@ -1647,8 +1640,23 @@ subtexture_error_check( GLcontext *ctx, GLuint dimensions, return GL_TRUE; } - destTex = _mesa_select_tex_image(ctx, texUnit, target, level); + if (!_mesa_is_legal_format_and_type(ctx, format, type)) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glTexSubImage%dD(format or type)", dimensions); + return GL_TRUE; + } + + return GL_FALSE; +} +static GLboolean +subtexture_error_check2( GLcontext *ctx, GLuint dimensions, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint width, GLint height, GLint depth, + GLenum format, GLenum type, + const struct gl_texture_image *destTex ) +{ if (!destTex) { /* undefined image level */ _mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage%dD", dimensions); @@ -1688,12 +1696,6 @@ subtexture_error_check( GLcontext *ctx, GLuint dimensions, } } - if (!_mesa_is_legal_format_and_type(ctx, format, type)) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glTexSubImage%dD(format or type)", dimensions); - return GL_TRUE; - } - #if FEATURE_EXT_texture_sRGB if (destTex->InternalFormat == GL_COMPRESSED_SRGB_S3TC_DXT1_EXT || destTex->InternalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT || @@ -1709,11 +1711,6 @@ subtexture_error_check( GLcontext *ctx, GLuint dimensions, #endif if (destTex->IsCompressed) { - const struct gl_texture_unit *texUnit; - const struct gl_texture_image *texImage; - texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) { /* OK */ } @@ -1735,12 +1732,12 @@ subtexture_error_check( GLcontext *ctx, GLuint dimensions, return GL_TRUE; } /* size must be multiple of 4 or equal to whole texture size */ - if ((width & 3) && (GLuint) width != texImage->Width) { + if ((width & 3) && (GLuint) width != destTex->Width) { _mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage%D(width)", dimensions); return GL_TRUE; } - if ((height & 3) && (GLuint) height != texImage->Height) { + if ((height & 3) && (GLuint) height != destTex->Height) { _mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage%D(width)", dimensions); return GL_TRUE; @@ -1781,6 +1778,11 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions, /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */ if (level < 0 || level >= MAX_TEXTURE_LEVELS) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyTexImage%dD(level=%d)", dimensions, level); + return GL_TRUE; + } + /* Check that the source buffer is complete */ if (ctx->ReadBuffer->Name) { _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer); @@ -1791,11 +1793,6 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions, } } - _mesa_error(ctx, GL_INVALID_VALUE, - "glCopyTexImage%dD(level=%d)", dimensions, level); - return GL_TRUE; - } - /* Check border */ if (border < 0 || border > 1 || ((target == GL_TEXTURE_RECTANGLE_NV || @@ -1945,11 +1942,8 @@ static GLboolean copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height ) + GLsizei width, GLsizei height) { - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - struct gl_texture_image *teximage; - /* Check target */ /* Check that the source buffer is complete */ if (ctx->ReadBuffer->Name) { @@ -2012,7 +2006,16 @@ copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions, return GL_TRUE; } - teximage = _mesa_select_tex_image(ctx, texUnit, target, level); + return GL_FALSE; +} + +static GLboolean +copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, + const struct gl_texture_image *teximage ) +{ if (!teximage) { _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexSubImage%dD(undefined texture level: %d)", @@ -2186,59 +2189,66 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format, if (!pixels) return; - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - if (!texImage) { - /* invalid mipmap level, not an error */ - return; - } + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_select_tex_image(ctx, texObj, target, level); + if (!texImage) { + /* invalid mipmap level, not an error */ + goto out; + } - /* Make sure the requested image format is compatible with the - * texture's format. Note that a color index texture can be converted - * to RGBA so that combo is allowed. - */ - if (is_color_format(format) - && !is_color_format(texImage->TexFormat->BaseFormat) - && !is_index_format(texImage->TexFormat->BaseFormat)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); - return; - } - else if (is_index_format(format) - && !is_index_format(texImage->TexFormat->BaseFormat)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); - return; - } - else if (is_depth_format(format) - && !is_depth_format(texImage->TexFormat->BaseFormat) - && !is_depthstencil_format(texImage->TexFormat->BaseFormat)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); - return; - } - else if (is_ycbcr_format(format) - && !is_ycbcr_format(texImage->TexFormat->BaseFormat)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); - return; - } - else if (is_depthstencil_format(format) - && !is_depthstencil_format(texImage->TexFormat->BaseFormat)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); - return; - } - if (ctx->Pack.BufferObj->Name) { - /* packing texture image into a PBO */ - const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2; - if (!_mesa_validate_pbo_access(dimensions, &ctx->Pack, texImage->Width, - texImage->Height, texImage->Depth, - format, type, pixels)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetTexImage(invalid PBO access)"); - return; + /* Make sure the requested image format is compatible with the + * texture's format. Note that a color index texture can be converted + * to RGBA so that combo is allowed. + */ + if (is_color_format(format) + && !is_color_format(texImage->TexFormat->BaseFormat) + && !is_index_format(texImage->TexFormat->BaseFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); + goto out; + } + else if (is_index_format(format) + && !is_index_format(texImage->TexFormat->BaseFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); + goto out; + } + else if (is_depth_format(format) + && !is_depth_format(texImage->TexFormat->BaseFormat) + && !is_depthstencil_format(texImage->TexFormat->BaseFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); + goto out; + } + else if (is_ycbcr_format(format) + && !is_ycbcr_format(texImage->TexFormat->BaseFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); + goto out; + } + else if (is_depthstencil_format(format) + && !is_depthstencil_format(texImage->TexFormat->BaseFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); + goto out; + } + + if (ctx->Pack.BufferObj->Name) { + /* packing texture image into a PBO */ + const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2; + if (!_mesa_validate_pbo_access(dimensions, &ctx->Pack, texImage->Width, + texImage->Height, texImage->Depth, + format, type, pixels)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTexImage(invalid PBO access)"); + goto out; + } } - } - /* typically, this will call _mesa_get_teximage() */ - ctx->Driver.GetTexImage(ctx, target, level, format, type, pixels, - texObj, texImage); + /* typically, this will call _mesa_get_teximage() */ + ctx->Driver.GetTexImage(ctx, target, level, format, type, pixels, + texObj, texImage); + + } + out: + _mesa_unlock_texture(ctx, texObj); } @@ -2301,40 +2311,47 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, return; /* error was recorded */ } - texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_get_tex_image(ctx, texUnit, target, level); - - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); - return; - } - else if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } - ASSERT(texImage->Data == NULL); - clear_teximage_fields(texImage); /* not really needed, but helpful */ - _mesa_init_teximage_fields(ctx, target, texImage, - postConvWidth, 1, 1, - border, internalFormat); - if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) - _mesa_update_state(ctx); + _mesa_update_state(ctx); - ASSERT(ctx->Driver.TexImage1D); + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_get_tex_image(ctx, texObj, target, level); + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); + goto out; + } + + if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); + } - /* Give the texture to the driver! may be null! */ - (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat, - width, border, format, type, pixels, - &ctx->Unpack, texObj, texImage); + ASSERT(texImage->Data == NULL); - ASSERT(texImage->TexFormat); + clear_teximage_fields(texImage); /* not really needed, but helpful */ + _mesa_init_teximage_fields(ctx, target, texImage, + postConvWidth, 1, 1, + border, internalFormat); + + ASSERT(ctx->Driver.TexImage1D); - update_fbo_texture(ctx, texObj, face, level); + /* Give the texture to the driver! may be null! */ + (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat, + width, border, format, type, pixels, + &ctx->Unpack, texObj, texImage); + + ASSERT(texImage->TexFormat); - /* state update */ - texObj->Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; + update_fbo_texture(ctx, texObj, face, level); + + /* state update */ + texObj->Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + out: + _mesa_unlock_texture(ctx, texObj); } else if (target == GL_PROXY_TEXTURE_1D) { /* Proxy texture: check for errors and update proxy state */ @@ -2396,39 +2413,46 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, return; /* error was recorded */ } - texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_get_tex_image(ctx, texUnit, target, level); - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); - return; - } - else if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } - ASSERT(texImage->Data == NULL); - clear_teximage_fields(texImage); /* not really needed, but helpful */ - _mesa_init_teximage_fields(ctx, target, texImage, - postConvWidth, postConvHeight, 1, - border, internalFormat); - if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) - _mesa_update_state(ctx); + _mesa_update_state(ctx); - ASSERT(ctx->Driver.TexImage2D); - - /* Give the texture to the driver! may be null! */ - (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat, - width, height, border, format, type, pixels, - &ctx->Unpack, texObj, texImage); - - ASSERT(texImage->TexFormat); - - update_fbo_texture(ctx, texObj, face, level); - - /* state update */ - texObj->Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_get_tex_image(ctx, texObj, target, level); + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + goto out; + } + + if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); + } + + ASSERT(texImage->Data == NULL); + clear_teximage_fields(texImage); /* not really needed, but helpful */ + _mesa_init_teximage_fields(ctx, target, texImage, + postConvWidth, postConvHeight, 1, + border, internalFormat); + + ASSERT(ctx->Driver.TexImage2D); + + /* Give the texture to the driver! may be null! */ + (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat, + width, height, border, format, type, pixels, + &ctx->Unpack, texObj, texImage); + + ASSERT(texImage->TexFormat); + + update_fbo_texture(ctx, texObj, face, level); + + /* state update */ + texObj->Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + out: + _mesa_unlock_texture(ctx, texObj); } else if (target == GL_PROXY_TEXTURE_2D || (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB && @@ -2486,39 +2510,46 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, return; /* error was recorded */ } + if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) + _mesa_update_state(ctx); + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_get_tex_image(ctx, texUnit, target, level); - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); - return; - } - else if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } - ASSERT(texImage->Data == NULL); - clear_teximage_fields(texImage); /* not really needed, but helpful */ - _mesa_init_teximage_fields(ctx, target, texImage, - width, height, depth, - border, internalFormat); - - if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) - _mesa_update_state(ctx); + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_get_tex_image(ctx, texObj, target, level); + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); + goto out; + } + + if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); + } + + ASSERT(texImage->Data == NULL); + clear_teximage_fields(texImage); /* not really needed, but helpful */ + _mesa_init_teximage_fields(ctx, target, texImage, + width, height, depth, + border, internalFormat); - ASSERT(ctx->Driver.TexImage3D); + ASSERT(ctx->Driver.TexImage3D); - /* Give the texture to the driver! may be null! */ - (*ctx->Driver.TexImage3D)(ctx, target, level, internalFormat, - width, height, depth, border, format, type, - pixels, &ctx->Unpack, texObj, texImage); + /* Give the texture to the driver! may be null! */ + (*ctx->Driver.TexImage3D)(ctx, target, level, internalFormat, + width, height, depth, border, format, type, + pixels, &ctx->Unpack, texObj, texImage); - ASSERT(texImage->TexFormat); + ASSERT(texImage->TexFormat); - update_fbo_texture(ctx, texObj, face, level); + update_fbo_texture(ctx, texObj, face, level); - /* state update */ - texObj->Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; + /* state update */ + texObj->Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + out: + _mesa_unlock_texture(ctx, texObj); } else if (target == GL_PROXY_TEXTURE_3D) { /* Proxy texture: check for errors and update proxy state */ @@ -2566,7 +2597,7 @@ _mesa_TexSubImage1D( GLenum target, GLint level, GLsizei postConvWidth = width; struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; - struct gl_texture_image *texImage; + struct gl_texture_image *texImage = NULL; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); @@ -2579,26 +2610,38 @@ _mesa_TexSubImage1D( GLenum target, GLint level, } if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0, - postConvWidth, 1, 1, format, type)) { + postConvWidth, 1, 1, format, type)) { return; /* error was detected */ } + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - assert(texImage); + assert(texObj); - if (width == 0) - return; /* no-op, not an error */ + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_select_tex_image(ctx, texObj, target, level); - /* If we have a border, xoffset=-1 is legal. Bias by border width */ - xoffset += texImage->Border; + if (subtexture_error_check2(ctx, 1, target, level, xoffset, 0, 0, + postConvWidth, 1, 1, format, type, texImage)) { + goto out; /* error was detected */ + } + + if (width == 0) + goto out; /* no-op, not an error */ + + /* If we have a border, xoffset=-1 is legal. Bias by border width */ + xoffset += texImage->Border; - ASSERT(ctx->Driver.TexSubImage1D); - (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width, - format, type, pixels, &ctx->Unpack, - texObj, texImage); - ctx->NewState |= _NEW_TEXTURE; + ASSERT(ctx->Driver.TexSubImage1D); + (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width, + format, type, pixels, &ctx->Unpack, + texObj, texImage); + ctx->NewState |= _NEW_TEXTURE; + } + out: + _mesa_unlock_texture(ctx, texObj); } @@ -2626,27 +2669,37 @@ _mesa_TexSubImage2D( GLenum target, GLint level, } if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0, - postConvWidth, postConvHeight, 1, format, type)) { + postConvWidth, postConvHeight, 1, format, type)) { return; /* error was detected */ } texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - assert(texImage); + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_select_tex_image(ctx, texObj, target, level); - if (width == 0 || height == 0) - return; /* no-op, not an error */ + if (subtexture_error_check2(ctx, 2, target, level, xoffset, yoffset, 0, + postConvWidth, postConvHeight, 1, format, type, + texImage)) { + goto out; /* error was detected */ + } - /* If we have a border, xoffset=-1 is legal. Bias by border width */ - xoffset += texImage->Border; - yoffset += texImage->Border; + if (width == 0 || height == 0) + goto out; /* no-op, not an error */ - ASSERT(ctx->Driver.TexSubImage2D); - (*ctx->Driver.TexSubImage2D)(ctx, target, level, xoffset, yoffset, - width, height, format, type, pixels, - &ctx->Unpack, texObj, texImage); - ctx->NewState |= _NEW_TEXTURE; + /* If we have a border, xoffset=-1 is legal. Bias by border width */ + xoffset += texImage->Border; + yoffset += texImage->Border; + + ASSERT(ctx->Driver.TexSubImage2D); + (*ctx->Driver.TexSubImage2D)(ctx, target, level, xoffset, yoffset, + width, height, format, type, pixels, + &ctx->Unpack, texObj, texImage); + ctx->NewState |= _NEW_TEXTURE; + } + out: + _mesa_unlock_texture(ctx, texObj); } @@ -2674,24 +2727,34 @@ _mesa_TexSubImage3D( GLenum target, GLint level, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - assert(texImage); - - if (width == 0 || height == 0 || height == 0) - return; /* no-op, not an error */ - - /* If we have a border, xoffset=-1 is legal. Bias by border width */ - xoffset += texImage->Border; - yoffset += texImage->Border; - zoffset += texImage->Border; - - ASSERT(ctx->Driver.TexSubImage3D); - (*ctx->Driver.TexSubImage3D)(ctx, target, level, - xoffset, yoffset, zoffset, - width, height, depth, - format, type, pixels, - &ctx->Unpack, texObj, texImage ); - ctx->NewState |= _NEW_TEXTURE; + + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_select_tex_image(ctx, texObj, target, level); + + if (subtexture_error_check2(ctx, 3, target, level, xoffset, yoffset, zoffset, + width, height, depth, format, type, texImage)) { + goto out; /* error was detected */ + } + + if (width == 0 || height == 0 || height == 0) + goto out; /* no-op, not an error */ + + /* If we have a border, xoffset=-1 is legal. Bias by border width */ + xoffset += texImage->Border; + yoffset += texImage->Border; + zoffset += texImage->Border; + + ASSERT(ctx->Driver.TexSubImage3D); + (*ctx->Driver.TexSubImage3D)(ctx, target, level, + xoffset, yoffset, zoffset, + width, height, depth, + format, type, pixels, + &ctx->Unpack, texObj, texImage ); + ctx->NewState |= _NEW_TEXTURE; + } + out: + _mesa_unlock_texture(ctx, texObj); } @@ -2723,32 +2786,39 @@ _mesa_CopyTexImage1D( GLenum target, GLint level, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_get_tex_image(ctx, texUnit, target, level); - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D"); - return; - } - else if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } - ASSERT(texImage->Data == NULL); + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_get_tex_image(ctx, texObj, target, level); + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D"); + goto out; + } + + if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); + } + + ASSERT(texImage->Data == NULL); - clear_teximage_fields(texImage); /* not really needed, but helpful */ - _mesa_init_teximage_fields(ctx, target, texImage, postConvWidth, 1, 1, - border, internalFormat); + clear_teximage_fields(texImage); /* not really needed, but helpful */ + _mesa_init_teximage_fields(ctx, target, texImage, postConvWidth, 1, 1, + border, internalFormat); - ASSERT(ctx->Driver.CopyTexImage1D); - (*ctx->Driver.CopyTexImage1D)(ctx, target, level, internalFormat, - x, y, width, border); + ASSERT(ctx->Driver.CopyTexImage1D); + (*ctx->Driver.CopyTexImage1D)(ctx, target, level, internalFormat, + x, y, width, border); - ASSERT(texImage->TexFormat); + ASSERT(texImage->TexFormat); - update_fbo_texture(ctx, texObj, face, level); + update_fbo_texture(ctx, texObj, face, level); - /* state update */ - texObj->Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; + /* state update */ + texObj->Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + out: + _mesa_unlock_texture(ctx, texObj); } @@ -2780,41 +2850,50 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_get_tex_image(ctx, texUnit, target, level); - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D"); - return; - } - else if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } - ASSERT(texImage->Data == NULL); - clear_teximage_fields(texImage); /* not really needed, but helpful */ - _mesa_init_teximage_fields(ctx, target, texImage, - postConvWidth, postConvHeight, 1, - border, internalFormat); + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_get_tex_image(ctx, texObj, target, level); - ASSERT(ctx->Driver.CopyTexImage2D); - (*ctx->Driver.CopyTexImage2D)(ctx, target, level, internalFormat, - x, y, width, height, border); + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D"); + goto out; + } + + if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); + } + + ASSERT(texImage->Data == NULL); - ASSERT(texImage->TexFormat); + clear_teximage_fields(texImage); /* not really needed, but helpful */ + _mesa_init_teximage_fields(ctx, target, texImage, + postConvWidth, postConvHeight, 1, + border, internalFormat); + + ASSERT(ctx->Driver.CopyTexImage2D); + (*ctx->Driver.CopyTexImage2D)(ctx, target, level, internalFormat, + x, y, width, height, border); + + ASSERT(texImage->TexFormat); - update_fbo_texture(ctx, texObj, face, level); + update_fbo_texture(ctx, texObj, face, level); - /* state update */ - texObj->Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; + /* state update */ + texObj->Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + out: + _mesa_unlock_texture(ctx, texObj); } - void GLAPIENTRY _mesa_CopyTexSubImage1D( GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width ) { struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; struct gl_texture_image *texImage; GLsizei postConvWidth = width; GET_CURRENT_CONTEXT(ctx); @@ -2831,15 +2910,27 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level, return; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - ASSERT(texImage); + texObj = _mesa_select_tex_object(ctx, texUnit, target); + + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_select_tex_image(ctx, texObj, target, level); + + if (copytexsubimage_error_check2(ctx, 1, target, level, + xoffset, 0, 0, postConvWidth, 1, + texImage)) + goto out; + - /* If we have a border, xoffset=-1 is legal. Bias by border width */ - xoffset += texImage->Border; + /* If we have a border, xoffset=-1 is legal. Bias by border width */ + xoffset += texImage->Border; - ASSERT(ctx->Driver.CopyTexSubImage1D); - (*ctx->Driver.CopyTexSubImage1D)(ctx, target, level, xoffset, x, y, width); - ctx->NewState |= _NEW_TEXTURE; + ASSERT(ctx->Driver.CopyTexSubImage1D); + (*ctx->Driver.CopyTexSubImage1D)(ctx, target, level, xoffset, x, y, width); + ctx->NewState |= _NEW_TEXTURE; + } + out: + _mesa_unlock_texture(ctx, texObj); } @@ -2850,6 +2941,7 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level, GLint x, GLint y, GLsizei width, GLsizei height ) { struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; struct gl_texture_image *texImage; GLsizei postConvWidth = width, postConvHeight = height; GET_CURRENT_CONTEXT(ctx); @@ -2866,17 +2958,27 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level, return; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - ASSERT(texImage); + texObj = _mesa_select_tex_object(ctx, texUnit, target); + + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_select_tex_image(ctx, texObj, target, level); - /* If we have a border, xoffset=-1 is legal. Bias by border width */ - xoffset += texImage->Border; - yoffset += texImage->Border; + if (copytexsubimage_error_check2(ctx, 2, target, level, xoffset, yoffset, 0, + postConvWidth, postConvHeight, texImage)) + goto out; - ASSERT(ctx->Driver.CopyTexSubImage2D); - (*ctx->Driver.CopyTexSubImage2D)(ctx, target, level, - xoffset, yoffset, x, y, width, height); - ctx->NewState |= _NEW_TEXTURE; + /* If we have a border, xoffset=-1 is legal. Bias by border width */ + xoffset += texImage->Border; + yoffset += texImage->Border; + + ASSERT(ctx->Driver.CopyTexSubImage2D); + (*ctx->Driver.CopyTexSubImage2D)(ctx, target, level, + xoffset, yoffset, x, y, width, height); + ctx->NewState |= _NEW_TEXTURE; + } + out: + _mesa_unlock_texture(ctx, texObj); } @@ -2887,6 +2989,7 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level, GLint x, GLint y, GLsizei width, GLsizei height ) { struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; struct gl_texture_image *texImage; GLsizei postConvWidth = width, postConvHeight = height; GET_CURRENT_CONTEXT(ctx); @@ -2903,19 +3006,30 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level, return; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - ASSERT(texImage); + texObj = _mesa_select_tex_object(ctx, texUnit, target); - /* If we have a border, xoffset=-1 is legal. Bias by border width */ - xoffset += texImage->Border; - yoffset += texImage->Border; - zoffset += texImage->Border; + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_select_tex_image(ctx, texObj, target, level); - ASSERT(ctx->Driver.CopyTexSubImage3D); - (*ctx->Driver.CopyTexSubImage3D)(ctx, target, level, - xoffset, yoffset, zoffset, - x, y, width, height); - ctx->NewState |= _NEW_TEXTURE; + if (copytexsubimage_error_check2(ctx, 3, target, level, xoffset, yoffset, + zoffset, postConvWidth, postConvHeight, + texImage)) + goto out; + + /* If we have a border, xoffset=-1 is legal. Bias by border width */ + xoffset += texImage->Border; + yoffset += texImage->Border; + zoffset += texImage->Border; + + ASSERT(ctx->Driver.CopyTexSubImage3D); + (*ctx->Driver.CopyTexSubImage3D)(ctx, target, level, + xoffset, yoffset, zoffset, + x, y, width, height); + ctx->NewState |= _NEW_TEXTURE; + } + out: + _mesa_unlock_texture(ctx, texObj); } @@ -3136,28 +3250,35 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_get_tex_image(ctx, texUnit, target, level); - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1D"); - return; - } - else if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } - ASSERT(texImage->Data == NULL); - _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1, - border, internalFormat); + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_get_tex_image(ctx, texObj, target, level); + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1D"); + goto out; + } + + if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); + } + ASSERT(texImage->Data == NULL); + + _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1, + border, internalFormat); - ASSERT(ctx->Driver.CompressedTexImage1D); - (*ctx->Driver.CompressedTexImage1D)(ctx, target, level, - internalFormat, width, border, - imageSize, data, - texObj, texImage); + ASSERT(ctx->Driver.CompressedTexImage1D); + (*ctx->Driver.CompressedTexImage1D)(ctx, target, level, + internalFormat, width, border, + imageSize, data, + texObj, texImage); - /* state update */ - texObj->Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; + /* state update */ + texObj->Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + out: + _mesa_unlock_texture(ctx, texObj); } else if (target == GL_PROXY_TEXTURE_1D) { /* Proxy texture: check for errors and update proxy state */ @@ -3179,11 +3300,18 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level, else { /* store the teximage parameters */ struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; struct gl_texture_image *texImage; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1, - border, internalFormat); + texObj = _mesa_select_tex_object(ctx, texUnit, target); + + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_select_tex_image(ctx, texObj, target, level); + _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1, + border, internalFormat); + } + _mesa_unlock_texture(ctx, texObj); } } else { @@ -3219,28 +3347,35 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_get_tex_image(ctx, texUnit, target, level); - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); - return; - } - else if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } - ASSERT(texImage->Data == NULL); - _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, - border, internalFormat); + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_get_tex_image(ctx, texObj, target, level); + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); + goto out; + } + + if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); + } + ASSERT(texImage->Data == NULL); - ASSERT(ctx->Driver.CompressedTexImage2D); - (*ctx->Driver.CompressedTexImage2D)(ctx, target, level, - internalFormat, width, height, - border, imageSize, data, - texObj, texImage); + _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, + border, internalFormat); - /* state update */ - texObj->Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; + ASSERT(ctx->Driver.CompressedTexImage2D); + (*ctx->Driver.CompressedTexImage2D)(ctx, target, level, + internalFormat, width, height, + border, imageSize, data, + texObj, texImage); + + /* state update */ + texObj->Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + out: + _mesa_unlock_texture(ctx, texObj); } else if (target == GL_PROXY_TEXTURE_2D || (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB && @@ -3264,11 +3399,18 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level, else { /* store the teximage parameters */ struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; struct gl_texture_image *texImage; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, - border, internalFormat); + texObj = _mesa_select_tex_object(ctx, texUnit, target); + + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_select_tex_image(ctx, texObj, target, level); + _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, + border, internalFormat); + } + _mesa_unlock_texture(ctx, texObj); } } else { @@ -3301,29 +3443,35 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_get_tex_image(ctx, texUnit, target, level); - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3D"); - return; - } - else if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } - ASSERT(texImage->Data == NULL); - - _mesa_init_teximage_fields(ctx, target, texImage, width, height, depth, - border, internalFormat); + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_get_tex_image(ctx, texObj, target, level); + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3D"); + goto out; + } + + if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); + } + ASSERT(texImage->Data == NULL); - ASSERT(ctx->Driver.CompressedTexImage3D); - (*ctx->Driver.CompressedTexImage3D)(ctx, target, level, - internalFormat, - width, height, depth, - border, imageSize, data, - texObj, texImage); + _mesa_init_teximage_fields(ctx, target, texImage, width, height, depth, + border, internalFormat); - /* state update */ - texObj->Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; + ASSERT(ctx->Driver.CompressedTexImage3D); + (*ctx->Driver.CompressedTexImage3D)(ctx, target, level, + internalFormat, + width, height, depth, + border, imageSize, data, + texObj, texImage); + + /* state update */ + texObj->Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + out: + _mesa_unlock_texture(ctx, texObj); } else if (target == GL_PROXY_TEXTURE_3D) { /* Proxy texture: check for errors and update proxy state */ @@ -3345,11 +3493,17 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level, else { /* store the teximage parameters */ struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; struct gl_texture_image *texImage; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - _mesa_init_teximage_fields(ctx, target, texImage, width, height, - depth, border, internalFormat); + texObj = _mesa_select_tex_object(ctx, texUnit, target); + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_select_tex_image(ctx, texObj, target, level); + _mesa_init_teximage_fields(ctx, target, texImage, width, height, + depth, border, internalFormat); + } + _mesa_unlock_texture(ctx, texObj); } } else { @@ -3382,30 +3536,35 @@ _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - assert(texImage); + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_select_tex_image(ctx, texObj, target, level); + assert(texImage); - if ((GLint) format != texImage->InternalFormat) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glCompressedTexSubImage1D(format)"); - return; - } + if ((GLint) format != texImage->InternalFormat) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCompressedTexSubImage1D(format)"); + goto out; + } - if ((width == 1 || width == 2) && (GLuint) width != texImage->Width) { - _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage1D(width)"); - return; - } + if ((width == 1 || width == 2) && (GLuint) width != texImage->Width) { + _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage1D(width)"); + goto out; + } - if (width == 0) - return; /* no-op, not an error */ + if (width == 0) + goto out; /* no-op, not an error */ - if (ctx->Driver.CompressedTexSubImage1D) { - (*ctx->Driver.CompressedTexSubImage1D)(ctx, target, level, - xoffset, width, - format, imageSize, data, - texObj, texImage); + if (ctx->Driver.CompressedTexSubImage1D) { + (*ctx->Driver.CompressedTexSubImage1D)(ctx, target, level, + xoffset, width, + format, imageSize, data, + texObj, texImage); + } + ctx->NewState |= _NEW_TEXTURE; } - ctx->NewState |= _NEW_TEXTURE; + out: + _mesa_unlock_texture(ctx, texObj); } @@ -3434,31 +3593,36 @@ _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - assert(texImage); + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_select_tex_image(ctx, texObj, target, level); + assert(texImage); - if ((GLint) format != texImage->InternalFormat) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glCompressedTexSubImage2D(format)"); - return; - } + if ((GLint) format != texImage->InternalFormat) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCompressedTexSubImage2D(format)"); + goto out; + } - if (((width == 1 || width == 2) && (GLuint) width != texImage->Width) || - ((height == 1 || height == 2) && (GLuint) height != texImage->Height)) { - _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage2D(size)"); - return; - } + if (((width == 1 || width == 2) && (GLuint) width != texImage->Width) || + ((height == 1 || height == 2) && (GLuint) height != texImage->Height)) { + _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage2D(size)"); + goto out; + } - if (width == 0 || height == 0) - return; /* no-op, not an error */ + if (width == 0 || height == 0) + goto out; /* no-op, not an error */ - if (ctx->Driver.CompressedTexSubImage2D) { - (*ctx->Driver.CompressedTexSubImage2D)(ctx, target, level, - xoffset, yoffset, width, height, - format, imageSize, data, - texObj, texImage); + if (ctx->Driver.CompressedTexSubImage2D) { + (*ctx->Driver.CompressedTexSubImage2D)(ctx, target, level, + xoffset, yoffset, width, height, + format, imageSize, data, + texObj, texImage); + } + ctx->NewState |= _NEW_TEXTURE; } - ctx->NewState |= _NEW_TEXTURE; + out: + _mesa_unlock_texture(ctx, texObj); } @@ -3486,33 +3650,38 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - assert(texImage); + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_select_tex_image(ctx, texObj, target, level); + assert(texImage); - if ((GLint) format != texImage->InternalFormat) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glCompressedTexSubImage3D(format)"); - return; - } + if ((GLint) format != texImage->InternalFormat) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCompressedTexSubImage3D(format)"); + goto out; + } - if (((width == 1 || width == 2) && (GLuint) width != texImage->Width) || - ((height == 1 || height == 2) && (GLuint) height != texImage->Height) || - ((depth == 1 || depth == 2) && (GLuint) depth != texImage->Depth)) { - _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage3D(size)"); - return; - } + if (((width == 1 || width == 2) && (GLuint) width != texImage->Width) || + ((height == 1 || height == 2) && (GLuint) height != texImage->Height) || + ((depth == 1 || depth == 2) && (GLuint) depth != texImage->Depth)) { + _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage3D(size)"); + goto out; + } - if (width == 0 || height == 0 || depth == 0) - return; /* no-op, not an error */ + if (width == 0 || height == 0 || depth == 0) + goto out; /* no-op, not an error */ - if (ctx->Driver.CompressedTexSubImage3D) { - (*ctx->Driver.CompressedTexSubImage3D)(ctx, target, level, - xoffset, yoffset, zoffset, - width, height, depth, - format, imageSize, data, - texObj, texImage); + if (ctx->Driver.CompressedTexSubImage3D) { + (*ctx->Driver.CompressedTexSubImage3D)(ctx, target, level, + xoffset, yoffset, zoffset, + width, height, depth, + format, imageSize, data, + texObj, texImage); + } + ctx->NewState |= _NEW_TEXTURE; } - ctx->NewState |= _NEW_TEXTURE; + out: + _mesa_unlock_texture(ctx, texObj); } @@ -3520,12 +3689,13 @@ void GLAPIENTRY _mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img) { const struct gl_texture_unit *texUnit; - const struct gl_texture_object *texObj; + struct gl_texture_object *texObj; struct gl_texture_image *texImage; GLint maxLevels; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); if (!texObj) { @@ -3546,18 +3716,24 @@ _mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img) return; } - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - if (!texImage) { - /* probably invalid mipmap level */ - _mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)"); - return; - } - if (!texImage->IsCompressed) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetCompressedTexImageARB"); - return; - } + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_select_tex_image(ctx, texObj, target, level); + if (!texImage) { + /* probably invalid mipmap level */ + _mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)"); + goto out; + } + + if (!texImage->IsCompressed) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetCompressedTexImageARB"); + goto out; + } - /* this typically calls _mesa_get_compressed_teximage() */ - ctx->Driver.GetCompressedTexImage(ctx, target, level, img, texObj,texImage); + /* this typically calls _mesa_get_compressed_teximage() */ + ctx->Driver.GetCompressedTexImage(ctx, target, level, img, texObj,texImage); + } + out: + _mesa_unlock_texture(ctx, texObj); } diff --git a/src/mesa/main/teximage.h b/src/mesa/main/teximage.h index 410789fe04..68457f4728 100644 --- a/src/mesa/main/teximage.h +++ b/src/mesa/main/teximage.h @@ -84,12 +84,12 @@ _mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit, extern struct gl_texture_image * -_mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit, +_mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_object *texObj, GLenum target, GLint level); extern struct gl_texture_image * -_mesa_get_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit, +_mesa_get_tex_image(GLcontext *ctx, struct gl_texture_object *texObj, GLenum target, GLint level); @@ -106,6 +106,23 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level, GLint internalFormat, GLenum format, GLenum type, GLint width, GLint height, GLint depth, GLint border); + +/* Lock a texture for updating. See also _mesa_lock_context_textures(). + */ +static INLINE void _mesa_lock_texture(GLcontext *ctx, + struct gl_texture_object *texObj) +{ + _glthread_LOCK_MUTEX(ctx->Shared->TexMutex); + ctx->Shared->TextureStateStamp++; + (void) texObj; +} + +static INLINE void _mesa_unlock_texture(GLcontext *ctx, + struct gl_texture_object *texObj) +{ + _glthread_UNLOCK_MUTEX(ctx->Shared->TexMutex); +} + /*@}*/ diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c index 8b42c2a712..1d27cd3f7c 100644 --- a/src/mesa/main/texobj.c +++ b/src/mesa/main/texobj.c @@ -697,7 +697,11 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures) if (textures[i] > 0) { struct gl_texture_object *delObj = _mesa_lookup_texture(ctx, textures[i]); + if (delObj) { + GLboolean delete; + + _mesa_lock_texture(ctx, delObj); /* Check if texture is bound to any framebuffer objects. * If so, unbind. @@ -724,7 +728,14 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures) * XXX all RefCount accesses should be protected by a mutex. */ delObj->RefCount--; - if (delObj->RefCount == 0) { + delete = (delObj->RefCount == 0); + _mesa_unlock_texture(ctx, delObj); + + /* We know that refcount went to zero above, so this is + * the only pointer left to delObj, so we don't have to + * worry about locking any more: + */ + if (delete) { ASSERT(delObj->Name != 0); /* Never delete default tex objs */ ASSERT(ctx->Driver.DeleteTexture); (*ctx->Driver.DeleteTexture)(ctx, delObj); @@ -1052,4 +1063,30 @@ _mesa_IsTexture( GLuint texture ) return t && t->Target; } +/* Simplest implementation of texture locking: Grab the a new mutex in + * the shared context. Examine the shared context state timestamp and + * if there has been a change, set the appropriate bits in + * ctx->NewState. + * + * See also _mesa_lock/unlock_texture in texobj.h + */ +void _mesa_lock_context_textures( GLcontext *ctx ) +{ + _glthread_LOCK_MUTEX(ctx->Shared->TexMutex); + + if (ctx->Shared->TextureStateStamp != ctx->TextureStateTimestamp) { + ctx->NewState |= _NEW_TEXTURE; + ctx->TextureStateTimestamp = ctx->Shared->TextureStateStamp; + } +} + + +void _mesa_unlock_context_textures( GLcontext *ctx ) +{ + assert(ctx->Shared->TextureStateStamp == ctx->TextureStateTimestamp); + _glthread_UNLOCK_MUTEX(ctx->Shared->TexMutex); +} + /*@}*/ + + diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h index ac66ac69d3..ec7cf8cd86 100644 --- a/src/mesa/main/texobj.h +++ b/src/mesa/main/texobj.h @@ -61,6 +61,9 @@ extern void _mesa_test_texobj_completeness( const GLcontext *ctx, struct gl_texture_object *obj ); +extern void _mesa_unlock_context_textures( GLcontext *ctx ); +extern void _mesa_lock_context_textures( GLcontext *ctx ); + /*@}*/ @@ -95,4 +98,5 @@ _mesa_IsTexture( GLuint texture ); /*@}*/ + #endif diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 0687e5760c..bcedcafe19 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -144,6 +144,8 @@ _mesa_copy_texture_state( const GLcontext *src, GLcontext *dst ) dst->Texture.Unit[i].Combine.ScaleShiftA = src->Texture.Unit[i].Combine.ScaleShiftA; /* copy texture object bindings, not contents of texture objects */ + _mesa_lock_context_textures(dst); + copy_texture_binding(src, &dst->Texture.Unit[i].Current1D, src->Texture.Unit[i].Current1D); copy_texture_binding(src, &dst->Texture.Unit[i].Current2D, @@ -154,6 +156,8 @@ _mesa_copy_texture_state( const GLcontext *src, GLcontext *dst ) src->Texture.Unit[i].CurrentCubeMap); copy_texture_binding(src, &dst->Texture.Unit[i].CurrentRect, src->Texture.Unit[i].CurrentRect); + + _mesa_unlock_context_textures(dst); } } @@ -1700,6 +1704,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, GLenum pname, GLint *params ) { const struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; const struct gl_texture_image *img = NULL; GLuint dimensions; GLboolean isProxy; @@ -1734,14 +1739,17 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, return; } - img = _mesa_select_tex_image(ctx, texUnit, target, level); + texObj = _mesa_select_tex_object(ctx, texUnit, target); + _mesa_lock_texture(ctx, texObj); + + img = _mesa_select_tex_image(ctx, texObj, target, level); if (!img || !img->TexFormat) { /* undefined texture image */ if (pname == GL_TEXTURE_COMPONENTS) *params = 1; else *params = 0; - return; + goto out; } isProxy = _mesa_is_proxy_texture(target); @@ -1749,37 +1757,37 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, switch (pname) { case GL_TEXTURE_WIDTH: *params = img->Width; - return; + break; case GL_TEXTURE_HEIGHT: *params = img->Height; - return; + break; case GL_TEXTURE_DEPTH: *params = img->Depth; - return; + break; case GL_TEXTURE_INTERNAL_FORMAT: *params = img->InternalFormat; - return; + break; case GL_TEXTURE_BORDER: *params = img->Border; - return; + break; case GL_TEXTURE_RED_SIZE: if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA) *params = img->TexFormat->RedBits; else *params = 0; - return; + break; case GL_TEXTURE_GREEN_SIZE: if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA) *params = img->TexFormat->GreenBits; else *params = 0; - return; + break; case GL_TEXTURE_BLUE_SIZE: if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA) *params = img->TexFormat->BlueBits; else *params = 0; - return; + break; case GL_TEXTURE_ALPHA_SIZE: if (img->_BaseFormat == GL_ALPHA || img->_BaseFormat == GL_LUMINANCE_ALPHA || @@ -1787,7 +1795,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, *params = img->TexFormat->AlphaBits; else *params = 0; - return; + break; case GL_TEXTURE_INTENSITY_SIZE: if (img->_BaseFormat != GL_INTENSITY) *params = 0; @@ -1795,7 +1803,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, *params = img->TexFormat->IntensityBits; else /* intensity probably stored as rgb texture */ *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits); - return; + break; case GL_TEXTURE_LUMINANCE_SIZE: if (img->_BaseFormat != GL_LUMINANCE && img->_BaseFormat != GL_LUMINANCE_ALPHA) @@ -1804,13 +1812,13 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, *params = img->TexFormat->LuminanceBits; else /* luminance probably stored as rgb texture */ *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits); - return; + break; case GL_TEXTURE_INDEX_SIZE_EXT: if (img->_BaseFormat == GL_COLOR_INDEX) *params = img->TexFormat->IndexBits; else *params = 0; - return; + break; case GL_TEXTURE_DEPTH_SIZE_ARB: if (ctx->Extensions.SGIX_depth_texture || ctx->Extensions.ARB_depth_texture) @@ -1818,7 +1826,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, else _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); - return; + break; case GL_TEXTURE_STENCIL_SIZE_EXT: if (ctx->Extensions.EXT_packed_depth_stencil) { *params = img->TexFormat->StencilBits; @@ -1827,7 +1835,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } - return; + break; /* GL_ARB_texture_compression */ case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: @@ -1849,7 +1857,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } - return; + break; case GL_TEXTURE_COMPRESSED: if (ctx->Extensions.ARB_texture_compression) { *params = (GLint) img->IsCompressed; @@ -1858,7 +1866,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } - return; + break; /* GL_ARB_texture_float */ case GL_TEXTURE_RED_TYPE_ARB: @@ -1869,7 +1877,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } - return; + break; case GL_TEXTURE_GREEN_TYPE_ARB: if (ctx->Extensions.ARB_texture_float) { *params = img->TexFormat->GreenBits ? img->TexFormat->DataType : GL_NONE; @@ -1878,7 +1886,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } - return; + break; case GL_TEXTURE_BLUE_TYPE_ARB: if (ctx->Extensions.ARB_texture_float) { *params = img->TexFormat->BlueBits ? img->TexFormat->DataType : GL_NONE; @@ -1887,7 +1895,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } - return; + break; case GL_TEXTURE_ALPHA_TYPE_ARB: if (ctx->Extensions.ARB_texture_float) { *params = img->TexFormat->AlphaBits ? img->TexFormat->DataType : GL_NONE; @@ -1896,7 +1904,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } - return; + break; case GL_TEXTURE_LUMINANCE_TYPE_ARB: if (ctx->Extensions.ARB_texture_float) { *params = img->TexFormat->LuminanceBits ? img->TexFormat->DataType : GL_NONE; @@ -1905,7 +1913,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } - return; + break; case GL_TEXTURE_INTENSITY_TYPE_ARB: if (ctx->Extensions.ARB_texture_float) { *params = img->TexFormat->IntensityBits ? img->TexFormat->DataType : GL_NONE; @@ -1914,7 +1922,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } - return; + break; case GL_TEXTURE_DEPTH_TYPE_ARB: if (ctx->Extensions.ARB_texture_float) { *params = img->TexFormat->DepthBits ? img->TexFormat->DataType : GL_NONE; @@ -1923,12 +1931,15 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } - return; + break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } + + out: + _mesa_unlock_texture(ctx, texObj); } @@ -1938,6 +1949,7 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) { struct gl_texture_unit *texUnit; struct gl_texture_object *obj; + GLboolean error = GL_FALSE; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -1955,28 +1967,29 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) return; } + _mesa_lock_texture(ctx, obj); switch (pname) { case GL_TEXTURE_MAG_FILTER: *params = ENUM_TO_FLOAT(obj->MagFilter); - return; + break; case GL_TEXTURE_MIN_FILTER: *params = ENUM_TO_FLOAT(obj->MinFilter); - return; + break; case GL_TEXTURE_WRAP_S: *params = ENUM_TO_FLOAT(obj->WrapS); - return; + break; case GL_TEXTURE_WRAP_T: *params = ENUM_TO_FLOAT(obj->WrapT); - return; + break; case GL_TEXTURE_WRAP_R: *params = ENUM_TO_FLOAT(obj->WrapR); - return; + break; case GL_TEXTURE_BORDER_COLOR: params[0] = CLAMP(obj->BorderColor[0], 0.0F, 1.0F); params[1] = CLAMP(obj->BorderColor[1], 0.0F, 1.0F); params[2] = CLAMP(obj->BorderColor[2], 0.0F, 1.0F); params[3] = CLAMP(obj->BorderColor[3], 0.0F, 1.0F); - return; + break; case GL_TEXTURE_RESIDENT: { GLboolean resident; @@ -1986,82 +1999,94 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) resident = GL_TRUE; *params = ENUM_TO_FLOAT(resident); } - return; + break; case GL_TEXTURE_PRIORITY: *params = obj->Priority; - return; + break; case GL_TEXTURE_MIN_LOD: *params = obj->MinLod; - return; + break; case GL_TEXTURE_MAX_LOD: *params = obj->MaxLod; - return; + break; case GL_TEXTURE_BASE_LEVEL: *params = (GLfloat) obj->BaseLevel; - return; + break; case GL_TEXTURE_MAX_LEVEL: *params = (GLfloat) obj->MaxLevel; - return; + break; case GL_TEXTURE_MAX_ANISOTROPY_EXT: if (ctx->Extensions.EXT_texture_filter_anisotropic) { *params = obj->MaxAnisotropy; - return; } + else + error = 1; break; case GL_TEXTURE_COMPARE_SGIX: if (ctx->Extensions.SGIX_shadow) { *params = (GLfloat) obj->CompareFlag; - return; } + else + error = 1; break; case GL_TEXTURE_COMPARE_OPERATOR_SGIX: if (ctx->Extensions.SGIX_shadow) { *params = (GLfloat) obj->CompareOperator; - return; } + else + error = 1; break; case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */ if (ctx->Extensions.SGIX_shadow_ambient) { *params = obj->ShadowAmbient; - return; } + else + error = 1; break; case GL_GENERATE_MIPMAP_SGIS: if (ctx->Extensions.SGIS_generate_mipmap) { *params = (GLfloat) obj->GenerateMipmap; - return; } + else + error = 1; break; case GL_TEXTURE_COMPARE_MODE_ARB: if (ctx->Extensions.ARB_shadow) { *params = (GLfloat) obj->CompareMode; - return; } + else + error = 1; break; case GL_TEXTURE_COMPARE_FUNC_ARB: if (ctx->Extensions.ARB_shadow) { *params = (GLfloat) obj->CompareFunc; - return; } + else + error = 1; break; case GL_DEPTH_TEXTURE_MODE_ARB: if (ctx->Extensions.ARB_depth_texture) { *params = (GLfloat) obj->DepthMode; - return; } + else + error = 1; break; case GL_TEXTURE_LOD_BIAS: if (ctx->Extensions.EXT_texture_lod_bias) { *params = obj->LodBias; - return; } + else + error = 1; break; default: - ; /* silence warnings */ + error = 1; + break; } - /* If we get here, pname was an unrecognized enum */ - _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)", - pname); + if (error) + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)", + pname); + + _mesa_unlock_texture(ctx, obj); } diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c index b8e5e4bd8a..43e3bc183d 100644 --- a/src/mesa/shader/arbprogparse.c +++ b/src/mesa/shader/arbprogparse.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5.1 + * Version: 6.5.2 * * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * @@ -2571,8 +2571,6 @@ parse_fp_vector_src_reg(GLcontext * ctx, const GLubyte ** inst, reg->File = file; reg->Index = index; - reg->Abs = 0; /* NV only */ - reg->NegateAbs = 0; /* NV only */ reg->NegateBase = negate; reg->Swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], swizzle[2], swizzle[3]); return 0; @@ -2595,8 +2593,6 @@ parse_fp_dst_reg(GLcontext * ctx, const GLubyte ** inst, if (parse_masked_dst_reg (ctx, inst, vc_head, Program, &file, &idx, &mask)) return 1; - reg->CondMask = 0; /* NV only */ - reg->CondSwizzle = 0; /* NV only */ reg->File = file; reg->Index = idx; reg->WriteMask = mask; @@ -2632,8 +2628,6 @@ parse_fp_scalar_src_reg (GLcontext * ctx, const GLubyte ** inst, reg->File = File; reg->Index = Index; - reg->Abs = 0; /* NV only */ - reg->NegateAbs = 0; /* NV only */ reg->NegateBase = Negate; reg->Swizzle = (Swizzle[0] << 0); @@ -2656,7 +2650,7 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst, GLubyte instClass, type, code; GLboolean rel; - _mesa_init_instruction(fp); + _mesa_init_instructions(fp, 1); /* Record the position in the program string for debugging */ fp->StringPos = Program->Position; @@ -3148,7 +3142,7 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst, /* The actual opcode name */ code = *(*inst)++; - _mesa_init_instruction(vp); + _mesa_init_instructions(vp, 1); /* Record the position in the program string for debugging */ vp->StringPos = Program->Position; @@ -3690,7 +3684,7 @@ parse_instructions(GLcontext * ctx, const GLubyte * inst, /* Finally, tag on an OPCODE_END instruction */ { const GLuint numInst = Program->Base.NumInstructions; - _mesa_init_instruction(Program->Base.Instructions + numInst); + _mesa_init_instructions(Program->Base.Instructions + numInst, 1); Program->Base.Instructions[numInst].Opcode = OPCODE_END; /* YYY Wrong Position in program, whatever, at least not random -> crash Program->Position = parse_position (&inst); diff --git a/src/mesa/shader/nvfragparse.c b/src/mesa/shader/nvfragparse.c index 49ce220944..5f3a30b741 100644 --- a/src/mesa/shader/nvfragparse.c +++ b/src/mesa/shader/nvfragparse.c @@ -1273,7 +1273,7 @@ Parse_InstructionSequence(struct parse_state *parseState, GLubyte token[100]; /* Initialize the instruction */ - _mesa_init_instruction(inst); + _mesa_init_instructions(inst, 1); /* special instructions */ if (Parse_String(parseState, "DEFINE")) { diff --git a/src/mesa/shader/nvprogram.c b/src/mesa/shader/nvprogram.c index 47d2b61a62..0e9a01dcab 100644 --- a/src/mesa/shader/nvprogram.c +++ b/src/mesa/shader/nvprogram.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5.1 + * Version: 6.5.2 * * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * @@ -77,10 +77,7 @@ _mesa_ExecuteProgramNV(GLenum target, GLuint id, const GLfloat *params) return; } - _mesa_init_vp_per_vertex_registers(ctx); - _mesa_init_vp_per_primitive_registers(ctx); - COPY_4V(ctx->VertexProgram.Machine.Inputs[VERT_ATTRIB_POS], params); - _mesa_exec_vertex_program(ctx, vprog); + _mesa_exec_vertex_state_program(ctx, vprog, params); } diff --git a/src/mesa/shader/nvvertexec.c b/src/mesa/shader/nvvertexec.c index 1985593659..10962d7e14 100644 --- a/src/mesa/shader/nvvertexec.c +++ b/src/mesa/shader/nvvertexec.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.2 * * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * @@ -47,23 +47,23 @@ static const GLfloat ZeroVec[4] = { 0.0F, 0.0F, 0.0F, 0.0F }; * per-vertex. */ void -_mesa_init_vp_per_vertex_registers(GLcontext *ctx) +_mesa_init_vp_per_vertex_registers(GLcontext *ctx, struct vp_machine *machine) { /* Input registers get initialized from the current vertex attribs */ - MEMCPY(ctx->VertexProgram.Machine.Inputs, ctx->Current.Attrib, + MEMCPY(machine->Inputs, ctx->Current.Attrib, MAX_VERTEX_PROGRAM_ATTRIBS * 4 * sizeof(GLfloat)); if (ctx->VertexProgram.Current->IsNVProgram) { GLuint i; /* Output/result regs are initialized to [0,0,0,1] */ for (i = 0; i < MAX_NV_VERTEX_PROGRAM_OUTPUTS; i++) { - ASSIGN_4V(ctx->VertexProgram.Machine.Outputs[i], 0.0F, 0.0F, 0.0F, 1.0F); + ASSIGN_4V(machine->Outputs[i], 0.0F, 0.0F, 0.0F, 1.0F); } /* Temp regs are initialized to [0,0,0,0] */ for (i = 0; i < MAX_NV_VERTEX_PROGRAM_TEMPS; i++) { - ASSIGN_4V(ctx->VertexProgram.Machine.Temporaries[i], 0.0F, 0.0F, 0.0F, 0.0F); + ASSIGN_4V(machine->Temporaries[i], 0.0F, 0.0F, 0.0F, 0.0F); } - ASSIGN_4V(ctx->VertexProgram.Machine.AddressReg, 0, 0, 0, 0); + ASSIGN_4V(machine->AddressReg, 0, 0, 0, 0); } } @@ -139,7 +139,7 @@ _mesa_init_vp_per_primitive_registers(GLcontext *ctx) continue; } - /* load the matrix */ + /* load the matrix values into sequential registers */ if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_IDENTITY_NV) { load_matrix(ctx->VertexProgram.Parameters, i*4, mat->m); } @@ -176,36 +176,37 @@ _mesa_init_vp_per_primitive_registers(GLcontext *ctx) * For debugging. Dump the current vertex program machine registers. */ void -_mesa_dump_vp_state( const struct gl_vertex_program_state *state ) +_mesa_dump_vp_state( const struct gl_vertex_program_state *state, + const struct vp_machine *machine) { int i; _mesa_printf("VertexIn:\n"); for (i = 0; i < MAX_NV_VERTEX_PROGRAM_INPUTS; i++) { _mesa_printf("%d: %f %f %f %f ", i, - state->Machine.Inputs[i][0], - state->Machine.Inputs[i][1], - state->Machine.Inputs[i][2], - state->Machine.Inputs[i][3]); + machine->Inputs[i][0], + machine->Inputs[i][1], + machine->Inputs[i][2], + machine->Inputs[i][3]); } _mesa_printf("\n"); _mesa_printf("VertexOut:\n"); for (i = 0; i < MAX_NV_VERTEX_PROGRAM_OUTPUTS; i++) { _mesa_printf("%d: %f %f %f %f ", i, - state->Machine.Outputs[i][0], - state->Machine.Outputs[i][1], - state->Machine.Outputs[i][2], - state->Machine.Outputs[i][3]); + machine->Outputs[i][0], + machine->Outputs[i][1], + machine->Outputs[i][2], + machine->Outputs[i][3]); } _mesa_printf("\n"); _mesa_printf("Registers:\n"); for (i = 0; i < MAX_NV_VERTEX_PROGRAM_TEMPS; i++) { _mesa_printf("%d: %f %f %f %f ", i, - state->Machine.Temporaries[i][0], - state->Machine.Temporaries[i][1], - state->Machine.Temporaries[i][2], - state->Machine.Temporaries[i][3]); + machine->Temporaries[i][0], + machine->Temporaries[i][1], + machine->Temporaries[i][2], + machine->Temporaries[i][3]); } _mesa_printf("\n"); @@ -227,41 +228,45 @@ _mesa_dump_vp_state( const struct gl_vertex_program_state *state ) * source register. */ static INLINE const GLfloat * -get_register_pointer( const struct prog_src_register *source, - const struct gl_vertex_program_state *state ) +get_register_pointer( GLcontext *ctx, + const struct prog_src_register *source, + struct vp_machine *machine, + const struct gl_vertex_program *program ) { if (source->RelAddr) { - const GLint reg = source->Index + state->Machine.AddressReg[0]; + const GLint reg = source->Index + machine->AddressReg[0]; ASSERT( (source->File == PROGRAM_ENV_PARAM) || (source->File == PROGRAM_STATE_VAR) ); if (reg < 0 || reg > MAX_NV_VERTEX_PROGRAM_PARAMS) return ZeroVec; else if (source->File == PROGRAM_ENV_PARAM) - return state->Parameters[reg]; - else - return state->Current->Base.Parameters->ParameterValues[reg]; + return ctx->VertexProgram.Parameters[reg]; + else { + ASSERT(source->File == PROGRAM_LOCAL_PARAM); + return program->Base.Parameters->ParameterValues[reg]; + } } else { switch (source->File) { case PROGRAM_TEMPORARY: ASSERT(source->Index < MAX_NV_VERTEX_PROGRAM_TEMPS); - return state->Machine.Temporaries[source->Index]; + return machine->Temporaries[source->Index]; case PROGRAM_INPUT: ASSERT(source->Index < MAX_NV_VERTEX_PROGRAM_INPUTS); - return state->Machine.Inputs[source->Index]; + return machine->Inputs[source->Index]; case PROGRAM_OUTPUT: /* This is only needed for the PRINT instruction */ ASSERT(source->Index < MAX_NV_VERTEX_PROGRAM_OUTPUTS); - return state->Machine.Outputs[source->Index]; + return machine->Outputs[source->Index]; case PROGRAM_LOCAL_PARAM: ASSERT(source->Index < MAX_PROGRAM_LOCAL_PARAMS); - return state->Current->Base.LocalParams[source->Index]; + return program->Base.LocalParams[source->Index]; case PROGRAM_ENV_PARAM: ASSERT(source->Index < MAX_NV_VERTEX_PROGRAM_PARAMS); - return state->Parameters[source->Index]; + return ctx->VertexProgram.Parameters[source->Index]; case PROGRAM_STATE_VAR: - ASSERT(source->Index < state->Current->Base.Parameters->NumParameters); - return state->Current->Base.Parameters->ParameterValues[source->Index]; + ASSERT(source->Index < program->Base.Parameters->NumParameters); + return program->Base.Parameters->ParameterValues[source->Index]; default: _mesa_problem(NULL, "Bad source register file in get_register_pointer"); @@ -277,23 +282,23 @@ get_register_pointer( const struct prog_src_register *source, * Apply swizzling and negating as needed. */ static INLINE void -fetch_vector4( const struct prog_src_register *source, - const struct gl_vertex_program_state *state, +fetch_vector4( GLcontext *ctx, + const struct prog_src_register *source, + struct vp_machine *machine, + const struct gl_vertex_program *program, GLfloat result[4] ) { - const GLfloat *src = get_register_pointer(source, state); - + const GLfloat *src = get_register_pointer(ctx, source, machine, program); + ASSERT(src); + result[0] = src[GET_SWZ(source->Swizzle, 0)]; + result[1] = src[GET_SWZ(source->Swizzle, 1)]; + result[2] = src[GET_SWZ(source->Swizzle, 2)]; + result[3] = src[GET_SWZ(source->Swizzle, 3)]; if (source->NegateBase) { - result[0] = -src[GET_SWZ(source->Swizzle, 0)]; - result[1] = -src[GET_SWZ(source->Swizzle, 1)]; - result[2] = -src[GET_SWZ(source->Swizzle, 2)]; - result[3] = -src[GET_SWZ(source->Swizzle, 3)]; - } - else { - result[0] = src[GET_SWZ(source->Swizzle, 0)]; - result[1] = src[GET_SWZ(source->Swizzle, 1)]; - result[2] = src[GET_SWZ(source->Swizzle, 2)]; - result[3] = src[GET_SWZ(source->Swizzle, 3)]; + result[0] = -result[0]; + result[1] = -result[1]; + result[2] = -result[2]; + result[3] = -result[3]; } } @@ -303,17 +308,17 @@ fetch_vector4( const struct prog_src_register *source, * As above, but only return result[0] element. */ static INLINE void -fetch_vector1( const struct prog_src_register *source, - const struct gl_vertex_program_state *state, +fetch_vector1( GLcontext *ctx, + const struct prog_src_register *source, + struct vp_machine *machine, + const struct gl_vertex_program *program, GLfloat result[4] ) { - const GLfloat *src = get_register_pointer(source, state); - + const GLfloat *src = get_register_pointer(ctx, source, machine, program); + ASSERT(src); + result[0] = src[GET_SWZ(source->Swizzle, 0)]; if (source->NegateBase) { - result[0] = -src[GET_SWZ(source->Swizzle, 0)]; - } - else { - result[0] = src[GET_SWZ(source->Swizzle, 0)]; + result[0] = -result[0]; } } @@ -322,19 +327,21 @@ fetch_vector1( const struct prog_src_register *source, * Store 4 floats into a register. */ static void -store_vector4( const struct prog_dst_register *dest, - struct gl_vertex_program_state *state, +store_vector4( const struct prog_instruction *inst, + struct vp_machine *machine, const GLfloat value[4] ) { + const struct prog_dst_register *dest = &(inst->DstReg); GLfloat *dst; switch (dest->File) { - case PROGRAM_TEMPORARY: - dst = state->Machine.Temporaries[dest->Index]; - break; case PROGRAM_OUTPUT: - dst = state->Machine.Outputs[dest->Index]; + dst = machine->Outputs[dest->Index]; + break; + case PROGRAM_TEMPORARY: + dst = machine->Temporaries[dest->Index]; break; case PROGRAM_ENV_PARAM: + /* Only for VP state programs */ { /* a slight hack */ GET_CURRENT_CONTEXT(ctx); @@ -379,9 +386,10 @@ store_vector4( const struct prog_dst_register *dest, * Execute the given vertex program */ void -_mesa_exec_vertex_program(GLcontext *ctx, const struct gl_vertex_program *program) +_mesa_exec_vertex_program(GLcontext *ctx, + struct vp_machine *machine, + const struct gl_vertex_program *program) { - struct gl_vertex_program_state *state = &ctx->VertexProgram; const struct prog_instruction *inst; ctx->_CurrentProgram = GL_VERTEX_PROGRAM_ARB; /* or NV, doesn't matter */ @@ -390,9 +398,9 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct gl_vertex_program *progra * by the MVP matrix and store in the vertex position result register. */ if (ctx->VertexProgram.Current->IsPositionInvariant) { - TRANSFORM_POINT( ctx->VertexProgram.Machine.Outputs[VERT_RESULT_HPOS], + TRANSFORM_POINT( machine->Outputs[VERT_RESULT_HPOS], ctx->_ModelProjectMatrix.m, - ctx->VertexProgram.Machine.Inputs[VERT_ATTRIB_POS]); + machine->Inputs[VERT_ATTRIB_POS]); /* XXX: This could go elsewhere */ ctx->VertexProgram.Current->Base.OutputsWritten |= VERT_BIT_POS; @@ -411,15 +419,15 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct gl_vertex_program *progra case OPCODE_MOV: { GLfloat t[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - store_vector4( &inst->DstReg, state, t ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + store_vector4( inst, machine, t ); } break; case OPCODE_LIT: { const GLfloat epsilon = 1.0F / 256.0F; /* per NV spec */ GLfloat t[4], lit[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); t[0] = MAX2(t[0], 0.0F); t[1] = MAX2(t[1], 0.0F); t[3] = CLAMP(t[3], -(128.0F - epsilon), (128.0F - epsilon)); @@ -427,32 +435,32 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct gl_vertex_program *progra lit[1] = t[0]; lit[2] = (t[0] > 0.0) ? (GLfloat) _mesa_pow(t[1], t[3]) : 0.0F; lit[3] = 1.0; - store_vector4( &inst->DstReg, state, lit ); + store_vector4( inst, machine, lit ); } break; case OPCODE_RCP: { GLfloat t[4]; - fetch_vector1( &inst->SrcReg[0], state, t ); + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t ); if (t[0] != 1.0F) t[0] = 1.0F / t[0]; /* div by zero is infinity! */ t[1] = t[2] = t[3] = t[0]; - store_vector4( &inst->DstReg, state, t ); + store_vector4( inst, machine, t ); } break; case OPCODE_RSQ: { GLfloat t[4]; - fetch_vector1( &inst->SrcReg[0], state, t ); + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t ); t[0] = INV_SQRTF(FABSF(t[0])); t[1] = t[2] = t[3] = t[0]; - store_vector4( &inst->DstReg, state, t ); + store_vector4( inst, machine, t ); } break; case OPCODE_EXP: { GLfloat t[4], q[4], floor_t0; - fetch_vector1( &inst->SrcReg[0], state, t ); + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t ); floor_t0 = FLOORF(t[0]); if (floor_t0 > FLT_MAX_EXP) { SET_POS_INFINITY(q[0]); @@ -475,13 +483,13 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct gl_vertex_program *progra } q[1] = t[0] - floor_t0; q[3] = 1.0F; - store_vector4( &inst->DstReg, state, q ); + store_vector4( inst, machine, q ); } break; case OPCODE_LOG: { GLfloat t[4], q[4], abs_t0; - fetch_vector1( &inst->SrcReg[0], state, t ); + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t ); abs_t0 = FABSF(t[0]); if (abs_t0 != 0.0F) { /* Since we really can't handle infinite values on VMS @@ -512,147 +520,147 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct gl_vertex_program *progra SET_NEG_INFINITY(q[2]); } q[3] = 1.0; - store_vector4( &inst->DstReg, state, q ); + store_vector4( inst, machine, q ); } break; case OPCODE_MUL: { GLfloat t[4], u[4], prod[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - fetch_vector4( &inst->SrcReg[1], state, u ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); prod[0] = t[0] * u[0]; prod[1] = t[1] * u[1]; prod[2] = t[2] * u[2]; prod[3] = t[3] * u[3]; - store_vector4( &inst->DstReg, state, prod ); + store_vector4( inst, machine, prod ); } break; case OPCODE_ADD: { GLfloat t[4], u[4], sum[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - fetch_vector4( &inst->SrcReg[1], state, u ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); sum[0] = t[0] + u[0]; sum[1] = t[1] + u[1]; sum[2] = t[2] + u[2]; sum[3] = t[3] + u[3]; - store_vector4( &inst->DstReg, state, sum ); + store_vector4( inst, machine, sum ); } break; case OPCODE_DP3: { GLfloat t[4], u[4], dot[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - fetch_vector4( &inst->SrcReg[1], state, u ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2]; dot[1] = dot[2] = dot[3] = dot[0]; - store_vector4( &inst->DstReg, state, dot ); + store_vector4( inst, machine, dot ); } break; case OPCODE_DP4: { GLfloat t[4], u[4], dot[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - fetch_vector4( &inst->SrcReg[1], state, u ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2] + t[3] * u[3]; dot[1] = dot[2] = dot[3] = dot[0]; - store_vector4( &inst->DstReg, state, dot ); + store_vector4( inst, machine, dot ); } break; case OPCODE_DST: { GLfloat t[4], u[4], dst[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - fetch_vector4( &inst->SrcReg[1], state, u ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); dst[0] = 1.0F; dst[1] = t[1] * u[1]; dst[2] = t[2]; dst[3] = u[3]; - store_vector4( &inst->DstReg, state, dst ); + store_vector4( inst, machine, dst ); } break; case OPCODE_MIN: { GLfloat t[4], u[4], min[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - fetch_vector4( &inst->SrcReg[1], state, u ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); min[0] = (t[0] < u[0]) ? t[0] : u[0]; min[1] = (t[1] < u[1]) ? t[1] : u[1]; min[2] = (t[2] < u[2]) ? t[2] : u[2]; min[3] = (t[3] < u[3]) ? t[3] : u[3]; - store_vector4( &inst->DstReg, state, min ); + store_vector4( inst, machine, min ); } break; case OPCODE_MAX: { GLfloat t[4], u[4], max[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - fetch_vector4( &inst->SrcReg[1], state, u ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); max[0] = (t[0] > u[0]) ? t[0] : u[0]; max[1] = (t[1] > u[1]) ? t[1] : u[1]; max[2] = (t[2] > u[2]) ? t[2] : u[2]; max[3] = (t[3] > u[3]) ? t[3] : u[3]; - store_vector4( &inst->DstReg, state, max ); + store_vector4( inst, machine, max ); } break; case OPCODE_SLT: { GLfloat t[4], u[4], slt[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - fetch_vector4( &inst->SrcReg[1], state, u ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); slt[0] = (t[0] < u[0]) ? 1.0F : 0.0F; slt[1] = (t[1] < u[1]) ? 1.0F : 0.0F; slt[2] = (t[2] < u[2]) ? 1.0F : 0.0F; slt[3] = (t[3] < u[3]) ? 1.0F : 0.0F; - store_vector4( &inst->DstReg, state, slt ); + store_vector4( inst, machine, slt ); } break; case OPCODE_SGE: { GLfloat t[4], u[4], sge[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - fetch_vector4( &inst->SrcReg[1], state, u ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); sge[0] = (t[0] >= u[0]) ? 1.0F : 0.0F; sge[1] = (t[1] >= u[1]) ? 1.0F : 0.0F; sge[2] = (t[2] >= u[2]) ? 1.0F : 0.0F; sge[3] = (t[3] >= u[3]) ? 1.0F : 0.0F; - store_vector4( &inst->DstReg, state, sge ); + store_vector4( inst, machine, sge ); } break; case OPCODE_MAD: { GLfloat t[4], u[4], v[4], sum[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - fetch_vector4( &inst->SrcReg[1], state, u ); - fetch_vector4( &inst->SrcReg[2], state, v ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); + fetch_vector4( ctx, &inst->SrcReg[2], machine, program, v ); sum[0] = t[0] * u[0] + v[0]; sum[1] = t[1] * u[1] + v[1]; sum[2] = t[2] * u[2] + v[2]; sum[3] = t[3] * u[3] + v[3]; - store_vector4( &inst->DstReg, state, sum ); + store_vector4( inst, machine, sum ); } break; case OPCODE_ARL: { GLfloat t[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - state->Machine.AddressReg[0] = (GLint) FLOORF(t[0]); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + machine->AddressReg[0] = (GLint) FLOORF(t[0]); } break; case OPCODE_DPH: { GLfloat t[4], u[4], dot[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - fetch_vector4( &inst->SrcReg[1], state, u ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2] + u[3]; dot[1] = dot[2] = dot[3] = dot[0]; - store_vector4( &inst->DstReg, state, dot ); + store_vector4( inst, machine, dot ); } break; case OPCODE_RCC: { GLfloat t[4], u; - fetch_vector1( &inst->SrcReg[0], state, t ); + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t ); if (t[0] == 1.0F) u = 1.0F; else @@ -674,115 +682,120 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct gl_vertex_program *progra } } t[0] = t[1] = t[2] = t[3] = u; - store_vector4( &inst->DstReg, state, t ); + store_vector4( inst, machine, t ); } break; case OPCODE_SUB: /* GL_NV_vertex_program1_1 */ { GLfloat t[4], u[4], sum[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - fetch_vector4( &inst->SrcReg[1], state, u ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); sum[0] = t[0] - u[0]; sum[1] = t[1] - u[1]; sum[2] = t[2] - u[2]; sum[3] = t[3] - u[3]; - store_vector4( &inst->DstReg, state, sum ); + store_vector4( inst, machine, sum ); } break; case OPCODE_ABS: /* GL_NV_vertex_program1_1 */ { GLfloat t[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); if (t[0] < 0.0) t[0] = -t[0]; if (t[1] < 0.0) t[1] = -t[1]; if (t[2] < 0.0) t[2] = -t[2]; if (t[3] < 0.0) t[3] = -t[3]; - store_vector4( &inst->DstReg, state, t ); + store_vector4( inst, machine, t ); } break; case OPCODE_FLR: /* GL_ARB_vertex_program */ { GLfloat t[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); t[0] = FLOORF(t[0]); t[1] = FLOORF(t[1]); t[2] = FLOORF(t[2]); t[3] = FLOORF(t[3]); - store_vector4( &inst->DstReg, state, t ); + store_vector4( inst, machine, t ); } break; case OPCODE_FRC: /* GL_ARB_vertex_program */ { GLfloat t[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); t[0] = t[0] - FLOORF(t[0]); t[1] = t[1] - FLOORF(t[1]); t[2] = t[2] - FLOORF(t[2]); t[3] = t[3] - FLOORF(t[3]); - store_vector4( &inst->DstReg, state, t ); + store_vector4( inst, machine, t ); } break; case OPCODE_EX2: /* GL_ARB_vertex_program */ { GLfloat t[4]; - fetch_vector1( &inst->SrcReg[0], state, t ); + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t ); t[0] = t[1] = t[2] = t[3] = (GLfloat)_mesa_pow(2.0, t[0]); - store_vector4( &inst->DstReg, state, t ); + store_vector4( inst, machine, t ); } break; case OPCODE_LG2: /* GL_ARB_vertex_program */ { GLfloat t[4]; - fetch_vector1( &inst->SrcReg[0], state, t ); + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t ); t[0] = t[1] = t[2] = t[3] = LOG2(t[0]); - store_vector4( &inst->DstReg, state, t ); + store_vector4( inst, machine, t ); } break; case OPCODE_POW: /* GL_ARB_vertex_program */ { GLfloat t[4], u[4]; - fetch_vector1( &inst->SrcReg[0], state, t ); - fetch_vector1( &inst->SrcReg[1], state, u ); + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t ); + fetch_vector1( ctx, &inst->SrcReg[1], machine, program, u ); t[0] = t[1] = t[2] = t[3] = (GLfloat)_mesa_pow(t[0], u[0]); - store_vector4( &inst->DstReg, state, t ); + store_vector4( inst, machine, t ); } break; case OPCODE_XPD: /* GL_ARB_vertex_program */ { GLfloat t[4], u[4], cross[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - fetch_vector4( &inst->SrcReg[1], state, u ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); cross[0] = t[1] * u[2] - t[2] * u[1]; cross[1] = t[2] * u[0] - t[0] * u[2]; cross[2] = t[0] * u[1] - t[1] * u[0]; - store_vector4( &inst->DstReg, state, cross ); + store_vector4( inst, machine, cross ); } break; case OPCODE_SWZ: /* GL_ARB_vertex_program */ { const struct prog_src_register *source = &inst->SrcReg[0]; - const GLfloat *src = get_register_pointer(source, state); + const GLfloat *src = get_register_pointer(ctx, source, + machine, program); GLfloat result[4]; GLuint i; /* do extended swizzling here */ for (i = 0; i < 4; i++) { - if (GET_SWZ(source->Swizzle, i) == SWIZZLE_ZERO) + const GLuint swz = GET_SWZ(source->Swizzle, i); + if (swz == SWIZZLE_ZERO) result[i] = 0.0; - else if (GET_SWZ(source->Swizzle, i) == SWIZZLE_ONE) + else if (swz == SWIZZLE_ONE) result[i] = 1.0; - else - result[i] = src[GET_SWZ(source->Swizzle, i)]; + else { + ASSERT(swz >= 0); + ASSERT(swz <= 3); + result[i] = src[swz]; + } if (source->NegateBase & (1 << i)) result[i] = -result[i]; } - store_vector4( &inst->DstReg, state, result ); + store_vector4( inst, machine, result ); } break; case OPCODE_PRINT: if (inst->SrcReg[0].File) { GLfloat t[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); _mesa_printf("%s%g, %g, %g, %g\n", (char *) inst->Data, t[0], t[1], t[2], t[3]); } @@ -805,48 +818,18 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct gl_vertex_program *progra } - /** -Thoughts on vertex program optimization: - -The obvious thing to do is to compile the vertex program into X86/SSE/3DNow! -assembly code. That will probably be a lot of work. - -Another approach might be to replace the vp_instruction->Opcode field with -a pointer to a specialized C function which executes the instruction. -In particular we can write functions which skip swizzling, negating, -masking, relative addressing, etc. when they're not needed. - -For example: - -void simple_add( struct prog_instruction *inst ) + * Execute a vertex state program. + * \sa _mesa_ExecuteProgramNV + */ +void +_mesa_exec_vertex_state_program(GLcontext *ctx, + struct gl_vertex_program *vprog, + const GLfloat *params) { - GLfloat *sum = machine->Registers[inst->DstReg.Register]; - GLfloat *a = machine->Registers[inst->SrcReg[0].Register]; - GLfloat *b = machine->Registers[inst->SrcReg[1].Register]; - sum[0] = a[0] + b[0]; - sum[1] = a[1] + b[1]; - sum[2] = a[2] + b[2]; - sum[3] = a[3] + b[3]; + struct vp_machine machine; + _mesa_init_vp_per_vertex_registers(ctx, &machine); + _mesa_init_vp_per_primitive_registers(ctx); + COPY_4V(machine.Inputs[VERT_ATTRIB_POS], params); + _mesa_exec_vertex_program(ctx, &machine, vprog); } - -*/ - -/* - -KW: - -A first step would be to 'vectorize' the programs in the same way as -the normal transformation code in the tnl module. Thus each opcode -takes zero or more input vectors (registers) and produces one or more -output vectors. - -These operations would intially be coded in C, with machine-specific -assembly following, as is currently the case for matrix -transformations in the math/ directory. The preprocessing scheme for -selecting simpler operations Brian describes above would also work -here. - -This should give reasonable performance without excessive effort. - -*/ diff --git a/src/mesa/shader/nvvertexec.h b/src/mesa/shader/nvvertexec.h index e0fd46a766..b1cf31bd3c 100644 --- a/src/mesa/shader/nvvertexec.h +++ b/src/mesa/shader/nvvertexec.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.1 + * Version: 6.5.2 * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + * 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"), @@ -28,16 +28,40 @@ #ifndef NVVERTEXEC_H #define NVVERTEXEC_H + +/** + * Virtual vertex program machine state. + * Only used during program execution. + */ +struct vp_machine +{ + GLfloat Temporaries[MAX_NV_VERTEX_PROGRAM_TEMPS][4]; + GLfloat Inputs[MAX_NV_VERTEX_PROGRAM_INPUTS][4]; + GLuint InputsSize[MAX_NV_VERTEX_PROGRAM_INPUTS]; + GLfloat Outputs[MAX_NV_VERTEX_PROGRAM_OUTPUTS][4]; + GLint AddressReg[4]; +}; + + + extern void -_mesa_init_vp_per_vertex_registers(GLcontext *ctx); +_mesa_init_vp_per_vertex_registers(GLcontext *ctx, struct vp_machine *machine); extern void _mesa_init_vp_per_primitive_registers(GLcontext *ctx); extern void -_mesa_exec_vertex_program(GLcontext *ctx, const struct gl_vertex_program *program); +_mesa_exec_vertex_program(GLcontext *ctx, + struct vp_machine *machine, + const struct gl_vertex_program *program); + +extern void +_mesa_exec_vertex_state_program(GLcontext *ctx, + struct gl_vertex_program *vprog, + const GLfloat *params); extern void -_mesa_dump_vp_state( const struct gl_vertex_program_state *state ); +_mesa_dump_vp_state( const struct gl_vertex_program_state *state, + const struct vp_machine *machine); #endif diff --git a/src/mesa/shader/nvvertparse.c b/src/mesa/shader/nvvertparse.c index f3821d7f43..ecfe8ec334 100644 --- a/src/mesa/shader/nvvertparse.c +++ b/src/mesa/shader/nvvertparse.c @@ -1143,7 +1143,7 @@ Parse_InstructionSequence(struct parse_state *parseState, struct prog_instruction *inst = program + parseState->numInst; /* Initialize the instruction */ - _mesa_init_instruction(inst); + _mesa_init_instructions(inst, 1); if (Parse_String(parseState, "MOV")) { if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_MOV)) diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index 8ac38ae119..681584941e 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5.1 + * Version: 6.5.2 * * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * @@ -45,7 +45,7 @@ static const char * make_state_string(const GLint stateTokens[6]); -static GLuint +static GLbitfield make_state_flags(const GLint state[]); @@ -485,8 +485,7 @@ _mesa_add_state_reference(struct gl_program_parameter_list *paramList, paramList->Parameters[index].StateIndexes[i] = (enum state_index) stateTokens[i]; } - paramList->StateFlags |= - make_state_flags(stateTokens); + paramList->StateFlags |= make_state_flags(stateTokens); } /* free name string here since we duplicated it in add_parameter() */ @@ -580,37 +579,29 @@ _mesa_fetch_state(GLcontext *ctx, const enum state_index state[], { /* state[1] is either 0=front or 1=back side */ const GLuint face = (GLuint) state[1]; + const struct gl_material *mat = &ctx->Light.Material; + ASSERT(face == 0 || face == 1); + /* we rely on tokens numbered so that _BACK_ == _FRONT_+ 1 */ + ASSERT(MAT_ATTRIB_FRONT_AMBIENT + 1 == MAT_ATTRIB_BACK_AMBIENT); + /* XXX we could get rid of this switch entirely with a little + * work in arbprogparse.c's parse_state_single_item(). + */ /* state[2] is the material attribute */ switch (state[2]) { case STATE_AMBIENT: - if (face == 0) - COPY_4V(value, ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT]); - else - COPY_4V(value, ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_AMBIENT]); + COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_AMBIENT + face]); return; case STATE_DIFFUSE: - if (face == 0) - COPY_4V(value, ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE]); - else - COPY_4V(value, ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE]); + COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_DIFFUSE + face]); return; case STATE_SPECULAR: - if (face == 0) - COPY_4V(value, ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR]); - else - COPY_4V(value, ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_SPECULAR]); + COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_SPECULAR + face]); return; case STATE_EMISSION: - if (face == 0) - COPY_4V(value, ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION]); - else - COPY_4V(value, ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_EMISSION]); + COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_EMISSION + face]); return; case STATE_SHININESS: - if (face == 0) - value[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SHININESS][0]; - else - value[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_SHININESS][0]; + value[0] = mat->Attrib[MAT_ATTRIB_FRONT_SHININESS + face][0]; value[1] = 0.0F; value[2] = 0.0F; value[3] = 1.0F; @@ -941,10 +932,14 @@ _mesa_fetch_state(GLcontext *ctx, const enum state_index state[], /** - * Return a bit mask of the Mesa state flags under which a parameter's - * value might change. + * Return a bitmask of the Mesa state flags (_NEW_* values) which would + * indicate that the given context state may have changed. + * The bitmask is used during validation to determine if we need to update + * vertex/fragment program parameters (like "state.material.color") when + * some GL state has changed. */ -static GLuint make_state_flags(const GLint state[]) +static GLbitfield +make_state_flags(const GLint state[]) { switch (state[0]) { case STATE_MATERIAL: @@ -1307,26 +1302,32 @@ _mesa_load_state_parameters(GLcontext *ctx, /** * Initialize program instruction fields to defaults. + * \param inst first instruction to initialize + * \param count number of instructions to initialize */ void -_mesa_init_instruction(struct prog_instruction *inst) +_mesa_init_instructions(struct prog_instruction *inst, GLuint count) { - _mesa_bzero(inst, sizeof(struct prog_instruction)); - - inst->SrcReg[0].File = PROGRAM_UNDEFINED; - inst->SrcReg[0].Swizzle = SWIZZLE_NOOP; - inst->SrcReg[1].File = PROGRAM_UNDEFINED; - inst->SrcReg[1].Swizzle = SWIZZLE_NOOP; - inst->SrcReg[2].File = PROGRAM_UNDEFINED; - inst->SrcReg[2].Swizzle = SWIZZLE_NOOP; - - inst->DstReg.File = PROGRAM_UNDEFINED; - inst->DstReg.WriteMask = WRITEMASK_XYZW; - inst->DstReg.CondMask = COND_TR; - inst->DstReg.CondSwizzle = SWIZZLE_NOOP; - - inst->SaturateMode = SATURATE_OFF; - inst->Precision = FLOAT32; + GLuint i; + + _mesa_bzero(inst, count * sizeof(struct prog_instruction)); + + for (i = 0; i < count; i++) { + inst[i].SrcReg[0].File = PROGRAM_UNDEFINED; + inst[i].SrcReg[0].Swizzle = SWIZZLE_NOOP; + inst[i].SrcReg[1].File = PROGRAM_UNDEFINED; + inst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP; + inst[i].SrcReg[2].File = PROGRAM_UNDEFINED; + inst[i].SrcReg[2].Swizzle = SWIZZLE_NOOP; + + inst[i].DstReg.File = PROGRAM_UNDEFINED; + inst[i].DstReg.WriteMask = WRITEMASK_XYZW; + inst[i].DstReg.CondMask = COND_TR; + inst[i].DstReg.CondSwizzle = SWIZZLE_NOOP; + + inst[i].SaturateMode = SATURATE_OFF; + inst[i].Precision = FLOAT32; + } } @@ -2102,7 +2103,9 @@ _mesa_GetProgramRegisterfvMESA(GLenum target, "glGetProgramRegisterfvMESA(registerName)"); return; } - COPY_4V(v, ctx->VertexProgram.Machine.Temporaries[i]); +#if 0 /* FIX ME */ + ctx->Driver.GetVertexProgramRegister(ctx, PROGRAM_TEMPORARY, i, v); +#endif } else if (reg[0] == 'v' && reg[1] == '[') { /* Vertex Input attribute */ @@ -2113,7 +2116,10 @@ _mesa_GetProgramRegisterfvMESA(GLenum target, _mesa_sprintf(number, "%d", i); if (_mesa_strncmp(reg + 2, name, 4) == 0 || _mesa_strncmp(reg + 2, number, _mesa_strlen(number)) == 0) { - COPY_4V(v, ctx->VertexProgram.Machine.Inputs[i]); +#if 0 /* FIX ME */ + ctx->Driver.GetVertexProgramRegister(ctx, PROGRAM_INPUT, + i, v); +#endif return; } } diff --git a/src/mesa/shader/program_instruction.h b/src/mesa/shader/program_instruction.h index 93bcfc240a..cdec0ceb2a 100644 --- a/src/mesa/shader/program_instruction.h +++ b/src/mesa/shader/program_instruction.h @@ -343,7 +343,7 @@ struct prog_instruction extern void -_mesa_init_instruction(struct prog_instruction *inst); +_mesa_init_instructions(struct prog_instruction *inst, GLuint count); extern GLuint _mesa_num_inst_src_regs(enum prog_opcode opcode); diff --git a/src/mesa/shader/programopt.c b/src/mesa/shader/programopt.c index 55991dcce3..172d373b57 100644 --- a/src/mesa/shader/programopt.c +++ b/src/mesa/shader/programopt.c @@ -85,8 +85,8 @@ _mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog) * newInst[2] = DP4 result.position.z, mvp.row[2], vertex.position; * newInst[3] = DP4 result.position.w, mvp.row[3], vertex.position; */ + _mesa_init_instructions(newInst, 4); for (i = 0; i < 4; i++) { - _mesa_init_instruction(newInst + i); newInst[i].Opcode = OPCODE_DP4; newInst[i].DstReg.File = PROGRAM_OUTPUT; newInst[i].DstReg.Index = VERT_RESULT_HPOS; @@ -137,7 +137,7 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) GLfloat fogVals[4]; GLuint fogConsts; /* constant values for EXP, EXP2 mode */ - if (fprog->FogOption != GL_NONE) { + if (fprog->FogOption == GL_NONE) { _mesa_problem(ctx, "_mesa_append_fog_code() called for fragment program" " with FogOption == GL_NONE"); return; @@ -191,8 +191,7 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) } assert(inst->Opcode == OPCODE_END); /* we'll overwrite this inst */ - for (i = 0; i < 6; i++) - _mesa_init_instruction(inst + i); + _mesa_init_instructions(inst, 6); /* emit instructions to compute fog blending factor */ if (fprog->FogOption == GL_LINEAR) { diff --git a/src/mesa/swrast/s_arbshader.c b/src/mesa/swrast/s_arbshader.c index 9e41d7c673..ee971a36ec 100644 --- a/src/mesa/swrast/s_arbshader.c +++ b/src/mesa/swrast/s_arbshader.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.6 * * Copyright (C) 2006 Brian Paul All Rights Reserved. * @@ -106,6 +106,15 @@ _swrast_exec_arbshader(GLcontext *ctx, SWspan *span) (**pro).UpdateFixedVarying(pro, SLANG_FRAGMENT_FIXED_FRAGCOLOR, vec, 0, 4 * sizeof(GLfloat), GL_FALSE); COPY_4V(span->array->color.sz4.rgba[i], vec); + + (**pro).UpdateFixedVarying(pro, SLANG_FRAGMENT_FIXED_FRAGDEPTH, vec, 0, + sizeof (GLfloat), GL_FALSE); + if (vec[0] <= 0.0f) + span->array->z[i] = 0; + else if (vec[0] >= 1.0f) + span->array->z[i] = ctx->DrawBuffer->_DepthMax; + else + span->array->z[i] = IROUND(vec[0] * ctx->DrawBuffer->_DepthMaxF); } } } diff --git a/src/mesa/swrast/s_buffers.c b/src/mesa/swrast/s_buffers.c index bb85ee5777..284ea2b517 100644 --- a/src/mesa/swrast/s_buffers.c +++ b/src/mesa/swrast/s_buffers.c @@ -293,18 +293,15 @@ clear_color_buffers(GLcontext *ctx) /** * Called via the device driver's ctx->Driver.Clear() function if the * device driver can't clear one or more of the buffers itself. - * \param mask bitfield of BUFER_BIT_* values indicating which renderbuffers - * are to be cleared. + * \param buffers bitfield of BUFFER_BIT_* values indicating which + * renderbuffers are to be cleared. * \param all if GL_TRUE, clear whole buffer, else clear specified region. */ void -_swrast_Clear(GLcontext *ctx, GLbitfield mask, - GLboolean all, GLint x, GLint y, GLint width, GLint height) +_swrast_Clear(GLcontext *ctx, GLbitfield buffers) { SWcontext *swrast = SWRAST_CONTEXT(ctx); - (void) all; (void) x; (void) y; (void) width; (void) height; - #ifdef DEBUG_FOO { const GLbitfield legalBits = @@ -319,25 +316,25 @@ _swrast_Clear(GLcontext *ctx, GLbitfield mask, BUFFER_BIT_AUX1 | BUFFER_BIT_AUX2 | BUFFER_BIT_AUX3; - assert((mask & (~legalBits)) == 0); + assert((buffers & (~legalBits)) == 0); } #endif RENDER_START(swrast,ctx); /* do software clearing here */ - if (mask) { - if (mask & ctx->DrawBuffer->_ColorDrawBufferMask[0]) { + if (buffers) { + if (buffers & ctx->DrawBuffer->_ColorDrawBufferMask[0]) { clear_color_buffers(ctx); } - if (mask & BUFFER_BIT_DEPTH) { + if (buffers & BUFFER_BIT_DEPTH) { _swrast_clear_depth_buffer(ctx, ctx->DrawBuffer->_DepthBuffer); } - if (mask & BUFFER_BIT_ACCUM) { + if (buffers & BUFFER_BIT_ACCUM) { _swrast_clear_accum_buffer(ctx, ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer); } - if (mask & BUFFER_BIT_STENCIL) { + if (buffers & BUFFER_BIT_STENCIL) { _swrast_clear_stencil_buffer(ctx, ctx->DrawBuffer->_StencilBuffer); } } diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c index 18f5fe497b..62cf6f2f5a 100644 --- a/src/mesa/swrast/s_context.c +++ b/src/mesa/swrast/s_context.c @@ -223,11 +223,12 @@ _swrast_update_fog_state( GLcontext *ctx ) * program parameters with current state values. */ static void -_swrast_update_fragment_program( GLcontext *ctx ) +_swrast_update_fragment_program(GLcontext *ctx, GLbitfield newState) { if (ctx->FragmentProgram._Enabled) { const struct gl_fragment_program *fp = ctx->FragmentProgram._Current; - _mesa_load_state_parameters(ctx, fp->Base.Parameters); + if (fp->Base.Parameters->StateFlags & newState) + _mesa_load_state_parameters(ctx, fp->Base.Parameters); } } @@ -521,8 +522,18 @@ _swrast_validate_derived( GLcontext *ctx ) if (swrast->NewState & (_NEW_FOG | _NEW_PROGRAM)) _swrast_update_fog_state( ctx ); - if (swrast->NewState & _NEW_PROGRAM) - _swrast_update_fragment_program( ctx ); + if (swrast->NewState & (_NEW_MODELVIEW | + _NEW_PROJECTION | + _NEW_TEXTURE_MATRIX | + _NEW_FOG | + _NEW_LIGHT | + _NEW_LINE | + _NEW_TEXTURE | + _NEW_TRANSFORM | + _NEW_POINT | + _NEW_VIEWPORT | + _NEW_PROGRAM)) + _swrast_update_fragment_program( ctx, swrast->NewState ); if (swrast->NewState & _NEW_TEXTURE) _swrast_update_texture_samplers( ctx ); diff --git a/src/mesa/swrast/s_nvfragprog.c b/src/mesa/swrast/s_nvfragprog.c index dfca960005..7a6785b1d2 100644 --- a/src/mesa/swrast/s_nvfragprog.c +++ b/src/mesa/swrast/s_nvfragprog.c @@ -41,7 +41,10 @@ #include "s_span.h" -/* if 1, print some debugging info */ +/* See comments below for info about this */ +#define LAMBDA_ZERO 1 + +/* debug predicate */ #define DEBUG_FRAG 0 @@ -178,8 +181,8 @@ get_register_pointer( GLcontext *ctx, ASSERT(source->Index < (GLint) program->Base.Parameters->NumParameters); return program->Base.Parameters->ParameterValues[source->Index]; default: - _mesa_problem(ctx, "Invalid input register file %d in fetch_vector4", - source->File); + _mesa_problem(ctx, "Invalid input register file %d in fp " + "get_register_pointer", source->File); return NULL; } } @@ -458,7 +461,7 @@ store_vector4( const struct prog_instruction *inst, return; } -#if DEBUG_FRAG +#if 0 if (value[0] > 1.0e10 || IS_INF_OR_NAN(value[0]) || IS_INF_OR_NAN(value[1]) || @@ -646,9 +649,9 @@ execute_program( GLcontext *ctx, { GLuint pc; -#if DEBUG_FRAG - printf("execute fragment program --------------------\n"); -#endif + if (DEBUG_FRAG) { + printf("execute fragment program --------------------\n"); + } for (pc = 0; pc < maxInst; pc++) { const struct prog_instruction *inst = program->Base.Instructions + pc; @@ -660,6 +663,10 @@ execute_program( GLcontext *ctx, ctx->FragmentProgram.CallbackData); } + if (DEBUG_FRAG) { + _mesa_print_instruction(inst); + } + switch (inst->Opcode) { case OPCODE_ABS: { @@ -682,6 +689,12 @@ execute_program( GLcontext *ctx, result[2] = a[2] + b[2]; result[3] = a[3] + b[3]; store_vector4( inst, machine, result ); + if (DEBUG_FRAG) { + printf("ADD (%g %g %g %g) = (%g %g %g %g) + (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], + b[0], b[1], b[2], b[3]); + } } break; case OPCODE_CMP: @@ -758,10 +771,10 @@ execute_program( GLcontext *ctx, fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); result[0] = result[1] = result[2] = result[3] = DOT3(a, b); store_vector4( inst, machine, result ); -#if DEBUG_FRAG - printf("DP3 %g = (%g %g %g) . (%g %g %g)\n", - result[0], a[0], a[1], a[2], b[0], b[1], b[2]); -#endif + if (DEBUG_FRAG) { + printf("DP3 %g = (%g %g %g) . (%g %g %g)\n", + result[0], a[0], a[1], a[2], b[0], b[1], b[2]); + } } break; case OPCODE_DP4: @@ -771,10 +784,11 @@ execute_program( GLcontext *ctx, fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); result[0] = result[1] = result[2] = result[3] = DOT4(a,b); store_vector4( inst, machine, result ); -#if DEBUG_FRAG - printf("DP4 %g = (%g, %g %g %g) . (%g, %g %g %g)\n", - result[0], a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]); -#endif + if (DEBUG_FRAG) { + printf("DP4 %g = (%g, %g %g %g) . (%g, %g %g %g)\n", + result[0], a[0], a[1], a[2], a[3], + b[0], b[1], b[2], b[3]); + } } break; case OPCODE_DPH: @@ -882,6 +896,11 @@ execute_program( GLcontext *ctx, } result[3] = 1.0F; store_vector4( inst, machine, result ); + if (DEBUG_FRAG) { + printf("LIT (%g %g %g %g) : (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3]); + } } break; case OPCODE_LRP: @@ -895,14 +914,14 @@ execute_program( GLcontext *ctx, result[2] = a[2] * b[2] + (1.0F - a[2]) * c[2]; result[3] = a[3] * b[3] + (1.0F - a[3]) * c[3]; store_vector4( inst, machine, result ); -#if DEBUG_FRAG - printf("LRP (%g %g %g %g) = (%g %g %g %g), " - "(%g %g %g %g), (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3], - b[0], b[1], b[2], b[3], - c[0], c[1], c[2], c[3]); -#endif + if (DEBUG_FRAG) { + printf("LRP (%g %g %g %g) = (%g %g %g %g), " + "(%g %g %g %g), (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], + b[0], b[1], b[2], b[3], + c[0], c[1], c[2], c[3]); + } } break; case OPCODE_MAD: @@ -916,6 +935,14 @@ execute_program( GLcontext *ctx, result[2] = a[2] * b[2] + c[2]; result[3] = a[3] * b[3] + c[3]; store_vector4( inst, machine, result ); + if (DEBUG_FRAG) { + printf("MAD (%g %g %g %g) = (%g %g %g %g) * " + "(%g %g %g %g) + (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], + b[0], b[1], b[2], b[3], + c[0], c[1], c[2], c[3]); + } } break; case OPCODE_MAX: @@ -928,12 +955,12 @@ execute_program( GLcontext *ctx, result[2] = MAX2(a[2], b[2]); result[3] = MAX2(a[3], b[3]); store_vector4( inst, machine, result ); -#if DEBUG_FRAG - printf("MAX (%g %g %g %g) = (%g %g %g %g), (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3], - b[0], b[1], b[2], b[3]); -#endif + if (DEBUG_FRAG) { + printf("MAX (%g %g %g %g) = (%g %g %g %g), (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], + b[0], b[1], b[2], b[3]); + } } break; case OPCODE_MIN: @@ -953,10 +980,10 @@ execute_program( GLcontext *ctx, GLfloat result[4]; fetch_vector4( ctx, &inst->SrcReg[0], machine, program, result ); store_vector4( inst, machine, result ); -#if DEBUG_FRAG - printf("MOV (%g %g %g %g)\n", - result[0], result[1], result[2], result[3]); -#endif + if (DEBUG_FRAG) { + printf("MOV (%g %g %g %g)\n", + result[0], result[1], result[2], result[3]); + } } break; case OPCODE_MUL: @@ -969,12 +996,12 @@ execute_program( GLcontext *ctx, result[2] = a[2] * b[2]; result[3] = a[3] * b[3]; store_vector4( inst, machine, result ); -#if DEBUG_FRAG - printf("MUL (%g %g %g %g) = (%g %g %g %g) * (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3], - b[0], b[1], b[2], b[3]); -#endif + if (DEBUG_FRAG) { + printf("MUL (%g %g %g %g) = (%g %g %g %g) * (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], + b[0], b[1], b[2], b[3]); + } } break; case OPCODE_PK2H: /* pack two 16-bit floats in one 32-bit float */ @@ -1056,12 +1083,12 @@ execute_program( GLcontext *ctx, { GLfloat a[4], result[4]; fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); -#if DEBUG_FRAG - if (a[0] == 0) - printf("RCP(0)\n"); - else if (IS_INF_OR_NAN(a[0])) - printf("RCP(inf)\n"); -#endif + if (DEBUG_FRAG) { + if (a[0] == 0) + printf("RCP(0)\n"); + else if (IS_INF_OR_NAN(a[0])) + printf("RCP(inf)\n"); + } result[0] = result[1] = result[2] = result[3] = 1.0F / a[0]; store_vector4( inst, machine, result ); } @@ -1087,9 +1114,9 @@ execute_program( GLcontext *ctx, a[0] = FABSF(a[0]); result[0] = result[1] = result[2] = result[3] = INV_SQRTF(a[0]); store_vector4( inst, machine, result ); -#if DEBUG_FRAG - printf("RSQ %g = 1/sqrt(|%g|)\n", result[0], a[0]); -#endif + if (DEBUG_FRAG) { + printf("RSQ %g = 1/sqrt(|%g|)\n", result[0], a[0]); + } } break; case OPCODE_SCS: /* sine and cos */ @@ -1206,11 +1233,11 @@ execute_program( GLcontext *ctx, result[2] = a[2] - b[2]; result[3] = a[3] - b[3]; store_vector4( inst, machine, result ); -#if DEBUG_FRAG - printf("SUB (%g %g %g %g) = (%g %g %g %g) - (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]); -#endif + if (DEBUG_FRAG) { + printf("SUB (%g %g %g %g) = (%g %g %g %g) - (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]); + } } break; case OPCODE_SWZ: /* extended swizzle */ @@ -1240,44 +1267,47 @@ execute_program( GLcontext *ctx, case OPCODE_TEX: /* Both ARB and NV frag prog */ /* Texel lookup */ { - GLfloat texcoord[4], color[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, texcoord ); - /* Note: we pass 0 for LOD. The ARB extension requires it - * while the NV extension says it's implementation dependant. + /* Note: only use the precomputed lambda value when we're + * sampling texture unit [K] with texcoord[K]. + * Otherwise, the lambda value may have no relation to the + * instruction's texcoord or texture image. Using the wrong + * lambda is usually bad news. + * The rest of the time, just use zero (until we get a more + * sophisticated way of computing lambda). */ - /* KW: Previously lambda was passed as zero, but I - * believe this is incorrect, the spec seems to - * indicate rather that lambda should not be - * changed/biased, unlike TXB where texcoord[3] is - * added to the lambda calculations. The lambda should - * still be calculated normally for TEX & TXP though, - * not set to zero. Otherwise it's very difficult to - * implement normal GL semantics through the fragment - * shader. - */ - fetch_texel( ctx, texcoord, - span->array->lambda[inst->TexSrcUnit][column], - inst->TexSrcUnit, color ); -#if DEBUG_FRAG - if (color[3]) - printf("color[3] = %f\n", color[3]); -#endif + GLfloat coord[4], color[4], lambda; + if (inst->SrcReg[0].File == PROGRAM_INPUT && + inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) + lambda = span->array->lambda[inst->TexSrcUnit][column]; + else + lambda = 0.0; + fetch_vector4(ctx, &inst->SrcReg[0], machine, program, coord); + fetch_texel( ctx, coord, lambda, inst->TexSrcUnit, color ); + if (DEBUG_FRAG) { + printf("TEX (%g, %g, %g, %g) = texture[%d][%g, %g, %g, %g], " + "lod %f\n", + color[0], color[1], color[2], color[3], + inst->TexSrcUnit, + coord[0], coord[1], coord[2], coord[3], lambda); + } store_vector4( inst, machine, color ); } break; case OPCODE_TXB: /* GL_ARB_fragment_program only */ /* Texel lookup with LOD bias */ { - GLfloat texcoord[4], color[4], bias, lambda; - - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, texcoord ); - /* texcoord[3] is the bias to add to lambda */ + GLfloat coord[4], color[4], lambda, bias; + if (inst->SrcReg[0].File == PROGRAM_INPUT && + inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) + lambda = span->array->lambda[inst->TexSrcUnit][column]; + else + lambda = 0.0; + fetch_vector4(ctx, &inst->SrcReg[0], machine, program, coord); + /* coord[3] is the bias to add to lambda */ bias = ctx->Texture.Unit[inst->TexSrcUnit].LodBias + ctx->Texture.Unit[inst->TexSrcUnit]._Current->LodBias - + texcoord[3]; - lambda = span->array->lambda[inst->TexSrcUnit][column] + bias; - fetch_texel( ctx, texcoord, lambda, - inst->TexSrcUnit, color ); + + coord[3]; + fetch_texel(ctx, coord, lambda + bias, inst->TexSrcUnit, color); store_vector4( inst, machine, color ); } break; @@ -1296,8 +1326,13 @@ execute_program( GLcontext *ctx, case OPCODE_TXP: /* GL_ARB_fragment_program only */ /* Texture lookup w/ projective divide */ { - GLfloat texcoord[4], color[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, texcoord ); + GLfloat texcoord[4], color[4], lambda; + if (inst->SrcReg[0].File == PROGRAM_INPUT && + inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) + lambda = span->array->lambda[inst->TexSrcUnit][column]; + else + lambda = 0.0; + fetch_vector4(ctx, &inst->SrcReg[0], machine, program,texcoord); /* Not so sure about this test - if texcoord[3] is * zero, we'd probably be fine except for an ASSERT in * IROUND_POS() which gets triggered by the inf values created. @@ -1307,34 +1342,27 @@ execute_program( GLcontext *ctx, texcoord[1] /= texcoord[3]; texcoord[2] /= texcoord[3]; } - /* KW: Previously lambda was passed as zero, but I - * believe this is incorrect, the spec seems to - * indicate rather that lambda should not be - * changed/biased, unlike TXB where texcoord[3] is - * added to the lambda calculations. The lambda should - * still be calculated normally for TEX & TXP though, - * not set to zero. - */ - fetch_texel( ctx, texcoord, - span->array->lambda[inst->TexSrcUnit][column], - inst->TexSrcUnit, color ); + fetch_texel( ctx, texcoord, lambda, inst->TexSrcUnit, color ); store_vector4( inst, machine, color ); } break; case OPCODE_TXP_NV: /* GL_NV_fragment_program only */ /* Texture lookup w/ projective divide */ { - GLfloat texcoord[4], color[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, texcoord ); + GLfloat texcoord[4], color[4], lambda; + if (inst->SrcReg[0].File == PROGRAM_INPUT && + inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) + lambda = span->array->lambda[inst->TexSrcUnit][column]; + else + lambda = 0.0; + fetch_vector4(ctx, &inst->SrcReg[0], machine, program,texcoord); if (inst->TexSrcTarget != TEXTURE_CUBE_INDEX && texcoord[3] != 0.0) { texcoord[0] /= texcoord[3]; texcoord[1] /= texcoord[3]; texcoord[2] /= texcoord[3]; } - fetch_texel( ctx, texcoord, - span->array->lambda[inst->TexSrcUnit][column], - inst->TexSrcUnit, color ); + fetch_texel( ctx, texcoord, lambda, inst->TexSrcUnit, color ); store_vector4( inst, machine, color ); } break; @@ -1572,10 +1600,6 @@ _swrast_exec_fragment_program( GLcontext *ctx, SWspan *span ) ctx->_CurrentProgram = GL_FRAGMENT_PROGRAM_ARB; /* or NV, doesn't matter */ - if (program->Base.Parameters) { - _mesa_load_state_parameters(ctx, program->Base.Parameters); - } - run_program(ctx, span, 0, span->end); if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) { diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index 2e20f7a296..c74b98facf 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -353,32 +353,38 @@ interpolate_specular(SWspan *span) case GL_FLOAT: { GLfloat (*spec)[4] = span->array->color.sz4.spec; +#if CHAN_BITS <= 16 + GLfloat r = CHAN_TO_FLOAT(FixedToChan(span->specRed)); + GLfloat g = CHAN_TO_FLOAT(FixedToChan(span->specGreen)); + GLfloat b = CHAN_TO_FLOAT(FixedToChan(span->specBlue)); +#else + GLfloat r = span->specRed; + GLfloat g = span->specGreen; + GLfloat b = span->specBlue; +#endif + GLfloat dr, dg, db; if (span->interpMask & SPAN_FLAT) { - GLfloat color[4]; - color[RCOMP] = span->specRed; - color[GCOMP] = span->specGreen; - color[BCOMP] = span->specBlue; - color[ACOMP] = 0.0F; - for (i = 0; i < n; i++) { - COPY_4V(spec[i], color); - } + dr = dg = db = 0.0; } else { - GLfloat r = span->specRed; - GLfloat g = span->specGreen; - GLfloat b = span->specBlue; - GLfloat dr = span->specRedStep; - GLfloat dg = span->specGreenStep; - GLfloat db = span->specBlueStep; - for (i = 0; i < n; i++) { - spec[i][RCOMP] = r; - spec[i][GCOMP] = g; - spec[i][BCOMP] = b; - spec[i][ACOMP] = 0.0F; - r += dr; - g += dg; - b += db; - } +#if CHAN_BITS <= 16 + dr = CHAN_TO_FLOAT(FixedToChan(span->specRedStep)); + dg = CHAN_TO_FLOAT(FixedToChan(span->specGreenStep)); + db = CHAN_TO_FLOAT(FixedToChan(span->specBlueStep)); +#else + dr = span->specRedStep; + dg = span->specGreenStep; + db = span->specBlueStep; +#endif + } + for (i = 0; i < n; i++) { + spec[i][RCOMP] = r; + spec[i][GCOMP] = g; + spec[i][BCOMP] = b; + spec[i][ACOMP] = 0.0F; + r += dr; + g += dg; + b += db; } } break; diff --git a/src/mesa/swrast/s_texstore.c b/src/mesa/swrast/s_texstore.c index ddaf7471f5..3f49b40d9c 100644 --- a/src/mesa/swrast/s_texstore.c +++ b/src/mesa/swrast/s_texstore.c @@ -254,7 +254,7 @@ _swrast_copy_teximage1d( GLcontext *ctx, GLenum target, GLint level, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); ASSERT(texObj); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + texImage = _mesa_select_tex_image(ctx, texObj, target, level); ASSERT(texImage); ASSERT(ctx->Driver.TexImage1D); @@ -331,7 +331,7 @@ _swrast_copy_teximage2d( GLcontext *ctx, GLenum target, GLint level, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); ASSERT(texObj); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + texImage = _mesa_select_tex_image(ctx, texObj, target, level); ASSERT(texImage); ASSERT(ctx->Driver.TexImage2D); @@ -400,7 +400,7 @@ _swrast_copy_texsubimage1d( GLcontext *ctx, GLenum target, GLint level, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); ASSERT(texObj); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + texImage = _mesa_select_tex_image(ctx, texObj, target, level); ASSERT(texImage); ASSERT(ctx->Driver.TexImage1D); @@ -474,7 +474,7 @@ _swrast_copy_texsubimage2d( GLcontext *ctx, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); ASSERT(texObj); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + texImage = _mesa_select_tex_image(ctx, texObj, target, level); ASSERT(texImage); ASSERT(ctx->Driver.TexImage2D); @@ -547,7 +547,7 @@ _swrast_copy_texsubimage3d( GLcontext *ctx, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); ASSERT(texObj); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + texImage = _mesa_select_tex_image(ctx, texObj, target, level); ASSERT(texImage); ASSERT(ctx->Driver.TexImage3D); diff --git a/src/mesa/swrast/swrast.h b/src/mesa/swrast/swrast.h index 04bd01a0cd..09686c8380 100644 --- a/src/mesa/swrast/swrast.h +++ b/src/mesa/swrast/swrast.h @@ -130,8 +130,7 @@ _swrast_BlitFramebuffer(GLcontext *ctx, GLbitfield mask, GLenum filter); extern void -_swrast_Clear( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint x, GLint y, GLint width, GLint height ); +_swrast_Clear(GLcontext *ctx, GLbitfield buffers); extern void _swrast_Accum(GLcontext *ctx, GLenum op, GLfloat value); diff --git a/src/mesa/tnl/t_context.c b/src/mesa/tnl/t_context.c index 5d6b6dd97d..bd459a7747 100644 --- a/src/mesa/tnl/t_context.c +++ b/src/mesa/tnl/t_context.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.2 * * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * @@ -135,7 +135,8 @@ _tnl_InvalidateState( GLcontext *ctx, GLuint new_state ) if (ctx->Fog.Enabled || (ctx->FragmentProgram._Active && - ctx->FragmentProgram._Current->FogOption != GL_NONE)) + (ctx->FragmentProgram._Current->FogOption != GL_NONE || + ctx->FragmentProgram._Current->Base.InputsRead & FRAG_BIT_FOGC))) RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_FOG ); if (ctx->Polygon.FrontMode != GL_FILL || diff --git a/src/mesa/tnl/t_vb_program.c b/src/mesa/tnl/t_vb_program.c index b8828ec36a..f11ac616f1 100644 --- a/src/mesa/tnl/t_vb_program.c +++ b/src/mesa/tnl/t_vb_program.c @@ -76,6 +76,7 @@ run_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage ) struct vp_stage_data *store = VP_STAGE_DATA(stage); struct vertex_buffer *VB = &tnl->vb; struct gl_vertex_program *program = ctx->VertexProgram.Current; + struct vp_machine machine; GLuint i; if (ctx->ShaderObjects._VertexShaderPresent) @@ -91,7 +92,7 @@ run_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage ) for (i = 0; i < VB->Count; i++) { GLuint attr; - _mesa_init_vp_per_vertex_registers(ctx); + _mesa_init_vp_per_vertex_registers(ctx, &machine); #if 0 printf("Input %d: %f, %f, %f, %f\n", i, @@ -118,30 +119,29 @@ run_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage ) const GLuint size = VB->AttribPtr[attr]->size; const GLuint stride = VB->AttribPtr[attr]->stride; const GLfloat *data = (GLfloat *) (ptr + stride * i); - COPY_CLEAN_4V(ctx->VertexProgram.Machine.Inputs[attr], size, data); + COPY_CLEAN_4V(machine.Inputs[attr], size, data); } } /* execute the program */ ASSERT(program); - _mesa_exec_vertex_program(ctx, program); + _mesa_exec_vertex_program(ctx, &machine, program); /* Fixup fog an point size results if needed */ if (ctx->Fog.Enabled && (program->Base.OutputsWritten & (1 << VERT_RESULT_FOGC)) == 0) { - ctx->VertexProgram.Machine.Outputs[VERT_RESULT_FOGC][0] = 1.0; + machine.Outputs[VERT_RESULT_FOGC][0] = 1.0; } if (ctx->VertexProgram.PointSizeEnabled && (program->Base.OutputsWritten & (1 << VERT_RESULT_PSIZ)) == 0) { - ctx->VertexProgram.Machine.Outputs[VERT_RESULT_PSIZ][0] = ctx->Point.Size; + machine.Outputs[VERT_RESULT_PSIZ][0] = ctx->Point.Size; } /* copy the output registers into the VB->attribs arrays */ /* XXX (optimize) could use a conditional and smaller loop limit here */ for (attr = 0; attr < 15; attr++) { - COPY_4V(store->attribs[attr].data[i], - ctx->VertexProgram.Machine.Outputs[attr]); + COPY_4V(store->attribs[attr].data[i], machine.Outputs[attr]); } } -- cgit v1.2.3 From 5a652f595716a82ebd79e33011f6082199c4b0d0 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 2 Nov 2006 18:00:43 +0000 Subject: Fill in missing input slots in the vertex-array + no-vertex-program path. --- src/mesa/vbo/vbo_exec_array.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index b3650e2697..481c4ee546 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -81,7 +81,8 @@ static GLuint get_max_index( GLuint count, GLuint type, */ static void bind_array_obj( GLcontext *ctx ) { - struct vbo_exec_context *exec = &vbo_context(ctx)->exec; + struct vbo_context *vbo = vbo_context(ctx); + struct vbo_exec_context *exec = &vbo->exec; GLuint i; /* TODO: Fix the ArrayObj struct to keep legacy arrays in an array @@ -89,6 +90,7 @@ static void bind_array_obj( GLcontext *ctx ) * go away. */ exec->array.legacy_array[VERT_ATTRIB_POS] = &ctx->Array.ArrayObj->Vertex; + exec->array.legacy_array[VERT_ATTRIB_WEIGHT] = &vbo->legacy_currval[i]; exec->array.legacy_array[VERT_ATTRIB_NORMAL] = &ctx->Array.ArrayObj->Normal; exec->array.legacy_array[VERT_ATTRIB_COLOR0] = &ctx->Array.ArrayObj->Color; exec->array.legacy_array[VERT_ATTRIB_COLOR1] = &ctx->Array.ArrayObj->SecondaryColor; @@ -133,6 +135,13 @@ static void recalculate_input_bindings( GLcontext *ctx ) for (i = 0; i < MAT_ATTRIB_MAX; i++) { inputs[VERT_ATTRIB_GENERIC0 + i] = &vbo->mat_currval[i]; } + + /* Could use just about anything, just to fill in the empty + * slots: + */ + for (i = MAT_ATTRIB_MAX; i < VERT_ATTRIB_MAX; i++) + inputs[i] = &vbo->generic_currval[i - VERT_ATTRIB_GENERIC0]; + break; case VP_NV: /* NV_vertex_program - attribute arrays alias and override -- cgit v1.2.3 From 301acdf34ad01315f41c14638d92aa7fe0c2d2dc Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 2 Nov 2006 18:02:17 +0000 Subject: Similarly, fill in missing input slots in the vertex-array + NV_vertex_program path. --- src/mesa/vbo/vbo_exec_array.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index 481c4ee546..aab5748626 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -156,6 +156,13 @@ static void recalculate_input_bindings( GLcontext *ctx ) else inputs[i] = &vbo->legacy_currval[i]; } + + /* Could use just about anything, just to fill in the empty + * slots: + */ + for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) + inputs[i] = &vbo->generic_currval[i - VERT_ATTRIB_GENERIC0]; + break; case VP_ARB: /* ARB_vertex_program - Only the attribute zero (position) array -- cgit v1.2.3 From 01e238e5d51dabd28646356de825aa43a7290373 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 2 Nov 2006 19:02:04 +0000 Subject: Fix typo in last commit --- src/mesa/vbo/vbo_exec_array.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index aab5748626..8f5c26920b 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -90,7 +90,7 @@ static void bind_array_obj( GLcontext *ctx ) * go away. */ exec->array.legacy_array[VERT_ATTRIB_POS] = &ctx->Array.ArrayObj->Vertex; - exec->array.legacy_array[VERT_ATTRIB_WEIGHT] = &vbo->legacy_currval[i]; + exec->array.legacy_array[VERT_ATTRIB_WEIGHT] = &vbo->legacy_currval[VERT_ATTRIB_WEIGHT]; exec->array.legacy_array[VERT_ATTRIB_NORMAL] = &ctx->Array.ArrayObj->Normal; exec->array.legacy_array[VERT_ATTRIB_COLOR0] = &ctx->Array.ArrayObj->Color; exec->array.legacy_array[VERT_ATTRIB_COLOR1] = &ctx->Array.ArrayObj->SecondaryColor; -- cgit v1.2.3 From 7e9c3684ef45e0df8426317f28c883d16f27c031 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 2 Nov 2006 19:11:16 +0000 Subject: Fix type-conversion of incoming vertices. Fix mis-application of increment to pointer variable. --- src/mesa/tnl/t_draw.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mesa/tnl/t_draw.c b/src/mesa/tnl/t_draw.c index c84a10856e..e0a16e284d 100644 --- a/src/mesa/tnl/t_draw.c +++ b/src/mesa/tnl/t_draw.c @@ -108,7 +108,8 @@ static void _tnl_import_array( GLcontext *ctx, if (input->Type != GL_FLOAT) { const GLuint sz = input->Size; - GLfloat *fptr = get_space(ctx, count * sz * sizeof(GLfloat)); + char *buf = get_space(ctx, count * sz * sizeof(GLfloat)); + GLfloat *fptr = (GLfloat *)buf; switch (input->Type) { case GL_BYTE: @@ -137,7 +138,7 @@ static void _tnl_import_array( GLcontext *ctx, break; } - ptr = (const char *)fptr; + ptr = buf; stride = sz * sizeof(GLfloat); } @@ -197,7 +198,7 @@ static void bind_inputs( GLcontext *ctx, if (inputs[i]->BufferObj->Name) { if (!inputs[i]->BufferObj->Pointer) { bo[*nr_bo] = inputs[i]->BufferObj; - *nr_bo++; + (*nr_bo)++; ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER, GL_READ_ONLY_ARB, @@ -268,7 +269,7 @@ static void bind_indicies( GLcontext *ctx, if (ib->obj->Name && !ib->obj->Pointer) { bo[*nr_bo] = ib->obj; - *nr_bo++; + (*nr_bo)++; ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY_ARB, -- cgit v1.2.3 From a93f4a73100f00d8114ee9931fd80eaa8f6f0375 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Thu, 2 Nov 2006 20:44:03 +0000 Subject: Move r300 to new fbo interface based on Keith Whithwell. Tested with progs/redbook/varray. --- src/mesa/drivers/dri/r300/radeon_vtxfmt_a.c | 304 ++++++++-------------------- 1 file changed, 86 insertions(+), 218 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/r300/radeon_vtxfmt_a.c b/src/mesa/drivers/dri/r300/radeon_vtxfmt_a.c index 72c03c53ad..0625e5bc57 100644 --- a/src/mesa/drivers/dri/r300/radeon_vtxfmt_a.c +++ b/src/mesa/drivers/dri/r300/radeon_vtxfmt_a.c @@ -46,6 +46,8 @@ #include "state.h" #include "image.h" +#include "vbo/vbo_context.h" + #define CONV_VB(a, b) rvb->AttribPtr[(a)].size = vb->b->size, \ rvb->AttribPtr[(a)].type = GL_FLOAT, \ rvb->AttribPtr[(a)].stride = vb->b->stride, \ @@ -129,15 +131,7 @@ static int setup_arrays(r300ContextPtr rmesa, GLint start) CONV(i, VertexAttrib[i]); for (i=0; i < VERT_ATTRIB_MAX; i++) { - if (enabled & (1 << i)) { - rmesa->state.VB.AttribPtr[i].data += rmesa->state.VB.AttribPtr[i].stride * start; - } else { - def.data = ctx->Current.Attrib[i]; - memcpy(&rmesa->state.VB.AttribPtr[i], &def, sizeof(struct dt)); - } - - /*if(rmesa->state.VB.AttribPtr[i].data == ctx->Current.Attrib[i]) - fprintf(stderr, "%d is default coord\n", i);*/ + rmesa->state.VB.AttribPtr[i].data += rmesa->state.VB.AttribPtr[i].stride * start; } for(i=0; i < VERT_ATTRIB_MAX; i++){ @@ -177,177 +171,18 @@ static int setup_arrays(r300ContextPtr rmesa, GLint start) void radeon_init_vtxfmt_a(r300ContextPtr rmesa); -static void radeonDrawElements( GLenum mode, GLsizei count, GLenum type, const GLvoid *c_indices ) -{ - GET_CURRENT_CONTEXT(ctx); - r300ContextPtr rmesa = R300_CONTEXT(ctx); - int elt_size; - int i; - unsigned int min = ~0, max = 0; - struct tnl_prim prim; - static void *ptr = NULL; - struct r300_dma_region rvb; - const GLvoid *indices = c_indices; - - if (count > 65535) { - WARN_ONCE("Too many verts!\n"); - goto fallback; - } - - 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 = (GLvoid *) - ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Data, (const GLubyte *) c_indices); - } - - if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) - return; - - FLUSH_CURRENT( ctx, 0 ); - - memset(&rvb, 0, sizeof(rvb)); - switch (type) { - case GL_UNSIGNED_BYTE: - for (i=0; i < count; i++) { - if(((unsigned char *)indices)[i] < min) - min = ((unsigned char *)indices)[i]; - if(((unsigned char *)indices)[i] > max) - max = ((unsigned char *)indices)[i]; - } - -#ifdef FORCE_32BITS_ELTS - elt_size = 4; -#else - elt_size = 2; -#endif - r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size); - rvb.aos_offset = GET_START(&rvb); - ptr = rvb.address + rvb.start; - -#ifdef FORCE_32BITS_ELTS - for (i=0; i < count; i++) - ((unsigned int *)ptr)[i] = ((unsigned char *)indices)[i] - min; -#else - for (i=0; i < count; i++) - ((unsigned short int *)ptr)[i] = ((unsigned char *)indices)[i] - min; -#endif - break; - - case GL_UNSIGNED_SHORT: - for (i=0; i < count; i++) { - if(((unsigned short int *)indices)[i] < min) - min = ((unsigned short int *)indices)[i]; - if(((unsigned short int *)indices)[i] > max) - max = ((unsigned short int *)indices)[i]; - } - -#ifdef FORCE_32BITS_ELTS - elt_size = 4; -#else - elt_size = 2; -#endif - - r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size); - rvb.aos_offset = GET_START(&rvb); - ptr = rvb.address + rvb.start; - -#ifdef FORCE_32BITS_ELTS - for (i=0; i < count; i++) - ((unsigned int *)ptr)[i] = ((unsigned short int *)indices)[i] - min; -#else - for (i=0; i < count; i++) - ((unsigned short int *)ptr)[i] = ((unsigned short int *)indices)[i] - min; -#endif - break; - - case GL_UNSIGNED_INT: - for (i=0; i < count; i++) { - if(((unsigned int *)indices)[i] < min) - min = ((unsigned int *)indices)[i]; - if(((unsigned int *)indices)[i] > max) - max = ((unsigned int *)indices)[i]; - } - -#ifdef FORCE_32BITS_ELTS - elt_size = 4; -#else - if (max - min <= 65535) - elt_size = 2; - else - elt_size = 4; -#endif - r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size); - rvb.aos_offset = GET_START(&rvb); - ptr = rvb.address + rvb.start; - - - if (elt_size == 2) - for (i=0; i < count; i++) - ((unsigned short int *)ptr)[i] = ((unsigned int *)indices)[i] - min; - else - for (i=0; i < count; i++) - ((unsigned int *)ptr)[i] = ((unsigned int *)indices)[i] - min; - break; - - default: - WARN_ONCE("Unknown elt type!\n"); - goto fallback; - } - - if (ctx->NewState) - _mesa_update_state( ctx ); - - r300UpdateShaders(rmesa); - - if (setup_arrays(rmesa, min) >= R300_FALLBACK_TCL) { - r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__); - goto fallback; - } - - rmesa->state.VB.Count = max - min + 1; - - r300UpdateShaderStates(rmesa); - - rmesa->state.VB.Primitive = &prim; - rmesa->state.VB.PrimitiveCount = 1; - - prim.mode = mode | PRIM_BEGIN | PRIM_END; - if (rmesa->state.VB.LockCount) - prim.start = min - rmesa->state.VB.LockFirst; - else - prim.start = 0; - prim.count = count; - - rmesa->state.VB.Elts = ptr; - rmesa->state.VB.elt_size = elt_size; - - if (r300_run_vb_render(ctx, NULL)) { - r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__); - goto fallback; - } - - if(rvb.buf) - radeon_mm_use(rmesa, rvb.buf->id); - - r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__); - return; - - fallback: - _tnl_array_init(ctx); - _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt ); - CALL_DrawElements(GET_DISPATCH(), (mode, count, type, c_indices)); - radeon_init_vtxfmt_a(rmesa); - _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt ); -} -static void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei count, GLenum type, const GLvoid *c_indices) +static void radeonDrawRangeElements(GLcontext *ctx, + GLenum mode, + GLuint min, + GLuint max, + GLsizei count, + GLenum type, + const GLvoid *c_indices) { - GET_CURRENT_CONTEXT(ctx); +#if 1 + return GL_FALSE; +#else r300ContextPtr rmesa = R300_CONTEXT(ctx); struct tnl_prim prim; int elt_size; @@ -371,26 +206,23 @@ static void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei indices += i * _mesa_sizeof_type(type); count -= i; } - return ; + return GL_TRUE; } WARN_ONCE("Too many verts!\n"); - goto fallback; + return GL_FALSE; } 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; + return GL_TRUE; } /* actual address is the sum of pointers */ indices = (GLvoid *) ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Data, (const GLubyte *) c_indices); } - if (!_mesa_validate_DrawRangeElements( ctx, mode, min, max, count, type, indices )) - return; - FLUSH_CURRENT( ctx, 0 ); #ifdef OPTIMIZE_ELTS min = 0; @@ -465,7 +297,7 @@ static void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei default: WARN_ONCE("Unknown elt type!\n"); - goto fallback; + return GL_FALSE; } /* XXX: setup_arrays before state update? */ @@ -477,7 +309,7 @@ static void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei if (setup_arrays(rmesa, min) >= R300_FALLBACK_TCL) { r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__); - goto fallback; + return GL_FALSE; } rmesa->state.VB.Count = max - min + 1; @@ -501,37 +333,34 @@ static void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei if (r300_run_vb_render(ctx, NULL)) { r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__); - goto fallback; + return GL_FALSE; } if(rvb.buf) radeon_mm_use(rmesa, rvb.buf->id); r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__); - return ; - - fallback: - _tnl_array_init(ctx); - _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt ); - CALL_DrawRangeElements(GET_DISPATCH(), (mode, min, max, count, type, c_indices)); - radeon_init_vtxfmt_a(rmesa); - _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt ); + return GL_TRUE; +#endif } -static void radeonDrawArrays( GLenum mode, GLint start, GLsizei count ) +static GLboolean radeonDrawArrays( GLcontext *ctx, + GLenum mode, GLint start, GLsizei count ) { +#if 1 + return GL_FALSE; +#else GET_CURRENT_CONTEXT(ctx); r300ContextPtr rmesa = R300_CONTEXT(ctx); struct tnl_prim prim; if (count > 65535) { + /* TODO: split into multiple draws. + */ WARN_ONCE("Too many verts!\n"); - goto fallback; + return GL_FALSE; } - if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) - return; - FLUSH_CURRENT( ctx, 0 ); if (ctx->NewState) @@ -542,7 +371,7 @@ static void radeonDrawArrays( GLenum mode, GLint start, GLsizei count ) r300UpdateShaders(rmesa); if (setup_arrays(rmesa, start) >= R300_FALLBACK_TCL) - goto fallback; + return GL_FALSE; rmesa->state.VB.Count = count; @@ -564,31 +393,70 @@ static void radeonDrawArrays( GLenum mode, GLint start, GLsizei count ) rmesa->state.VB.elt_max = 0; if (r300_run_vb_render(ctx, NULL)) - goto fallback; + return GL_FALSE; - return ; - - fallback: - _tnl_array_init(ctx); - _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt ); - CALL_DrawArrays(GET_DISPATCH(), (mode, start, count)); - radeon_init_vtxfmt_a(rmesa); - _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt ); + return GL_TRUE; +#endif } +static void radeon_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) +{ + if (ib == NULL) { + for (i = 0; i < nr_prims; i++) { + if (!radeonDrawArrays(ctx, + prim->mode, + prim->start, + prim->count)) { + /* Fallback + */ + _tnl_draw_prims(ctx, + arrays, + prim + i, + nr_prims - i, + ib, + min_index, + max_index); + return; + } + } + } else { + for (i = 0; i < nr_prims; i++) { + if (!radeonDrawRangeElements(ctx, + prim->mode, + min_index, + max_index, + prim->count, + ib->types, + ib->ptr)) { + /* Fallback + */ + _tnl_draw_prims(ctx, + arrays, + prim + i, + nr_prims - i, + ib, + min_index, + max_index); + return; + } + } + } +} + void radeon_init_vtxfmt_a(r300ContextPtr rmesa) { GLcontext *ctx; - GLvertexformat *vfmt; - - ctx = rmesa->radeon.glCtx; - vfmt = (GLvertexformat *)ctx->TnlModule.Current; - - vfmt->DrawElements = radeonDrawElements; - vfmt->DrawArrays = radeonDrawArrays; - vfmt->DrawRangeElements = radeonDrawRangeElements; + struct vbo_context *vbo = vbo_context(ctx); + vbo->draw_prims = radeon_draw_prims; } + #endif #ifdef HW_VBOS -- cgit v1.2.3 From 25b2e50229592ecd4cc3d058471bdee1cb8a0c55 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Fri, 3 Nov 2006 12:30:55 +0000 Subject: remove remaining traces of r200FlushVertices... --- src/mesa/drivers/dri/r200/r200_context.c | 1 - src/mesa/drivers/dri/r200/r200_swtcl.h | 1 - 2 files changed, 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c index 02651587a6..a1533d7f3e 100644 --- a/src/mesa/drivers/dri/r200/r200_context.c +++ b/src/mesa/drivers/dri/r200/r200_context.c @@ -442,7 +442,6 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, */ _tnl_destroy_pipeline( ctx ); _tnl_install_pipeline( ctx, r200_pipeline ); - ctx->Driver.FlushVertices = r200FlushVertices; /* Try and keep materials and vertices separate: */ diff --git a/src/mesa/drivers/dri/r200/r200_swtcl.h b/src/mesa/drivers/dri/r200/r200_swtcl.h index ce2b6b5f06..ccf817988c 100644 --- a/src/mesa/drivers/dri/r200/r200_swtcl.h +++ b/src/mesa/drivers/dri/r200/r200_swtcl.h @@ -42,7 +42,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. extern void r200InitSwtcl( GLcontext *ctx ); extern void r200DestroySwtcl( GLcontext *ctx ); -extern void r200FlushVertices( GLcontext *ctx, GLuint flags ); extern void r200ChooseRenderState( GLcontext *ctx ); extern void r200ChooseVertexState( GLcontext *ctx ); -- cgit v1.2.3 From c3da1501b81a31e92f485ee9fbd99e60cc3a4337 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Fri, 3 Nov 2006 12:33:29 +0000 Subject: need to call bind_arrays() in vbo_exec_DrawRangeElements. --- src/mesa/vbo/vbo_exec_array.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index 8f5c26920b..803e58c148 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -290,7 +290,9 @@ vbo_exec_DrawRangeElements(GLenum mode, if (ctx->NewState) _mesa_update_state( ctx ); - + + bind_arrays( ctx ); + ib.count = count; ib.type = type; ib.obj = ctx->Array.ElementArrayBufferObj; -- cgit v1.2.3 From 188a4db49c4c22429bfa7ae87d4b1a0c35bf0285 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 3 Nov 2006 13:04:08 +0000 Subject: Fix compiler warnings. Add missing code for translating non-GLuint elements. --- src/mesa/tnl/t_draw.c | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/mesa/tnl/t_draw.c b/src/mesa/tnl/t_draw.c index e0a16e284d..0f9615e7cc 100644 --- a/src/mesa/tnl/t_draw.c +++ b/src/mesa/tnl/t_draw.c @@ -41,13 +41,13 @@ -static GLfloat *get_space(GLcontext *ctx, GLuint bytes) +static GLubyte *get_space(GLcontext *ctx, GLuint bytes) { TNLcontext *tnl = TNL_CONTEXT(ctx); GLubyte *space = _mesa_malloc(bytes); tnl->block[tnl->nr_blocks++] = space; - return (GLfloat *)space; + return space; } @@ -97,7 +97,7 @@ static void _tnl_import_array( GLcontext *ctx, GLuint start, GLuint end, const struct gl_client_array *input, - const char *ptr ) + const GLubyte *ptr ) { TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; @@ -108,7 +108,7 @@ static void _tnl_import_array( GLcontext *ctx, if (input->Type != GL_FLOAT) { const GLuint sz = input->Size; - char *buf = get_space(ctx, count * sz * sizeof(GLfloat)); + GLubyte *buf = get_space(ctx, count * sz * sizeof(GLfloat)); GLfloat *fptr = (GLfloat *)buf; switch (input->Type) { @@ -263,6 +263,8 @@ static void bind_indicies( GLcontext *ctx, { TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; + GLuint i; + void *ptr; if (!ib) return; @@ -278,18 +280,30 @@ static void bind_indicies( GLcontext *ctx, assert(ib->obj->Pointer); } - VB->Elts = (GLuint *)ADD_POINTERS(ib->obj->Pointer, - ib->ptr); - - VB->Elts += ib->rebase; + ptr = ADD_POINTERS(ib->obj->Pointer, ib->ptr); - switch (ib->type) { - case GL_UNSIGNED_INT: - return; - case GL_UNSIGNED_SHORT: - break; - case GL_UNSIGNED_BYTE: - break; + if (ib->type == GL_UNSIGNED_INT) { + VB->Elts = (GLuint *) ptr; + VB->Elts += ib->rebase; + } + else { + GLuint *elts = (GLuint *)get_space(ctx, ib->count * sizeof(GLuint)); + VB->Elts = elts; + + switch (ib->type) { + case GL_UNSIGNED_SHORT: { + const GLushort *in = ((GLushort *)ptr) + ib->rebase; + for (i = 0; i < ib->count; i++) + *elts++ = *in++; + break; + } + case GL_UNSIGNED_BYTE: { + const GLubyte *in = ((GLubyte *)ptr) + ib->rebase; + for (i = 0; i < ib->count; i++) + *elts++ = *in++; + break; + } + } } } -- cgit v1.2.3 From dd60eaa6d9f61735141976db0e83d25176ac73c7 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 20 Nov 2006 11:49:58 +0000 Subject: Don't perform dangling attribute check on POS attribute. It can't by definition dangle (every vertex has a position). However save->currentsz isn't properly maintained for this attribute, as there is no current position value to track. Based on patch from Haihao Xiang. --- src/mesa/vbo/vbo_save_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c index 8ceba2b832..efe018b09e 100644 --- a/src/mesa/vbo/vbo_save_api.c +++ b/src/mesa/vbo/vbo_save_api.c @@ -527,7 +527,7 @@ static void _save_upgrade_vertex( GLcontext *ctx, /* Need to note this and fix up at runtime (or loopback): */ - if (save->currentsz[attr][0] == 0) { + if (attr != VBO_ATTRIB_POS && save->currentsz[attr][0] == 0) { assert(oldsz == 0); save->dangling_attr_ref = GL_TRUE; } -- cgit v1.2.3 From 92fb742065f4de941e444916c5a146db87c71701 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Thu, 21 Dec 2006 17:30:00 +0100 Subject: intel_finalize_mipmap_tree: Only flush batchbuffer when necessary. --- src/mesa/drivers/dri/i915tex/intel_tex_validate.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_validate.c b/src/mesa/drivers/dri/i915tex/intel_tex_validate.c index e73c9c2f21..79d587a174 100644 --- a/src/mesa/drivers/dri/i915tex/intel_tex_validate.c +++ b/src/mesa/drivers/dri/i915tex/intel_tex_validate.c @@ -110,6 +110,8 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) GLuint nr_faces = 0; struct intel_texture_image *firstImage; + GLboolean need_flush = GL_FALSE; + /* We know/require this is true by now: */ assert(intelObj->base.Complete); @@ -201,11 +203,13 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) */ if (intelObj->mt != intelImage->mt) { copy_image_data_to_tree(intel, intelObj, intelImage); + need_flush = GL_TRUE; } } } - intel_batchbuffer_flush(intel->batch); + if (need_flush) + intel_batchbuffer_flush(intel->batch); return GL_TRUE; } -- cgit v1.2.3 From dfabf9660751f0d7cfc7cad6539af4d7ccd9147e Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Thu, 21 Dec 2006 18:06:58 +0100 Subject: i915tex: Remove unused tex_program field. --- src/mesa/drivers/dri/i915tex/i915_context.h | 1 - src/mesa/drivers/dri/i915tex/i915_state.c | 1 - src/mesa/drivers/dri/i915tex/i915_tex.c | 35 ----------------------------- 3 files changed, 37 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/i915_context.h b/src/mesa/drivers/dri/i915tex/i915_context.h index 5ae76fcd18..d2713e88f9 100644 --- a/src/mesa/drivers/dri/i915tex/i915_context.h +++ b/src/mesa/drivers/dri/i915tex/i915_context.h @@ -243,7 +243,6 @@ struct i915_context GLuint lodbias_ss2[MAX_TEXTURE_UNITS]; - struct i915_fragment_program tex_program; struct i915_fragment_program *current_program; struct i915_hw_state meta, initial, state, *current; diff --git a/src/mesa/drivers/dri/i915tex/i915_state.c b/src/mesa/drivers/dri/i915tex/i915_state.c index 2f5a30787e..7c742a7bd9 100644 --- a/src/mesa/drivers/dri/i915tex/i915_state.c +++ b/src/mesa/drivers/dri/i915tex/i915_state.c @@ -520,7 +520,6 @@ update_specular(GLcontext * ctx) /* A hack to trigger the rebuild of the fragment program. */ intel_context(ctx)->NewGLState |= _NEW_TEXTURE; - I915_CONTEXT(ctx)->tex_program.translated = 0; } static void diff --git a/src/mesa/drivers/dri/i915tex/i915_tex.c b/src/mesa/drivers/dri/i915tex/i915_tex.c index a53abe9a92..59e148ca04 100644 --- a/src/mesa/drivers/dri/i915tex/i915_tex.c +++ b/src/mesa/drivers/dri/i915tex/i915_tex.c @@ -52,27 +52,6 @@ i915TexEnv(GLcontext * ctx, GLenum target, struct i915_context *i915 = I915_CONTEXT(ctx); switch (pname) { - case GL_TEXTURE_ENV_COLOR: /* Should be a tracked param */ - case GL_TEXTURE_ENV_MODE: - case GL_COMBINE_RGB: - case GL_COMBINE_ALPHA: - case GL_SOURCE0_RGB: - case GL_SOURCE1_RGB: - case GL_SOURCE2_RGB: - case GL_SOURCE0_ALPHA: - case GL_SOURCE1_ALPHA: - case GL_SOURCE2_ALPHA: - case GL_OPERAND0_RGB: - case GL_OPERAND1_RGB: - case GL_OPERAND2_RGB: - case GL_OPERAND0_ALPHA: - case GL_OPERAND1_ALPHA: - case GL_OPERAND2_ALPHA: - case GL_RGB_SCALE: - case GL_ALPHA_SCALE: - i915->tex_program.translated = 0; - break; - case GL_TEXTURE_LOD_BIAS:{ GLuint unit = ctx->Texture.CurrentUnit; GLint b = (int) ((*param) * 16.0); @@ -92,22 +71,8 @@ i915TexEnv(GLcontext * ctx, GLenum target, } -static void -i915BindTexture(GLcontext * ctx, GLenum target, - struct gl_texture_object *texobj) -{ - /* Need this if image format changes between bound textures. - * Could try and shortcircuit by checking for differences in - * state between incoming and outgoing textures: - */ - I915_CONTEXT(ctx)->tex_program.translated = 0; -} - - - void i915InitTextureFuncs(struct dd_function_table *functions) { - functions->BindTexture = i915BindTexture; functions->TexEnv = i915TexEnv; } -- cgit v1.2.3 From 96c5db5f7ae2cb9d98f534285c34217ce9c2abf3 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Tue, 9 Jan 2007 14:42:22 +0100 Subject: put back missing Driver.PolygonMode call (bug 9578) --- src/mesa/main/polygon.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/mesa/main/polygon.c b/src/mesa/main/polygon.c index 814f7ec5fa..fd02e5a652 100644 --- a/src/mesa/main/polygon.c +++ b/src/mesa/main/polygon.c @@ -166,6 +166,9 @@ _mesa_PolygonMode( GLenum face, GLenum mode ) _mesa_error( ctx, GL_INVALID_ENUM, "glPolygonMode(face)" ); return; } + + if (ctx->Driver.PolygonMode) + ctx->Driver.PolygonMode(ctx, face, mode); } #if _HAVE_FULL_GL -- cgit v1.2.3 From 3dd243c59eb48bcf330a5d667d93b93c1226eae2 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 9 Jan 2007 16:39:10 -0800 Subject: Track rename of DamagePost -> DamageAdd. --- src/glx/x11/glxext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/glx/x11/glxext.c b/src/glx/x11/glxext.c index 29b3a1c01c..7f3857360d 100644 --- a/src/glx/x11/glxext.c +++ b/src/glx/x11/glxext.c @@ -758,7 +758,7 @@ static void __glXReportDamage(__DRInativeDisplay *dpy, int screen, xrects[i].height = rects[i].y2 - rects[i].y1; } region = XFixesCreateRegion(dpy, xrects, num_rects); - XDamagePost(dpy, drawable, region); + XDamageAdd(dpy, drawable, region); XFixesDestroyRegion(dpy, region); #endif } -- cgit v1.2.3 From b55f1ec9af30ddc5fa44818f85518fffe4580dc6 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Thu, 11 Jan 2007 12:53:06 +0100 Subject: Fix typo from commit 1d312ae0137eb39bf74fac91eb97ed25c289a4ca . --- src/mesa/drivers/dri/r300/r300_fragprog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c index 179bc58e9e..6e85f0b5dd 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog.c @@ -463,7 +463,7 @@ static int swz_native(struct r300_fragment_program *rp, GLuint arbneg) { /* Native swizzle, handle negation */ - src = (src & ~REG_NEGS_SHIFT) | + src = (src & ~REG_NEGS_MASK) | (((arbneg >> 3) & 1) << REG_NEGS_SHIFT); if ((arbneg & 0x7) == 0x0) { -- cgit v1.2.3 From ca75853f9d9e7d131f25daeaa7c646894ab4807e Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 13 Jan 2007 13:22:03 +0100 Subject: nv10 has alpha color mask --- src/mesa/drivers/dri/nouveau/nv10_state.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index c028be2867..162a5e2718 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -106,13 +106,12 @@ static void nv10ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) OUT_RING_CACHEf(equation[3]); } -/* Seems does not support alpha in color mask */ static void nv10ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, GLboolean bmask, GLboolean amask ) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_COLOR_MASK, 1); - OUT_RING_CACHE(/*((amask && 0x01) << 24) |*/ ((rmask && 0x01) << 16) | ((gmask && 0x01)<< 8) | ((bmask && 0x01) << 0)); + OUT_RING_CACHE(((amask && 0x01) << 24) | ((rmask && 0x01) << 16) | ((gmask && 0x01)<< 8) | ((bmask && 0x01) << 0)); } static void nv10ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode) -- cgit v1.2.3 From 308ef2dc3208e9c274763726b541f28e2169324b Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 13 Jan 2007 13:56:18 +0100 Subject: nouveau: Add clear color for nv10 --- src/mesa/drivers/dri/nouveau/nouveau_context.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 134e2a417e..c7bf387210 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -119,7 +119,10 @@ typedef struct nouveau_context { struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; GLuint vertex_attr_count; - /* Depth/stencil clear state */ + /* Color buffer clear value */ + uint32_t clear_color_value; + + /* Depth/stencil clear value */ uint32_t clear_value; /* Light state */ -- cgit v1.2.3 From fb5f359b93073d85f4cae05cd89ff1012fafeda6 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 13 Jan 2007 14:14:19 +0100 Subject: nouveau: update nv10 state --- src/mesa/drivers/dri/nouveau/nv10_state.c | 116 +++++++++++++++--------------- 1 file changed, 56 insertions(+), 60 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 162a5e2718..d65eb94e42 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -61,40 +61,42 @@ static void nv10BlendColor(GLcontext *ctx, const GLfloat color[4]) static void nv10BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_EQUATION, 1); - OUT_RING_CACHE((modeA<<16) | modeRGB); + /* Not for NV10 */ } static void nv10BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2); - OUT_RING_CACHE((sfactorA<<16) | sfactorRGB); - OUT_RING_CACHE((dfactorA<<16) | dfactorRGB); + /* Not for NV10 */ +} + +static void nv10Clear(GLcontext *ctx, GLbitfield mask) +{ + /* TODO */ } -/* static void nv10ClearColor(GLcontext *ctx, const GLfloat color[4]) { + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte c[4]; + UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,color); + nmesa->clear_color_value = PACK_COLOR_8888(c[3],c[0],c[1],c[2]); } static void nv10ClearDepth(GLcontext *ctx, GLclampd d) { + /* FIXME: check if 16 or 24/32 bits depth buffer */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nmesa->clear_value=((nmesa->clear_value&0x000000FF)|(((uint32_t)(d*0xFFFFFF))<<8)); } -*/ -/* we're don't support indexed buffers - void (*ClearIndex)(GLcontext *ctx, GLuint index) - */ - -/* static void nv10ClearStencil(GLcontext *ctx, GLint s) { + /* FIXME: not valid for 16 bits depth buffer (0 stencil bits) */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nmesa->clear_value=((nmesa->clear_value&0xFFFFFF00)|(s&0x000000FF)); } -*/ static void nv10ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) { @@ -116,7 +118,7 @@ static void nv10ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, static void nv10ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode) { - // TODO I need love + /* TODO I need love */ } static void nv10CullFace(GLcontext *ctx, GLenum mode) @@ -320,7 +322,7 @@ static void nv10Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) static void nv10Hint(GLcontext *ctx, GLenum target, GLenum mode) { - // TODO I need love (fog and line_smooth hints) + /* TODO I need love (fog and line_smooth hints) */ } // void (*IndexMask)(GLcontext *ctx, GLuint mask); @@ -448,6 +450,7 @@ static void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params) static void nv10LineStipple(GLcontext *ctx, GLint factor, GLushort pattern ) { + /* Not for NV10 */ } static void nv10LineWidth(GLcontext *ctx, GLfloat width) @@ -471,7 +474,6 @@ static void nv10PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *pa } -/** Specify the diameter of rasterized points */ static void nv10PointSize(GLcontext *ctx, GLfloat size) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); @@ -479,7 +481,6 @@ static void nv10PointSize(GLcontext *ctx, GLfloat size) OUT_RING_CACHE(((int) (size * 8.0)) & -4); } -/** Select a polygon rasterization mode */ static void nv10PolygonMode(GLcontext *ctx, GLenum face, GLenum mode) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); @@ -495,9 +496,20 @@ static void nv10PolygonMode(GLcontext *ctx, GLenum face, GLenum mode) } /** Set the scale and units used to calculate depth values */ -void (*PolygonOffset)(GLcontext *ctx, GLfloat factor, GLfloat units); +static void nv10PolygonOffset(GLcontext *ctx, GLfloat factor, GLfloat units) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR, 2); + OUT_RING_CACHEf(factor); + OUT_RING_CACHEf(units); +} + /** Set the polygon stippling pattern */ -void (*PolygonStipple)(GLcontext *ctx, const GLubyte *mask ); +static void nv10PolygonStipple(GLcontext *ctx, const GLubyte *mask ) +{ + /* Not for NV10 */ +} + /* Specifies the current buffer for reading */ void (*ReadBuffer)( GLcontext *ctx, GLenum buffer ); /** Set rasterization mode */ @@ -517,37 +529,21 @@ static void nv10ShadeModel(GLcontext *ctx, GLenum mode) OUT_RING_CACHE(mode); } -/** OpenGL 2.0 two-sided StencilFunc */ static void nv10StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, GLint ref, GLuint mask) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC, 3); - OUT_RING_CACHE(func); - OUT_RING_CACHE(ref); - OUT_RING_CACHE(mask); + /* Not for NV10 */ } -/** OpenGL 2.0 two-sided StencilMask */ static void nv10StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_MASK, 1); - OUT_RING_CACHE(mask); + /* Not for NV10 */ } -/** OpenGL 2.0 two-sided StencilOp */ static void nv10StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, GLenum zfail, GLenum zpass) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_OP_FAIL, 1); - OUT_RING_CACHE(fail); - OUT_RING_CACHE(zfail); - OUT_RING_CACHE(zpass); + /* Not for NV10 */ } /** Control the generation of texture coordinates */ @@ -560,7 +556,14 @@ void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname, void (*TexParameter)(GLcontext *ctx, GLenum target, struct gl_texture_object *texObj, GLenum pname, const GLfloat *params); -void (*TextureMatrix)(GLcontext *ctx, GLuint unit, const GLmatrix *mat); + +static void nv10TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16); + /*XXX: This SHOULD work.*/ + OUT_RING_CACHEp(mat->m, 16); +} /** Set the viewport */ static void nv10Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) @@ -597,13 +600,12 @@ void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) func->AlphaFunc = nv10AlphaFunc; func->BlendColor = nv10BlendColor; - func->BlendEquationSeparate = nv10BlendEquationSeparate; - func->BlendFuncSeparate = nv10BlendFuncSeparate; -#if 0 + func->BlendEquationSeparate = nv10BlendEquationSeparate; /* Not for NV10 */ + func->BlendFuncSeparate = nv10BlendFuncSeparate; /* Not for NV10 */ + func->Clear = nv10Clear; func->ClearColor = nv10ClearColor; func->ClearDepth = nv10ClearDepth; func->ClearStencil = nv10ClearStencil; -#endif func->ClipPlane = nv10ClipPlane; func->ColorMask = nv10ColorMask; func->ColorMaterial = nv10ColorMaterial; @@ -617,32 +619,26 @@ void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) func->Hint = nv10Hint; func->Lightfv = nv10Lightfv; /* func->LightModelfv = nv10LightModelfv; */ - func->LineStipple = nv10LineStipple; + func->LineStipple = nv10LineStipple; /* Not for NV10 */ func->LineWidth = nv10LineWidth; func->LogicOpcode = nv10LogicOpcode; func->PointParameterfv = nv10PointParameterfv; func->PointSize = nv10PointSize; func->PolygonMode = nv10PolygonMode; -#if 0 func->PolygonOffset = nv10PolygonOffset; - func->PolygonStipple = nv10PolygonStipple; - func->ReadBuffer = nv10ReadBuffer; - func->RenderMode = nv10RenderMode; -#endif + func->PolygonStipple = nv10PolygonStipple; /* Not for NV10 */ +/* func->ReadBuffer = nv10ReadBuffer;*/ +/* func->RenderMode = nv10RenderMode;*/ func->Scissor = nv10Scissor; func->ShadeModel = nv10ShadeModel; - func->StencilFuncSeparate = nv10StencilFuncSeparate; - func->StencilMaskSeparate = nv10StencilMaskSeparate; - func->StencilOpSeparate = nv10StencilOpSeparate; -#if 0 - func->TexGen = nv10TexGen; - func->TexParameter = nv10TexParameter; + func->StencilFuncSeparate = nv10StencilFuncSeparate; /* Not for NV10 */ + func->StencilMaskSeparate = nv10StencilMaskSeparate; /* Not for NV10 */ + func->StencilOpSeparate = nv10StencilOpSeparate; /* Not for NV10 */ +/* func->TexGen = nv10TexGen;*/ +/* func->TexParameter = nv10TexParameter;*/ func->TextureMatrix = nv10TextureMatrix; -#endif - func->Viewport = nv10Viewport; nmesa->hw_func.InitCard = nv10InitCard; nmesa->hw_func.BindBuffers = nv10BindBuffers; nmesa->hw_func.WindowMoved = nv10WindowMoved; } - -- cgit v1.2.3 From f1ad10b338996275a376809d98c420cda4d6d05a Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sun, 14 Jan 2007 12:45:15 +0100 Subject: nouveau: nv10 blending done, remove nv10Viewport --- src/mesa/drivers/dri/nouveau/nv10_state.c | 38 +++++++++++++++++++------------ 1 file changed, 24 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index d65eb94e42..518ceb31f1 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -45,6 +45,14 @@ static void nv10AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) OUT_RING_CACHE(ubRef); /* NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF */ } +/* + Supported blend extensions on NV10 + EXT_blend_color + EXT_blend_minmax + EXT_blend_subtract + NV_blend_square +*/ + static void nv10BlendColor(GLcontext *ctx, const GLfloat color[4]) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); @@ -61,14 +69,26 @@ static void nv10BlendColor(GLcontext *ctx, const GLfloat color[4]) static void nv10BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA) { - /* Not for NV10 */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + assert( modeRGB == modeA ); + + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_EQUATION, 1); + OUT_RING_CACHE(modeRGB); } static void nv10BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA) { - /* Not for NV10 */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + assert( sfactorRGB == sfactorA ); + assert( dfactorRGB == dfactorA ); + + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2); + OUT_RING_CACHE(sfactorRGB); + OUT_RING_CACHE(dfactorRGB); /* NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_DST */ } static void nv10Clear(GLcontext *ctx, GLbitfield mask) @@ -565,16 +585,6 @@ static void nv10TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) OUT_RING_CACHEp(mat->m, 16); } -/** Set the viewport */ -static void nv10Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) -{ - /* TODO: Where do the VIEWPORT_XFRM_* regs come in? */ - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2); - OUT_RING_CACHE((w << 16) | x); - OUT_RING_CACHE((h << 16) | y); -} - /* Initialise any card-specific non-GL related state */ static GLboolean nv10InitCard(nouveauContextPtr nmesa) { @@ -600,8 +610,8 @@ void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) func->AlphaFunc = nv10AlphaFunc; func->BlendColor = nv10BlendColor; - func->BlendEquationSeparate = nv10BlendEquationSeparate; /* Not for NV10 */ - func->BlendFuncSeparate = nv10BlendFuncSeparate; /* Not for NV10 */ + func->BlendEquationSeparate = nv10BlendEquationSeparate; + func->BlendFuncSeparate = nv10BlendFuncSeparate; func->Clear = nv10Clear; func->ClearColor = nv10ClearColor; func->ClearDepth = nv10ClearDepth; -- cgit v1.2.3 From 29484f24fb2c21772c6a3ddf33a77ec83d415fdc Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sun, 14 Jan 2007 12:51:30 +0100 Subject: nouveau: nv10: currently fails initcard and bindbuffers, till done --- src/mesa/drivers/dri/nouveau/nv10_state.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 518ceb31f1..17336a7b2a 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -588,7 +588,7 @@ static void nv10TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) /* Initialise any card-specific non-GL related state */ static GLboolean nv10InitCard(nouveauContextPtr nmesa) { - return GL_TRUE; + return GL_FALSE; } /* Update buffer offset/pitch/format */ @@ -596,7 +596,7 @@ static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color, nouveau_renderbuffer **color, nouveau_renderbuffer *depth) { - return GL_TRUE; + return GL_FALSE; } /* Update anything that depends on the window position/size */ -- cgit v1.2.3 From faada2485a864298562b5e59b0703748c6f6f9d5 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sun, 14 Jan 2007 14:03:42 +0100 Subject: nouveau: nv10: stencil functions --- src/mesa/drivers/dri/nouveau/nv10_state.c | 45 +++++++++++++++++++------------ 1 file changed, 28 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 17336a7b2a..a9cce932d8 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -41,18 +41,10 @@ static void nv10AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) CLAMPED_FLOAT_TO_UBYTE(ubRef, ref); BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC, 2); - OUT_RING_CACHE(func); /* NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC */ - OUT_RING_CACHE(ubRef); /* NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF */ + OUT_RING_CACHE(func); + OUT_RING_CACHE(ubRef); } -/* - Supported blend extensions on NV10 - EXT_blend_color - EXT_blend_minmax - EXT_blend_subtract - NV_blend_square -*/ - static void nv10BlendColor(GLcontext *ctx, const GLfloat color[4]) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); @@ -88,7 +80,7 @@ static void nv10BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfac BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2); OUT_RING_CACHE(sfactorRGB); - OUT_RING_CACHE(dfactorRGB); /* NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_DST */ + OUT_RING_CACHE(dfactorRGB); } static void nv10Clear(GLcontext *ctx, GLbitfield mask) @@ -549,21 +541,40 @@ static void nv10ShadeModel(GLcontext *ctx, GLenum mode) OUT_RING_CACHE(mode); } +/** OpenGL 2.0 two-sided StencilFunc */ static void nv10StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, GLint ref, GLuint mask) { - /* Not for NV10 */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + /* NV10 do not have separate FRONT and BACK stencils */ + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC, 3); + OUT_RING_CACHE(func); + OUT_RING_CACHE(ref); + OUT_RING_CACHE(mask); } +/** OpenGL 2.0 two-sided StencilMask */ static void nv10StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask) { - /* Not for NV10 */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + /* NV10 do not have separate FRONT and BACK stencils */ + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_MASK, 1); + OUT_RING_CACHE(mask); } +/** OpenGL 2.0 two-sided StencilOp */ static void nv10StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, GLenum zfail, GLenum zpass) { - /* Not for NV10 */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + /* NV10 do not have separate FRONT and BACK stencils */ + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_OP_FAIL, 3); + OUT_RING_CACHE(fail); + OUT_RING_CACHE(zfail); + OUT_RING_CACHE(zpass); } /** Control the generation of texture coordinates */ @@ -641,9 +652,9 @@ void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) /* func->RenderMode = nv10RenderMode;*/ func->Scissor = nv10Scissor; func->ShadeModel = nv10ShadeModel; - func->StencilFuncSeparate = nv10StencilFuncSeparate; /* Not for NV10 */ - func->StencilMaskSeparate = nv10StencilMaskSeparate; /* Not for NV10 */ - func->StencilOpSeparate = nv10StencilOpSeparate; /* Not for NV10 */ + func->StencilFuncSeparate = nv10StencilFuncSeparate; + func->StencilMaskSeparate = nv10StencilMaskSeparate; + func->StencilOpSeparate = nv10StencilOpSeparate; /* func->TexGen = nv10TexGen;*/ /* func->TexParameter = nv10TexParameter;*/ func->TextureMatrix = nv10TextureMatrix; -- cgit v1.2.3 From 86f10c7144d08bc0603a796a9b8aa53f1a37a7e0 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sun, 14 Jan 2007 14:09:04 +0100 Subject: nouveau: import color material r,g,b,a --- src/mesa/drivers/dri/nouveau/nouveau_reg.h | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_reg.h b/src/mesa/drivers/dri/nouveau/nouveau_reg.h index 200e770903..74f55c649a 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_reg.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_reg.h @@ -383,7 +383,10 @@ Object NV11_TCL_PRIMITIVE_3D used on: NV15 # define NV10_TCL_PRIMITIVE_3D_CULL_FACE 0x0000039c # define NV10_TCL_PRIMITIVE_3D_FRONT_FACE 0x000003a0 # define NV10_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE 0x000003a4 -# define NV10_TCL_PRIMITIVE_3D_MATERIAL_DIFFUSE_ALPHA_FRONT 0x000003b4 +# define NV10_TCL_PRIMITIVE_3D_COLOR_MATERIAL_R 0x000003a8 +# define NV10_TCL_PRIMITIVE_3D_COLOR_MATERIAL_G 0x000003ac +# define NV10_TCL_PRIMITIVE_3D_COLOR_MATERIAL_B 0x000003b0 +# define NV10_TCL_PRIMITIVE_3D_COLOR_MATERIAL_A 0x000003b4 # define NV10_TCL_PRIMITIVE_3D_COLOR_CONTROL 0x000003b8 /* Parameters: color_control */ # define NV10_TCL_PRIMITIVE_3D_ENABLED_LIGHTS 0x000003bc /* Parameters: light 7 light 6 light 5 light 4 light 3 light 2 light 1 light 0 */ # define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE( d) (0x000003c0 + d * 0x0004) @@ -729,8 +732,10 @@ Object NV20_TCL_PRIMITIVE_3D used on: NV20 # define NV20_TCL_PRIMITIVE_3D_CULL_FACE 0x0000039c # define NV20_TCL_PRIMITIVE_3D_FRONT_FACE 0x000003a0 # define NV20_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE 0x000003a4 -# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT 0x000003a8 -# define NV20_TCL_PRIMITIVE_3D_MATERIAL_DIFFUSE_ALPHA_FRONT 0x000003b4 +# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT_R 0x000003a8 +# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT_G 0x000003ac +# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT_B 0x000003b0 +# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT_A 0x000003b4 # define NV20_TCL_PRIMITIVE_3D_SEPARATE_SPECULAR_ENABLE 0x000003b8 # define NV20_TCL_PRIMITIVE_3D_ENABLED_LIGHTS 0x000003bc /* Parameters: light 7 light 6 light 5 light 4 light 3 light 2 light 1 light 0 */ # define NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(d) (0x000003c0 + d * 0x0004) @@ -930,8 +935,10 @@ Object NV20_TCL_PRIMITIVE_3D used on: NV20 # define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R 0x000017a0 # define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_G 0x000017a4 # define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_B 0x000017a8 -# define NV20_TCL_PRIMITIVE_3D_MATERIAL_DIFFUSE_ALPHA_BACK 0x000017ac -# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK 0x000017b0 +# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_A 0x000017ac +# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_R 0x000017b0 +# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_G 0x000017b4 +# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_B 0x000017b8 # define NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE 0x000017bc # define NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP 0x000017c0 # define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_TWO_SIDE_ENABLE 0x000017c4 @@ -1004,7 +1011,10 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE 0x0000037c # define NV30_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR 0x00000394 # define NV30_TCL_PRIMITIVE_3D_DEPTH_RANGE_FAR 0x00000398 -# define NV30_TCL_PRIMITIVE_3D_MATERIAL_DIFFUSE_ALPHA_FRONT 0x000003b4 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT_R 0x000003a0 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT_G 0x000003a4 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT_B 0x000003a8 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT_A 0x000003b4 # define NV30_TCL_PRIMITIVE_3D_LINE_WIDTH_SMOOTH 0x000003b8 # define NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(d) (0x00000400 + d * 0x0004) # define NV30_TCL_PRIMITIVE_3D_MODELVIEW_MATRIX( d) (0x00000480 + d * 0x0004) @@ -1196,7 +1206,10 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R 0x000017a0 # define NV30_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_G 0x000017a4 # define NV30_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_B 0x000017a8 -# define NV30_TCL_PRIMITIVE_3D_MATERIAL_DIFFUSE_ALPHA_BACK 0x000017c0 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_R 0x000017b0 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_G 0x000017b4 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_B 0x000017b8 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_A 0x000017c0 # define NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM 0x000008e4 # define NV30_TCL_PRIMITIVE_3D_TX_ADDRESS_UNIT(d) (0x00001a00 + d * 0x0020) # define NV30_TCL_PRIMITIVE_3D_TX_FORMAT_UNIT(d) (0x00001a04 + d * 0x0020) /* Parameters: mipmap type format ncomp cubic */ -- cgit v1.2.3 From e7112be7321c58e6039fde28f47ffe3dce5cc205 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sun, 14 Jan 2007 14:11:10 +0100 Subject: nouveau: remove already defined NV15_TCL and NV17_TCL --- src/mesa/drivers/dri/nouveau/nouveau_card.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_card.c b/src/mesa/drivers/dri/nouveau/nouveau_card.c index a0628389bf..ae4f4c7ae5 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_card.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_card.c @@ -2,9 +2,6 @@ #include "nouveau_card.h" #include "nouveau_reg.h" #include "nouveau_drm.h" -// FIXME hack for now -#define NV15_TCL_PRIMITIVE_3D 0x0096 -#define NV17_TCL_PRIMITIVE_3D 0x0099 #include "nouveau_card_list.h" -- cgit v1.2.3 From 6dd967e74ff4cb03220d5785bd583203464d299d Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Sun, 14 Jan 2007 14:49:36 +0100 Subject: mesa: Update _Current ptr along Current when a new vertex program is bind. On new vertex program bind only the Current ptr where updated to point to the new program; this could lead to _Current pointing to and out of date or even a no more existing program which in turn could lead to a segfault in some driver. To avoid this _Current ptr is updated along Current if _Current where previously pointing to the same program. --- src/mesa/shader/program.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index ddfad47b89..6db62f591c 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -1947,6 +1947,8 @@ _mesa_BindProgram(GLenum target, GLuint id) /* bind newProg */ if (target == GL_VERTEX_PROGRAM_ARB) { /* == GL_VERTEX_PROGRAM_NV */ + if (ctx->VertexProgram._Current == ctx->VertexProgram.Current) + ctx->VertexProgram._Current = (struct gl_vertex_program *) newProg; ctx->VertexProgram.Current = (struct gl_vertex_program *) newProg; } else if (target == GL_FRAGMENT_PROGRAM_NV || @@ -1969,7 +1971,7 @@ _mesa_BindProgram(GLenum target, GLuint id) * \note Not compiled into display lists. * \note Called by both glDeleteProgramsNV and glDeleteProgramsARB. */ -void GLAPIENTRY +void GLAPIENTRY _mesa_DeletePrograms(GLsizei n, const GLuint *ids) { GLint i; -- cgit v1.2.3 From 9a4e49aef2abb277544138640c2b71169badaa42 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Sun, 14 Jan 2007 19:31:30 +0100 Subject: r300: Fix vertex program position invariant bug, force position reading. When we have a position invariant program we need to force routing the position otherwise you may handle transform quite random data which might be funny but unlikely what you want :). --- src/mesa/drivers/dri/r300/r300_vertexprog.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/r300/r300_vertexprog.c b/src/mesa/drivers/dri/r300/r300_vertexprog.c index 2492a4a3a0..c08c98767e 100644 --- a/src/mesa/drivers/dri/r300/r300_vertexprog.c +++ b/src/mesa/drivers/dri/r300/r300_vertexprog.c @@ -1072,6 +1072,8 @@ static void insert_wpos(struct r300_vertex_program *vp, vpi = &prog->Instructions[prog->NumInstructions-1]; assert(vpi->Opcode == OPCODE_END); + /* we need position, don't we ? :) */ + prog->InputsRead |= (1 << VERT_ATTRIB_POS); } static void pos_as_texcoord(struct r300_vertex_program *vp, @@ -1101,8 +1103,9 @@ static struct r300_vertex_program *build_program(struct r300_vertex_program_key vp->wpos_idx = wpos_idx; - if(mesa_vp->IsPositionInvariant) + if(mesa_vp->IsPositionInvariant) { position_invariant(&mesa_vp->Base); + } if(wpos_idx > -1) pos_as_texcoord(vp, &mesa_vp->Base); @@ -1158,6 +1161,10 @@ void r300_select_vertex_shader(r300ContextPtr r300) wanted_key.OutputsWritten |= 1 << (VERT_RESULT_TEX0 + i); wanted_key.InputsRead = vpc->mesa_program.Base.InputsRead; + if(vpc->mesa_program.IsPositionInvariant) { + /* we wan't position don't we ? */ + wanted_key.InputsRead |= (1 << VERT_ATTRIB_POS); + } for (vp = vpc->progs; vp; vp = vp->next) if (_mesa_memcmp(&vp->key, &wanted_key, sizeof(wanted_key)) == 0) { @@ -1170,6 +1177,5 @@ void r300_select_vertex_shader(r300ContextPtr r300) vp = build_program(&wanted_key, &vpc->mesa_program, wpos_idx); vp->next = vpc->progs; vpc->progs = vp; - r300->selected_vp = vp; } -- cgit v1.2.3 From 8aabd636f5dd303774a07f8705068d812f7feef8 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sun, 14 Jan 2007 19:55:45 +0100 Subject: nouveau: nv10: added missing functions --- src/mesa/drivers/dri/nouveau/nv10_state.c | 91 +++++++++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index a9cce932d8..8785879d9d 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -596,10 +596,67 @@ static void nv10TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) OUT_RING_CACHEp(mat->m, 16); } +/* Update anything that depends on the window position/size */ +static void nv10WindowMoved(nouveauContextPtr nmesa) +{ + GLcontext *ctx = nmesa->glCtx; + GLfloat *v = nmesa->viewport.m; + GLuint w = ctx->Viewport.Width; + GLuint h = ctx->Viewport.Height; + GLuint x = ctx->Viewport.X + nmesa->drawX; + GLuint y = ctx->Viewport.Y + nmesa->drawY; + int i; + + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2); + OUT_RING_CACHE((w << 16) | x); + OUT_RING_CACHE((h << 16) | y); + + /* something to do with clears, possibly doesn't belong here */ + BEGIN_RING_CACHE(NvSub3D, + NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 2); + OUT_RING_CACHE(((w+x) << 16) | x | 0x800); + OUT_RING_CACHE(((h+y) << 16) | y | 0x800); + for (i=1; i<7; i++) { + BEGIN_RING_CACHE(NvSub3D, + NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 2); + OUT_RING_CACHE(0); + OUT_RING_CACHE(0); + } + + /* viewport transform */ + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X, 4); + OUT_RING_CACHEf ((GLfloat) x); + OUT_RING_CACHEf ((GLfloat) (y+h)); + OUT_RING_CACHEf (0.0); + OUT_RING_CACHEf (0.0); + + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X, 4); + OUT_RING_CACHEf ((((GLfloat) w) * 0.5) - 2048.0); + OUT_RING_CACHEf ((((GLfloat) h) * 0.5) - 2048.0); + OUT_RING_CACHEf (16777215.0 * 0.5); + OUT_RING_CACHEf (0.0); +} + /* Initialise any card-specific non-GL related state */ static GLboolean nv10InitCard(nouveauContextPtr nmesa) { - return GL_FALSE; + nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); + + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY0, 2); + OUT_RING(NvDmaFB); /* 184 dma_in_memory0 */ + OUT_RING(NvDmaFB); /* 188 dma_in_memory1 */ + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY2, 2); + OUT_RING(NvDmaFB); /* 194 dma_in_memory2 */ + OUT_RING(NvDmaFB); /* 198 dma_in_memory3 */ + + BEGIN_RING_SIZE(NvSub3D, 0x02b4, 1); + OUT_RING(0); + BEGIN_RING_SIZE(NvSub3D, 0x0290, 1); + OUT_RING(0x00100001); + BEGIN_RING_SIZE(NvSub3D, 0x03f4, 1); + OUT_RING(0); + + return GL_FALSE; } /* Update buffer offset/pitch/format */ @@ -607,12 +664,34 @@ static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color, nouveau_renderbuffer **color, nouveau_renderbuffer *depth) { - return GL_FALSE; -} + GLuint x, y, w, h; + GLuint pitch, format; -/* Update anything that depends on the window position/size */ -static void nv10WindowMoved(nouveauContextPtr nmesa) -{ + w = color[0]->mesa.Width; + h = color[0]->mesa.Height; + x = nmesa->drawX; + y = nmesa->drawY; + + if (num_color != 1) + return GL_FALSE; + + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 6); + OUT_RING_CACHE((w << 16) | x); + OUT_RING_CACHE((h << 16) | y); + pitch = color[0]->pitch; + if (depth) { + pitch |= (depth->pitch << 16); + } + format = 0x108; + if (color[0]->mesa._ActualFormat != GL_RGBA8) { + /* FIXME: set 16 bits format */ + } + OUT_RING(format); + OUT_RING(pitch); + OUT_RING(color[0]->offset); + OUT_RING(depth ? depth->offset : color[0]->offset); + + return GL_TRUE; } void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) -- cgit v1.2.3 From 81bd826de8897f3784ad301023bde6e7eb77b5b2 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sun, 14 Jan 2007 20:14:58 +0100 Subject: nouveau: nv10: 16 bits color buffer format --- src/mesa/drivers/dri/nouveau/nv10_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 8785879d9d..dbd8bf306e 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -684,7 +684,7 @@ static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color, } format = 0x108; if (color[0]->mesa._ActualFormat != GL_RGBA8) { - /* FIXME: set 16 bits format */ + format = 0x103; /* R5G6B5 color buffer */ } OUT_RING(format); OUT_RING(pitch); -- cgit v1.2.3 From d57ce408b34b604f9b85114eedc88b5463df4218 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sat, 13 Jan 2007 23:56:55 +0100 Subject: nouveau: Cleanup the nv10 swtcl module. --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 58 ------------------------------- 1 file changed, 58 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 37d9f001d1..12b277de45 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -56,9 +56,6 @@ static void nv10ResetLineStipple( GLcontext *ctx ); -/* the size above which we fire the ring. this is a performance-tunable */ -#define NOUVEAU_FIRE_SIZE (2048/4) - static inline void nv10StartPrimitive(struct nouveau_context* nmesa,uint32_t primitive,uint32_t size) { if (nmesa->screen->card->type==NV_10) @@ -99,52 +96,6 @@ static inline void nv10ExtendPrimitive(struct nouveau_context* nmesa, int size) } } -static inline void nv10_draw_quad(nouveauContextPtr nmesa, - nouveauVertexPtr v0, - nouveauVertexPtr v1, - nouveauVertexPtr v2, - nouveauVertexPtr v3) -{ - GLuint vertsize = nmesa->vertex_size; - nv10ExtendPrimitive(nmesa, 4 * 4 * vertsize); - - OUT_RINGp(v0,vertsize); - OUT_RINGp(v1,vertsize); - OUT_RINGp(v2,vertsize); - OUT_RINGp(v3,vertsize); -} - -static inline void nv10_draw_triangle(nouveauContextPtr nmesa, - nouveauVertexPtr v0, - nouveauVertexPtr v1, - nouveauVertexPtr v2) -{ - GLuint vertsize = nmesa->vertex_size; - nv10ExtendPrimitive(nmesa, 3 * 4 * vertsize); - - OUT_RINGp(v0,vertsize); - OUT_RINGp(v1,vertsize); - OUT_RINGp(v2,vertsize); -} - -static inline void nv10_draw_line(nouveauContextPtr nmesa, - nouveauVertexPtr v0, - nouveauVertexPtr v1) -{ - GLuint vertsize = nmesa->vertex_size; - nv10ExtendPrimitive(nmesa, 2 * 4 * vertsize); - OUT_RINGp(v0,vertsize); - OUT_RINGp(v1,vertsize); -} - -static inline void nv10_draw_point(nouveauContextPtr nmesa, - nouveauVertexPtr v0) -{ - GLuint vertsize = nmesa->vertex_size; - nv10ExtendPrimitive(nmesa, 1 * 4 * vertsize); - OUT_RINGp(v0,vertsize); -} - /**********************************************************************/ /* Render unclipped begin/end objects */ /**********************************************************************/ @@ -343,10 +294,6 @@ static void nv10ChooseRenderState(GLcontext *ctx) TNLcontext *tnl = TNL_CONTEXT(ctx); struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - nmesa->draw_point = nv10_draw_point; - nmesa->draw_line = nv10_draw_line; - nmesa->draw_tri = nv10_draw_triangle; - tnl->Driver.Render.PrimTabVerts = nv10_render_tab_verts; tnl->Driver.Render.PrimTabElts = nv10_render_tab_elts; tnl->Driver.Render.ClippedLine = NULL; @@ -538,11 +485,6 @@ static void nv10RenderStart(GLcontext *ctx) nmesa->new_render_state |= nmesa->new_state; } - if (nmesa->Fallback) { - tnl->Driver.Render.Start(ctx); - return; - } - if (nmesa->new_render_state) { nv10ChooseVertexState(ctx); nv10ChooseRenderState(ctx); -- cgit v1.2.3 From 8d7e5651fba9fd62e1055c05d1814c7d2de7f43c Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sun, 14 Jan 2007 20:37:57 +0100 Subject: nouveau: add the nv04 swtcl module (it's untested for now). --- src/mesa/drivers/dri/nouveau/Makefile | 1 + src/mesa/drivers/dri/nouveau/nouveau_swtcl.c | 4 +- src/mesa/drivers/dri/nouveau/nv04_swtcl.c | 570 +++++++++++++++++++++++++++ src/mesa/drivers/dri/nouveau/nv04_swtcl.h | 12 + 4 files changed, 585 insertions(+), 2 deletions(-) create mode 100644 src/mesa/drivers/dri/nouveau/nv04_swtcl.c create mode 100644 src/mesa/drivers/dri/nouveau/nv04_swtcl.h (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile index d31b42a568..9eb40fb9c1 100644 --- a/src/mesa/drivers/dri/nouveau/Makefile +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -26,6 +26,7 @@ DRIVER_SOURCES = \ nouveau_tex.c \ nouveau_swtcl.c \ nouveau_sync.c \ + nv04_swtcl.c \ nv10_swtcl.c \ nv10_state.c \ nv20_state.c \ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c b/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c index 746b0fac8c..f5c92a1b4e 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c @@ -82,7 +82,7 @@ void nouveauFallback(struct nouveau_context *nmesa, GLuint bit, GLboolean mode) nmesa->Fallback |= bit; if (oldfallback == 0) { if (nmesa->screen->card->typescreen->card->type +#include + +#include "glheader.h" +#include "context.h" +#include "mtypes.h" +#include "macros.h" +#include "colormac.h" +#include "enums.h" + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" + +#include "nouveau_swtcl.h" +#include "nv04_swtcl.h" +#include "nouveau_context.h" +#include "nouveau_span.h" +#include "nouveau_reg.h" +#include "nouveau_tex.h" +#include "nouveau_fifo.h" +#include "nouveau_msg.h" +#include "nouveau_object.h" + +static void nv04RasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim ); +static void nv04RenderPrimitive( GLcontext *ctx, GLenum prim ); +static void nv04ResetLineStipple( GLcontext *ctx ); + + +static inline void nv04_2triangles(struct nouveau_context *nmesa,nouveauVertex* v0,nouveauVertex* v1,nouveauVertex* v2,nouveauVertex* v3,nouveauVertex* v4,nouveauVertex* v5) +{ + BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0xA),49); + OUT_RINGp(v0,8); + OUT_RINGp(v1,8); + OUT_RINGp(v2,8); + OUT_RINGp(v3,8); + OUT_RINGp(v4,8); + OUT_RINGp(v5,8); + OUT_RING(0xFEDCBA); +} + +static inline void nv04_1triangle(struct nouveau_context *nmesa,nouveauVertex* v0,nouveauVertex* v1,nouveauVertex* v2) +{ + BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0xD),25); + OUT_RINGp(v0,8); + OUT_RINGp(v1,8); + OUT_RINGp(v2,8); + OUT_RING(0xFED); +} + +static inline void nv04_1quad(struct nouveau_context *nmesa,nouveauVertex* v0,nouveauVertex* v1,nouveauVertex* v2,nouveauVertex* v3) +{ + BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0xC),33); + OUT_RINGp(v0,8); + OUT_RINGp(v1,8); + OUT_RINGp(v2,8); + OUT_RINGp(v3,8); + OUT_RING(0xFECEDC); +} + +/**********************************************************************/ +/* Render unclipped begin/end objects */ +/**********************************************************************/ + +static void nv04_render_points_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + // erm +} + +static void nv04_render_lines_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + // umm +} + +static void nv04_render_line_strip_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + // yeah +} + +static void nv04_render_line_loop_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + // right +} + +static void nv04_render_triangles_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + int i; + + for(i=start;iverts; + GLuint vertsize = nmesa->vertex_size; + uint32_t striptbl[]={0x321210,0x543432,0x765654,0x987876,0xBA9A98,0xDCBCBA,0xFEDEDC}; + int i,j; + + for(i=start;iverts; + GLuint vertsize = nmesa->vertex_size; + uint32_t fantbl[]={0x320210,0x540430,0x760650,0x980870,0xBA0A90,0xDC0CB0,0xFE0ED0}; + int i,j; + + BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0),8); + OUT_RINGp((nouveauVertex*)(vertptr+start*vertsize),8); + + for(i=start+1;iverts; + GLuint vertsize = nmesa->vertex_size; + int i; + + for(i=start;iverts; + GLuint vertsize = nmesa->vertex_size; + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; + int i; + + for(i=start;iverts; + GLuint vertsize = nmesa->vertex_size; + uint32_t striptbl[]={0x321210,0x543432,0x765654,0x987876,0xBA9A98,0xDCBCBA,0xFEDEDC}; + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; + int i,j; + + for(i=start;iverts; + GLuint vertsize = nmesa->vertex_size; + uint32_t fantbl[]={0x320210,0x540430,0x760650,0x980870,0xBA0A90,0xDC0CB0,0xFE0ED0}; + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; + int i,j; + + BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0),8); + OUT_RINGp((nouveauVertex*)(vertptr+elt[start]*vertsize),8); + + for(i=start+1;iverts; + GLuint vertsize = nmesa->vertex_size; + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; + int i; + + for(i=start;ivertex_attrs[nmesa->vertex_attr_count].attrib = (ATTR); \ + nmesa->vertex_attrs[nmesa->vertex_attr_count].format = (STYLE); \ + nmesa->vertex_attr_count++; \ +} while (0) + +#define EMIT_PAD( N ) \ +do { \ + nmesa->vertex_attrs[nmesa->vertex_attr_count].attrib = 0; \ + nmesa->vertex_attrs[nmesa->vertex_attr_count].format = EMIT_PAD; \ + nmesa->vertex_attrs[nmesa->vertex_attr_count].offset = (N); \ + nmesa->vertex_attr_count++; \ +} while (0) + + +static void nv04ChooseRenderState(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + tnl->Driver.Render.PrimTabVerts = nv04_render_tab_verts; + tnl->Driver.Render.PrimTabElts = nv04_render_tab_elts; + tnl->Driver.Render.ClippedLine = NULL; + tnl->Driver.Render.ClippedPolygon = NULL; +} + + + +static inline void nv04OutputVertexFormat(struct nouveau_context* nmesa) +{ + GLcontext* ctx=nmesa->glCtx; + DECLARE_RENDERINPUTS(index); + + /* + * Tell t_vertex about the vertex format + */ + RENDERINPUTS_COPY(index, nmesa->render_inputs_bitset); + + // SX SY SZ INVW + // FIXME : we use W instead of INVW, but since W=1 it doesn't matter + if (RENDERINPUTS_TEST(index, _TNL_ATTRIB_POS)) + EMIT_ATTR(_TNL_ATTRIB_POS,EMIT_4F_VIEWPORT); + else + EMIT_PAD(4*sizeof(float)); + + // COLOR + if (RENDERINPUTS_TEST(index, _TNL_ATTRIB_COLOR0)) + EMIT_ATTR(_TNL_ATTRIB_COLOR0,EMIT_4UB_4F_ABGR); + else + EMIT_PAD(4); + + // SPECULAR + if (RENDERINPUTS_TEST(index, _TNL_ATTRIB_COLOR1)) + EMIT_ATTR(_TNL_ATTRIB_COLOR1,EMIT_4UB_4F_ABGR); + else + EMIT_PAD(4); + + // TEXTURE + if (RENDERINPUTS_TEST(index, _TNL_ATTRIB_TEX0)) + EMIT_ATTR(_TNL_ATTRIB_TEX0,EMIT_2F); + else + EMIT_PAD(2*sizeof(float)); + + nmesa->vertex_size=_tnl_install_attrs( ctx, + nmesa->vertex_attrs, + nmesa->vertex_attr_count, + ctx->Viewport._WindowMap.m, 0 ); +} + + +static void nv04ChooseVertexState( GLcontext *ctx ) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + DECLARE_RENDERINPUTS(index); + + RENDERINPUTS_COPY(index, tnl->render_inputs_bitset); + if (!RENDERINPUTS_EQUAL(index, nmesa->render_inputs_bitset)) + { + RENDERINPUTS_COPY(nmesa->render_inputs_bitset, index); + nv04OutputVertexFormat(nmesa); + } +} + + +/**********************************************************************/ +/* High level hooks for t_vb_render.c */ +/**********************************************************************/ + + +static void nv04RenderStart(GLcontext *ctx) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + + if (nmesa->new_state) { + nmesa->new_render_state |= nmesa->new_state; + } + + if (nmesa->new_render_state) { + nv04ChooseVertexState(ctx); + nv04ChooseRenderState(ctx); + nmesa->new_render_state = 0; + } +} + +static void nv04RenderFinish(GLcontext *ctx) +{ +} + + +/* System to flush dma and emit state changes based on the rasterized + * primitive. + */ +void nv04RasterPrimitive(GLcontext *ctx, + GLenum glprim, + GLuint hwprim) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + + assert (!nmesa->new_state); + + if (hwprim != nmesa->current_primitive) + { + nmesa->current_primitive=hwprim; + + } +} + +static const GLuint hw_prim[GL_POLYGON+1] = { + GL_POINTS+1, + GL_LINES+1, + GL_LINE_STRIP+1, + GL_LINE_LOOP+1, + GL_TRIANGLES+1, + GL_TRIANGLE_STRIP+1, + GL_TRIANGLE_FAN+1, + GL_QUADS+1, + GL_QUAD_STRIP+1, + GL_POLYGON+1 +}; + +/* Callback for mesa: + */ +static void nv04RenderPrimitive( GLcontext *ctx, GLuint prim ) +{ + nv04RasterPrimitive( ctx, prim, hw_prim[prim] ); +} + +static void nv04ResetLineStipple( GLcontext *ctx ) +{ + /* FIXME do something here */ + WARN_ONCE("Unimplemented nv04ResetLineStipple\n"); +} + + +/**********************************************************************/ +/* Initialization. */ +/**********************************************************************/ + +void nv04TriInitFunctions(GLcontext *ctx) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + + tnl->Driver.RunPipeline = nouveauRunPipeline; + tnl->Driver.Render.Start = nv04RenderStart; + tnl->Driver.Render.Finish = nv04RenderFinish; + tnl->Driver.Render.PrimitiveNotify = nv04RenderPrimitive; + tnl->Driver.Render.ResetLineStipple = nv04ResetLineStipple; + tnl->Driver.Render.BuildVertices = _tnl_build_vertices; + tnl->Driver.Render.CopyPV = _tnl_copy_pv; + tnl->Driver.Render.Interp = _tnl_interp; + + _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12, 32 ); + + nmesa->verts = (GLubyte *)tnl->clipspace.vertex_buf; +} + + diff --git a/src/mesa/drivers/dri/nouveau/nv04_swtcl.h b/src/mesa/drivers/dri/nouveau/nv04_swtcl.h new file mode 100644 index 0000000000..42dde5383e --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_swtcl.h @@ -0,0 +1,12 @@ +#ifndef __NV04_SWTCL_H__ +#define __NV04_SWTCL_H__ + +#include "mtypes.h" + +extern void nv04Fallback( GLcontext *ctx, GLuint bit, GLboolean mode ); +extern void nv04FinishPrimitive(struct nouveau_context *nmesa); +extern void nv04TriInitFunctions(GLcontext *ctx); +#define FALLBACK( nmesa, bit, mode ) nouveauFallback( nmesa->glCtx, bit, mode ) + +#endif /* __NV04_SWTCL_H__ */ + -- cgit v1.2.3 From 65e3d5e45e3d14f4ff98a15af0662e6c6e589cd2 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sun, 14 Jan 2007 21:17:08 +0100 Subject: nouveau: Make the state cache hierarchical. --- src/mesa/drivers/dri/nouveau/nouveau_fifo.h | 3 +++ src/mesa/drivers/dri/nouveau/nouveau_state_cache.c | 5 +++++ src/mesa/drivers/dri/nouveau/nouveau_state_cache.h | 8 +++++++- 3 files changed, 15 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h index 05d00d4769..9056bfb255 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h @@ -31,6 +31,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_context.h" #include "nouveau_ctrlreg.h" +#include "nouveau_state_cache.h" //#define NOUVEAU_RING_DEBUG //#define NOUVEAU_STATE_CACHE_DISABLE @@ -114,6 +115,7 @@ extern void nouveau_state_cache_init(nouveauContextPtr nmesa); #define OUT_RING_CACHE(n) do { \ if (nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value!=(n)) { \ nmesa->state_cache.atoms[nmesa->state_cache.current_pos].dirty=1; \ + nmesa->state_cache.hdirty[nmesa->state_cache.current_pos/NOUVEAU_STATE_CACHE_HIER_SIZE]=1; \ nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value=(n); \ } \ nmesa->state_cache.current_pos++; \ @@ -122,6 +124,7 @@ extern void nouveau_state_cache_init(nouveauContextPtr nmesa); #define OUT_RING_CACHEf(n) do { \ if ((*(float*)(&nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value))!=(n)){ \ nmesa->state_cache.atoms[nmesa->state_cache.current_pos].dirty=1; \ + nmesa->state_cache.hdirty[nmesa->state_cache.current_pos/NOUVEAU_STATE_CACHE_HIER_SIZE]=1; \ (*(float*)(&nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value))=(n);\ } \ nmesa->state_cache.current_pos++; \ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state_cache.c b/src/mesa/drivers/dri/nouveau/nouveau_state_cache.c index 36f0c1024b..cb4b9d3027 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state_cache.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_state_cache.c @@ -25,6 +25,8 @@ void nouveau_state_cache_flush(nouveauContextPtr nmesa) do { // jump to a dirty state + while((nmesa->state_cache.hdirty[i/NOUVEAU_STATE_CACHE_HIER_SIZE]==0)&&(istate_cache.atoms[i].dirty==0)&&(istate_cache.atoms[i+j].value); nmesa->state_cache.atoms[i+j].dirty=0; + if ((i+j)%NOUVEAU_STATE_CACHE_HIER_SIZE==0) + nmesa->state_cache.hdirty[(i+j)/NOUVEAU_STATE_CACHE_HIER_SIZE-1]=0; } i+=run; } } while(istate_cache.hdirty[NOUVEAU_STATE_CACHE_HIER_SIZE/NOUVEAU_STATE_CACHE_HIER_SIZE-1]=0; } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state_cache.h b/src/mesa/drivers/dri/nouveau/nouveau_state_cache.h index 2488274846..5f9d426450 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state_cache.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_state_cache.h @@ -5,6 +5,10 @@ #include "mtypes.h" #define NOUVEAU_STATE_CACHE_ENTRIES 2048 +// size of a dirty requests block +// you can play with that and tune the value to increase/decrease performance +// but keep it a power of 2 ! +#define NOUVEAU_STATE_CACHE_HIER_SIZE 32 typedef struct nouveau_state_atom_t{ uint32_t value; @@ -14,8 +18,10 @@ typedef struct nouveau_state_atom_t{ typedef struct nouveau_state_cache_t{ nouveau_state_atom atoms[NOUVEAU_STATE_CACHE_ENTRIES]; uint32_t current_pos; + // hierarchical dirty flags + uint8_t hdirty[NOUVEAU_STATE_CACHE_ENTRIES/NOUVEAU_STATE_CACHE_HIER_SIZE]; // master dirty flag - uint32_t dirty; + uint8_t dirty; }nouveau_state_cache; -- cgit v1.2.3 From e2295511f5ee5fc4f5b39cba9e9c1c7a2f4e1eb5 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sun, 14 Jan 2007 22:39:37 +0100 Subject: nouveau: Update nouveau_reg.h from renouveau to the latest version. --- src/mesa/drivers/dri/nouveau/nouveau_reg.h | 230 ++++++++++++++++++++++++++--- 1 file changed, 212 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_reg.h b/src/mesa/drivers/dri/nouveau/nouveau_reg.h index 74f55c649a..f52d381f74 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_reg.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_reg.h @@ -43,7 +43,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ************************************************************************** - Created from objects.c rev. 1.350 + Created from objects.c rev. 1.398 */ #ifndef _NOUVEAU_REG_H @@ -60,6 +60,7 @@ Object NV01_CONTEXT_CLIP_RECTANGLE used on: NV03 NV04 NV10 NV15 NV20 NV40 G70 Object NV_MEMORY_TO_MEMORY_FORMAT used on: NV04 NV10 NV15 NV20 NV30 NV40 G70 */ #define NV_MEMORY_TO_MEMORY_FORMAT 0x00000039 +# define NV_MEMORY_TO_MEMORY_FORMAT_NOP 0x00000100 # define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY 0x00000104 # define NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY 0x00000180 # define NV_MEMORY_TO_MEMORY_FORMAT_OBJECT_IN 0x00000184 @@ -70,6 +71,8 @@ Object NV_MEMORY_TO_MEMORY_FORMAT used on: NV04 NV10 NV15 NV20 NV30 NV40 G70 # define NV_MEMORY_TO_MEMORY_FORMAT_PITCH_OUT 0x00000318 # define NV_MEMORY_TO_MEMORY_FORMAT_LINE_LENGTH_IN 0x0000031c # define NV_MEMORY_TO_MEMORY_FORMAT_LINE_COUNT 0x00000320 +# define NV_MEMORY_TO_MEMORY_FORMAT_FORMAT 0x00000324 /* Parameters: src_inc dst_inc */ +# define NV_MEMORY_TO_MEMORY_FORMAT_BUF_NOTIFY 0x00000328 /****************************************** Object NV03_PRIMITIVE_RASTER_OP used on: NV03 NV04 NV10 NV15 NV20 NV30 NV40 G70 @@ -322,18 +325,19 @@ Object NV11_TCL_PRIMITIVE_3D used on: NV15 # define NV10_TCL_PRIMITIVE_3D_TX_NPOT_PITCH(d) (0x00000230 + d * 0x0004) /* Parameters: pitch */ # define NV10_TCL_PRIMITIVE_3D_TX_NPOT_SIZE(d) (0x00000240 + d * 0x0004) /* Parameters: width height */ # define NV10_TCL_PRIMITIVE_3D_TX_FILTER(d) (0x00000248 + d * 0x0004) /* Parameters: mag_filter min_filter */ +# define NV10_TCL_PRIMITIVE_3D_TX_PALETTE_OFFSET(d) (0x00000250 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_TX_MATRIX_ENABLE(d) (0x000003e0 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_TX_MATRIX(x,y) (0x00000540 + y * 0x0010 + x * 0x0004) # define NV10_TCL_PRIMITIVE_3D_RC_IN_ALPHA(d) (0x00000260 + d * 0x0004) /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ # define NV10_TCL_PRIMITIVE_3D_RC_IN_RGB(d) (0x00000268 + d * 0x0004) /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ # define NV10_TCL_PRIMITIVE_3D_RC_OUT_ALPHA(d) (0x00000278 + d * 0x0004) /* Parameters: scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ # define NV10_TCL_PRIMITIVE_3D_RC_OUT_RGB(d) (0x00000280 + d * 0x0004) /* Parameters: rc1_tx_units_enabled rc1_rc_enabled scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ -# define NV10_TCL_PRIMITIVE_3D_TX_MATRIX_ENABLE(d) (0x000003e0 + d * 0x0004) -# define NV10_TCL_PRIMITIVE_3D_TX_MATRIX(x,y) (0x00000540 + y * 0x0010 + x * 0x0004) # define NV10_TCL_PRIMITIVE_3D_RC_COLOR0 0x00000270 /* Parameters: a r g b */ # define NV10_TCL_PRIMITIVE_3D_RC_COLOR1 0x00000274 /* Parameters: a r g b */ # define NV10_TCL_PRIMITIVE_3D_RC_FINAL0 0x00000288 /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ # define NV10_TCL_PRIMITIVE_3D_RC_FINAL1 0x0000028c /* Parameters: vare_mapping vare_component_usage vare_input varf_mapping varf_component_usage varf_input varg_mapping varg_component_usage varg_input color_sum_clamp */ # define NV10_TCL_PRIMITIVE_3D_LIGHT_MODEL 0x00000294 /* Parameters: local_viewer color_control */ -# define NV10_TCL_PRIMITIVE_3D_COLOR_MATERIAL 0x00000298 /* Parameters: specular diffuse ambient emission */ +# define NV10_TCL_PRIMITIVE_3D_COLOR_MATERIAL_ENABLE 0x00000298 /* Parameters: specular diffuse ambient emission */ # define NV10_TCL_PRIMITIVE_3D_FOG_MODE 0x0000029c # define NV10_TCL_PRIMITIVE_3D_FOG_COORD_DIST 0x000002a0 # define NV10_TCL_PRIMITIVE_3D_FOG_ENABLE 0x000002a4 @@ -363,7 +367,7 @@ Object NV11_TCL_PRIMITIVE_3D used on: NV15 # define NV10_TCL_PRIMITIVE_3D_BLEND_COLOR 0x0000034c /* Parameters: a r g b */ # define NV10_TCL_PRIMITIVE_3D_BLEND_EQUATION 0x00000350 # define NV10_TCL_PRIMITIVE_3D_DEPTH_FUNC 0x00000354 -# define NV10_TCL_PRIMITIVE_3D_COLOR_MASK 0x00000358 /* Parameters: r g b */ +# define NV10_TCL_PRIMITIVE_3D_COLOR_MASK 0x00000358 /* Parameters: a r g b */ # define NV10_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE 0x0000035c # define NV10_TCL_PRIMITIVE_3D_STENCIL_MASK 0x00000360 # define NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC 0x00000364 @@ -498,7 +502,7 @@ Object NV11_TCL_PRIMITIVE_3D used on: NV15 # define NV10_TCL_PRIMITIVE_3D_VERTEX_FOG_1F 0x00000ce0 # define NV10_TCL_PRIMITIVE_3D_VERTEX_WGH_1F 0x00000ce4 # define NV10_TCL_PRIMITIVE_3D_EDGEFLAG_ENABLE 0x00000cec -# define NV10_TCL_PRIMITIVE_3D_VERTEX_ATTR( d) (0x00000d04 + d * 0x0008) +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ATTR( d) (0x00000d04 + d * 0x0008) /* Parameters: stride fields type */ # define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_VALIDATE 0x00000cf0 # define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_POS 0x00000d00 # define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_POS 0x00000d04 /* Parameters: stride fields type */ @@ -595,6 +599,7 @@ Object NV10_UNK0072 used on: NV10 NV15 NV20 NV40 G70 */ #define NV10_UNK0072 0x00000072 # define NV10_UNK0072_COUNTER 0x00000050 +# define NV40_UNK0072_SET_OBJECT 0x00000060 # define NV10_UNK0072_SET_DMA_NOTIFY 0x00000180 /****************************************** @@ -667,6 +672,8 @@ Object NV20_SWIZZLED_SURFACE used on: NV20 NV30 NV40 G70 Object NV20_TCL_PRIMITIVE_3D used on: NV20 */ #define NV20_TCL_PRIMITIVE_3D 0x00000097 +# define NV20_TCL_PRIMITIVE_3D_NOP 0x00000100 +# define NV20_TCL_PRIMITIVE_3D_NOTIFY 0x00000104 # define NV20_TCL_PRIMITIVE_3D_SET_OBJECT0 0x00000180 # define NV20_TCL_PRIMITIVE_3D_SET_OBJECT1 0x00000184 # define NV20_TCL_PRIMITIVE_3D_SET_OBJECT2 0x00000188 @@ -691,6 +698,8 @@ Object NV20_TCL_PRIMITIVE_3D used on: NV20 # define NV20_TCL_PRIMITIVE_3D_FOG_MODE 0x0000029c # define NV20_TCL_PRIMITIVE_3D_FOG_COORD_DIST 0x000002a0 # define NV20_TCL_PRIMITIVE_3D_FOG_ENABLE 0x000002a4 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(d) (0x000002c0 + d * 0x0004) /* Parameters: x2 x1 */ +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(d) (0x000002e0 + d * 0x0004) /* Parameters: y2 y1 */ # define NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE 0x00000300 # define NV20_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE 0x00000304 # define NV20_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE 0x00000308 @@ -759,6 +768,10 @@ Object NV20_TCL_PRIMITIVE_3D used on: NV20 # define NV20_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_E 0x000009f0 # define NV20_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_F 0x000009f4 # define NV20_TCL_PRIMITIVE_3D_POINT_SPRITE 0x00000a1c /* Parameters: coord_replace r_mode enable */ +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_OX 0x00000a20 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_OY 0x00000a24 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_DEPTH_AVG_S 0x00000a28 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_UNKNOWN_A 0x00000a2c # define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_A 0x00000a30 # define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_B 0x00000a34 # define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_C 0x00000a38 @@ -767,6 +780,10 @@ Object NV20_TCL_PRIMITIVE_3D used on: NV20 # define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_F 0x00000a44 # define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_G 0x00000a48 # define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_H 0x00000a4c +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_PX_DIV2 0x00000af0 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_PY_DIV2 0x00000af4 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_DEPTH_HALF_S 0x00000af8 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_UNKNOWN_B 0x00000afc # define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_INST0 0x00000b00 # define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_INST1 0x00000b04 # define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_INST2 0x00000b08 @@ -781,10 +798,13 @@ Object NV20_TCL_PRIMITIVE_3D used on: NV20 # define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_B 0x00000a18 # define NV20_TCL_PRIMITIVE_3D_TX_OFFSET(d) (0x00001b00 + d * 0x0040) # define NV20_TCL_PRIMITIVE_3D_TX_FORMAT(d) (0x00001b04 + d * 0x0040) /* Parameters: log2(height) log2(width) lod format cube_map */ +# define NV20_TCL_PRIMITIVE_3D_TX_WRAP(d) (0x00001b08 + d * 0x0040) /* Parameters: wrap_s wrap_t wrap_r */ # define NV20_TCL_PRIMITIVE_3D_TX_ENABLE(d) (0x00001b0c + d * 0x0040) /* Parameters: enable anisotropy */ # define NV20_TCL_PRIMITIVE_3D_TX_NPOT_PITCH(d) (0x00001b10 + d * 0x0040) /* Parameters: pitch */ # define NV20_TCL_PRIMITIVE_3D_TX_FILTER(d) (0x00001b14 + d * 0x0040) /* Parameters: mag_filter min_filter */ # define NV20_TCL_PRIMITIVE_3D_TX_NPOT_SIZE(d) (0x00001b1c + d * 0x0040) /* Parameters: width height */ +# define NV20_TCL_PRIMITIVE_3D_TX_PALETTE_OFFSET(d) (0x00001b20 + d * 0x0040) +# define NV20_TCL_PRIMITIVE_3D_RC_ENABLE 0x00001e60 /* Parameters: number of rc enabled */ # define NV20_TCL_PRIMITIVE_3D_TX_SHADER_OP 0x00001e70 /* Parameters: op0 op1 op2 op3 */ # define NV20_TCL_PRIMITIVE_3D_TX_SHADER_CULL_MODE 0x000017f8 /* Parameters: cull0 cull1 cull2 cull3 */ # define NV20_TCL_PRIMITIVE_3D_TX_SHADER_PREVIOUS 0x00001e78 /* Parameters: prev2 prev3 */ @@ -794,6 +814,8 @@ Object NV20_TCL_PRIMITIVE_3D used on: NV20 # define NV20_TCL_PRIMITIVE_3D_RC_FINAL1 0x0000028c /* Parameters: vare_mapping vare_component_usage vare_input varf_mapping varf_component_usage varf_input varg_mapping varg_component_usage varg_input color_sum_clamp */ # define NV20_TCL_PRIMITIVE_3D_RC_IN_ALPHA(d) (0x00000260 + d * 0x0004) /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ # define NV20_TCL_PRIMITIVE_3D_RC_IN_RGB(d) (0x00000ac0 + d * 0x0004) /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ +# define NV20_TCL_PRIMITIVE_3D_RC_CONSTANT_COLOR0(d) (0x00000a60 + d * 0x0004) /* Parameters: a r g b */ +# define NV20_TCL_PRIMITIVE_3D_RC_CONSTANT_COLOR1(d) (0x00000a80 + d * 0x0004) /* Parameters: a r g b */ # define NV20_TCL_PRIMITIVE_3D_RC_OUT_ALPHA(d) (0x00000aa0 + d * 0x0004) /* Parameters: scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ # define NV20_TCL_PRIMITIVE_3D_RC_OUT_RGB(d) (0x00001e40 + d * 0x0004) /* Parameters: scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ # define NV20_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(d) (0x0000105c + d * 0x0080) @@ -943,12 +965,18 @@ Object NV20_TCL_PRIMITIVE_3D used on: NV20 # define NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP 0x000017c0 # define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_TWO_SIDE_ENABLE 0x000017c4 # define NV20_TCL_PRIMITIVE_3D_BEGIN_END 0x000017fc +# define NV20_TCL_PRIMITIVE_3D_SCISSOR_X2_X1 0x00001c30 /* Parameters: x2 x1 */ +# define NV20_TCL_PRIMITIVE_3D_SCISSOR_Y2_Y1 0x00001c50 /* Parameters: y2 y1 */ # define NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH 0x00001d8c # define NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB 0x00001d90 # define NV20_TCL_PRIMITIVE_3D_CLEAR_WHICH_BUFFERS 0x00001d94 /* Parameters: clear color a clear color b clear color g clear color r clear depth clear stencil */ # define NV20_TCL_PRIMITIVE_3D_INDEX_DATA 0x00001800 /* Parameters: index1 index0 */ # define NV20_TCL_PRIMITIVE_3D_VB_VERTEX_BATCH 0x00001810 /* Parameters: count_vertices offset_vertices */ # define NV20_TCL_PRIMITIVE_3D_VERTEX_DATA 0x00001818 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X 0x00001f00 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_Y 0x00001f04 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_Z 0x00001f08 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_W 0x00001f0c /****************************************** Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 @@ -965,8 +993,8 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_SET_OBJECT8 0x000001ac # define NV30_TCL_PRIMITIVE_3D_SET_OBJECT9 0x000001b4 # define NV30_TCL_PRIMITIVE_3D_SET_OBJECT10 0x000001b8 -# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT11 0x0000019c -# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT12 0x000001a0 +# define NV30_TCL_PRIMITIVE_3D_SET_VB_SRC0_OBJECT 0x0000019c +# define NV30_TCL_PRIMITIVE_3D_SET_VB_SRC1_OBJECT 0x000001a0 # define NV30_TCL_PRIMITIVE_3D_BUFFER0_PITCH 0x0000020c /* Parameters: depth/stencil buffer pitch color0 buffer pitch */ # define NV30_TCL_PRIMITIVE_3D_COLOR0_OFFSET 0x00000210 # define NV30_TCL_PRIMITIVE_3D_DEPTH_OFFSET 0x00000214 @@ -1016,6 +1044,7 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT_B 0x000003a8 # define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT_A 0x000003b4 # define NV30_TCL_PRIMITIVE_3D_LINE_WIDTH_SMOOTH 0x000003b8 +# define NV30_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE 0x000003bc # define NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(d) (0x00000400 + d * 0x0004) # define NV30_TCL_PRIMITIVE_3D_MODELVIEW_MATRIX( d) (0x00000480 + d * 0x0004) # define NV30_TCL_PRIMITIVE_3D_INVERSE_MODELVIEW_MATRIX( d) (0x00000580 + d * 0x0004) @@ -1027,12 +1056,17 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT 0x000008d0 # define NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_LINEAR 0x000008d4 # define NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_QUADRATIC 0x000008d8 +# define NV30_TCL_PRIMITIVE_3D_RC_COLOR0 0x000008ec /* Parameters: a r g b */ +# define NV30_TCL_PRIMITIVE_3D_RC_COLOR1 0x000008f0 /* Parameters: a r g b */ # define NV30_TCL_PRIMITIVE_3D_RC_FINAL0 0x000008f4 /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ # define NV30_TCL_PRIMITIVE_3D_RC_FINAL1 0x000008f8 /* Parameters: vare_mapping vare_component_usage vare_input varf_mapping varf_component_usage varf_input varg_mapping varg_component_usage varg_input color_sum_clamp */ -# define NV30_TCL_PRIMITIVE_3D_RC_IN_ALPHA 0x00000900 /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ -# define NV30_TCL_PRIMITIVE_3D_RC_IN_RGB 0x00000904 /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ -# define NV30_TCL_PRIMITIVE_3D_RC_OUT_ALPHA 0x00000910 /* Parameters: scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ -# define NV30_TCL_PRIMITIVE_3D_RC_OUT_RGB 0x00000914 /* Parameters: scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ +# define NV30_TCL_PRIMITIVE_3D_RC_ENABLE 0x000008fc /* Parameters: number of rc enabled */ +# define NV30_TCL_PRIMITIVE_3D_RC_IN_ALPHA(d) (0x00000900 + d * 0x0020) /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ +# define NV30_TCL_PRIMITIVE_3D_RC_IN_RGB(d) (0x00000904 + d * 0x0020) /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ +# define NV30_TCL_PRIMITIVE_3D_RC_CONSTANT_COLOR0(d) (0x00000908 + d * 0x0020) /* Parameters: a r g b */ +# define NV30_TCL_PRIMITIVE_3D_RC_CONSTANT_COLOR1(d) (0x0000090c + d * 0x0020) /* Parameters: a r g b */ +# define NV30_TCL_PRIMITIVE_3D_RC_OUT_ALPHA(d) (0x00000910 + d * 0x0020) /* Parameters: scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ +# define NV30_TCL_PRIMITIVE_3D_RC_OUT_RGB(d) (0x00000914 + d * 0x0020) /* Parameters: scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ # define NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_DIM0 0x00000200 /* Parameters: width x_offset */ # define NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_DIM1 0x00000204 /* Parameters: height y_offset */ # define NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_OFS0 0x000002c0 /* Parameters: width x_offset */ @@ -1054,6 +1088,7 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_F 0x00001ed4 # define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_G 0x00001ed8 # define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_H 0x00001edc +# define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETERS_ENABLE 0x00001ee4 # define NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_OX 0x00000a20 # define NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_OY 0x00000a24 # define NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_NPF_DIV2 0x00000a28 @@ -1074,6 +1109,10 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_INST1 0x00000b84 # define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_INST2 0x00000b88 # define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_INST3 0x00000b8c +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_R 0x000017b0 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_G 0x000017b4 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_B 0x000017b8 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_A 0x000017c0 # define NV30_TCL_PRIMITIVE_3D_OCC_QUERY_OR_COLOR_BUFF_ENABLE 0x000017c8 # define NV30_TCL_PRIMITIVE_3D_STORE_RESULT 0x00001800 # define NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_A(d) (0x00000e00 + d * 0x0010) @@ -1115,7 +1154,9 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_E 0x00001410 # define NV30_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_F 0x00001414 # define NV30_TCL_PRIMITIVE_3D_ENABLED_LIGHTS 0x00001420 /* Parameters: light 7 light 6 light 5 light 4 light 3 light 2 light 1 light 0 */ -# define NV30_TCL_PRIMITIVE_3D_LINE_STIPPLE 0x00001db4 +# define NV30_TCL_PRIMITIVE_3D_UNK1D6C_OFFSET 0x00001d6c +# define NV30_TCL_PRIMITIVE_3D_UNK1D70_VALUE 0x00001d70 +# define NV30_TCL_PRIMITIVE_3D_LINE_STIPPLE_ENABLE 0x00001db4 # define NV30_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN 0x00001db8 /* Parameters: factor pattern */ # define NV30_TCL_PRIMITIVE_3D_BEGIN_END 0x00001808 # define NV30_TCL_PRIMITIVE_3D_CULL_FACE 0x00001830 @@ -1159,7 +1200,7 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_VTX_ATTR_4Y(d) (0x00001c04 + d * 0x0010) # define NV30_TCL_PRIMITIVE_3D_VTX_ATTR_4Z(d) (0x00001c08 + d * 0x0010) # define NV30_TCL_PRIMITIVE_3D_VTX_ATTR_4W(d) (0x00001c0c + d * 0x0010) -# define NV30_TCL_PRIMITIVE_3D_VB_POINTER_ATTR(d) (0x00001680 + d * 0x0004) /* Parameters: enabled? offset */ +# define NV30_TCL_PRIMITIVE_3D_VB_POINTER_ATTR(d) (0x00001680 + d * 0x0004) /* Parameters: source: offset */ # define NV30_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_XY 0x00000a90 /* Parameters: y x */ # define NV30_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_Z 0x00000a94 /* Parameters: z */ # define NV30_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_S 0x000018c0 @@ -1206,10 +1247,6 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R 0x000017a0 # define NV30_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_G 0x000017a4 # define NV30_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_B 0x000017a8 -# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_R 0x000017b0 -# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_G 0x000017b4 -# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_B 0x000017b8 -# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_A 0x000017c0 # define NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM 0x000008e4 # define NV30_TCL_PRIMITIVE_3D_TX_ADDRESS_UNIT(d) (0x00001a00 + d * 0x0020) # define NV30_TCL_PRIMITIVE_3D_TX_FORMAT_UNIT(d) (0x00001a04 + d * 0x0020) /* Parameters: mipmap type format ncomp cubic */ @@ -1221,6 +1258,8 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_TX_UNK07_UNIT(d) (0x00001a1c + d * 0x0020) # define NV30_TCL_PRIMITIVE_3D_TX_DEPTH_UNIT(d) (0x00001840 + d * 0x0004) /* Parameters: depth NPOT pitch */ # define NV30_TCL_PRIMITIVE_3D_VB_VERTEX_BATCH 0x00001814 /* Parameters: count_vertices offset_vertices */ +# define NV30_TCL_PRIMITIVE_3D_VB_ELEMENT_U16 0x0000180c /* Parameters: 1: 0: */ +# define NV30_TCL_PRIMITIVE_3D_VB_ELEMENT_U32 0x00001810 # define NV30_TCL_PRIMITIVE_3D_VERTEX_DATA 0x00001818 # define NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE 0x00000374 # define NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP 0x00000378 @@ -1244,6 +1283,161 @@ Object NV30_CLEAR_BUFFER used on: NV30 NV40 G70 # define NV30_CLEAR_BUFFER_SET_CONTEXT_SURFACE_2D 0x00000198 # define NV30_CLEAR_BUFFER_UNK002fc 0x000002fc +/****************************************** +Object NV50_TCL_PRIMITIVE_3D used on: +*/ +#define NV50_TCL_PRIMITIVE_3D 0x00000097 +# define NV50_TCL_PRIMITIVE_3D_SET_OBJECT_0( d) (0x00000180 + d * 0x0004) +# define NV50_TCL_PRIMITIVE_3D_SET_OBJECT_1( d) (0x000001c0 + d * 0x0004) +# define NV50_TCL_PRIMITIVE_3D_VERTEX_FOG_1F 0x00000314 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_2F_X 0x00000380 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_2F_Y 0x00000384 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_S 0x000003c0 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_T 0x000003c4 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_S 0x000003c8 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_T 0x000003cc +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX2_2F_S 0x000003d0 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX2_2F_T 0x000003d4 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX3_2F_S 0x000003d8 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX3_2F_T 0x000003dc +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_3F_X 0x00000400 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_3F_Y 0x00000404 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_3F_Z 0x00000408 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_X 0x00000420 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_Y 0x00000424 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_Z 0x00000428 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL_3F_R 0x00000430 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL_3F_G 0x00000434 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL_3F_B 0x00000438 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_R 0x00000440 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_G 0x00000444 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_B 0x00000448 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_4F_X 0x00000500 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_4F_Y 0x00000504 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_4F_Z 0x00000508 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_4F_W 0x0000050c +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL_4F_R 0x00000530 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL_4F_G 0x00000534 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL_4F_B 0x00000538 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL_4F_A 0x0000053c +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_S 0x00000580 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_T 0x00000584 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_R 0x00000588 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_Q 0x0000058c +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_S 0x00000590 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_T 0x00000594 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_R 0x00000598 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_Q 0x0000059c +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX2_4F_S 0x000005a0 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX2_4F_T 0x000005a4 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX2_4F_R 0x000005a8 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX2_4F_Q 0x000005ac +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX3_4F_S 0x000005b0 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX3_4F_T 0x000005b4 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX3_4F_R 0x000005b8 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX3_4F_Q 0x000005bc +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX0_2I 0x000006a0 /* Parameters: t s */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX1_2I 0x000006a4 /* Parameters: t s */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX2_2I 0x000006a8 /* Parameters: t s */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX3_2I 0x000006ac /* Parameters: t s */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_4I_XY 0x00000700 /* Parameters: y x */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_4I_ZW 0x00000704 /* Parameters: w z */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX0_4I_ST 0x00000740 /* Parameters: t s */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX0_4I_RQ 0x00000744 /* Parameters: q r */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX1_4I_ST 0x00000748 /* Parameters: t s */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX1_4I_RQ 0x0000074c /* Parameters: q r */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX2_4I_ST 0x00000750 /* Parameters: t s */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX2_4I_RQ 0x00000754 /* Parameters: q r */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX3_4I_ST 0x00000758 /* Parameters: t s */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX3_4I_RQ 0x0000075c /* Parameters: q r */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_XY 0x00000790 /* Parameters: y x */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_Z 0x00000794 /* Parameters: z */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL_4I 0x0000088c /* Parameters: a b g r */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL2_3I 0x00000890 /* Parameters: a b g r */ +# define NV50_TCL_PRIMITIVE_3D_VIEWPORT_UNK0_X 0x00000a00 +# define NV50_TCL_PRIMITIVE_3D_VIEWPORT_UNK0_Y 0x00000a04 +# define NV50_TCL_PRIMITIVE_3D_VIEWPORT_UNK0_Z 0x00000a08 +# define NV50_TCL_PRIMITIVE_3D_VIEWPORT_UNK1_X 0x00000a0c +# define NV50_TCL_PRIMITIVE_3D_VIEWPORT_UNK1_Y 0x00000a10 +# define NV50_TCL_PRIMITIVE_3D_VIEWPORT_UNK1_Z 0x00000a14 +# define NV50_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR 0x00000c08 +# define NV50_TCL_PRIMITIVE_3D_DEPTH_RANGE_FAR 0x00000c0c +# define NV50_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(d) (0x00000d00 + d * 0x0008) /* Parameters: x2 x1 */ +# define NV50_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(d) (0x00000d04 + d * 0x0008) /* Parameters: y2 y1 */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_BUFFER_FIRST 0x00000d74 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_BUFFER_COUNT 0x00000d78 +# define NV50_TCL_PRIMITIVE_3D_CLEAR_COLOR_R 0x00000d80 +# define NV50_TCL_PRIMITIVE_3D_CLEAR_COLOR_G 0x00000d84 +# define NV50_TCL_PRIMITIVE_3D_CLEAR_COLOR_B 0x00000d88 +# define NV50_TCL_PRIMITIVE_3D_CLEAR_COLOR_A 0x00000d8c +# define NV50_TCL_PRIMITIVE_3D_CLEAR_DEPTH 0x00000d90 +# define NV50_TCL_PRIMITIVE_3D_CLEAR_STENCIL 0x00000da0 +# define NV50_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT 0x00000dac +# define NV50_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK 0x00000db0 +# define NV50_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE 0x00000db4 +# define NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE 0x00000dc0 +# define NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE 0x00000dc4 +# define NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE 0x00000dc8 +# define NV50_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS 0x00000e04 /* Parameters: w x */ +# define NV50_TCL_PRIMITIVE_3D_SCISSOR_HEIGHT_YPOS 0x00000e08 /* Parameters: h y */ +# define NV50_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_ID 0x00000f00 +# define NV50_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_X 0x00000f04 +# define NV50_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_Y 0x00000f08 +# define NV50_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_Z 0x00000f0c +# define NV50_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_W 0x00000f10 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_REF 0x00000f54 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_MASK 0x00000f58 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_MASK 0x00000f5c +# define NV50_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE 0x000012cc +# define NV50_TCL_PRIMITIVE_3D_SHADE_MODEL 0x000012d4 +# define NV50_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE 0x000012e8 +# define NV50_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE 0x000012ec +# define NV50_TCL_PRIMITIVE_3D_DEPTH_FUNC 0x0000130c +# define NV50_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF 0x00001310 +# define NV50_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC 0x00001314 +# define NV50_TCL_PRIMITIVE_3D_BLEND_COLOR_R 0x0000131c +# define NV50_TCL_PRIMITIVE_3D_BLEND_COLOR_G 0x00001320 +# define NV50_TCL_PRIMITIVE_3D_BLEND_COLOR_B 0x00001324 +# define NV50_TCL_PRIMITIVE_3D_BLEND_COLOR_A 0x00001328 +# define NV50_TCL_PRIMITIVE_3D_BLEND_EQUATION_RGB 0x00001340 +# define NV50_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC_RGB 0x00001344 +# define NV50_TCL_PRIMITIVE_3D_BLEND_FUNC_DST_RGB 0x00001348 +# define NV50_TCL_PRIMITIVE_3D_BLEND_EQUATION_ALPHA 0x0000134c +# define NV50_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC_ALPHA 0x00001350 +# define NV50_TCL_PRIMITIVE_3D_BLEND_FUNC_DST_ALPHA 0x00001358 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_ENABLE 0x00001380 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_FAIL 0x00001384 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_ZFAIL 0x00001388 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_ZPASS 0x0000138c +# define NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_FUNC 0x00001390 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_REF 0x00001394 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_MASK 0x00001398 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_MASK 0x0000139c +# define NV50_TCL_PRIMITIVE_3D_LINE_WIDTH 0x000013b0 +# define NV50_TCL_PRIMITIVE_3D_POINT_SIZE 0x00001518 +# define NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR 0x0000156c +# define NV50_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE 0x00001570 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_ENABLE 0x00001594 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_FAIL 0x00001598 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_ZFAIL 0x0000159c +# define NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_ZPASS 0x000015a0 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_FUNC 0x000015a4 +# define NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_UNITS 0x000015bc +# define NV50_TCL_PRIMITIVE_3D_VERTEX_BEGIN 0x000015dc +# define NV50_TCL_PRIMITIVE_3D_VERTEX_END 0x000015e0 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_DATA 0x00001640 +# define NV50_TCL_PRIMITIVE_3D_LINE_STIPPLE_ENABLE 0x0000166c +# define NV50_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN 0x00001680 /* Parameters: pattern factor */ +# define NV50_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE 0x0000168c +# define NV50_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN( d) (0x00001700 + d * 0x0004) +# define NV50_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE 0x00001918 +# define NV50_TCL_PRIMITIVE_3D_FRONT_FACE 0x0000191c +# define NV50_TCL_PRIMITIVE_3D_CULL_FACE 0x00001920 +# define NV50_TCL_PRIMITIVE_3D_LOGIC_OP_ENABLE 0x000019c4 +# define NV50_TCL_PRIMITIVE_3D_LOGIC_OP_OP 0x000019c8 +# define NV50_TCL_PRIMITIVE_3D_CLEAR_BUFFERS 0x000019d0 /* Parameters: color stencil depth */ +# define NV50_TCL_PRIMITIVE_3D_COLOR_MASK( d) (0x00001a00 + d * 0x0004) /* Parameters: a b g r */ + /****************************************** Object NV_DMA_FROM_MEMORY used on: NV03 NV04 NV10 NV15 NV20 NV30 NV40 G70 */ -- cgit v1.2.3 From 89f91d1804c0c4919c25d6b9931973733db1e664 Mon Sep 17 00:00:00 2001 From: Carlos Martín Nieto Date: Mon, 15 Jan 2007 00:00:30 +0100 Subject: nouveau: Implement much of the fog handling. --- src/mesa/drivers/dri/nouveau/nouveau_reg.h | 1 + src/mesa/drivers/dri/nouveau/nv30_state.c | 66 +++++++++++++++++++++++++++--- 2 files changed, 61 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_reg.h b/src/mesa/drivers/dri/nouveau/nouveau_reg.h index f52d381f74..8758b538c8 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_reg.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_reg.h @@ -1035,6 +1035,7 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_ZPASS 0x00000364 # define NV30_TCL_PRIMITIVE_3D_SHADE_MODEL 0x00000368 # define NV30_TCL_PRIMITIVE_3D_FOG_ENABLE 0x0000036c +# define NV30_TCL_PRIMITIVE_3D_FOG_COLOR 0x00000370 # define NV40_TCL_PRIMITIVE_3D_COLOR_MASK_BUFFER123 0x00000370 /* Parameters: buffer3 b buffer3 g buffer3 r buffer3 a buffer2 b buffer2 g buffer2 r buffer2 a buffer1 b buffer1 g buffer1 r buffer1 a */ # define NV30_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE 0x0000037c # define NV30_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR 0x00000394 diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 9bf5f2adea..4d79bb6127 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -348,17 +348,71 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) static void nv30Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (NOUVEAU_CARD_USING_SHADERS) + return; + switch(pname) { - case GL_FOG_MODE: - //BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_MODE, 1); - //OUT_RING_CACHE (params); + case GL_FOG_MODE: + { + int mode = 0; + /* The modes are different in GL and the card. */ + switch(ctx->Fog.Mode) + { + case GL_LINEAR: + mode = 0x804; break; - /* TODO: unsure about the rest.*/ - default: + case GL_EXP: + mode = 0x802; break; + case GL_EXP2: + mode = 0x803; + break; + } + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_MODE, 1); + OUT_RING_CACHE (mode); + break; + } + case GL_FOG_COLOR: + { + GLubyte c[4]; + UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,params); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_COLOR, 1); + /* nvidia ignores the alpha channel */ + OUT_RING_CACHE(PACK_COLOR_8888_REV(c[0],c[1],c[2],c[3])); + break; + } + case GL_FOG_DENSITY: + case GL_FOG_START: + case GL_FOG_END: + { + GLfloat f=0., c=0.; + switch(ctx->Fog.Mode) + { + case GL_LINEAR: + f = -1.0/(ctx->Fog.End - ctx->Fog.Start); + c = ctx->Fog.Start/(ctx->Fog.End - ctx->Fog.Start) + 2.001953; + break; + case GL_EXP: + f = -0.090168*ctx->Fog.Density; + c = 1.5; + case GL_EXP2: + f = -0.212330*ctx->Fog.Density; + c = 1.5; + } + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_LINEAR, 1); + OUT_RING_CACHE(f); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT, 1); + OUT_RING_CACHE(c); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_QUADRATIC, 1); + OUT_RING_CACHE(0); /* Is this always the same? */ + break; + } +// case GL_FOG_COORD_SRC: + default: + break; } - } static void nv30Hint(GLcontext *ctx, GLenum target, GLenum mode) -- cgit v1.2.3 From 634b4b3487dcb22e1660959b6a7ce9a42fa50fe2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 15 Jan 2007 17:23:04 +1100 Subject: nouveau: fail CreateScreen on unknown cards instead of guessing. --- src/mesa/drivers/dri/nouveau/nouveau_card.c | 4 ++-- src/mesa/drivers/dri/nouveau/nouveau_screen.c | 9 ++++++++- 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_card.c b/src/mesa/drivers/dri/nouveau/nouveau_card.c index ae4f4c7ae5..91f12f0d70 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_card.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_card.c @@ -10,8 +10,8 @@ nouveau_card* nouveau_card_lookup(uint32_t device_id) int i; for(i=0;icard=nouveau_card_lookup(dri_priv->device_id); + if (!screen->card) { + __driUtilMessage("%s: Unknown card type 0x%04x:0x%04x\n", + __func__, dri_priv->device_id >> 16, dri_priv->device_id & 0xFFFF); + FREE(screen); + return NULL; + } + /* parse information in __driConfigOptions */ driParseOptionInfo (&screen->optionCache,__driConfigOptions, __driNConfigOptions); @@ -82,7 +90,6 @@ static nouveauScreenPtr nouveauCreateScreen(__DRIscreenPrivate *sPriv) screen->depthOffset = dri_priv->depth_offset; screen->depthPitch = dri_priv->depth_pitch; - screen->card=nouveau_card_lookup(dri_priv->device_id); screen->driScreen = sPriv; return screen; } -- cgit v1.2.3 From 16f35a3a22fa782f6bb8a51ef32d6668a5c60e85 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 15 Jan 2007 17:28:56 +1100 Subject: nouveau: Add 0x0244 pciid manually for now.. pciids.sf.net is slow to add it so our generator picks it up, and it's *really* annoying me :) --- src/mesa/drivers/dri/nouveau/nouveau_card_list.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_card_list.h b/src/mesa/drivers/dri/nouveau/nouveau_card_list.h index f8ea3c355e..14e7b69802 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_card_list.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_card_list.h @@ -132,6 +132,7 @@ static nouveau_card nouveau_card_list[]={ {0x0221, "GeForce 6200", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, {0x0240, "GeForce 6150", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, {0x0242, "GeForce 6100", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, +{0x0244, "GeForce 6150 Go", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, {0x0250, "GeForce4 Ti 4600", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, {0x0251, "GeForce4 Ti 4400", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, {0x0252, "GeForce4 Ti", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, -- cgit v1.2.3 From 4c7d36b688866129a17c3f59aa9374b2f9a874de Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Mon, 15 Jan 2007 12:38:24 +0100 Subject: nouveau: Fix a bug in the nv04 swtcl. --- src/mesa/drivers/dri/nouveau/nv04_swtcl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv04_swtcl.c b/src/mesa/drivers/dri/nouveau/nv04_swtcl.c index e4ace92134..f31c0d692d 100644 --- a/src/mesa/drivers/dri/nouveau/nv04_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv04_swtcl.c @@ -178,7 +178,7 @@ static void nv04_render_tri_fan_verts(GLcontext *ctx,GLuint start,GLuint count,G for(i=start+1;i Date: Mon, 15 Jan 2007 11:52:58 +0000 Subject: New files to manage splitting drawing commands --- src/mesa/vbo/vbo_split.c | 161 ++++++++++++ src/mesa/vbo/vbo_split.h | 72 +++++ src/mesa/vbo/vbo_split_copy.c | 549 +++++++++++++++++++++++++++++++++++++++ src/mesa/vbo/vbo_split_inplace.c | 301 +++++++++++++++++++++ 4 files changed, 1083 insertions(+) create mode 100644 src/mesa/vbo/vbo_split.c create mode 100644 src/mesa/vbo/vbo_split.h create mode 100644 src/mesa/vbo/vbo_split_copy.c create mode 100644 src/mesa/vbo/vbo_split_inplace.c (limited to 'src') diff --git a/src/mesa/vbo/vbo_split.c b/src/mesa/vbo/vbo_split.c new file mode 100644 index 0000000000..171859a18e --- /dev/null +++ b/src/mesa/vbo/vbo_split.c @@ -0,0 +1,161 @@ + +/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * 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 + */ + +/* Deal with hardware and/or swtnl maximums: + * - maximum number of vertices in buffer + * - maximum number of elements (maybe zero) + * + * The maximums may vary with opengl state (eg if a larger hardware + * vertex is required in this state, the maximum number of vertices + * may be smaller than in another state). + * + * We want buffer splitting to be a convenience function for the code + * actually drawing the primitives rather than a system-wide maximum, + * otherwise it is hard to avoid pessimism. + * + * For instance, if a driver has no hardware limits on vertex buffer + * dimensions, it would not ordinarily want to split vbos. But if + * there is an unexpected fallback, eg memory manager fails to upload + * textures, it will want to pass the drawing commands onto swtnl, + * which does have limitations. A convenience function allows swtnl + * to split the drawing and vbos internally without imposing its + * limitations on drivers which want to use it as a fallback path. + */ + +#include "glheader.h" +#include "imports.h" +#include "mtypes.h" + +#include "vbo_split.h" +#include "vbo.h" + +/* True if a primitive can be split without copying of vertices, false + * otherwise. + */ +GLboolean split_prim_inplace(GLenum mode, GLuint *first, GLuint *incr) +{ + switch (mode) { + case GL_POINTS: + *first = 1; + *incr = 1; + return GL_TRUE; + case GL_LINES: + *first = 2; + *incr = 2; + return GL_TRUE; + case GL_LINE_STRIP: + *first = 2; + *incr = 1; + return GL_TRUE; + case GL_TRIANGLES: + *first = 3; + *incr = 3; + return GL_TRUE; + case GL_TRIANGLE_STRIP: + *first = 3; + *incr = 1; + return GL_TRUE; + case GL_QUADS: + *first = 4; + *incr = 4; + return GL_TRUE; + case GL_QUAD_STRIP: + *first = 4; + *incr = 2; + return GL_TRUE; + default: + *first = 0; + *incr = 1; /* so that count % incr works */ + return GL_FALSE; + } +} + + + +void vbo_split_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, + vbo_draw_func draw, + const struct split_limits *limits ) +{ + + if (ib) { + if (limits->max_indices == 0) { + /* Could traverse the indices, re-emitting vertices in turn. + * But it's hard to see why this case would be needed - for + * software tnl, it is better to convert to non-indexed + * rendering after transformation is complete, as is done in + * the t_dd_rendertmp.h templates. Are there any devices + * with hardware tnl that cannot do indexed rendering? + * + * For now, this path is disabled. + */ + assert(0); + } + else if (max_index - min_index > limits->max_verts) { + /* The vertex buffers are too large for hardware (or the + * swtnl module). Traverse the indices, re-emitting vertices + * in turn. Use a vertex cache to preserve some of the + * sharing from the original index list. + */ + vbo_split_copy(ctx, arrays, prim, nr_prims, ib, + draw, limits ); + } + else if (ib->count > limits->max_indices) { + /* The index buffer is too large for hardware. Try to split + * on whole-primitive boundaries, otherwise try to split the + * individual primitives. + */ + vbo_split_inplace(ctx, arrays, prim, nr_prims, ib, + min_index, max_index, draw, limits ); + } + else { + /* Why were we called? */ + assert(0); + } + } + else { + if (max_index - min_index >= limits->max_verts) { + /* The vertex buffer is too large for hardware (or the swtnl + * module). Try to split on whole-primitive boundaries, + * otherwise try to split the individual primitives. + */ + vbo_split_inplace(ctx, arrays, prim, nr_prims, ib, + min_index, max_index, draw, limits ); + } + else { + /* Why were we called? */ + assert(0); + } + } +} + diff --git a/src/mesa/vbo/vbo_split.h b/src/mesa/vbo/vbo_split.h new file mode 100644 index 0000000000..05888d048c --- /dev/null +++ b/src/mesa/vbo/vbo_split.h @@ -0,0 +1,72 @@ +/* + * mesa 3-D graphics library + * Version: 6.5 + * + * 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 vbo_context.h + * \brief VBO builder module datatypes and definitions. + * \author Keith Whitwell + */ + + +/** + * \mainpage The VBO splitter + * + * This is the private data used internally to the vbo_split_prims() + * helper function. Nobody outside the vbo_split* files needs to + * include or know about this structure. + */ + + +#ifndef _VBO_SPLIT_H +#define _VBO_SPLIT_H + +#include "vbo.h" + + +/* True if a primitive can be split without copying of vertices, false + * otherwise. + */ +GLboolean split_prim_inplace(GLenum mode, GLuint *first, GLuint *incr); + +void vbo_split_inplace( 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, + vbo_draw_func draw, + const struct split_limits *limits ); + +/* Requires ib != NULL: + */ +void vbo_split_copy( GLcontext *ctx, + const struct gl_client_array *arrays[], + const struct _mesa_prim *prim, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + vbo_draw_func draw, + const struct split_limits *limits ); + +#endif diff --git a/src/mesa/vbo/vbo_split_copy.c b/src/mesa/vbo/vbo_split_copy.c new file mode 100644 index 0000000000..0adad71732 --- /dev/null +++ b/src/mesa/vbo/vbo_split_copy.c @@ -0,0 +1,549 @@ + +/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * 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 + */ + +/* Split indexed primitives with per-vertex copying. + */ + +#include "glheader.h" +#include "imports.h" +#include "macros.h" +#include "enums.h" +#include "mtypes.h" + +#include "vbo_split.h" +#include "vbo.h" + + +#define ELT_TABLE_SIZE 16 + +/* Used for vertex-level splitting of indexed buffers. Note that + * non-indexed primitives may be converted to indexed in some cases + * (eg loops, fans) in order to use this splitting path. + */ +struct copy_context { + + GLcontext *ctx; + const struct gl_client_array **array; + const struct _mesa_prim *prim; + GLuint nr_prims; + const struct _mesa_index_buffer *ib; + vbo_draw_func draw; + + const struct split_limits *limits; + + struct { + GLuint attr; + GLuint size; + const struct gl_client_array *array; + const GLubyte *src_ptr; + + struct gl_client_array dstarray; + + } varying[VERT_ATTRIB_MAX]; + GLuint nr_varying; + + const struct gl_client_array *dstarray_ptr[VERT_ATTRIB_MAX]; + struct _mesa_index_buffer dstib; + + GLuint *translated_elt_buf; + const GLuint *srcelt; + + /* A baby hash table to avoid re-emitting (some) duplicate + * vertices when splitting indexed primitives. + */ + struct { + GLuint in; + GLuint out; + } vert_cache[ELT_TABLE_SIZE]; + + + GLuint vertex_size; + GLubyte *dstbuf; + GLubyte *dstptr; /* dstptr == dstbuf + dstelt_max * vertsize */ + GLuint dstbuf_size; /* in vertices */ + GLuint dstbuf_nr; /* count of emitted vertices, also the + * largest value in dstelt. Our + * MaxIndex. + */ + + GLuint *dstelt; + GLuint dstelt_nr; + GLuint dstelt_size; + +#define MAX_PRIM 32 + struct _mesa_prim dstprim[MAX_PRIM]; + GLuint dstprim_nr; + +}; + + +static GLuint type_size( GLenum type ) +{ + switch(type) { + case GL_BYTE: return sizeof(GLbyte); + case GL_UNSIGNED_BYTE: return sizeof(GLubyte); + case GL_SHORT: return sizeof(GLshort); + case GL_UNSIGNED_SHORT: return sizeof(GLushort); + case GL_INT: return sizeof(GLint); + case GL_UNSIGNED_INT: return sizeof(GLuint); + case GL_FLOAT: return sizeof(GLfloat); + case GL_DOUBLE: return sizeof(GLdouble); + default: return 0; + } +} + +static GLuint attr_size( const struct gl_client_array *array ) +{ + return array->Size * type_size(array->Type); +} + + +/* Starts returning true slightly before the buffer fills, to ensure + * that there is sufficient room for any remaining vertices to finish + * off the prim: + */ +static GLboolean check_flush( struct copy_context *copy ) +{ + if (copy->dstbuf_nr + 4 > copy->dstbuf_size) + return GL_TRUE; + + if (copy->dstelt_nr + 4 > copy->dstelt_size) + return GL_TRUE; + + return GL_FALSE; +} + +static void flush( struct copy_context *copy ) +{ + GLuint i; + + /* Set some counters: + */ + copy->dstib.count = copy->dstelt_nr; + + copy->draw( copy->ctx, + copy->dstarray_ptr, + copy->dstprim, + copy->dstprim_nr, + ©->dstib, + 0, + copy->dstbuf_nr ); + + /* Reset all pointers: + */ + copy->dstprim_nr = 0; + copy->dstelt_nr = 0; + copy->dstbuf_nr = 0; + copy->dstptr = copy->dstbuf; + + /* Clear the vertex cache: + */ + for (i = 0; i < ELT_TABLE_SIZE; i++) + copy->vert_cache[i].in = ~0; +} + + + +static void begin( struct copy_context *copy, GLenum mode, GLboolean begin_flag ) +{ + struct _mesa_prim *prim = ©->dstprim[copy->dstprim_nr]; + + _mesa_printf("begin %s (%d)\n", _mesa_lookup_enum_by_nr(mode), begin_flag); + + prim->mode = mode; + prim->begin = begin_flag; +} + + +/* Use a hashtable to attempt to identify recently-emitted vertices + * and avoid re-emitting them. + */ +static GLuint elt(struct copy_context *copy, GLuint elt_idx) +{ + GLuint elt = copy->srcelt[elt_idx]; + GLuint slot = elt & (ELT_TABLE_SIZE-1); + + _mesa_printf("elt %d\n", elt); + + /* Look up the incoming element in the vertex cache. Re-emit if + * necessary. + */ + if (copy->vert_cache[slot].in != elt) { + GLubyte *csr = copy->dstptr; + GLuint i; + + _mesa_printf(" --> emit to dstelt %d\n", copy->dstbuf_nr); + + for (i = 0; i < copy->nr_varying; i++) { + const struct gl_client_array *srcarray = copy->varying[i].array; + const GLubyte *srcptr = copy->varying[i].src_ptr + elt * srcarray->StrideB; + + memcpy(csr, srcptr, copy->varying[i].size); + csr += copy->varying[i].size; + + { + const GLuint *f = (const GLuint *)srcptr; + GLuint j; + _mesa_printf(" varying %d: ", i); + for(j = 0; j < copy->varying[i].size / 4; j++) + _mesa_printf("%x ", f[j]); + _mesa_printf("\n"); + } + + } + + copy->vert_cache[slot].in = elt; + copy->vert_cache[slot].out = copy->dstbuf_nr++; + copy->dstptr += copy->vertex_size; + + assert(csr == copy->dstptr); + assert(copy->dstptr == (copy->dstbuf + + copy->dstbuf_nr * + copy->vertex_size)); + } + else + _mesa_printf(" --> reuse vertex\n"); + + _mesa_printf(" --> emit %d\n", copy->vert_cache[slot].out); + copy->dstelt[copy->dstelt_nr++] = copy->vert_cache[slot].out; + return check_flush(copy); +} + +static void end( struct copy_context *copy, GLboolean end_flag ) +{ + struct _mesa_prim *prim = ©->dstprim[copy->dstprim_nr]; + + _mesa_printf("end (%d)\n", end_flag); + + prim->end = end_flag; + prim->count = copy->dstelt_nr - prim->start; + + if (++copy->dstprim_nr == MAX_PRIM || + check_flush(copy)) + flush(copy); +} + + + +static void replay_elts( struct copy_context *copy ) +{ + GLuint i, j, k; + GLboolean split; + + for (i = 0; i < copy->nr_prims; i++) { + const struct _mesa_prim *prim = ©->prim[i]; + const GLuint start = prim->start; + GLuint first, incr; + + switch (prim->mode) { + + case GL_LINE_LOOP: + /* Convert to linestrip and emit the final vertex explicitly, + * but only in the resultant strip that requires it. + */ + j = 0; + while (j != prim->count) { + begin(copy, GL_LINE_STRIP, prim->begin && j == 0); + + for (split = GL_FALSE; j != prim->count && !split; j++) + split = elt(copy, start + j); + + if (j == prim->count) { + /* Done, emit final line. Split doesn't matter as + * it is always raised a bit early so we can emit + * the last verts if necessary! + */ + if (prim->end) + (void)elt(copy, start + 0); + + end(copy, prim->end); + } + else { + /* Wrap + */ + assert(split); + end(copy, 0); + j--; + } + } + break; + + case GL_TRIANGLE_FAN: + case GL_POLYGON: + j = 2; + while (j != prim->count) { + begin(copy, prim->mode, prim->begin && j == 0); + + split = elt(copy, start+0); + assert(!split); + + split = elt(copy, start+j-1); + assert(!split); + + for (; j != prim->count && !split; j++) + split = elt(copy, start+j); + + end(copy, prim->end && j == prim->count); + + if (j != prim->count) { + /* Wrapped the primitive, need to repeat some vertices: + */ + j -= 1; + } + } + break; + + default: + (void)split_prim_inplace(prim->mode, &first, &incr); + + j = 0; + while (j != prim->count) { + + begin(copy, prim->mode, prim->begin && j == 0); + + split = 0; + for (k = 0; k < first; k++, j++) + split |= elt(copy, start+j); + + assert(!split); + + for (; j != prim->count && !split; ) + for (k = 0; k < incr; k++, j++) + split |= elt(copy, start+j); + + end(copy, prim->end && j == prim->count); + + if (j != prim->count) { + /* Wrapped the primitive, need to repeat some vertices: + */ + assert(j > first - incr); + j -= (first - incr); + } + } + break; + } + } + + if (copy->dstprim_nr) + flush(copy); +} + + +static void replay_init( struct copy_context *copy ) +{ + GLcontext *ctx = copy->ctx; + GLuint i; + GLuint offset; + + /* Make a list of varying attributes and their vbo's. Also + * calculate vertex size. + */ + copy->vertex_size = 0; + for (i = 0; i < VERT_ATTRIB_MAX; i++) { + struct gl_buffer_object *vbo = copy->array[i]->BufferObj; + + if (copy->array[i]->StrideB == 0) { + copy->dstarray_ptr[i] = copy->array[i]; + } + else { + GLuint j = copy->nr_varying++; + + copy->varying[j].attr = i; + copy->varying[j].array = copy->array[i]; + copy->varying[j].size = attr_size(copy->array[i]); + copy->vertex_size += attr_size(copy->array[i]); + + if (vbo->Name && !vbo->Pointer) + ctx->Driver.MapBuffer(ctx, + GL_ARRAY_BUFFER_ARB, + GL_DYNAMIC_DRAW_ARB, /* XXX */ + vbo); + + copy->varying[j].src_ptr = ADD_POINTERS(vbo->Pointer, + copy->array[i]->Ptr); + + copy->dstarray_ptr[i] = ©->varying[j].dstarray; + } + } + + /* There must always be an index buffer. Currently require the + * caller convert non-indexed prims to indexed. Could alternately + * do it internally. + */ + if (copy->ib->obj->Name && !copy->ib->obj->Pointer) + ctx->Driver.MapBuffer(ctx, + GL_ARRAY_BUFFER_ARB, /* XXX */ + GL_DYNAMIC_DRAW_ARB, /* XXX */ + copy->ib->obj); + + switch (copy->ib->type) { + case GL_UNSIGNED_BYTE: + copy->translated_elt_buf = _mesa_malloc(sizeof(GLuint) * copy->ib->count); + copy->srcelt = copy->translated_elt_buf; + + for (i = 0; i < copy->ib->count; i++) + copy->translated_elt_buf[i] = ((const GLubyte *)copy->ib->ptr)[i]; + break; + + case GL_UNSIGNED_SHORT: + copy->translated_elt_buf = _mesa_malloc(sizeof(GLuint) * copy->ib->count); + copy->srcelt = copy->translated_elt_buf; + + for (i = 0; i < copy->ib->count; i++) + copy->translated_elt_buf[i] = ((const GLushort *)copy->ib->ptr)[i]; + break; + + case GL_UNSIGNED_INT: + copy->translated_elt_buf = NULL; + copy->srcelt = (const GLuint *)ADD_POINTERS(copy->ib->obj->Pointer, + copy->ib->ptr); + break; + } + + + /* Figure out the maximum allowed vertex buffer size: + */ + if (copy->vertex_size * copy->limits->max_verts <= copy->limits->max_vb_size) { + copy->dstbuf_size = copy->limits->max_verts; + } + else { + copy->dstbuf_size = copy->limits->max_vb_size / copy->vertex_size; + } + + /* Allocate an output vertex buffer: + * + * XXX: This should be a VBO! + */ + copy->dstbuf = _mesa_malloc(copy->dstbuf_size * + copy->vertex_size); + copy->dstptr = copy->dstbuf; + + /* Setup new vertex arrays to point into the output buffer: + */ + for (offset = 0, i = 0; i < copy->nr_varying; i++) { + const struct gl_client_array *src = copy->varying[i].array; + struct gl_client_array *dst = ©->varying[i].dstarray; + + dst->Size = src->Size; + dst->Type = src->Type; + dst->Stride = copy->vertex_size; + dst->StrideB = copy->vertex_size; + dst->Ptr = copy->dstbuf + offset; + dst->Enabled = GL_TRUE; + dst->Normalized = GL_TRUE; + dst->BufferObj = ctx->Array.NullBufferObj; + dst->_MaxElement = copy->dstbuf_size; /* may be less! */ + + offset += copy->varying[i].size; + } + + /* Allocate an output element list: + */ + copy->dstelt_size = MIN2(65536, + copy->ib->count * 2); + copy->dstelt_size = MIN2(copy->dstelt_size, + copy->limits->max_indices); + copy->dstelt = _mesa_malloc(copy->dstelt_size); + copy->dstelt_nr = 0; + + /* Setup the new index buffer to point to the allocated element + * list: + */ + copy->dstib.count = 0; /* duplicates dstelt_nr */ + copy->dstib.type = GL_UNSIGNED_INT; + copy->dstib.obj = ctx->Array.NullBufferObj; + copy->dstib.ptr = copy->dstelt; + copy->dstib.rebase = 0; +} + + +static void replay_finish( struct copy_context *copy ) +{ + GLcontext *ctx = copy->ctx; + GLuint i; + + /* Free our vertex and index buffers: + */ + _mesa_free(copy->translated_elt_buf); + _mesa_free(copy->dstbuf); + _mesa_free(copy->dstelt); + + /* Unmap VBO's + */ + for (i = 0; i < copy->nr_varying; i++) { + struct gl_buffer_object *vbo = copy->varying[i].array->BufferObj; + + if (vbo->Name && vbo->Pointer) + ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER_ARB, vbo); + } + + /* Unmap index buffer: + */ + if (copy->ib->obj->Name && copy->ib->obj->Pointer) { + ctx->Driver.UnmapBuffer(ctx, + GL_ARRAY_BUFFER_ARB, /* XXX */ + copy->ib->obj); + } +} + +void vbo_split_copy( GLcontext *ctx, + const struct gl_client_array *arrays[], + const struct _mesa_prim *prim, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + vbo_draw_func draw, + const struct split_limits *limits ) +{ + struct copy_context copy; + GLuint i; + + memset(©, 0, sizeof(copy)); + + /* Require indexed primitives: + */ + assert(ib); + + copy.ctx = ctx; + copy.array = arrays; + copy.prim = prim; + copy.nr_prims = nr_prims; + copy.ib = ib; + copy.draw = draw; + copy.limits = limits; + + + /* Clear the vertex cache: + */ + for (i = 0; i < ELT_TABLE_SIZE; i++) + copy.vert_cache[i].in = ~0; + + + replay_init(©); + replay_elts(©); + replay_finish(©); +} diff --git a/src/mesa/vbo/vbo_split_inplace.c b/src/mesa/vbo/vbo_split_inplace.c new file mode 100644 index 0000000000..66c94aceaa --- /dev/null +++ b/src/mesa/vbo/vbo_split_inplace.c @@ -0,0 +1,301 @@ + +/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * 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 + */ + + +#include "mtypes.h" +#include "macros.h" +#include "enums.h" +#include "vbo_split.h" + + +#define MAX_PRIM 32 + +/* Used for splitting without copying. + */ +struct split_context { + GLcontext *ctx; + const struct gl_client_array **array; + const struct _mesa_prim *prim; + GLuint nr_prims; + const struct _mesa_index_buffer *ib; + GLuint min_index; + GLuint max_index; + vbo_draw_func draw; + + const struct split_limits *limits; + +/* GLuint out_maxindex; */ +/* GLuint out_minindex; */ + + struct _mesa_prim dstprim[MAX_PRIM]; + GLuint dstprim_nr; +}; + + + + +static void flush_vertex( struct split_context *split ) +{ + GLint min_index, max_index; + + if (!split->dstprim_nr) + return; + + if (split->ib) { + /* This should basically be multipass rendering over the same + * unchanging set of VBO's. Would like the driver not to + * re-upload the data, or swtnl not to re-transform the + * vertices. + */ + assert(split->max_index - split->min_index < split->limits->max_verts); + min_index = split->min_index; + max_index = split->max_index; + } + else { + /* Non-indexed rendering. Cannot assume that the primitives are + * ordered by increasing vertex, because of entrypoints like + * MultiDrawArrays. + */ + GLuint i; + min_index = split->dstprim[0].start; + max_index = min_index + split->dstprim[0].count - 1; + + for (i = 1; i < split->dstprim_nr; i++) { + GLuint tmp_min = split->dstprim[i].start; + GLuint tmp_max = tmp_min + split->dstprim[i].count - 1; + + if (tmp_min < min_index) + min_index = tmp_min; + + if (tmp_max > max_index) + max_index = tmp_max; + } + } + + assert(max_index >= min_index); + + split->draw( split->ctx, + split->array, + split->dstprim, + split->dstprim_nr, + NULL, + min_index, + max_index); + + split->dstprim_nr = 0; +} + + +static struct _mesa_prim *next_outprim( struct split_context *split ) +{ + if (split->dstprim_nr == MAX_PRIM-1) { + flush_vertex(split); + } + + { + struct _mesa_prim *prim = &split->dstprim[split->dstprim_nr++]; + memset(prim, 0, sizeof(*prim)); + return prim; + } +} + +static int align(int value, int alignment) +{ + return (value + alignment - 1) & ~(alignment - 1); +} + + + +/* Break large primitives into smaller ones. If not possible, convert + * the primitive to indexed and pass to split_elts(). + */ +static void split_prims( struct split_context *split) +{ + GLuint csr = 0; + GLuint i; + + for (i = 0; i < split->nr_prims; i++) { + const struct _mesa_prim *prim = &split->prim[i]; + GLuint first, incr; + GLboolean split_inplace = split_prim_inplace(prim->mode, &first, &incr); + GLuint count; + + /* Always wrap on an even numbered vertex to avoid problems with + * triangle strips. + */ + GLuint available = align(split->limits->max_verts - csr - 1, 2); + assert(split->limits->max_verts >= csr); + + _mesa_printf("%s: prim %d: %s %d..%d\n", __FUNCTION__, + i, + _mesa_lookup_enum_by_nr(prim->mode), + prim->start, prim->count); + + _mesa_printf("a: available %d\n", available); + + if (prim->count < first) + continue; + + count = prim->count - (prim->count - first) % incr; + + + if ((available < count && !split_inplace) || + (available < first && split_inplace)) { + flush_vertex(split); + csr = 0; + available = align(split->limits->max_verts - csr - 1, 2); + } + + _mesa_printf("b: available %d\n", available); + + if (available >= count) { + struct _mesa_prim *outprim = next_outprim(split); + *outprim = *prim; + csr += prim->count; + available = align(split->limits->max_verts - csr - 1, 2); + } + else if (0 && split_inplace) { + GLuint j, nr; + + + for (j = 0 ; j < count ; ) { + GLuint remaining = count - j; + struct _mesa_prim *outprim = next_outprim(split); + + nr = MIN2( available, remaining ); + + nr -= (nr - first) % incr; + + outprim->mode = prim->mode; + outprim->begin = (j == 0 && prim->begin); + outprim->end = (nr == remaining && prim->end); + outprim->start = prim->start + j; + outprim->count = nr; + + if (nr == remaining) { + /* Finished. + */ + j += nr; + csr += nr; + available = align(split->limits->max_verts - csr - 1, 2); + } + else { + /* Wrapped the primitive: + */ + _mesa_printf("wrap %d %d\n", nr, first-incr); + + j += nr - (first - incr); + flush_vertex(split); + csr = 0; + available = align(split->limits->max_verts - csr - 1, 2); + } + } + } + else if (split->ib == NULL) { + /* XXX: could at least send the first max_verts off from the + * inplace buffers. + */ + + /* else convert to indexed primitive and pass to split_elts, + * which will do the necessary copying and turn it back into a + * vertex primitive for rendering... + */ + struct _mesa_index_buffer ib; + struct _mesa_prim tmpprim; + GLuint *elts = malloc(count * sizeof(GLuint)); + GLuint j; + + for (j = 0; j < count; j++) + elts[j] = prim->start + j; + + ib.count = count; + ib.type = GL_UNSIGNED_INT; + ib.obj = split->ctx->Array.NullBufferObj; + ib.ptr = elts; + ib.rebase = 0; /* ? */ + + tmpprim = *prim; + tmpprim.indexed = 1; + tmpprim.start = 0; + tmpprim.count = count; + + flush_vertex(split); + + vbo_split_copy(split->ctx, + split->array, + &tmpprim, 1, + &ib, + split->draw, + split->limits); + + free(elts); + } + else { + flush_vertex(split); + + vbo_split_copy(split->ctx, + split->array, + prim, 1, + split->ib, + split->draw, + split->limits); + } + } + + flush_vertex(split); +} + + +void vbo_split_inplace( 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, + vbo_draw_func draw, + const struct split_limits *limits ) +{ + struct split_context split; + + memset(&split, 0, sizeof(split)); + + split.ctx = ctx; + split.array = arrays; + split.prim = prim; + split.nr_prims = nr_prims; + split.ib = ib; + split.min_index = min_index; + split.max_index = max_index; + split.draw = draw; + split.limits = limits; + + split_prims( &split ); +} + + -- cgit v1.2.3 From 4557dfe13206495916d4ff8557f1633194a12c0f Mon Sep 17 00:00:00 2001 From: keithw Date: Mon, 15 Jan 2007 11:54:40 +0000 Subject: Add vbo_split files --- src/mesa/sources | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/mesa/sources b/src/mesa/sources index b589111a19..a32ecaf027 100644 --- a/src/mesa/sources +++ b/src/mesa/sources @@ -143,6 +143,9 @@ VBO_SOURCES = \ vbo/vbo_exec_array.c \ vbo/vbo_exec_draw.c \ vbo/vbo_exec_eval.c \ + vbo/vbo_split.c \ + vbo/vbo_split_copy.c \ + vbo/vbo_split_inplace.c \ vbo/vbo_save.c \ vbo/vbo_save_api.c \ vbo/vbo_save_draw.c \ -- cgit v1.2.3 From 1b7c24c33c43e2c0db391735b2f2ca0026459cc9 Mon Sep 17 00:00:00 2001 From: keithw Date: Mon, 15 Jan 2007 11:58:06 +0000 Subject: Hook in split functionality --- src/mesa/vbo/vbo.h | 36 ++++++++++++++++++++++++++++++++++++ src/mesa/vbo/vbo_context.h | 8 +------- 2 files changed, 37 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/mesa/vbo/vbo.h b/src/mesa/vbo/vbo.h index 80f7a3322b..c81d83f9b6 100644 --- a/src/mesa/vbo/vbo.h +++ b/src/mesa/vbo/vbo.h @@ -65,4 +65,40 @@ void _vbo_DestroyContext( GLcontext *ctx ); void _vbo_InvalidateState( GLcontext *ctx, GLuint new_state ); +typedef void (*vbo_draw_func)( GLcontext *ctx, + const struct gl_client_array **arrays, + const struct _mesa_prim *prims, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLuint min_index, + GLuint max_index ); + + + + +/* Utility function to cope with various constraints on tnl modules or + * hardware. This can be used to split an incoming set of arrays and + * primitives against the following constraints: + * - Maximum number of indices in index buffer. + * - Maximum number of vertices referenced by index buffer. + * - Maximum hardware vertex buffer size. + */ +struct split_limits { + GLuint max_verts; + GLuint max_indices; + GLuint max_vb_size; /* bytes */ +}; + + +void vbo_split_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, + vbo_draw_func draw, + const struct split_limits *limits ); + + #endif diff --git a/src/mesa/vbo/vbo_context.h b/src/mesa/vbo/vbo_context.h index 4c5ed96765..0dc1019b39 100644 --- a/src/mesa/vbo/vbo_context.h +++ b/src/mesa/vbo/vbo_context.h @@ -79,13 +79,7 @@ struct vbo_context { /* Callback into the driver. This must always succeed, the driver * is responsible for initiating any fallback actions required: */ - void (*draw_prims)( GLcontext *ctx, - const struct gl_client_array *arrays[], - const struct _mesa_prim *prims, - GLuint nr_prims, - const struct _mesa_index_buffer *ib, - GLuint min_index, - GLuint max_index ); + vbo_draw_func draw_prims; }; -- cgit v1.2.3 From 2421b25dd777ebfd614ae45907fd4af8c2713102 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 15 Jan 2007 13:40:38 +0000 Subject: Remove special-case handling for index and edgeflag This isn't required with the changes to core mesa and the new attribute layout. --- src/mesa/vbo/vbo_attrib_tmp.h | 5 +- src/mesa/vbo/vbo_exec_array.c | 6 +- src/mesa/vbo/vbo_save.h | 2 - src/mesa/vbo/vbo_save_api.c | 44 ++++-------- src/mesa/vbo/vbo_save_loopback.c | 148 ++------------------------------------- 5 files changed, 24 insertions(+), 181 deletions(-) (limited to 'src') diff --git a/src/mesa/vbo/vbo_attrib_tmp.h b/src/mesa/vbo/vbo_attrib_tmp.h index 72a8b04aca..ff11c7d59a 100644 --- a/src/mesa/vbo/vbo_attrib_tmp.h +++ b/src/mesa/vbo/vbo_attrib_tmp.h @@ -357,9 +357,10 @@ static void GLAPIENTRY TAG(VertexAttrib4fvARB)( GLuint index, } -/* Although we don't export NV_vertex_program, these entrypoints are +/* In addition to supporting NV_vertex_program, these entrypoints are * used by the display list and other code specifically because of - * their property of aliasing with other attributes. + * their property of aliasing with other attributes. (See + * vbo_save_loopback.c) */ static void GLAPIENTRY TAG(VertexAttrib1fNV)( GLuint index, GLfloat x ) { diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index 803e58c148..15fbdcf8a5 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -96,10 +96,10 @@ static void bind_array_obj( GLcontext *ctx ) exec->array.legacy_array[VERT_ATTRIB_COLOR1] = &ctx->Array.ArrayObj->SecondaryColor; exec->array.legacy_array[VERT_ATTRIB_FOG] = &ctx->Array.ArrayObj->FogCoord; exec->array.legacy_array[VERT_ATTRIB_COLOR_INDEX] = &ctx->Array.ArrayObj->Index; - exec->array.legacy_array[VBO_ATTRIB_EDGEFLAG] = &ctx->Array.ArrayObj->EdgeFlag; + exec->array.legacy_array[VERT_ATTRIB_EDGEFLAG] = &ctx->Array.ArrayObj->EdgeFlag; for (i = 0; i < 8; i++) - exec->array.legacy_array[VBO_ATTRIB_TEX0 + i] = &ctx->Array.ArrayObj->TexCoord[i]; + exec->array.legacy_array[VERT_ATTRIB_TEX0 + i] = &ctx->Array.ArrayObj->TexCoord[i]; for (i = 0; i < VERT_ATTRIB_MAX; i++) exec->array.generic_array[i] = &ctx->Array.ArrayObj->VertexAttrib[i]; @@ -117,8 +117,6 @@ static void recalculate_input_bindings( GLcontext *ctx ) exec->array.program_mode = get_program_mode(ctx); exec->array.enabled_flags = ctx->Array.ArrayObj->_Enabled; - /* TODO: Get rid of NV_program (please!). - */ switch (exec->array.program_mode) { case VP_NONE: /* When no vertex program is active, we put the material values diff --git a/src/mesa/vbo/vbo_save.h b/src/mesa/vbo/vbo_save.h index 3051f5c59a..b81f275a60 100644 --- a/src/mesa/vbo/vbo_save.h +++ b/src/mesa/vbo/vbo_save.h @@ -142,8 +142,6 @@ struct vbo_save_context { struct vbo_save_copied_vtx copied; - GLfloat CurrentFloatEdgeFlag; - GLfloat *current[VBO_ATTRIB_MAX]; /* points into ctx->ListState */ GLubyte *currentsz[VBO_ATTRIB_MAX]; }; diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c index efe018b09e..f339436f84 100644 --- a/src/mesa/vbo/vbo_save_api.c +++ b/src/mesa/vbo/vbo_save_api.c @@ -415,26 +415,14 @@ static void _save_copy_to_current( GLcontext *ctx ) struct vbo_save_context *save = &vbo_context(ctx)->save; GLuint i; - for (i = VBO_ATTRIB_POS+1 ; i <= VBO_ATTRIB_INDEX ; i++) { + for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) { if (save->attrsz[i]) { save->currentsz[i][0] = save->attrsz[i]; COPY_CLEAN_4V(save->current[i], - save->attrsz[i], - save->attrptr[i]); + save->attrsz[i], + save->attrptr[i]); } } - - /* Edgeflag requires special treatment: - * - * TODO: change edgeflag to GLfloat in Mesa. - */ - if (save->attrsz[VBO_ATTRIB_EDGEFLAG]) { - ctx->ListState.ActiveEdgeFlag = 1; - save->CurrentFloatEdgeFlag = - save->attrptr[VBO_ATTRIB_EDGEFLAG][0]; - ctx->ListState.CurrentEdgeFlag = - (save->CurrentFloatEdgeFlag == 1.0); - } } @@ -443,7 +431,7 @@ static void _save_copy_from_current( GLcontext *ctx ) struct vbo_save_context *save = &vbo_context(ctx)->save; GLint i; - for (i = VBO_ATTRIB_POS+1 ; i <= VBO_ATTRIB_INDEX ; i++) + for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) { switch (save->attrsz[i]) { case 4: save->attrptr[i][3] = save->current[i][3]; case 3: save->attrptr[i][2] = save->current[i][2]; @@ -451,12 +439,6 @@ static void _save_copy_from_current( GLcontext *ctx ) case 1: save->attrptr[i][0] = save->current[i][0]; case 0: break; } - - /* Edgeflag requires special treatment: - */ - if (save->attrsz[VBO_ATTRIB_EDGEFLAG]) { - save->CurrentFloatEdgeFlag = (GLfloat)ctx->ListState.CurrentEdgeFlag; - save->attrptr[VBO_ATTRIB_EDGEFLAG][0] = save->CurrentFloatEdgeFlag; } } @@ -616,6 +598,8 @@ do { \ if (save->active_sz[A] != N) \ save_fixup_vertex(ctx, A, N); \ \ + _mesa_printf("Attr %d, sz %d: %f %f %f %f\n", A, N, V0, V1, V2, V3 ); \ + \ { \ GLfloat *dest = save->attrptr[A]; \ if (N>0) dest[0] = V0; \ @@ -1106,23 +1090,19 @@ static void _save_current_init( GLcontext *ctx ) struct vbo_save_context *save = &vbo_context(ctx)->save; GLint i; - for (i = 0; i < VBO_ATTRIB_FIRST_MATERIAL; i++) { - save->currentsz[i] = &ctx->ListState.ActiveAttribSize[i]; - save->current[i] = ctx->ListState.CurrentAttrib[i]; + for (i = VBO_ATTRIB_POS; i <= VBO_ATTRIB_GENERIC15; i++) { + const GLuint j = i - VBO_ATTRIB_POS; + ASSERT(j < VERT_ATTRIB_MAX); + save->currentsz[i] = &ctx->ListState.ActiveAttribSize[j]; + save->current[i] = ctx->ListState.CurrentAttrib[j]; } - for (i = VBO_ATTRIB_FIRST_MATERIAL; i < VBO_ATTRIB_INDEX; i++) { + for (i = VBO_ATTRIB_FIRST_MATERIAL; i <= VBO_ATTRIB_MAT_FRONT_AMBIENT; i++) { const GLuint j = i - VBO_ATTRIB_FIRST_MATERIAL; ASSERT(j < MAT_ATTRIB_MAX); save->currentsz[i] = &ctx->ListState.ActiveMaterialSize[j]; save->current[i] = ctx->ListState.CurrentMaterial[j]; } - - save->currentsz[VBO_ATTRIB_INDEX] = &ctx->ListState.ActiveIndex; - save->current[VBO_ATTRIB_INDEX] = &ctx->ListState.CurrentIndex; - - save->currentsz[VBO_ATTRIB_EDGEFLAG] = &ctx->ListState.ActiveEdgeFlag; - save->current[VBO_ATTRIB_EDGEFLAG] = &save->CurrentFloatEdgeFlag; } /** diff --git a/src/mesa/vbo/vbo_save_loopback.c b/src/mesa/vbo/vbo_save_loopback.c index 941c4beea9..2c28126cab 100644 --- a/src/mesa/vbo/vbo_save_loopback.c +++ b/src/mesa/vbo/vbo_save_loopback.c @@ -44,7 +44,9 @@ typedef void (*attr_func)( GLcontext *ctx, GLint target, const GLfloat * ); -/* Wrapper functions in case glVertexAttrib*fvNV doesn't exist */ +/* This file makes heavy use of the aliasing of NV vertex attributes + * with the legacy attributes. + */ static void VertexAttrib1fvNV(GLcontext *ctx, GLint target, const GLfloat *v) { CALL_VertexAttrib1fvNV(ctx->Exec, (target, v)); @@ -72,118 +74,6 @@ static attr_func vert_attrfunc[4] = { VertexAttrib4fvNV }; -#if 0 -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 -}; -#endif - - - - - - -static void mat_attr1fv( GLcontext *ctx, GLint target, const GLfloat *v ) -{ - switch (target) { - case VBO_ATTRIB_MAT_FRONT_SHININESS: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_SHININESS, v )); - break; - case VBO_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 VBO_ATTRIB_MAT_FRONT_INDEXES: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_COLOR_INDEXES, v )); - break; - case VBO_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 VBO_ATTRIB_MAT_FRONT_EMISSION: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_EMISSION, v )); - break; - case VBO_ATTRIB_MAT_BACK_EMISSION: - CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_EMISSION, v )); - break; - case VBO_ATTRIB_MAT_FRONT_AMBIENT: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_AMBIENT, v )); - break; - case VBO_ATTRIB_MAT_BACK_AMBIENT: - CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_AMBIENT, v )); - break; - case VBO_ATTRIB_MAT_FRONT_DIFFUSE: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_DIFFUSE, v )); - break; - case VBO_ATTRIB_MAT_BACK_DIFFUSE: - CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_DIFFUSE, v )); - break; - case VBO_ATTRIB_MAT_FRONT_SPECULAR: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_SPECULAR, v )); - break; - case VBO_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 index_attr1fv(GLcontext *ctx, GLint target, const GLfloat *v) -{ - (void) target; - CALL_Indexf(ctx->Exec, (v[0])); -} - -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; @@ -277,7 +167,10 @@ void vbo_loopback_vertex_list( GLcontext *ctx, struct loopback_attr la[VBO_ATTRIB_MAX]; GLuint i, nr = 0; - for (i = 0 ; i <= VBO_ATTRIB_TEX7 ; i++) { + /* All Legacy, NV, ARB and Material attributes are routed through + * the NV attributes entrypoints: + */ + for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) { if (attrsz[i]) { la[nr].target = i; la[nr].sz = attrsz[i]; @@ -286,33 +179,6 @@ void vbo_loopback_vertex_list( GLcontext *ctx, } } - for (i = VBO_ATTRIB_MAT_FRONT_AMBIENT ; - i <= VBO_ATTRIB_MAT_BACK_INDEXES ; - i++) { - if (attrsz[i]) { - la[nr].target = i; - la[nr].sz = attrsz[i]; - la[nr].func = mat_attrfunc[attrsz[i]-1]; - nr++; - } - } - - if (attrsz[VBO_ATTRIB_EDGEFLAG]) { - la[nr].target = VBO_ATTRIB_EDGEFLAG; - la[nr].sz = attrsz[VBO_ATTRIB_EDGEFLAG]; - la[nr].func = edgeflag_attr1fv; - nr++; - } - - if (attrsz[VBO_ATTRIB_INDEX]) { - la[nr].target = VBO_ATTRIB_INDEX; - la[nr].sz = attrsz[VBO_ATTRIB_INDEX]; - la[nr].func = index_attr1fv; - nr++; - } - - /* XXX ARB vertex attribs */ - for (i = 0 ; i < prim_count ; i++) { if ((prim[i].mode & VBO_SAVE_PRIM_WEAK) && (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END)) -- cgit v1.2.3 From 5464cd0a60f474753abc6af047fd21b0e29b8ac4 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 15 Jan 2007 13:54:08 +0000 Subject: Split too-large draw commands. Use the vbo_split_ functionality to split incoming drawing command to fit within the fixed-size buffers used by software t&l module. --- src/mesa/tnl/t_draw.c | 128 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 102 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/mesa/tnl/t_draw.c b/src/mesa/tnl/t_draw.c index 0f9615e7cc..25b8708948 100644 --- a/src/mesa/tnl/t_draw.c +++ b/src/mesa/tnl/t_draw.c @@ -32,6 +32,7 @@ #include "state.h" #include "mtypes.h" #include "macros.h" +#include "enums.h" #include "t_context.h" #include "t_pipeline.h" @@ -182,7 +183,7 @@ static GLboolean *_tnl_import_edgeflag( GLcontext *ctx, static void bind_inputs( GLcontext *ctx, const struct gl_client_array *inputs[], - GLint start, GLint end, + GLint min_index, GLint max_index, struct gl_buffer_object **bo, GLuint *nr_bo ) { @@ -214,15 +215,20 @@ static void bind_inputs( GLcontext *ctx, ptr = inputs[i]->Ptr; /* Just make sure the array is floating point, otherwise convert to - * temporary storage. Rebase arrays so that 'start' becomes + * temporary storage. Rebase arrays so that 'min_index' becomes * element zero. * * XXX: remove the GLvector4f type at some stage and just use * client arrays. */ - _tnl_import_array(ctx, i, start, end, inputs[i], ptr); + _tnl_import_array(ctx, i, min_index, max_index, inputs[i], ptr); } + /* We process only the vertices between min & max index: + */ + VB->Count = max_index - min_index; + + /* Legacy pointers -- remove one day. */ VB->ObjPtr = VB->AttribPtr[_TNL_ATTRIB_POS]; @@ -256,10 +262,11 @@ static void bind_inputs( GLcontext *ctx, /* Translate indices to GLuints and store in VB->Elts. */ -static void bind_indicies( GLcontext *ctx, - const struct _mesa_index_buffer *ib, - struct gl_buffer_object **bo, - GLuint *nr_bo) +static void bind_indices( GLcontext *ctx, + const struct _mesa_index_buffer *ib, + GLuint min_index, + struct gl_buffer_object **bo, + GLuint *nr_bo) { TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; @@ -282,7 +289,7 @@ static void bind_indicies( GLcontext *ctx, ptr = ADD_POINTERS(ib->obj->Pointer, ib->ptr); - if (ib->type == GL_UNSIGNED_INT) { + if (ib->type == GL_UNSIGNED_INT && min_index == 0) { VB->Elts = (GLuint *) ptr; VB->Elts += ib->rebase; } @@ -291,22 +298,54 @@ static void bind_indicies( GLcontext *ctx, VB->Elts = elts; switch (ib->type) { + case GL_UNSIGNED_INT: { + const GLuint *in = ((GLuint *)ptr) + ib->rebase; + for (i = 0; i < ib->count; i++) + *elts++ = *in++ - min_index; + break; + } case GL_UNSIGNED_SHORT: { const GLushort *in = ((GLushort *)ptr) + ib->rebase; for (i = 0; i < ib->count; i++) - *elts++ = *in++; + *elts++ = (GLuint)(*in++) - min_index; break; } case GL_UNSIGNED_BYTE: { const GLubyte *in = ((GLubyte *)ptr) + ib->rebase; for (i = 0; i < ib->count; i++) - *elts++ = *in++; + *elts++ = (GLuint)(*in++) - min_index; break; } } } } +static void bind_prims( GLcontext *ctx, + const struct _mesa_prim *prim, + GLuint nr_prims, + GLuint min_index ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint i; + + if (min_index != 0) { + struct _mesa_prim *tmp = (struct _mesa_prim *)get_space(ctx, nr_prims * sizeof(*prim)); + + for (i = 0; i < nr_prims; i++) { + tmp[i] = prim[i]; + tmp[i].start -= min_index; + } + + VB->Primitive = tmp; + } + else { + VB->Primitive = prim; + } + + VB->PrimitiveCount = nr_prims; +} + static void unmap_vbos( GLcontext *ctx, struct gl_buffer_object **bo, GLuint nr_bo ) @@ -335,26 +374,63 @@ void _tnl_draw_prims( GLcontext *ctx, { TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; + GLint max = VB->Size; + GLuint i; - /* May need to map a vertex buffer object for every attribute plus - * one for the index buffer. - */ - struct gl_buffer_object *bo[VERT_ATTRIB_MAX + 1]; - GLuint nr_bo = 0; - - /* Binding inputs may imply mapping some vertex buffer objects. - * They will need to be unmapped below. +#ifdef TEST_SPLIT + max = 8 + MAX_CLIPPED_VERTICES; +#endif + + assert(max_index > min_index); + assert(!(max_index & 0x80000000)); + + VB->Elts = NULL; + +#if 0 + _mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index); + for (i = 0; i < nr_prims; i++) + _mesa_printf("prim %d: %s start %d count %d\n", i, + _mesa_lookup_enum_by_nr(prim[i].mode), + prim[i].start, + prim[i].count); +#endif + + /* The software TNL pipeline has a fixed amount of storage for + * vertices and it is necessary to split incoming drawing commands + * if they exceed that limit. */ - bind_inputs(ctx, arrays, min_index, max_index, bo, &nr_bo); - bind_indicies(ctx, ib, bo, &nr_bo); + if (max_index - min_index >= max - MAX_CLIPPED_VERTICES) { + struct split_limits limits; + limits.max_verts = max - MAX_CLIPPED_VERTICES; + limits.max_vb_size = ~0; + limits.max_indices = ~0; + + /* This will split the buffers one way or another and + * recursively call back into this function. + */ + vbo_split_prims( ctx, arrays, prim, nr_prims, ib, + min_index, max_index, + _tnl_draw_prims, + &limits ); + } + else { + /* May need to map a vertex buffer object for every attribute plus + * one for the index buffer. + */ + struct gl_buffer_object *bo[VERT_ATTRIB_MAX + 1]; + GLuint nr_bo = 0; - VB->Primitive = prim; - VB->PrimitiveCount = nr_prims; - VB->Count = max_index - min_index; + /* Binding inputs may imply mapping some vertex buffer objects. + * They will need to be unmapped below. + */ + bind_inputs(ctx, arrays, min_index, max_index+1, bo, &nr_bo); + bind_indices(ctx, ib, min_index, bo, &nr_bo); + bind_prims(ctx, prim, nr_prims, VB->Elts ? 0 : min_index ); - TNL_CONTEXT(ctx)->Driver.RunPipeline(ctx); + TNL_CONTEXT(ctx)->Driver.RunPipeline(ctx); - unmap_vbos(ctx, bo, nr_bo); - free_space(ctx); + unmap_vbos(ctx, bo, nr_bo); + free_space(ctx); + } } -- cgit v1.2.3 From 82152a2a8e1afeb61710318e769b1379be6c02c6 Mon Sep 17 00:00:00 2001 From: keithw Date: Mon, 15 Jan 2007 14:10:42 +0000 Subject: Remove debug, reenable inplace splitting. --- src/mesa/tnl/t_draw.c | 16 +++++++++------- src/mesa/vbo/vbo_save_api.c | 2 -- src/mesa/vbo/vbo_save_loopback.c | 3 ++- src/mesa/vbo/vbo_split_inplace.c | 16 +--------------- 4 files changed, 12 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/mesa/tnl/t_draw.c b/src/mesa/tnl/t_draw.c index 25b8708948..0e7c2b6a68 100644 --- a/src/mesa/tnl/t_draw.c +++ b/src/mesa/tnl/t_draw.c @@ -375,7 +375,6 @@ void _tnl_draw_prims( GLcontext *ctx, TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; GLint max = VB->Size; - GLuint i; #ifdef TEST_SPLIT max = 8 + MAX_CLIPPED_VERTICES; @@ -387,12 +386,15 @@ void _tnl_draw_prims( GLcontext *ctx, VB->Elts = NULL; #if 0 - _mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index); - for (i = 0; i < nr_prims; i++) - _mesa_printf("prim %d: %s start %d count %d\n", i, - _mesa_lookup_enum_by_nr(prim[i].mode), - prim[i].start, - prim[i].count); + { + GLuint i; + _mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index); + for (i = 0; i < nr_prims; i++) + _mesa_printf("prim %d: %s start %d count %d\n", i, + _mesa_lookup_enum_by_nr(prim[i].mode), + prim[i].start, + prim[i].count); + } #endif /* The software TNL pipeline has a fixed amount of storage for diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c index f339436f84..ade48d220e 100644 --- a/src/mesa/vbo/vbo_save_api.c +++ b/src/mesa/vbo/vbo_save_api.c @@ -598,8 +598,6 @@ do { \ if (save->active_sz[A] != N) \ save_fixup_vertex(ctx, A, N); \ \ - _mesa_printf("Attr %d, sz %d: %f %f %f %f\n", A, N, V0, V1, V2, V3 ); \ - \ { \ GLfloat *dest = save->attrptr[A]; \ if (N>0) dest[0] = V0; \ diff --git a/src/mesa/vbo/vbo_save_loopback.c b/src/mesa/vbo/vbo_save_loopback.c index 2c28126cab..430333b84d 100644 --- a/src/mesa/vbo/vbo_save_loopback.c +++ b/src/mesa/vbo/vbo_save_loopback.c @@ -45,7 +45,8 @@ typedef void (*attr_func)( GLcontext *ctx, GLint target, const GLfloat * ); /* This file makes heavy use of the aliasing of NV vertex attributes - * with the legacy attributes. + * with the legacy attributes, and also with ARB and Material + * attributes as currently implemented. */ static void VertexAttrib1fvNV(GLcontext *ctx, GLint target, const GLfloat *v) { diff --git a/src/mesa/vbo/vbo_split_inplace.c b/src/mesa/vbo/vbo_split_inplace.c index 66c94aceaa..d3649c59db 100644 --- a/src/mesa/vbo/vbo_split_inplace.c +++ b/src/mesa/vbo/vbo_split_inplace.c @@ -49,9 +49,6 @@ struct split_context { const struct split_limits *limits; -/* GLuint out_maxindex; */ -/* GLuint out_minindex; */ - struct _mesa_prim dstprim[MAX_PRIM]; GLuint dstprim_nr; }; @@ -151,13 +148,6 @@ static void split_prims( struct split_context *split) GLuint available = align(split->limits->max_verts - csr - 1, 2); assert(split->limits->max_verts >= csr); - _mesa_printf("%s: prim %d: %s %d..%d\n", __FUNCTION__, - i, - _mesa_lookup_enum_by_nr(prim->mode), - prim->start, prim->count); - - _mesa_printf("a: available %d\n", available); - if (prim->count < first) continue; @@ -171,15 +161,13 @@ static void split_prims( struct split_context *split) available = align(split->limits->max_verts - csr - 1, 2); } - _mesa_printf("b: available %d\n", available); - if (available >= count) { struct _mesa_prim *outprim = next_outprim(split); *outprim = *prim; csr += prim->count; available = align(split->limits->max_verts - csr - 1, 2); } - else if (0 && split_inplace) { + else if (split_inplace) { GLuint j, nr; @@ -207,8 +195,6 @@ static void split_prims( struct split_context *split) else { /* Wrapped the primitive: */ - _mesa_printf("wrap %d %d\n", nr, first-incr); - j += nr - (first - incr); flush_vertex(split); csr = 0; -- cgit v1.2.3 From 50f76b9d9b4b17940798b44233b9b5af2f932117 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 15 Jan 2007 14:20:21 +0000 Subject: Correctly initialize current attribute sizes. Some legacy attributes (eg color) have an initial value other than {0,0,0,1} which means that their initial size != 1 either. --- src/mesa/vbo/vbo_context.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/vbo/vbo_context.c b/src/mesa/vbo/vbo_context.c index 165e32da8a..65998e7ff7 100644 --- a/src/mesa/vbo/vbo_context.c +++ b/src/mesa/vbo/vbo_context.c @@ -47,6 +47,14 @@ extern void _tnl_draw_prims( GLcontext *ctx, #define NR_GENERIC_ATTRIBS 16 #define NR_MAT_ATTRIBS 12 +static GLuint check_size( const GLfloat *attr ) +{ + if (attr[3] != 1.0) return 4; + if (attr[2] != 0.0) return 3; + if (attr[1] != 0.0) return 2; + return 1; +} + static void init_legacy_currval(GLcontext *ctx) { struct vbo_context *vbo = vbo_context(ctx); @@ -63,7 +71,7 @@ static void init_legacy_currval(GLcontext *ctx) /* Size will have to be determined at runtime: */ - cl->Size = 1; + cl->Size = check_size(ctx->Current.Attrib[i]); cl->Stride = 0; cl->StrideB = 0; cl->Enabled = 1; @@ -88,7 +96,6 @@ static void init_generic_currval(GLcontext *ctx) /* This will have to be determined at runtime: */ cl->Size = 1; - cl->Type = GL_FLOAT; cl->Ptr = (const void *)ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + i]; cl->Stride = 0; -- cgit v1.2.3 From 6ff9b48fe2bb2113689e45c89a7c643e44906d67 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 15 Jan 2007 14:30:16 +0000 Subject: Don't special-case FOG attribute initialization. Initial fog value was being set to {0,0,0,0}. This results in vector size 4, but isn't necessary. The regular {0,0,0,1} works fine. --- src/mesa/main/context.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 91f3af3c91..94d0ff6307 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -970,7 +970,6 @@ _mesa_init_current( GLcontext *ctx ) ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], 0.0, 0.0, 1.0, 1.0 ); ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 ); ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 1.0 ); - ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_FOG], 0.0, 0.0, 0.0, 0.0 ); ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX], 1.0, 0.0, 0.0, 1.0 ); ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG], 1.0, 0.0, 0.0, 1.0 ); } -- cgit v1.2.3 From 584def75ad8dd13add5b4ed7e364d13202539539 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 15 Jan 2007 16:57:01 +0000 Subject: Remove unused index buffer. --- src/mesa/vbo/vbo_exec.h | 3 --- src/mesa/vbo/vbo_exec_array.c | 8 +------- 2 files changed, 1 insertion(+), 10 deletions(-) (limited to 'src') diff --git a/src/mesa/vbo/vbo_exec.h b/src/mesa/vbo/vbo_exec.h index e28913b22a..a9b01e08e6 100644 --- a/src/mesa/vbo/vbo_exec.h +++ b/src/mesa/vbo/vbo_exec.h @@ -130,9 +130,6 @@ struct vbo_exec_context * programs: */ const struct gl_client_array *inputs[VERT_ATTRIB_MAX]; - - - struct gl_buffer_object *index_obj; } array; }; diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index 15fbdcf8a5..cec353cf43 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -360,8 +360,6 @@ vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *ind void vbo_exec_array_init( struct vbo_exec_context *exec ) { - GLcontext *ctx = exec->ctx; - #if 1 exec->vtxfmt.DrawArrays = vbo_exec_DrawArrays; exec->vtxfmt.DrawElements = vbo_exec_DrawElements; @@ -371,14 +369,10 @@ void vbo_exec_array_init( struct vbo_exec_context *exec ) exec->vtxfmt.DrawElements = _mesa_noop_DrawElements; exec->vtxfmt.DrawRangeElements = _mesa_noop_DrawRangeElements; #endif - - exec->array.index_obj = ctx->Driver.NewBufferObject(ctx, 1, GL_ARRAY_BUFFER_ARB); } void vbo_exec_array_destroy( struct vbo_exec_context *exec ) { - GLcontext *ctx = exec->ctx; - - ctx->Driver.DeleteBuffer(ctx, exec->array.index_obj); + /* nothing to do */ } -- cgit v1.2.3 From 7520478eb055350702d09e533db02258187d8c74 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Mon, 15 Jan 2007 18:58:24 +0100 Subject: nouveau:nv10: fix setting clip region --- src/mesa/drivers/dri/nouveau/nv10_state.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index dbd8bf306e..0e912e73ff 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -618,8 +618,10 @@ static void nv10WindowMoved(nouveauContextPtr nmesa) OUT_RING_CACHE(((h+y) << 16) | y | 0x800); for (i=1; i<7; i++) { BEGIN_RING_CACHE(NvSub3D, - NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 2); + NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 1); OUT_RING_CACHE(0); + BEGIN_RING_CACHE(NvSub3D, + NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(i), 1); OUT_RING_CACHE(0); } -- cgit v1.2.3 From a03fc8277180e2171519165a724849e2254ef0b7 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Mon, 15 Jan 2007 21:19:52 +0100 Subject: mesa: Update _Current along Current on fragment program bound. Same as a previously committed patch for vertex program, we update fragment program ptr _Current along the Current one so that _Current can't end up pointing to a no more valid program. --- src/mesa/shader/program.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index 6db62f591c..8442ba3248 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -1953,6 +1953,8 @@ _mesa_BindProgram(GLenum target, GLuint id) } else if (target == GL_FRAGMENT_PROGRAM_NV || target == GL_FRAGMENT_PROGRAM_ARB) { + if (ctx->FragmentProgram._Current == ctx->FragmentProgram.Current) + ctx->FragmentProgram._Current = (struct gl_fragment_program *) newProg; ctx->FragmentProgram.Current = (struct gl_fragment_program *) newProg; } newProg->RefCount++; -- cgit v1.2.3 From 3ad12fab454bc27334c8261780a1679da7d41cb1 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 16 Jan 2007 11:24:08 +0000 Subject: Merge vbo_0_1_branch Hopefully leaving behind the cruft generated by the CVS import. --- src/mesa/array_cache/sources | 7 - src/mesa/tnl/t_save_api.c | 1741 ---------------------------------------- src/mesa/tnl/t_save_playback.c | 216 ----- src/mesa/tnl/t_vtx_api.c | 1046 ------------------------ src/mesa/tnl/t_vtx_exec.c | 293 ------- 5 files changed, 3303 deletions(-) delete mode 100644 src/mesa/array_cache/sources delete mode 100644 src/mesa/tnl/t_save_api.c delete mode 100644 src/mesa/tnl/t_save_playback.c delete mode 100644 src/mesa/tnl/t_vtx_api.c delete mode 100644 src/mesa/tnl/t_vtx_exec.c (limited to 'src') diff --git a/src/mesa/array_cache/sources b/src/mesa/array_cache/sources deleted file mode 100644 index fb3328d10e..0000000000 --- a/src/mesa/array_cache/sources +++ /dev/null @@ -1,7 +0,0 @@ -MESA_ARRAY_CACHE_SOURCES = \ -ac_context.c \ -ac_import.c - -MESA_ARRAY_CACHE_HEADERS = \ -ac_context.h \ -acache.h diff --git a/src/mesa/tnl/t_save_api.c b/src/mesa/tnl/t_save_api.c deleted file mode 100644 index dbbd095fe4..0000000000 --- a/src/mesa/tnl/t_save_api.c +++ /dev/null @@ -1,1741 +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 - */ - - - -/** - * The display list compiler attempts to store lists of vertices with the - * same vertex layout. Additionally it attempts to minimize the need - * for execute-time fixup of these vertex lists, allowing them to be - * cached on hardware. - * - * There are still some circumstances where this can be thwarted, for - * example by building a list that consists of one very long primitive - * (eg Begin(Triangles), 1000 vertices, End), and calling that list - * from inside a different begin/end object (Begin(Lines), CallList, - * End). - * - * In that case the code will have to replay the list as individual - * commands through the Exec dispatch table, or fix up the copied - * vertices at execute-time. - * - * The other case where fixup is required is when a vertex attribute - * is introduced in the middle of a primitive. Eg: - * Begin(Lines) - * TexCoord1f() Vertex2f() - * TexCoord1f() Color3f() Vertex2f() - * End() - * - * If the current value of Color isn't known at compile-time, this - * primitive will require fixup. - * - * - * The list compiler currently doesn't attempt to compile lists - * containing EvalCoord or EvalPoint commands. On encountering one of - * these, compilation falls back to opcodes. - * - * This could be improved to fallback only when a mix of EvalCoord and - * Vertex commands are issued within a single primitive. - */ - - -#include "glheader.h" -#include "context.h" -#include "dlist.h" -#include "enums.h" -#include "macros.h" -#include "api_validate.h" -#include "api_arrayelt.h" -#include "vtxfmt.h" -#include "t_save_api.h" -#include "dispatch.h" - -/* - * NOTE: Old 'parity' issue is gone, but copying can still be - * wrong-footed on replay. - */ -static GLuint _save_copy_vertices( GLcontext *ctx, - const struct tnl_vertex_list *node ) -{ - TNLcontext *tnl = TNL_CONTEXT( ctx ); - const struct tnl_prim *prim = &node->prim[node->prim_count-1]; - GLuint nr = prim->count; - GLuint sz = tnl->save.vertex_size; - const GLfloat *src = node->buffer + prim->start * sz; - GLfloat *dst = tnl->save.copied.buffer; - GLuint ovf, i; - - if (prim->mode & PRIM_END) - return 0; - - switch( prim->mode & PRIM_MODE_MASK ) - { - 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; - default: - assert(0); - return 0; - } -} - - -static void -build_normal_lengths( struct tnl_vertex_list *node ) -{ - GLuint i; - GLfloat *len; - GLfloat *n = node->buffer; - GLuint stride = node->vertex_size; - GLuint count = node->count; - - len = node->normal_lengths = (GLfloat *) MALLOC( count * sizeof(GLfloat) ); - if (!len) - return; - - /* Find the normal of the first vertex: - */ - for (i = 0 ; i < _TNL_ATTRIB_NORMAL ; i++) - n += node->attrsz[i]; - - for (i = 0 ; i < count ; i++, n += stride) { - len[i] = LEN_3FV( n ); - if (len[i] > 0.0F) len[i] = 1.0F / len[i]; - } -} - -static struct tnl_vertex_store *alloc_vertex_store( GLcontext *ctx ) -{ - struct tnl_vertex_store *store = MALLOC_STRUCT(tnl_vertex_store); - (void) ctx; - store->used = 0; - store->refcount = 1; - return store; -} - -static struct tnl_primitive_store *alloc_prim_store( GLcontext *ctx ) -{ - struct tnl_primitive_store *store = MALLOC_STRUCT(tnl_primitive_store); - (void) ctx; - store->used = 0; - store->refcount = 1; - return store; -} - -static void _save_reset_counters( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - - tnl->save.prim = tnl->save.prim_store->buffer + tnl->save.prim_store->used; - tnl->save.buffer = (tnl->save.vertex_store->buffer + - tnl->save.vertex_store->used); - - if (tnl->save.vertex_size) - tnl->save.initial_counter = ((SAVE_BUFFER_SIZE - - tnl->save.vertex_store->used) / - tnl->save.vertex_size); - else - tnl->save.initial_counter = 0; - - if (tnl->save.initial_counter > ctx->Const.MaxArrayLockSize ) - tnl->save.initial_counter = ctx->Const.MaxArrayLockSize; - - tnl->save.counter = tnl->save.initial_counter; - tnl->save.prim_count = 0; - tnl->save.prim_max = SAVE_PRIM_SIZE - tnl->save.prim_store->used; - tnl->save.copied.nr = 0; - tnl->save.dangling_attr_ref = 0; -} - - -/* Insert the active immediate struct onto the display list currently - * being built. - */ -static void _save_compile_vertex_list( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct tnl_vertex_list *node; - - /* Allocate space for this structure in the display list currently - * being compiled. - */ - node = (struct tnl_vertex_list *) - _mesa_alloc_instruction(ctx, tnl->save.opcode_vertex_list, sizeof(*node)); - - if (!node) - return; - - /* Duplicate our template, increment refcounts to the storage structs: - */ - _mesa_memcpy(node->attrsz, tnl->save.attrsz, sizeof(node->attrsz)); - node->vertex_size = tnl->save.vertex_size; - node->buffer = tnl->save.buffer; - node->count = tnl->save.initial_counter - tnl->save.counter; - node->wrap_count = tnl->save.copied.nr; - node->have_materials = tnl->save.have_materials; - node->dangling_attr_ref = tnl->save.dangling_attr_ref; - node->normal_lengths = NULL; - node->prim = tnl->save.prim; - node->prim_count = tnl->save.prim_count; - node->vertex_store = tnl->save.vertex_store; - node->prim_store = tnl->save.prim_store; - - node->vertex_store->refcount++; - node->prim_store->refcount++; - - assert(node->attrsz[_TNL_ATTRIB_POS] != 0 || - node->count == 0); - - if (tnl->save.dangling_attr_ref) - ctx->ListState.CurrentList->flags |= MESA_DLIST_DANGLING_REFS; - - /* Maybe calculate normal lengths: - */ - if (tnl->CalcDListNormalLengths && - node->attrsz[_TNL_ATTRIB_NORMAL] == 3 && - !(ctx->ListState.CurrentList->flags & MESA_DLIST_DANGLING_REFS)) - build_normal_lengths( node ); - - - tnl->save.vertex_store->used += tnl->save.vertex_size * node->count; - tnl->save.prim_store->used += node->prim_count; - - /* Decide whether the storage structs are full, or can be used for - * the next vertex lists as well. - */ - if (tnl->save.vertex_store->used > - SAVE_BUFFER_SIZE - 16 * (tnl->save.vertex_size + 4)) { - - tnl->save.vertex_store->refcount--; - assert(tnl->save.vertex_store->refcount != 0); - tnl->save.vertex_store = alloc_vertex_store( ctx ); - tnl->save.vbptr = tnl->save.vertex_store->buffer; - } - - if (tnl->save.prim_store->used > SAVE_PRIM_SIZE - 6) { - tnl->save.prim_store->refcount--; - assert(tnl->save.prim_store->refcount != 0); - tnl->save.prim_store = alloc_prim_store( ctx ); - } - - /* Reset our structures for the next run of vertices: - */ - _save_reset_counters( ctx ); - - /* Copy duplicated vertices - */ - tnl->save.copied.nr = _save_copy_vertices( ctx, node ); - - - /* Deal with GL_COMPILE_AND_EXECUTE: - */ - if (ctx->ExecuteFlag) { - _tnl_playback_vertex_list( ctx, (void *) node ); - } -} - - -/* TODO -- If no new vertices have been stored, don't bother saving - * it. - */ -static void _save_wrap_buffers( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLint i = tnl->save.prim_count - 1; - GLenum mode; - - assert(i < (GLint) tnl->save.prim_max); - assert(i >= 0); - - /* Close off in-progress primitive. - */ - tnl->save.prim[i].count = ((tnl->save.initial_counter - tnl->save.counter) - - tnl->save.prim[i].start); - mode = tnl->save.prim[i].mode & ~(PRIM_BEGIN|PRIM_END); - - /* store the copied vertices, and allocate a new list. - */ - _save_compile_vertex_list( ctx ); - - /* Restart interrupted primitive - */ - tnl->save.prim[0].mode = mode; - tnl->save.prim[0].start = 0; - tnl->save.prim[0].count = 0; - tnl->save.prim_count = 1; -} - - - -/* Called only when buffers are wrapped as the result of filling the - * vertex_store struct. - */ -static void _save_wrap_filled_vertex( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLfloat *data = tnl->save.copied.buffer; - GLuint i; - - /* Emit a glEnd to close off the last vertex list. - */ - _save_wrap_buffers( ctx ); - - /* Copy stored stored vertices to start of new list. - */ - assert(tnl->save.counter > tnl->save.copied.nr); - - for (i = 0 ; i < tnl->save.copied.nr ; i++) { - _mesa_memcpy( tnl->save.vbptr, data, tnl->save.vertex_size * sizeof(GLfloat)); - data += tnl->save.vertex_size; - tnl->save.vbptr += tnl->save.vertex_size; - tnl->save.counter--; - } -} - - -static void _save_copy_to_current( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint i; - - /* XXX Use _TNL_FIRST_* and _TNL_LAST_* values instead? */ - for (i = _TNL_ATTRIB_POS+1 ; i <= _TNL_ATTRIB_EDGEFLAG ; i++) { - if (tnl->save.attrsz[i]) { - tnl->save.currentsz[i][0] = tnl->save.attrsz[i]; - COPY_CLEAN_4V(tnl->save.current[i], - tnl->save.attrsz[i], - tnl->save.attrptr[i]); - } - } - - /* Edgeflag requires special treatment: - * - * TODO: change edgeflag to GLfloat in Mesa. - */ - if (tnl->save.attrsz[_TNL_ATTRIB_EDGEFLAG]) { - ctx->ListState.ActiveEdgeFlag = 1; - tnl->save.CurrentFloatEdgeFlag = - tnl->save.attrptr[_TNL_ATTRIB_EDGEFLAG][0]; - ctx->ListState.CurrentEdgeFlag = - (tnl->save.CurrentFloatEdgeFlag == 1.0); - } -} - - -static void _save_copy_from_current( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLint i; - - for (i = _TNL_ATTRIB_POS+1 ; i <= _TNL_ATTRIB_EDGEFLAG ; i++) - switch (tnl->save.attrsz[i]) { - case 4: tnl->save.attrptr[i][3] = tnl->save.current[i][3]; - case 3: tnl->save.attrptr[i][2] = tnl->save.current[i][2]; - case 2: tnl->save.attrptr[i][1] = tnl->save.current[i][1]; - case 1: tnl->save.attrptr[i][0] = tnl->save.current[i][0]; - case 0: break; - } - - /* Edgeflag requires special treatment: - */ - if (tnl->save.attrsz[_TNL_ATTRIB_EDGEFLAG]) { - tnl->save.CurrentFloatEdgeFlag = (GLfloat)ctx->ListState.CurrentEdgeFlag; - tnl->save.attrptr[_TNL_ATTRIB_EDGEFLAG][0] = tnl->save.CurrentFloatEdgeFlag; - } -} - - - - -/* Flush existing data, set new attrib size, replay copied vertices. - */ -static void _save_upgrade_vertex( GLcontext *ctx, - GLuint attr, - GLuint newsz ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint oldsz; - GLuint i; - GLfloat *tmp; - - /* Store the current run of vertices, and emit a GL_END. Emit a - * BEGIN in the new buffer. - */ - if (tnl->save.initial_counter != tnl->save.counter) - _save_wrap_buffers( ctx ); - else - assert( tnl->save.copied.nr == 0 ); - - /* Do a COPY_TO_CURRENT to ensure back-copying works for the case - * when the attribute already exists in the vertex and is having - * its size increased. - */ - _save_copy_to_current( ctx ); - - /* Fix up sizes: - */ - oldsz = tnl->save.attrsz[attr]; - tnl->save.attrsz[attr] = newsz; - - tnl->save.vertex_size += newsz - oldsz; - tnl->save.counter = ((SAVE_BUFFER_SIZE - tnl->save.vertex_store->used) / - tnl->save.vertex_size); - if (tnl->save.counter > ctx->Const.MaxArrayLockSize ) - tnl->save.counter = ctx->Const.MaxArrayLockSize; - tnl->save.initial_counter = tnl->save.counter; - - /* Recalculate all the attrptr[] values: - */ - for (i = 0, tmp = tnl->save.vertex ; i < _TNL_ATTRIB_MAX ; i++) { - if (tnl->save.attrsz[i]) { - tnl->save.attrptr[i] = tmp; - tmp += tnl->save.attrsz[i]; - } - else - tnl->save.attrptr[i] = NULL; /* will not be dereferenced. */ - } - - /* Copy from current to repopulate the vertex with correct values. - */ - _save_copy_from_current( ctx ); - - /* Replay stored vertices to translate them to new format here. - * - * If there are copied vertices and the new (upgraded) attribute - * has not been defined before, this list is somewhat degenerate, - * and will need fixup at runtime. - */ - if (tnl->save.copied.nr) - { - GLfloat *data = tnl->save.copied.buffer; - GLfloat *dest = tnl->save.buffer; - GLuint j; - - /* Need to note this and fix up at runtime (or loopback): - */ - if (tnl->save.currentsz[attr][0] == 0) { - assert(oldsz == 0); - tnl->save.dangling_attr_ref = GL_TRUE; - -/* _mesa_debug(NULL, "_save_upgrade_vertex: dangling reference attr %d\n", */ -/* attr); */ - -#if 0 - /* The current strategy is to punt these degenerate cases - * through _tnl_loopback_vertex_list(), a lower-performance - * option. To minimize the impact of this, artificially - * reduce the size of this vertex_list. - */ - if (t->save.counter > 10) { - t->save.initial_counter = 10; - t->save.counter = 10; - } -#endif - } - - for (i = 0 ; i < tnl->save.copied.nr ; i++) { - for (j = 0 ; j < _TNL_ATTRIB_MAX ; j++) { - if (tnl->save.attrsz[j]) { - if (j == attr) { - if (oldsz) { - COPY_CLEAN_4V( dest, oldsz, data ); - data += oldsz; - dest += newsz; - } - else { - COPY_SZ_4V( dest, newsz, tnl->save.current[attr] ); - dest += newsz; - } - } - else { - GLint sz = tnl->save.attrsz[j]; - COPY_SZ_4V( dest, sz, data ); - data += sz; - dest += sz; - } - } - } - } - - tnl->save.vbptr = dest; - tnl->save.counter -= tnl->save.copied.nr; - } -} - - - - -/* Helper function for 'CHOOSE' macro. Do what's necessary when an - * entrypoint is called for the first time. - */ -static void do_choose( GLuint attr, GLuint sz, - void (*attr_func)( const GLfloat *), - void (*choose1)( const GLfloat *), - void (*choose2)( const GLfloat *), - void (*choose3)( const GLfloat *), - void (*choose4)( const GLfloat *), - const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - TNLcontext *tnl = TNL_CONTEXT(ctx); - static GLfloat id[4] = { 0, 0, 0, 1 }; - int i; - - if (tnl->save.attrsz[attr] < sz) { - /* New size is larger. Need to flush existing vertices and get - * an enlarged vertex format. - */ - _save_upgrade_vertex( ctx, attr, sz ); - } - else { - /* New size is equal or smaller - just need to fill in some - * zeros. - */ - for (i = sz ; i <= tnl->save.attrsz[attr] ; i++) - tnl->save.attrptr[attr][i-1] = id[i-1]; - } - - /* Reset any active pointers for this attribute - */ - tnl->save.tabfv[attr][0] = choose1; - tnl->save.tabfv[attr][1] = choose2; - tnl->save.tabfv[attr][2] = choose3; - tnl->save.tabfv[attr][3] = choose4; - - /* Update the secondary dispatch table with the new function - */ - tnl->save.tabfv[attr][sz-1] = attr_func; - - (*attr_func)(v); -} - - - -/* 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 save_choose_##ATTR##_##N( const GLfloat *v ); \ - \ -static void save_attrib_##ATTR##_##N( const GLfloat *v ) \ -{ \ - GET_CURRENT_CONTEXT( ctx ); \ - TNLcontext *tnl = TNL_CONTEXT(ctx); \ - \ - if ((ATTR) == 0) { \ - GLuint i; \ - \ - if (N>0) tnl->save.vbptr[0] = v[0]; \ - if (N>1) tnl->save.vbptr[1] = v[1]; \ - if (N>2) tnl->save.vbptr[2] = v[2]; \ - if (N>3) tnl->save.vbptr[3] = v[3]; \ - \ - for (i = N; i < tnl->save.vertex_size; i++) \ - tnl->save.vbptr[i] = tnl->save.vertex[i]; \ - \ - tnl->save.vbptr += tnl->save.vertex_size; \ - \ - if (--tnl->save.counter == 0) \ - _save_wrap_filled_vertex( ctx ); \ - } \ - else { \ - GLfloat *dest = tnl->save.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 CHOOSE( ATTR, N ) \ -static void save_choose_##ATTR##_##N( const GLfloat *v ) \ -{ \ - do_choose(ATTR, N, \ - save_attrib_##ATTR##_##N, \ - save_choose_##ATTR##_1, \ - save_choose_##ATTR##_2, \ - save_choose_##ATTR##_3, \ - save_choose_##ATTR##_4, \ - v ); \ -} - -#define INIT(ATTR) \ -static void save_init_##ATTR( TNLcontext *tnl ) \ -{ \ - tnl->save.tabfv[ATTR][0] = save_choose_##ATTR##_1; \ - tnl->save.tabfv[ATTR][1] = save_choose_##ATTR##_2; \ - tnl->save.tabfv[ATTR][2] = save_choose_##ATTR##_3; \ - tnl->save.tabfv[ATTR][3] = save_choose_##ATTR##_4; \ -} - -#define ATTRS( ATTRIB ) \ - ATTRFV( ATTRIB, 1 ) \ - ATTRFV( ATTRIB, 2 ) \ - ATTRFV( ATTRIB, 3 ) \ - ATTRFV( ATTRIB, 4 ) \ - CHOOSE( ATTRIB, 1 ) \ - CHOOSE( ATTRIB, 2 ) \ - CHOOSE( ATTRIB, 3 ) \ - CHOOSE( ATTRIB, 4 ) \ - INIT( ATTRIB ) \ - - -/* Generate a lot of functions. These are the actual worker - * functions, which are equivalent to those generated via codegen - * elsewhere. - */ -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 ) - - -static void _save_reset_vertex( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint i; - - save_init_0( tnl ); - save_init_1( tnl ); - save_init_2( tnl ); - save_init_3( tnl ); - save_init_4( tnl ); - save_init_5( tnl ); - save_init_6( tnl ); - save_init_7( tnl ); - save_init_8( tnl ); - save_init_9( tnl ); - save_init_10( tnl ); - save_init_11( tnl ); - save_init_12( tnl ); - save_init_13( tnl ); - save_init_14( tnl ); - save_init_15( tnl ); - - for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) - tnl->save.attrsz[i] = 0; - - tnl->save.vertex_size = 0; - tnl->save.have_materials = 0; - - _save_reset_counters( ctx ); -} - - - -/* Cope with aliasing of classic Vertex, Normal, etc. and the fan-out - * of glMultTexCoord and glProgramParamterNV by routing all these - * through a second level dispatch table. - */ -#define DISPATCH_ATTRFV( ATTR, COUNT, P ) \ -do { \ - GET_CURRENT_CONTEXT( ctx ); \ - TNLcontext *tnl = TNL_CONTEXT(ctx); \ - tnl->save.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 enum_error( void ) -{ - GET_CURRENT_CONTEXT( ctx ); - _mesa_compile_error( ctx, GL_INVALID_ENUM, "glVertexAttrib" ); -} - -static void GLAPIENTRY _save_Vertex2f( GLfloat x, GLfloat y ) -{ - DISPATCH_ATTR2F( _TNL_ATTRIB_POS, x, y ); -} - -static void GLAPIENTRY _save_Vertex2fv( const GLfloat *v ) -{ - DISPATCH_ATTR2FV( _TNL_ATTRIB_POS, v ); -} - -static void GLAPIENTRY _save_Vertex3f( GLfloat x, GLfloat y, GLfloat z ) -{ - DISPATCH_ATTR3F( _TNL_ATTRIB_POS, x, y, z ); -} - -static void GLAPIENTRY _save_Vertex3fv( const GLfloat *v ) -{ - DISPATCH_ATTR3FV( _TNL_ATTRIB_POS, v ); -} - -static void GLAPIENTRY _save_Vertex4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) -{ - DISPATCH_ATTR4F( _TNL_ATTRIB_POS, x, y, z, w ); -} - -static void GLAPIENTRY _save_Vertex4fv( const GLfloat *v ) -{ - DISPATCH_ATTR4FV( _TNL_ATTRIB_POS, v ); -} - -static void GLAPIENTRY _save_TexCoord1f( GLfloat x ) -{ - DISPATCH_ATTR1F( _TNL_ATTRIB_TEX0, x ); -} - -static void GLAPIENTRY _save_TexCoord1fv( const GLfloat *v ) -{ - DISPATCH_ATTR1FV( _TNL_ATTRIB_TEX0, v ); -} - -static void GLAPIENTRY _save_TexCoord2f( GLfloat x, GLfloat y ) -{ - DISPATCH_ATTR2F( _TNL_ATTRIB_TEX0, x, y ); -} - -static void GLAPIENTRY _save_TexCoord2fv( const GLfloat *v ) -{ - DISPATCH_ATTR2FV( _TNL_ATTRIB_TEX0, v ); -} - -static void GLAPIENTRY _save_TexCoord3f( GLfloat x, GLfloat y, GLfloat z ) -{ - DISPATCH_ATTR3F( _TNL_ATTRIB_TEX0, x, y, z ); -} - -static void GLAPIENTRY _save_TexCoord3fv( const GLfloat *v ) -{ - DISPATCH_ATTR3FV( _TNL_ATTRIB_TEX0, v ); -} - -static void GLAPIENTRY _save_TexCoord4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) -{ - DISPATCH_ATTR4F( _TNL_ATTRIB_TEX0, x, y, z, w ); -} - -static void GLAPIENTRY _save_TexCoord4fv( const GLfloat *v ) -{ - DISPATCH_ATTR4FV( _TNL_ATTRIB_TEX0, v ); -} - -static void GLAPIENTRY _save_Normal3f( GLfloat x, GLfloat y, GLfloat z ) -{ - DISPATCH_ATTR3F( _TNL_ATTRIB_NORMAL, x, y, z ); -} - -static void GLAPIENTRY _save_Normal3fv( const GLfloat *v ) -{ - DISPATCH_ATTR3FV( _TNL_ATTRIB_NORMAL, v ); -} - -static void GLAPIENTRY _save_FogCoordfEXT( GLfloat x ) -{ - DISPATCH_ATTR1F( _TNL_ATTRIB_FOG, x ); -} - -static void GLAPIENTRY _save_FogCoordfvEXT( const GLfloat *v ) -{ - DISPATCH_ATTR1FV( _TNL_ATTRIB_FOG, v ); -} - -static void GLAPIENTRY _save_Color3f( GLfloat x, GLfloat y, GLfloat z ) -{ - DISPATCH_ATTR3F( _TNL_ATTRIB_COLOR0, x, y, z ); -} - -static void GLAPIENTRY _save_Color3fv( const GLfloat *v ) -{ - DISPATCH_ATTR3FV( _TNL_ATTRIB_COLOR0, v ); -} - -static void GLAPIENTRY _save_Color4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) -{ - DISPATCH_ATTR4F( _TNL_ATTRIB_COLOR0, x, y, z, w ); -} - -static void GLAPIENTRY _save_Color4fv( const GLfloat *v ) -{ - DISPATCH_ATTR4FV( _TNL_ATTRIB_COLOR0, v ); -} - -static void GLAPIENTRY _save_SecondaryColor3fEXT( GLfloat x, GLfloat y, GLfloat z ) -{ - DISPATCH_ATTR3F( _TNL_ATTRIB_COLOR1, x, y, z ); -} - -static void GLAPIENTRY _save_SecondaryColor3fvEXT( const GLfloat *v ) -{ - DISPATCH_ATTR3FV( _TNL_ATTRIB_COLOR1, v ); -} - -static void GLAPIENTRY _save_MultiTexCoord1f( GLenum target, GLfloat x ) -{ - GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; - DISPATCH_ATTR1F( attr, x ); -} - -static void GLAPIENTRY _save_MultiTexCoord1fv( GLenum target, const GLfloat *v ) -{ - GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; - DISPATCH_ATTR1FV( attr, v ); -} - -static void GLAPIENTRY _save_MultiTexCoord2f( GLenum target, GLfloat x, GLfloat y ) -{ - GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; - DISPATCH_ATTR2F( attr, x, y ); -} - -static void GLAPIENTRY _save_MultiTexCoord2fv( GLenum target, const GLfloat *v ) -{ - GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; - DISPATCH_ATTR2FV( attr, v ); -} - -static void GLAPIENTRY _save_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 _save_MultiTexCoord3fv( GLenum target, const GLfloat *v ) -{ - GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; - DISPATCH_ATTR3FV( attr, v ); -} - -static void GLAPIENTRY _save_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 _save_MultiTexCoord4fv( GLenum target, const GLfloat *v ) -{ - GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; - DISPATCH_ATTR4FV( attr, v ); -} - -static void GLAPIENTRY _save_VertexAttrib1fNV( GLuint index, GLfloat x ) -{ - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) - DISPATCH_ATTR1F( index, x ); - else - enum_error(); -} - -static void GLAPIENTRY _save_VertexAttrib1fvNV( GLuint index, const GLfloat *v ) -{ - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) - DISPATCH_ATTR1FV( index, v ); - else - enum_error(); -} - -static void GLAPIENTRY _save_VertexAttrib2fNV( GLuint index, GLfloat x, GLfloat y ) -{ - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) - DISPATCH_ATTR2F( index, x, y ); - else - enum_error(); -} - -static void GLAPIENTRY _save_VertexAttrib2fvNV( GLuint index, const GLfloat *v ) -{ - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) - DISPATCH_ATTR2FV( index, v ); - else - enum_error(); -} - -static void GLAPIENTRY _save_VertexAttrib3fNV( GLuint index, GLfloat x, GLfloat y, - GLfloat z ) -{ - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) - DISPATCH_ATTR3F( index, x, y, z ); - else - enum_error(); -} - -static void GLAPIENTRY _save_VertexAttrib3fvNV( GLuint index, const GLfloat *v ) -{ - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) - DISPATCH_ATTR3FV( index, v ); - else - enum_error(); -} - -static void GLAPIENTRY _save_VertexAttrib4fNV( GLuint index, GLfloat x, GLfloat y, - GLfloat z, GLfloat w ) -{ - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) - DISPATCH_ATTR4F( index, x, y, z, w ); - else - enum_error(); -} - -static void GLAPIENTRY _save_VertexAttrib4fvNV( GLuint index, const GLfloat *v ) -{ - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) - DISPATCH_ATTR4FV( index, v ); - else - enum_error(); -} - - -static void GLAPIENTRY -_save_VertexAttrib1fARB( GLuint index, GLfloat x ) -{ - if (index < MAX_VERTEX_ATTRIBS) - DISPATCH_ATTR1F( index, x ); - else - enum_error(); -} - -static void GLAPIENTRY -_save_VertexAttrib1fvARB( GLuint index, const GLfloat *v ) -{ - if (index < MAX_VERTEX_ATTRIBS) - DISPATCH_ATTR1FV( index, v ); - else - enum_error(); -} - -static void GLAPIENTRY -_save_VertexAttrib2fARB( GLuint index, GLfloat x, GLfloat y ) -{ - if (index < MAX_VERTEX_ATTRIBS) - DISPATCH_ATTR2F( index, x, y ); - else - enum_error(); -} - -static void GLAPIENTRY -_save_VertexAttrib2fvARB( GLuint index, const GLfloat *v ) -{ - if (index < MAX_VERTEX_ATTRIBS) - DISPATCH_ATTR2FV( index, v ); - else - enum_error(); -} - -static void GLAPIENTRY -_save_VertexAttrib3fARB( GLuint index, GLfloat x, GLfloat y, GLfloat z ) -{ - if (index < MAX_VERTEX_ATTRIBS) - DISPATCH_ATTR3F( index, x, y, z ); - else - enum_error(); -} - -static void GLAPIENTRY -_save_VertexAttrib3fvARB( GLuint index, const GLfloat *v ) -{ - if (index < MAX_VERTEX_ATTRIBS) - DISPATCH_ATTR3FV( index, v ); - else - enum_error(); -} - -static void GLAPIENTRY -_save_VertexAttrib4fARB( GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w ) -{ - if (index < MAX_VERTEX_ATTRIBS) - DISPATCH_ATTR4F( index, x, y, z, w ); - else - enum_error(); -} - -static void GLAPIENTRY -_save_VertexAttrib4fvARB( GLuint index, const GLfloat *v ) -{ - if (index < MAX_VERTEX_ATTRIBS) - DISPATCH_ATTR4FV( index, v ); - else - enum_error(); -} - - -/* Materials: - * - * These are treated as per-vertex attributes, at indices above where - * the NV_vertex_program leaves off. There are a lot of good things - * about treating materials this way. - * - * However: I don't want to double the number of generated functions - * just to cope with this, so I unroll the 'C' varients of CHOOSE and - * ATTRF into this function, and dispense with codegen and - * second-level dispatch. - * - * There is no aliasing of material attributes with other entrypoints. - */ -#define MAT_ATTR( A, N, params ) \ -do { \ - if (tnl->save.attrsz[A] < N) { \ - _save_upgrade_vertex( ctx, A, N ); \ - tnl->save.have_materials = GL_TRUE; \ - } \ - \ - { \ - GLfloat *dest = tnl->save.attrptr[A]; \ - if (N>0) dest[0] = params[0]; \ - if (N>1) dest[1] = params[1]; \ - if (N>2) dest[2] = params[2]; \ - if (N>3) dest[3] = params[3]; \ - } \ -} while (0) - - -#define MAT( ATTR, N, face, params ) \ -do { \ - if (face != GL_BACK) \ - MAT_ATTR( ATTR, N, params ); /* front */ \ - if (face != GL_FRONT) \ - MAT_ATTR( ATTR + 1, N, params ); /* back */ \ -} while (0) - - -/* NOTE: Have to remove/deal-with colormaterial crossovers, probably - * later on - in the meantime just store everything. - */ -static void GLAPIENTRY _save_Materialfv( GLenum face, GLenum pname, - const GLfloat *params ) -{ - GET_CURRENT_CONTEXT( ctx ); - TNLcontext *tnl = TNL_CONTEXT(ctx); - - switch (pname) { - case GL_EMISSION: - MAT( _TNL_ATTRIB_MAT_FRONT_EMISSION, 4, face, params ); - break; - case GL_AMBIENT: - MAT( _TNL_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params ); - break; - case GL_DIFFUSE: - MAT( _TNL_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params ); - break; - case GL_SPECULAR: - MAT( _TNL_ATTRIB_MAT_FRONT_SPECULAR, 4, face, params ); - break; - case GL_SHININESS: - MAT( _TNL_ATTRIB_MAT_FRONT_SHININESS, 1, face, params ); - break; - case GL_COLOR_INDEXES: - MAT( _TNL_ATTRIB_MAT_FRONT_INDEXES, 3, face, params ); - break; - case GL_AMBIENT_AND_DIFFUSE: - MAT( _TNL_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params ); - MAT( _TNL_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params ); - break; - default: - _mesa_compile_error( ctx, GL_INVALID_ENUM, "glMaterialfv" ); - return; - } -} - - -#define IDX_ATTR( A, IDX ) \ -do { \ - GET_CURRENT_CONTEXT( ctx ); \ - TNLcontext *tnl = TNL_CONTEXT(ctx); \ - \ - if (tnl->save.attrsz[A] < 1) { \ - _save_upgrade_vertex( ctx, A, 1 ); \ - } \ - \ - { \ - GLfloat *dest = tnl->save.attrptr[A]; \ - dest[0] = IDX; \ - } \ -} while (0) - - -static void GLAPIENTRY _save_EdgeFlag( GLboolean b ) -{ - IDX_ATTR( _TNL_ATTRIB_EDGEFLAG, (GLfloat)b ); -} - - -static void GLAPIENTRY _save_Indexf( GLfloat f ) -{ - IDX_ATTR( _TNL_ATTRIB_COLOR_INDEX, f ); -} - -static void GLAPIENTRY _save_Indexfv( const GLfloat *f ) -{ - IDX_ATTR( _TNL_ATTRIB_COLOR_INDEX, f[0] ); -} - - - - -/* Cope with EvalCoord/CallList called within a begin/end object: - * -- Flush current buffer - * -- Fallback to opcodes for the rest of the begin/end object. - */ -#define FALLBACK(ctx) \ -do { \ - TNLcontext *tnl = TNL_CONTEXT(ctx); \ - \ - if (tnl->save.initial_counter != tnl->save.counter || \ - tnl->save.prim_count) \ - _save_compile_vertex_list( ctx ); \ - \ - _save_copy_to_current( ctx ); \ - _save_reset_vertex( ctx ); \ - _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); \ - ctx->Driver.SaveNeedFlush = 0; \ -} while (0) - -static void GLAPIENTRY _save_EvalCoord1f( GLfloat u ) -{ - GET_CURRENT_CONTEXT(ctx); - FALLBACK(ctx); - CALL_EvalCoord1f(ctx->Save, ( u )); -} - -static void GLAPIENTRY _save_EvalCoord1fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - FALLBACK(ctx); - CALL_EvalCoord1fv(ctx->Save, ( v )); -} - -static void GLAPIENTRY _save_EvalCoord2f( GLfloat u, GLfloat v ) -{ - GET_CURRENT_CONTEXT(ctx); - FALLBACK(ctx); - CALL_EvalCoord2f(ctx->Save, ( u, v )); -} - -static void GLAPIENTRY _save_EvalCoord2fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - FALLBACK(ctx); - CALL_EvalCoord2fv(ctx->Save, ( v )); -} - -static void GLAPIENTRY _save_EvalPoint1( GLint i ) -{ - GET_CURRENT_CONTEXT(ctx); - FALLBACK(ctx); - CALL_EvalPoint1(ctx->Save, ( i )); -} - -static void GLAPIENTRY _save_EvalPoint2( GLint i, GLint j ) -{ - GET_CURRENT_CONTEXT(ctx); - FALLBACK(ctx); - CALL_EvalPoint2(ctx->Save, ( i, j )); -} - -static void GLAPIENTRY _save_CallList( GLuint l ) -{ - GET_CURRENT_CONTEXT(ctx); - FALLBACK(ctx); - CALL_CallList(ctx->Save, ( l )); -} - -static void GLAPIENTRY _save_CallLists( GLsizei n, GLenum type, const GLvoid *v ) -{ - GET_CURRENT_CONTEXT(ctx); - FALLBACK(ctx); - CALL_CallLists(ctx->Save, ( n, type, v )); -} - - - - -/** - * Called via ctx->Driver.NotifySaveBegin(ctx, mode) when we get a - * glBegin() call while compiling a display list. - * See save_Begin() in dlist.c - * - * This plugs in our special TNL-related display list functions. - * All subsequent glBegin/glVertex/glEnd()s found while compiling a - * display list will get routed to the functions in this file. - * - * Updating of ctx->Driver.CurrentSavePrimitive is already taken care of. - */ -static GLboolean _save_NotifyBegin( GLcontext *ctx, GLenum mode ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - - if (1) { - GLuint i = tnl->save.prim_count++; - - assert(i < tnl->save.prim_max); - tnl->save.prim[i].mode = mode | PRIM_BEGIN; - tnl->save.prim[i].start = tnl->save.initial_counter - tnl->save.counter; - tnl->save.prim[i].count = 0; - - _mesa_install_save_vtxfmt( ctx, &tnl->save_vtxfmt ); - ctx->Driver.SaveNeedFlush = 1; - return GL_TRUE; - } - else - return GL_FALSE; -} - - - -static void GLAPIENTRY _save_End( void ) -{ - GET_CURRENT_CONTEXT( ctx ); - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLint i = tnl->save.prim_count - 1; - - ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END; - if (ctx->ExecuteFlag) - ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; - - tnl->save.prim[i].mode |= PRIM_END; - tnl->save.prim[i].count = ((tnl->save.initial_counter - tnl->save.counter) - - tnl->save.prim[i].start); - - if (i == (GLint) tnl->save.prim_max - 1) { - _save_compile_vertex_list( ctx ); - assert(tnl->save.copied.nr == 0); - } - - /* Swap out this vertex format while outside begin/end. Any color, - * etc. received between here and the next begin will be compiled - * as opcodes. - */ - _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); -} - - -/* These are all errors as this vtxfmt is only installed inside - * begin/end pairs. - */ -static void GLAPIENTRY _save_DrawElements(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) count; (void) type; (void) indices; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawElements" ); -} - - -static void GLAPIENTRY _save_DrawRangeElements(GLenum mode, - GLuint start, GLuint end, - GLsizei count, GLenum type, - const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) start; (void) end; (void) count; (void) type; (void) indices; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawRangeElements" ); -} - -static void GLAPIENTRY _save_DrawArrays(GLenum mode, GLint start, GLsizei count) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) start; (void) count; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawArrays" ); -} - -static void GLAPIENTRY _save_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) -{ - GET_CURRENT_CONTEXT(ctx); - (void) x1; (void) y1; (void) x2; (void) y2; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glRectf" ); -} - -static void GLAPIENTRY _save_EvalMesh1( GLenum mode, GLint i1, GLint i2 ) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) i1; (void) i2; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glEvalMesh1" ); -} - -static void GLAPIENTRY _save_EvalMesh2( GLenum mode, GLint i1, GLint i2, - GLint j1, GLint j2 ) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) i1; (void) i2; (void) j1; (void) j2; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glEvalMesh2" ); -} - -/** - * This is only called if someone tries to compile nested glBegin()s - * in their display list. - */ -static void GLAPIENTRY _save_Begin( GLenum mode ) -{ - GET_CURRENT_CONTEXT( ctx ); - (void) mode; - _mesa_compile_error(ctx, GL_INVALID_OPERATION, - "glBegin(called inside glBegin/End)"); -} - - -/* Unlike the functions above, these are to be hooked into the vtxfmt - * maintained in ctx->ListState, active when the list is known or - * suspected to be outside any begin/end primitive. - */ -static void GLAPIENTRY _save_OBE_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) -{ - GET_CURRENT_CONTEXT(ctx); - _save_NotifyBegin( ctx, GL_QUADS | PRIM_WEAK ); - CALL_Vertex2f(GET_DISPATCH(), ( x1, y1 )); - CALL_Vertex2f(GET_DISPATCH(), ( x2, y1 )); - CALL_Vertex2f(GET_DISPATCH(), ( x2, y2 )); - CALL_Vertex2f(GET_DISPATCH(), ( x1, y2 )); - CALL_End(GET_DISPATCH(), ()); -} - - -static void GLAPIENTRY _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei count) -{ - GET_CURRENT_CONTEXT(ctx); - GLint i; - - if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) - return; - - _ae_map_vbos( ctx ); - - _save_NotifyBegin( ctx, mode | PRIM_WEAK ); - for (i = 0; i < count; i++) - CALL_ArrayElement(GET_DISPATCH(), (start + i)); - CALL_End(GET_DISPATCH(), ()); - - _ae_unmap_vbos( ctx ); -} - - -static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - GLint i; - - if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) - return; - - _ae_map_vbos( ctx ); - - _save_NotifyBegin( ctx, mode | PRIM_WEAK ); - - switch (type) { - case GL_UNSIGNED_BYTE: - for (i = 0 ; i < count ; i++) - CALL_ArrayElement(GET_DISPATCH(), ( ((GLubyte *)indices)[i] )); - break; - case GL_UNSIGNED_SHORT: - for (i = 0 ; i < count ; i++) - CALL_ArrayElement(GET_DISPATCH(), ( ((GLushort *)indices)[i] )); - break; - case GL_UNSIGNED_INT: - for (i = 0 ; i < count ; i++) - CALL_ArrayElement(GET_DISPATCH(), ( ((GLuint *)indices)[i] )); - break; - default: - _mesa_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" ); - break; - } - - CALL_End(GET_DISPATCH(), ()); - - _ae_unmap_vbos( ctx ); -} - -static void GLAPIENTRY _save_OBE_DrawRangeElements(GLenum mode, - GLuint start, GLuint end, - GLsizei count, GLenum type, - const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - if (_mesa_validate_DrawRangeElements( ctx, mode, - start, end, - count, type, indices )) - _save_OBE_DrawElements( mode, count, type, indices ); -} - - - - - -static void _save_vtxfmt_init( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLvertexformat *vfmt = &tnl->save_vtxfmt; - - vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ - vfmt->Begin = _save_Begin; - vfmt->Color3f = _save_Color3f; - vfmt->Color3fv = _save_Color3fv; - vfmt->Color4f = _save_Color4f; - vfmt->Color4fv = _save_Color4fv; - vfmt->EdgeFlag = _save_EdgeFlag; - vfmt->End = _save_End; - vfmt->FogCoordfEXT = _save_FogCoordfEXT; - vfmt->FogCoordfvEXT = _save_FogCoordfvEXT; - vfmt->Indexf = _save_Indexf; - vfmt->Indexfv = _save_Indexfv; - vfmt->Materialfv = _save_Materialfv; - vfmt->MultiTexCoord1fARB = _save_MultiTexCoord1f; - vfmt->MultiTexCoord1fvARB = _save_MultiTexCoord1fv; - vfmt->MultiTexCoord2fARB = _save_MultiTexCoord2f; - vfmt->MultiTexCoord2fvARB = _save_MultiTexCoord2fv; - vfmt->MultiTexCoord3fARB = _save_MultiTexCoord3f; - vfmt->MultiTexCoord3fvARB = _save_MultiTexCoord3fv; - vfmt->MultiTexCoord4fARB = _save_MultiTexCoord4f; - vfmt->MultiTexCoord4fvARB = _save_MultiTexCoord4fv; - vfmt->Normal3f = _save_Normal3f; - vfmt->Normal3fv = _save_Normal3fv; - vfmt->SecondaryColor3fEXT = _save_SecondaryColor3fEXT; - vfmt->SecondaryColor3fvEXT = _save_SecondaryColor3fvEXT; - vfmt->TexCoord1f = _save_TexCoord1f; - vfmt->TexCoord1fv = _save_TexCoord1fv; - vfmt->TexCoord2f = _save_TexCoord2f; - vfmt->TexCoord2fv = _save_TexCoord2fv; - vfmt->TexCoord3f = _save_TexCoord3f; - vfmt->TexCoord3fv = _save_TexCoord3fv; - vfmt->TexCoord4f = _save_TexCoord4f; - vfmt->TexCoord4fv = _save_TexCoord4fv; - vfmt->Vertex2f = _save_Vertex2f; - vfmt->Vertex2fv = _save_Vertex2fv; - vfmt->Vertex3f = _save_Vertex3f; - vfmt->Vertex3fv = _save_Vertex3fv; - vfmt->Vertex4f = _save_Vertex4f; - vfmt->Vertex4fv = _save_Vertex4fv; - vfmt->VertexAttrib1fNV = _save_VertexAttrib1fNV; - vfmt->VertexAttrib1fvNV = _save_VertexAttrib1fvNV; - vfmt->VertexAttrib2fNV = _save_VertexAttrib2fNV; - vfmt->VertexAttrib2fvNV = _save_VertexAttrib2fvNV; - vfmt->VertexAttrib3fNV = _save_VertexAttrib3fNV; - vfmt->VertexAttrib3fvNV = _save_VertexAttrib3fvNV; - vfmt->VertexAttrib4fNV = _save_VertexAttrib4fNV; - vfmt->VertexAttrib4fvNV = _save_VertexAttrib4fvNV; - vfmt->VertexAttrib1fARB = _save_VertexAttrib1fARB; - vfmt->VertexAttrib1fvARB = _save_VertexAttrib1fvARB; - vfmt->VertexAttrib2fARB = _save_VertexAttrib2fARB; - vfmt->VertexAttrib2fvARB = _save_VertexAttrib2fvARB; - vfmt->VertexAttrib3fARB = _save_VertexAttrib3fARB; - vfmt->VertexAttrib3fvARB = _save_VertexAttrib3fvARB; - vfmt->VertexAttrib4fARB = _save_VertexAttrib4fARB; - vfmt->VertexAttrib4fvARB = _save_VertexAttrib4fvARB; - - /* This will all require us to fallback to saving the list as opcodes: - */ - vfmt->CallList = _save_CallList; /* inside begin/end */ - vfmt->CallLists = _save_CallLists; /* inside begin/end */ - vfmt->EvalCoord1f = _save_EvalCoord1f; - vfmt->EvalCoord1fv = _save_EvalCoord1fv; - vfmt->EvalCoord2f = _save_EvalCoord2f; - vfmt->EvalCoord2fv = _save_EvalCoord2fv; - vfmt->EvalPoint1 = _save_EvalPoint1; - vfmt->EvalPoint2 = _save_EvalPoint2; - - /* These are all errors as we at least know we are in some sort of - * begin/end pair: - */ - vfmt->EvalMesh1 = _save_EvalMesh1; - vfmt->EvalMesh2 = _save_EvalMesh2; - vfmt->Begin = _save_Begin; - vfmt->Rectf = _save_Rectf; - vfmt->DrawArrays = _save_DrawArrays; - vfmt->DrawElements = _save_DrawElements; - vfmt->DrawRangeElements = _save_DrawRangeElements; - -} - - -void _tnl_SaveFlushVertices( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - - /* Noop when we are actually active: - */ - if (ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM || - ctx->Driver.CurrentSavePrimitive <= GL_POLYGON) - return; - - if (tnl->save.initial_counter != tnl->save.counter || - tnl->save.prim_count) - _save_compile_vertex_list( ctx ); - - _save_copy_to_current( ctx ); - _save_reset_vertex( ctx ); - ctx->Driver.SaveNeedFlush = 0; -} - -void _tnl_NewList( GLcontext *ctx, GLuint list, GLenum mode ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - - (void) list; (void) mode; - - if (!tnl->save.prim_store) - tnl->save.prim_store = alloc_prim_store( ctx ); - - if (!tnl->save.vertex_store) { - tnl->save.vertex_store = alloc_vertex_store( ctx ); - tnl->save.vbptr = tnl->save.vertex_store->buffer; - } - - _save_reset_vertex( ctx ); - ctx->Driver.SaveNeedFlush = 0; -} - -void _tnl_EndList( GLcontext *ctx ) -{ - (void) ctx; - assert(TNL_CONTEXT(ctx)->save.vertex_size == 0); -} - -void _tnl_BeginCallList( GLcontext *ctx, struct mesa_display_list *dlist ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - tnl->save.replay_flags |= dlist->flags; - tnl->save.replay_flags |= tnl->LoopbackDListCassettes; -} - -void _tnl_EndCallList( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - - if (ctx->ListState.CallDepth == 1) - tnl->save.replay_flags = 0; -} - - -static void _tnl_destroy_vertex_list( GLcontext *ctx, void *data ) -{ - struct tnl_vertex_list *node = (struct tnl_vertex_list *)data; - (void) ctx; - - if ( --node->vertex_store->refcount == 0 ) - FREE( node->vertex_store ); - - if ( --node->prim_store->refcount == 0 ) - FREE( node->prim_store ); - - if ( node->normal_lengths ) - FREE( node->normal_lengths ); -} - - -static void _tnl_print_vertex_list( GLcontext *ctx, void *data ) -{ - struct tnl_vertex_list *node = (struct tnl_vertex_list *)data; - GLuint i; - (void) ctx; - - _mesa_debug(NULL, "TNL-VERTEX-LIST, %u vertices %d primitives, %d vertsize\n", - node->count, - node->prim_count, - node->vertex_size); - - for (i = 0 ; i < node->prim_count ; i++) { - struct tnl_prim *prim = &node->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)"); - } -} - - -static void _save_current_init( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLint i; - - for (i = 0; i < _TNL_ATTRIB_MAT_FRONT_AMBIENT; i++) { - ASSERT(i < VERT_ATTRIB_MAX); - tnl->save.currentsz[i] = &ctx->ListState.ActiveAttribSize[i]; - tnl->save.current[i] = ctx->ListState.CurrentAttrib[i]; - } - - for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) { - const GLuint j = i - _TNL_FIRST_MAT; - ASSERT(j < MAT_ATTRIB_MAX); - tnl->save.currentsz[i] = &ctx->ListState.ActiveMaterialSize[j]; - tnl->save.current[i] = ctx->ListState.CurrentMaterial[j]; - } - - tnl->save.currentsz[_TNL_ATTRIB_EDGEFLAG] = &ctx->ListState.ActiveEdgeFlag; - tnl->save.current[_TNL_ATTRIB_EDGEFLAG] = &tnl->save.CurrentFloatEdgeFlag; -} - -/** - * Initialize the display list compiler - */ -void _tnl_save_init( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct tnl_vertex_arrays *tmp = &tnl->save_inputs; - GLuint i; - - - for (i = 0; i < _TNL_ATTRIB_MAX; i++) - _mesa_vector4f_init( &tmp->Attribs[i], 0, NULL); - - tnl->save.opcode_vertex_list = - _mesa_alloc_opcode( ctx, - sizeof(struct tnl_vertex_list), - _tnl_playback_vertex_list, - _tnl_destroy_vertex_list, - _tnl_print_vertex_list ); - - ctx->Driver.NotifySaveBegin = _save_NotifyBegin; - - _save_vtxfmt_init( ctx ); - _save_current_init( ctx ); - - /* Hook our array functions into the outside-begin-end vtxfmt in - * ctx->ListState. - */ - ctx->ListState.ListVtxfmt.Rectf = _save_OBE_Rectf; - ctx->ListState.ListVtxfmt.DrawArrays = _save_OBE_DrawArrays; - ctx->ListState.ListVtxfmt.DrawElements = _save_OBE_DrawElements; - ctx->ListState.ListVtxfmt.DrawRangeElements = _save_OBE_DrawRangeElements; - _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); -} - - -/** - * Deallocate the immediate-mode buffer for the given context, if - * its reference count goes to zero. - */ -void _tnl_save_destroy( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - - /* Decrement the refcounts. References may still be held by - * display lists yet to be destroyed, so it may not yet be time to - * free these items. - */ - if (tnl->save.prim_store && - --tnl->save.prim_store->refcount == 0 ) - FREE( tnl->save.prim_store ); - - if (tnl->save.vertex_store && - --tnl->save.vertex_store->refcount == 0 ) - FREE( tnl->save.vertex_store ); -} diff --git a/src/mesa/tnl/t_save_playback.c b/src/mesa/tnl/t_save_playback.c deleted file mode 100644 index 426e94372e..0000000000 --- a/src/mesa/tnl/t_save_playback.c +++ /dev/null @@ -1,216 +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 - */ - -#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 ); - ctx->NewState |= _NEW_LIGHT; - } - - /* 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 ); -} diff --git a/src/mesa/tnl/t_vtx_api.c b/src/mesa/tnl/t_vtx_api.c deleted file mode 100644 index 77eec8b3b4..0000000000 --- a/src/mesa/tnl/t_vtx_api.c +++ /dev/null @@ -1,1046 +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 - */ - -#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" - -#include "dispatch.h" - -static void reset_attrfv( TNLcontext *tnl ); - -/** Note extra space for error index: */ -static tnl_attrfv_func choose[_TNL_ATTRIB_ERROR+1][4]; -static tnl_attrfv_func generic_attr_func[_TNL_MAX_ATTR_CODEGEN][4]; - - -/* Close off the last primitive, execute the buffer, restart the - * primitive. - */ -static void _tnl_wrap_buffers( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - - - if (tnl->vtx.prim_count == 0) { - tnl->vtx.copied.nr = 0; - tnl->vtx.counter = tnl->vtx.initial_counter; - tnl->vtx.vbptr = tnl->vtx.buffer; - } - else { - GLuint last_prim = tnl->vtx.prim[tnl->vtx.prim_count-1].mode; - GLuint last_count; - - if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) { - GLint i = tnl->vtx.prim_count - 1; - assert(i >= 0); - tnl->vtx.prim[i].count = ((tnl->vtx.initial_counter - - tnl->vtx.counter) - - tnl->vtx.prim[i].start); - } - - last_count = tnl->vtx.prim[tnl->vtx.prim_count-1].count; - - /* Execute the buffer and save copied vertices. - */ - if (tnl->vtx.counter != tnl->vtx.initial_counter) - _tnl_flush_vtx( ctx ); - else { - tnl->vtx.prim_count = 0; - tnl->vtx.copied.nr = 0; - } - - /* Emit a glBegin to start the new list. - */ - assert(tnl->vtx.prim_count == 0); - - if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) { - tnl->vtx.prim[0].mode = ctx->Driver.CurrentExecPrimitive; - tnl->vtx.prim[0].start = 0; - tnl->vtx.prim[0].count = 0; - tnl->vtx.prim_count++; - - if (tnl->vtx.copied.nr == last_count) - tnl->vtx.prim[0].mode |= last_prim & PRIM_BEGIN; - } - } -} - - -/* Deal with buffer wrapping where provoked by the vertex buffer - * filling up, as opposed to upgrade_vertex(). - * - * Make it GLAPIENTRY, so we can tail from the codegen'ed Vertex*fv - */ -void GLAPIENTRY _tnl_wrap_filled_vertex( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLfloat *data = tnl->vtx.copied.buffer; - GLuint i; - - /* Run pipeline on current vertices, copy wrapped vertices - * to tnl->copied. - */ - _tnl_wrap_buffers( ctx ); - - /* Copy stored stored vertices to start of new list. - */ - assert(tnl->vtx.counter > tnl->vtx.copied.nr); - - for (i = 0 ; i < tnl->vtx.copied.nr ; i++) { - _mesa_memcpy( tnl->vtx.vbptr, data, - tnl->vtx.vertex_size * sizeof(GLfloat)); - tnl->vtx.vbptr += tnl->vtx.vertex_size; - data += tnl->vtx.vertex_size; - tnl->vtx.counter--; - } - - tnl->vtx.copied.nr = 0; -} - - -/* - * Copy the active vertex's values to the ctx->Current fields. - */ -static void _tnl_copy_to_current( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint i; - - for (i = _TNL_ATTRIB_POS+1 ; i < _TNL_ATTRIB_EDGEFLAG ; i++) { - if (tnl->vtx.attrsz[i]) { - /* Note: the tnl->vtx.current[i] pointers points to - * the ctx->Current fields. The first 16 or so, anyway. - */ - COPY_CLEAN_4V(tnl->vtx.current[i], - tnl->vtx.attrsz[i], - tnl->vtx.attrptr[i]); - } - } - - /* Edgeflag requires additional treatment: - */ - if (tnl->vtx.attrsz[_TNL_ATTRIB_EDGEFLAG]) { - ctx->Current.EdgeFlag = - (tnl->vtx.CurrentFloatEdgeFlag == 1.0); - } - - /* Colormaterial -- this kindof sucks. - */ - if (ctx->Light.ColorMaterialEnabled) { - _mesa_update_color_material(ctx, - ctx->Current.Attrib[VERT_ATTRIB_COLOR0]); - } - - if (tnl->vtx.have_materials) { - tnl->Driver.NotifyMaterialChange( ctx ); - ctx->NewState |= _NEW_LIGHT; - } - - ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT; -} - - -static void _tnl_copy_from_current( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLint i; - - /* Edgeflag requires additional treatment: - */ - tnl->vtx.CurrentFloatEdgeFlag = (GLfloat) ctx->Current.EdgeFlag; - - for (i = _TNL_ATTRIB_POS+1 ; i < _TNL_ATTRIB_MAX ; i++) - switch (tnl->vtx.attrsz[i]) { - case 4: tnl->vtx.attrptr[i][3] = tnl->vtx.current[i][3]; - case 3: tnl->vtx.attrptr[i][2] = tnl->vtx.current[i][2]; - case 2: tnl->vtx.attrptr[i][1] = tnl->vtx.current[i][1]; - case 1: tnl->vtx.attrptr[i][0] = tnl->vtx.current[i][0]; - break; - } - - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; -} - - -/* Flush existing data, set new attrib size, replay copied vertices. - */ -static void _tnl_wrap_upgrade_vertex( GLcontext *ctx, - GLuint attr, - GLuint newsz ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint oldsz; - GLuint i; - GLfloat *tmp; - GLint lastcount = tnl->vtx.initial_counter - tnl->vtx.counter; - - /* Run pipeline on current vertices, copy wrapped vertices - * to tnl->vtx.copied. - */ - _tnl_wrap_buffers( ctx ); - - - /* Do a COPY_TO_CURRENT to ensure back-copying works for the case - * when the attribute already exists in the vertex and is having - * its size increased. - */ - _tnl_copy_to_current( ctx ); - - - /* Heuristic: Attempt to isolate attributes received outside - * begin/end so that they don't bloat the vertices. - */ - if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END && - tnl->vtx.attrsz[attr] == 0 && - lastcount > 8 && - tnl->vtx.vertex_size) { - reset_attrfv( tnl ); - } - - /* Fix up sizes: - */ - oldsz = tnl->vtx.attrsz[attr]; - tnl->vtx.attrsz[attr] = newsz; - - tnl->vtx.vertex_size += newsz - oldsz; - tnl->vtx.counter = MIN2( VERT_BUFFER_SIZE / tnl->vtx.vertex_size, - ctx->Const.MaxArrayLockSize ); - tnl->vtx.initial_counter = tnl->vtx.counter; - tnl->vtx.vbptr = tnl->vtx.buffer; - - - /* Recalculate all the attrptr[] values - */ - for (i = 0, tmp = tnl->vtx.vertex ; i < _TNL_ATTRIB_MAX ; i++) { - if (tnl->vtx.attrsz[i]) { - tnl->vtx.attrptr[i] = tmp; - tmp += tnl->vtx.attrsz[i]; - } - else - tnl->vtx.attrptr[i] = NULL; /* will not be dereferenced */ - } - - /* Copy from current to repopulate the vertex with correct values. - */ - _tnl_copy_from_current( ctx ); - - /* Replay stored vertices to translate them - * to new format here. - * - * -- No need to replay - just copy piecewise - */ - if (tnl->vtx.copied.nr) - { - const GLfloat *data = tnl->vtx.copied.buffer; - GLfloat *dest = tnl->vtx.buffer; - GLuint j; - - for (i = 0 ; i < tnl->vtx.copied.nr ; i++) { - for (j = 0 ; j < _TNL_ATTRIB_MAX ; j++) { - if (tnl->vtx.attrsz[j]) { - if (j == attr) { - if (oldsz) { - COPY_CLEAN_4V( dest, oldsz, data ); - data += oldsz; - dest += newsz; - } else { - COPY_SZ_4V( dest, newsz, tnl->vtx.current[j] ); - dest += newsz; - } - } - else { - GLuint sz = tnl->vtx.attrsz[j]; - COPY_SZ_4V( dest, sz, data ); - dest += sz; - data += sz; - } - } - } - } - - tnl->vtx.vbptr = dest; - tnl->vtx.counter -= tnl->vtx.copied.nr; - tnl->vtx.copied.nr = 0; - } - - /* For codegen - attrptr's may have changed, so need to redo - * codegen. Might be a reasonable place to try & detect attributes - * in the vertex which aren't being submitted any more. - */ - for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) - if (tnl->vtx.attrsz[i]) { - GLuint j = tnl->vtx.attrsz[i] - 1; - - if (i < _TNL_MAX_ATTR_CODEGEN) - tnl->vtx.tabfv[i][j] = choose[i][j]; - } - -} - - -static void _tnl_fixup_vertex( GLcontext *ctx, GLuint attr, GLuint sz ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - static const GLfloat id[4] = { 0, 0, 0, 1 }; - int i; - - if (0) - _mesa_printf("%s attr %d sz %d -> %d\n", - __FUNCTION__, attr, tnl->vtx.attrsz[attr], sz); - - if (tnl->vtx.attrsz[attr] < sz) { - /* New size is larger. Need to flush existing vertices and get - * an enlarged vertex format. - */ - _tnl_wrap_upgrade_vertex( ctx, attr, sz ); - } - else if (sz < tnl->vtx.active_sz[attr]) { - /* New size is smaller - just need to fill in some - * zeros. Don't need to flush or wrap. - */ - for (i = sz ; i <= tnl->vtx.attrsz[attr] ; i++) - tnl->vtx.attrptr[attr][i-1] = id[i-1]; - } - - tnl->vtx.active_sz[attr] = sz; - - /* Does setting NeedFlush belong here? Necessitates resetting - * vtxfmt on each flush (otherwise flags won't get reset - * afterwards). - */ - if (attr == 0) - ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; - else - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; -} - -#ifdef USE_X86_ASM - -static struct _tnl_dynfn *lookup( struct _tnl_dynfn *l, GLuint key ) -{ - struct _tnl_dynfn *f; - - foreach( f, l ) { - if (f->key == key) - return f; - } - - return NULL; -} - - -static tnl_attrfv_func do_codegen( GLcontext *ctx, GLuint attr, GLuint sz ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct _tnl_dynfn *dfn = NULL; - - if (attr == 0) { - GLuint key = tnl->vtx.vertex_size; - - dfn = lookup( &tnl->vtx.cache.Vertex[sz-1], key ); - - if (!dfn) - dfn = tnl->vtx.gen.Vertex[sz-1]( ctx, key ); - } - else { - GLuint key = (GLuint) tnl->vtx.attrptr[attr]; - - dfn = lookup( &tnl->vtx.cache.Attribute[sz-1], key ); - - if (!dfn) - dfn = tnl->vtx.gen.Attribute[sz-1]( ctx, key ); - } - - if (dfn) - return *(tnl_attrfv_func *) &dfn->code; - else - return NULL; -} - -#endif /* USE_X86_ASM */ - -/* Helper function for 'CHOOSE' macro. Do what's necessary when an - * entrypoint is called for the first time. - */ - -static tnl_attrfv_func do_choose( GLuint attr, GLuint sz ) -{ - GET_CURRENT_CONTEXT( ctx ); - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint oldsz = tnl->vtx.active_sz[attr]; - - assert(attr < _TNL_MAX_ATTR_CODEGEN); - - if (oldsz != sz) { - /* Reset any active pointers for this attribute - */ - if (oldsz) - tnl->vtx.tabfv[attr][oldsz-1] = choose[attr][oldsz-1]; - - _tnl_fixup_vertex( ctx, attr, sz ); - - } - - - /* Try to use codegen: - */ -#ifdef USE_X86_ASM - if (tnl->AllowCodegen) - tnl->vtx.tabfv[attr][sz-1] = do_codegen( ctx, attr, sz ); - else -#endif - tnl->vtx.tabfv[attr][sz-1] = NULL; - - /* Else use generic version: - */ - if (!tnl->vtx.tabfv[attr][sz-1]) - tnl->vtx.tabfv[attr][sz-1] = generic_attr_func[attr][sz-1]; - - ASSERT(tnl->vtx.tabfv[attr][sz-1]); - return tnl->vtx.tabfv[attr][sz-1]; -} - - - -#define CHOOSE( ATTR, N ) \ -static void choose_##ATTR##_##N( const GLfloat *v ) \ -{ \ - tnl_attrfv_func f = do_choose(ATTR, N); \ - ASSERT(f); \ - f( v ); \ -} - -#define CHOOSERS( ATTRIB ) \ - CHOOSE( ATTRIB, 1 ) \ - CHOOSE( ATTRIB, 2 ) \ - CHOOSE( ATTRIB, 3 ) \ - CHOOSE( ATTRIB, 4 ) \ - - -#define INIT_CHOOSERS(ATTR) \ - ASSERT(ATTR <= _TNL_ATTRIB_ERROR);\ - choose[ATTR][0] = choose_##ATTR##_1; \ - choose[ATTR][1] = choose_##ATTR##_2; \ - choose[ATTR][2] = choose_##ATTR##_3; \ - choose[ATTR][3] = choose_##ATTR##_4; - -/* conventional attributes */ -CHOOSERS( 0 ) -CHOOSERS( 1 ) -CHOOSERS( 2 ) -CHOOSERS( 3 ) -CHOOSERS( 4 ) -CHOOSERS( 5 ) -CHOOSERS( 6 ) -CHOOSERS( 7 ) -CHOOSERS( 8 ) -CHOOSERS( 9 ) -CHOOSERS( 10 ) -CHOOSERS( 11 ) -CHOOSERS( 12 ) -CHOOSERS( 13 ) -CHOOSERS( 14 ) -CHOOSERS( 15 ) - -/* generic attributes */ -CHOOSERS( 16 ) -CHOOSERS( 17 ) -CHOOSERS( 18 ) -CHOOSERS( 19 ) -CHOOSERS( 20 ) -CHOOSERS( 21 ) -CHOOSERS( 22 ) -CHOOSERS( 23 ) -CHOOSERS( 24 ) -CHOOSERS( 25 ) -CHOOSERS( 26 ) -CHOOSERS( 27 ) -CHOOSERS( 28 ) -CHOOSERS( 29 ) -CHOOSERS( 30 ) -CHOOSERS( 31 ) - - -/** - * This function will get called when glVertexAttribNV/ARB() is called - * with an invalid index parameter. - */ -static void -error_attrib(const GLfloat *unused) -{ - GET_CURRENT_CONTEXT( ctx ); - (void) unused; - _mesa_error( ctx, GL_INVALID_VALUE, "glVertexAttrib(index)" ); -} - - - -/** - * Reset all the per-vertex functions pointers to point to the default - * "chooser" functions. - */ -static void -reset_attrfv(TNLcontext *tnl) -{ - GLuint i; - - for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) - if (tnl->vtx.attrsz[i]) { - GLint j = tnl->vtx.attrsz[i] - 1; - tnl->vtx.attrsz[i] = 0; - tnl->vtx.active_sz[i] = 0; - - if (i < _TNL_MAX_ATTR_CODEGEN) { - while (j >= 0) { - tnl->vtx.tabfv[i][j] = choose[i][j]; - j--; - } - } - } - - tnl->vtx.vertex_size = 0; - tnl->vtx.have_materials = 0; -} - - - -/** - * Materials: - * - * These are treated as per-vertex attributes, at indices above where - * the NV_vertex_program leaves off. There are a lot of good things - * about treating materials this way. - * - * However: I don't want to double the number of generated functions - * just to cope with this, so I unroll the 'C' varients of CHOOSE and - * ATTRF into this function, and dispense with codegen and - * second-level dispatch. - * - * There is no aliasing of material attributes with other entrypoints. - */ -#define OTHER_ATTR( A, N, params ) \ -do { \ - if (tnl->vtx.active_sz[A] != N) { \ - _tnl_fixup_vertex( ctx, A, N ); \ - } \ - \ - { \ - GLfloat *dest = tnl->vtx.attrptr[A]; \ - if (N>0) dest[0] = (params)[0]; \ - if (N>1) dest[1] = (params)[1]; \ - if (N>2) dest[2] = (params)[2]; \ - if (N>3) dest[3] = (params)[3]; \ - } \ -} while (0) - - -#define MAT( ATTR, N, face, params ) \ -do { \ - if (face != GL_BACK) \ - OTHER_ATTR( ATTR, N, params ); /* front */ \ - if (face != GL_FRONT) \ - OTHER_ATTR( ATTR + 1, N, params ); /* back */ \ -} while (0) - - -/** - * Called by glMaterialfv(). - * Colormaterial is dealt with later on. - */ -static void GLAPIENTRY -_tnl_Materialfv( GLenum face, GLenum pname, const GLfloat *params ) -{ - GET_CURRENT_CONTEXT( ctx ); - TNLcontext *tnl = TNL_CONTEXT(ctx); - - switch (face) { - case GL_FRONT: - case GL_BACK: - case GL_FRONT_AND_BACK: - break; - default: - _mesa_error( ctx, GL_INVALID_ENUM, "glMaterialfv" ); - return; - } - - switch (pname) { - case GL_EMISSION: - MAT( _TNL_ATTRIB_MAT_FRONT_EMISSION, 4, face, params ); - break; - case GL_AMBIENT: - MAT( _TNL_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params ); - break; - case GL_DIFFUSE: - MAT( _TNL_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params ); - break; - case GL_SPECULAR: - MAT( _TNL_ATTRIB_MAT_FRONT_SPECULAR, 4, face, params ); - break; - case GL_SHININESS: - MAT( _TNL_ATTRIB_MAT_FRONT_SHININESS, 1, face, params ); - break; - case GL_COLOR_INDEXES: - MAT( _TNL_ATTRIB_MAT_FRONT_INDEXES, 3, face, params ); - break; - case GL_AMBIENT_AND_DIFFUSE: - MAT( _TNL_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params ); - MAT( _TNL_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params ); - break; - default: - _mesa_error( ctx, GL_INVALID_ENUM, "glMaterialfv" ); - return; - } - - tnl->vtx.have_materials = GL_TRUE; -} - - -static void GLAPIENTRY _tnl_EdgeFlag( GLboolean b ) -{ - GET_CURRENT_CONTEXT( ctx ); - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLfloat f = (GLfloat)b; - - OTHER_ATTR( _TNL_ATTRIB_EDGEFLAG, 1, &f ); -} - - -/* Eval - */ -static void GLAPIENTRY _tnl_EvalCoord1f( GLfloat u ) -{ - GET_CURRENT_CONTEXT( ctx ); - TNLcontext *tnl = TNL_CONTEXT(ctx); - - /* TODO: use a CHOOSE() function for this: */ - { - GLint i; - if (tnl->vtx.eval.new_state) - _tnl_update_eval( ctx ); - - for (i = 0; i < _TNL_NUM_EVAL; i++) { - if (tnl->vtx.eval.map1[i].map) - if (tnl->vtx.active_sz[i] != tnl->vtx.eval.map1[i].sz) - _tnl_fixup_vertex( ctx, i, tnl->vtx.eval.map1[i].sz ); - } - } - - - _mesa_memcpy( tnl->vtx.copied.buffer, tnl->vtx.vertex, - tnl->vtx.vertex_size * sizeof(GLfloat)); - - _tnl_do_EvalCoord1f( ctx, u ); - - _mesa_memcpy( tnl->vtx.vertex, tnl->vtx.copied.buffer, - tnl->vtx.vertex_size * sizeof(GLfloat)); -} - -static void GLAPIENTRY _tnl_EvalCoord2f( GLfloat u, GLfloat v ) -{ - GET_CURRENT_CONTEXT( ctx ); - TNLcontext *tnl = TNL_CONTEXT(ctx); - - /* TODO: use a CHOOSE() function for this: */ - { - GLint i; - if (tnl->vtx.eval.new_state) - _tnl_update_eval( ctx ); - - for (i = 0; i < _TNL_NUM_EVAL; i++) { - if (tnl->vtx.eval.map2[i].map) - if (tnl->vtx.active_sz[i] != tnl->vtx.eval.map2[i].sz) - _tnl_fixup_vertex( ctx, i, tnl->vtx.eval.map2[i].sz ); - } - - if (ctx->Eval.AutoNormal) - if (tnl->vtx.active_sz[_TNL_ATTRIB_NORMAL] != 3) - _tnl_fixup_vertex( ctx, _TNL_ATTRIB_NORMAL, 3 ); - } - - _mesa_memcpy( tnl->vtx.copied.buffer, tnl->vtx.vertex, - tnl->vtx.vertex_size * sizeof(GLfloat)); - - _tnl_do_EvalCoord2f( ctx, u, v ); - - _mesa_memcpy( tnl->vtx.vertex, tnl->vtx.copied.buffer, - tnl->vtx.vertex_size * sizeof(GLfloat)); -} - -static void GLAPIENTRY _tnl_EvalCoord1fv( const GLfloat *u ) -{ - _tnl_EvalCoord1f( u[0] ); -} - -static void GLAPIENTRY _tnl_EvalCoord2fv( const GLfloat *u ) -{ - _tnl_EvalCoord2f( u[0], u[1] ); -} - -static void GLAPIENTRY _tnl_EvalPoint1( GLint i ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLfloat du = ((ctx->Eval.MapGrid1u2 - ctx->Eval.MapGrid1u1) / - (GLfloat) ctx->Eval.MapGrid1un); - GLfloat u = i * du + ctx->Eval.MapGrid1u1; - - _tnl_EvalCoord1f( u ); -} - - -static void GLAPIENTRY _tnl_EvalPoint2( GLint i, GLint j ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLfloat du = ((ctx->Eval.MapGrid2u2 - ctx->Eval.MapGrid2u1) / - (GLfloat) ctx->Eval.MapGrid2un); - GLfloat dv = ((ctx->Eval.MapGrid2v2 - ctx->Eval.MapGrid2v1) / - (GLfloat) ctx->Eval.MapGrid2vn); - GLfloat u = i * du + ctx->Eval.MapGrid2u1; - GLfloat v = j * dv + ctx->Eval.MapGrid2v1; - - _tnl_EvalCoord2f( u, v ); -} - - -/** - * Called from glBegin. - * ctx->Driver.CurrentExecPrimitive will be set to . - */ -static void GLAPIENTRY _tnl_Begin( GLenum mode ) -{ - GET_CURRENT_CONTEXT( ctx ); - - if (mode > GL_POLYGON) { - _mesa_error(ctx, GL_INVALID_ENUM, "glBegin(mode)"); - return; - } - - if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) { - /* we're not inside a glBegin/End pair */ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint i; - - 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)"); - tnl->DiscardPrimitive = GL_TRUE; - return; - } - - if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { - _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, - "glBegin(incomplete framebuffer)"); - tnl->DiscardPrimitive = GL_TRUE; - return; - } - - tnl->DiscardPrimitive = GL_FALSE; - - if (!(tnl->Driver.NotifyBegin && - tnl->Driver.NotifyBegin( ctx, mode ))) - CALL_Begin(ctx->Exec, (mode)); - return; - } - - /* Heuristic: attempt to isolate attributes occuring outside - * begin/end pairs. - */ - if (tnl->vtx.vertex_size && !tnl->vtx.attrsz[0]) - _tnl_FlushVertices( ctx, ~0 ); - - i = tnl->vtx.prim_count++; - tnl->vtx.prim[i].mode = mode | PRIM_BEGIN; - tnl->vtx.prim[i].start = tnl->vtx.initial_counter - tnl->vtx.counter; - tnl->vtx.prim[i].count = 0; - - ctx->Driver.CurrentExecPrimitive = mode; - } - else { - /* already inside glBegin/End */ - _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" ); - } -} - - -/** - * Called from glEnd. - */ -static void GLAPIENTRY _tnl_End( void ) -{ - GET_CURRENT_CONTEXT( ctx ); - - if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) { - /* closing an open glBegin primitive */ - TNLcontext *tnl = TNL_CONTEXT(ctx); - int idx = tnl->vtx.initial_counter - tnl->vtx.counter; - int i = tnl->vtx.prim_count - 1; - - tnl->vtx.prim[i].mode |= PRIM_END; - tnl->vtx.prim[i].count = idx - tnl->vtx.prim[i].start; - - ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; - - /* Two choices which effect the way vertex attributes are - * carried over (or not) between adjacent primitives. - */ -#if 0 - if (tnl->vtx.prim_count == TNL_MAX_PRIM) - _tnl_FlushVertices( ctx, ~0 ); -#else - if (tnl->vtx.prim_count == TNL_MAX_PRIM) - _tnl_flush_vtx( ctx ); -#endif - - } - else { - /* glBegin hasn't been called! */ - _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" ); - } -} - - -/** - * XXX why aren't all members initialized here?? - */ -static void _tnl_exec_vtxfmt_init( GLcontext *ctx ) -{ - GLvertexformat *vfmt = &(TNL_CONTEXT(ctx)->exec_vtxfmt); - - vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ - vfmt->Begin = _tnl_Begin; - vfmt->CallList = _mesa_CallList; - vfmt->CallLists = _mesa_CallLists; - vfmt->EdgeFlag = _tnl_EdgeFlag; - vfmt->End = _tnl_End; - vfmt->EvalCoord1f = _tnl_EvalCoord1f; - vfmt->EvalCoord1fv = _tnl_EvalCoord1fv; - vfmt->EvalCoord2f = _tnl_EvalCoord2f; - vfmt->EvalCoord2fv = _tnl_EvalCoord2fv; - vfmt->EvalPoint1 = _tnl_EvalPoint1; - vfmt->EvalPoint2 = _tnl_EvalPoint2; - vfmt->Materialfv = _tnl_Materialfv; - - vfmt->Rectf = _mesa_noop_Rectf; - vfmt->EvalMesh1 = _mesa_noop_EvalMesh1; - vfmt->EvalMesh2 = _mesa_noop_EvalMesh2; -} - - - -void _tnl_FlushVertices( GLcontext *ctx, GLuint flags ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - (void) flags; - - if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) { - /* still inside a glBegin/End pair. How'd we get here??? */ - return; - } - - if (tnl->DiscardPrimitive) { - /* discard any primitives */ - tnl->vtx.prim_count = 0; - tnl->vtx.counter = tnl->vtx.initial_counter; - tnl->vtx.vbptr = tnl->vtx.buffer; - } - - if (tnl->vtx.counter != tnl->vtx.initial_counter) { - _tnl_flush_vtx( ctx ); - } - - if (tnl->vtx.vertex_size) { - _tnl_copy_to_current( ctx ); - reset_attrfv( tnl ); - } - - ctx->Driver.NeedFlush = 0; -} - - -/** - * Init the tnl->vtx->current[] pointers to point to the corresponding - * fields in ctx->Current attribute group. - */ -static void _tnl_current_init( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLint i; - - /* setup the pointers for the typical (32) vertex attributes */ - for (i = 0; i < VERT_ATTRIB_MAX; i++) - tnl->vtx.current[i] = ctx->Current.Attrib[i]; - - /* setup pointers for the 12 material attributes */ - for (i = 0; i < MAT_ATTRIB_MAX; i++) - tnl->vtx.current[_TNL_ATTRIB_MAT_FRONT_AMBIENT + i] = - ctx->Light.Material.Attrib[i]; - - /* special case */ - tnl->vtx.current[_TNL_ATTRIB_EDGEFLAG] = &tnl->vtx.CurrentFloatEdgeFlag; -} - -static struct _tnl_dynfn *no_codegen( GLcontext *ctx, int key ) -{ - (void) ctx; (void) key; - return NULL; -} - -void _tnl_vtx_init( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct tnl_vertex_arrays *tmp = &tnl->vtx_inputs; - GLuint i; - static int firsttime = 1; - - if (firsttime) { - firsttime = 0; - - /* conventional attributes */ - INIT_CHOOSERS( 0 ); - INIT_CHOOSERS( 1 ); - INIT_CHOOSERS( 2 ); - INIT_CHOOSERS( 3 ); - INIT_CHOOSERS( 4 ); - INIT_CHOOSERS( 5 ); - INIT_CHOOSERS( 6 ); - INIT_CHOOSERS( 7 ); - INIT_CHOOSERS( 8 ); - INIT_CHOOSERS( 9 ); - INIT_CHOOSERS( 10 ); - INIT_CHOOSERS( 11 ); - INIT_CHOOSERS( 12 ); - INIT_CHOOSERS( 13 ); - INIT_CHOOSERS( 14 ); - INIT_CHOOSERS( 15 ); - - /* generic attributes */ - INIT_CHOOSERS( 16 ); - INIT_CHOOSERS( 17 ); - INIT_CHOOSERS( 18 ); - INIT_CHOOSERS( 19 ); - INIT_CHOOSERS( 20 ); - INIT_CHOOSERS( 21 ); - INIT_CHOOSERS( 22 ); - INIT_CHOOSERS( 23 ); - INIT_CHOOSERS( 24 ); - INIT_CHOOSERS( 25 ); - INIT_CHOOSERS( 26 ); - INIT_CHOOSERS( 27 ); - INIT_CHOOSERS( 28 ); - INIT_CHOOSERS( 29 ); - INIT_CHOOSERS( 30 ); - INIT_CHOOSERS( 31 ); - - choose[_TNL_ATTRIB_ERROR][0] = error_attrib; - choose[_TNL_ATTRIB_ERROR][1] = error_attrib; - choose[_TNL_ATTRIB_ERROR][2] = error_attrib; - choose[_TNL_ATTRIB_ERROR][3] = error_attrib; - -#ifdef USE_X86_ASM - if (tnl->AllowCodegen) { - _tnl_x86choosers(choose, do_choose); /* x86 INIT_CHOOSERS */ - } -#endif - - _tnl_generic_attr_table_init( generic_attr_func ); - } - - for (i = 0; i < _TNL_ATTRIB_EDGEFLAG; i++) - _mesa_vector4f_init( &tmp->Attribs[i], 0, NULL); - - for (i = 0; i < 4; i++) { - make_empty_list( &tnl->vtx.cache.Vertex[i] ); - make_empty_list( &tnl->vtx.cache.Attribute[i] ); - tnl->vtx.gen.Vertex[i] = no_codegen; - tnl->vtx.gen.Attribute[i] = no_codegen; - } - -#ifdef USE_X86_ASM - _tnl_InitX86Codegen( &tnl->vtx.gen ); -#endif - - _tnl_current_init( ctx ); - _tnl_exec_vtxfmt_init( ctx ); - _tnl_generic_exec_vtxfmt_init( ctx ); -#ifdef USE_X86_ASM - if (tnl->AllowCodegen) { - _tnl_x86_exec_vtxfmt_init( ctx ); /* x86 DISPATCH_ATTRFV */ - } -#endif - - _mesa_install_exec_vtxfmt( ctx, &tnl->exec_vtxfmt ); - - _mesa_memcpy( tnl->vtx.tabfv, choose, sizeof(choose) ); - - for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) { - tnl->vtx.attrsz[i] = 0; - tnl->vtx.active_sz[i] = 0; - } - - tnl->vtx.vertex_size = 0; - tnl->vtx.have_materials = 0; -} - -static void free_funcs( struct _tnl_dynfn *l ) -{ - struct _tnl_dynfn *f, *tmp; - foreach_s (f, tmp, l) { - remove_from_list( f ); - ALIGN_FREE( f->code ); - FREE( f ); - } -} - - -void _tnl_vtx_destroy( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint i; - - for (i = 0; i < 4; i++) { - free_funcs( &tnl->vtx.cache.Vertex[i] ); - free_funcs( &tnl->vtx.cache.Attribute[i] ); - } -} - diff --git a/src/mesa/tnl/t_vtx_exec.c b/src/mesa/tnl/t_vtx_exec.c deleted file mode 100644 index 900c4ab6cc..0000000000 --- a/src/mesa/tnl/t_vtx_exec.c +++ /dev/null @@ -1,293 +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 - */ - -#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: - /* no parity issue, but need to make sure the tri is not drawn twice */ - if (nr & 1) { - tnl->vtx.prim[tnl->vtx.prim_count-1].count--; - } - /* fallthrough */ - 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; -} -- cgit v1.2.3 From fea6e5a69588012cf0373f36dff99a45b0202f55 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 16 Jan 2007 13:30:04 +0000 Subject: Don't special-case index, edgeflag. Remove display list opcodes for INDEX and EDGEFLAG, handle them through the regular ATTRIB mechanism now that Mesa understands them to just be regular attribs. --- src/mesa/main/dlist.c | 49 +++---------------------------------------------- 1 file changed, 3 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index dca6ede6cb..e472c6bfb4 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -343,8 +343,6 @@ typedef enum OPCODE_ATTR_3F_ARB, OPCODE_ATTR_4F_ARB, OPCODE_MATERIAL, - OPCODE_INDEX, - OPCODE_EDGEFLAG, OPCODE_BEGIN, OPCODE_END, OPCODE_RECTF, @@ -5110,45 +5108,19 @@ save_EvalPoint2(GLint x, GLint y) static void GLAPIENTRY save_Indexf(GLfloat x) { - GET_CURRENT_CONTEXT(ctx); - Node *n; - SAVE_FLUSH_VERTICES(ctx); - n = ALLOC_INSTRUCTION(ctx, OPCODE_INDEX, 1); - if (n) { - n[1].f = x; - } - - ctx->ListState.ActiveIndex = 1; - ctx->ListState.CurrentIndex = x; - - if (ctx->ExecuteFlag) { - CALL_Indexf(ctx->Exec, (x)); - } + save_Attr1fNV(VERT_ATTRIB_COLOR_INDEX, x); } static void GLAPIENTRY save_Indexfv(const GLfloat * v) { - save_Indexf(v[0]); + save_Attr1fNV(VERT_ATTRIB_COLOR_INDEX, v[0]); } static void GLAPIENTRY save_EdgeFlag(GLboolean x) { - GET_CURRENT_CONTEXT(ctx); - Node *n; - SAVE_FLUSH_VERTICES(ctx); - n = ALLOC_INSTRUCTION(ctx, OPCODE_EDGEFLAG, 1); - if (n) { - n[1].b = x; - } - - ctx->ListState.ActiveEdgeFlag = 1; - ctx->ListState.CurrentEdgeFlag = x; - - if (ctx->ExecuteFlag) { - CALL_EdgeFlag(ctx->Exec, (x)); - } + save_Attr1fNV(VERT_ATTRIB_EDGEFLAG, x ? 1.0 : 0.0); } static void GLAPIENTRY @@ -6602,12 +6574,6 @@ execute_list(GLcontext *ctx, GLuint list) CALL_Materialfv(ctx->Exec, (n[1].e, n[2].e, f)); } break; - case OPCODE_INDEX: - CALL_Indexf(ctx->Exec, (n[1].f)); - break; - case OPCODE_EDGEFLAG: - CALL_EdgeFlag(ctx->Exec, (n[1].b)); - break; case OPCODE_BEGIN: CALL_Begin(ctx->Exec, (n[1].e)); break; @@ -6793,9 +6759,6 @@ _mesa_NewList(GLuint list, GLenum mode) for (i = 0; i < MAT_ATTRIB_MAX; i++) ctx->ListState.ActiveMaterialSize[i] = 0; - ctx->ListState.ActiveIndex = 0; - ctx->ListState.ActiveEdgeFlag = 0; - ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN; ctx->Driver.NewList(ctx, list, mode); @@ -8421,12 +8384,6 @@ print_list(GLcontext *ctx, GLuint list) _mesa_printf("MATERIAL %x %x: %f %f %f %f\n", n[1].i, n[2].i, n[3].f, n[4].f, n[5].f, n[6].f); break; - case OPCODE_INDEX: - _mesa_printf("INDEX: %f\n", n[1].f); - break; - case OPCODE_EDGEFLAG: - _mesa_printf("EDGEFLAG: %d\n", n[1].i); - break; case OPCODE_BEGIN: _mesa_printf("BEGIN %x\n", n[1].i); break; -- cgit v1.2.3 From 7c8f311e406a4502982fd03e09d61f6269e0e82c Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Tue, 16 Jan 2007 21:43:54 +0100 Subject: nouveau: Use the most recent card list. --- src/mesa/drivers/dri/nouveau/nouveau_card_list.h | 170 ++++++++++++----------- 1 file changed, 86 insertions(+), 84 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_card_list.h b/src/mesa/drivers/dri/nouveau/nouveau_card_list.h index 14e7b69802..8ec5c4a188 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_card_list.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_card_list.h @@ -2,15 +2,15 @@ static nouveau_card nouveau_card_list[]={ {0x0008, "EDGE 3D", 0, NV_03, 0}, {0x0009, "EDGE 3D", 0, NV_03, 0}, {0x0010, "Mutara V08", 0, NV_03, 0}, -{0x0020, "RIVA TNT", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, -{0x0028, "RIVA TNT2/TNT2 Pro", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, -{0x0029, "RIVA TNT2 Ultra", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, -{0x002A, "Riva TnT2", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, -{0x002B, "Riva TnT2", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, -{0x002C, "Vanta/Vanta LT", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, -{0x002D, "RIVA TNT2 Model 64/Model 64 Pro", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, -{0x002E, "Vanta", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, -{0x002F, "Vanta", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, +{0x0020, "RIVA TNT", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x0028, "RIVA TNT2/TNT2 Pro", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x0029, "RIVA TNT2 Ultra", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x002A, "Riva TnT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x002B, "Riva TnT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x002C, "Vanta/Vanta LT", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x002D, "RIVA TNT2 Model 64/Model 64 Pro", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x002E, "Vanta", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x002F, "Vanta", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, {0x0040, "GeForce 6800 Ultra", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x0041, "GeForce 6800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x0042, "GeForce 6800 LE", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, @@ -30,7 +30,7 @@ static nouveau_card nouveau_card_list[]={ {0x0098, "GeForce Go 7800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x0099, "GE Force Go 7800 GTX", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x009D, "Quadro FX4500", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, -{0x00A0, "Aladdin TNT2", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, +{0x00A0, "Aladdin TNT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, {0x00C0, "GeForce 6800 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x00C1, "GeForce 6800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x00C2, "GeForce 6800 LE", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, @@ -49,11 +49,11 @@ static nouveau_card nouveau_card_list[]={ {0x00F6, "GeForce 6600 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x00F8, "Quadro FX 3400/4400", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x00F9, "GeForce 6800 Ultra/GeForce 6800 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, -{0x00FA, "GeForce PCX 5750", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, +{0x00FA, "GeForce PCX 5750", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, {0x00FB, "GeForce PCX 5900", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, {0x00FC, "Quadro FX 330/GeForce PCX 5300", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0}, {0x00FD, "Quadro FX 330/Quadro NVS280", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0}, -{0x00FE, "Quadro FX 1300", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, +{0x00FE, "Quadro FX 1300", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, {0x00FF, "GeForce PCX 4300", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, {0x0100, "GeForce 256 SDR", NV10_TCL_PRIMITIVE_3D, NV_10, 0}, {0x0101, "GeForce 256 DDR", NV10_TCL_PRIMITIVE_3D, NV_10, 0}, @@ -71,7 +71,8 @@ static nouveau_card nouveau_card_list[]={ {0x0148, "GeForce Go 6600", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x0149, "GeForce Go 6600 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x014A, "Quadro NVS 440", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, -{0x014D, "Quadro FX 550", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x014C, "Quadro FX 550", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x014D, "Quadro FX 550", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x014E, "Quadro FX 540", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x014F, "GeForce 6200", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x0150, "GeForce2 GTS/Pro", NV11_TCL_PRIMITIVE_3D, NV_15, 0}, @@ -121,10 +122,10 @@ static nouveau_card nouveau_card_list[]={ {0x01DA, "Quadro NVS 110M", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, {0x01DF, "GeForce 7300 GS", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, {0x01F0, "GeForce4 MX - nForce GPU", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, -{0x0200, "GeForce3", NV20_TCL_PRIMITIVE_3D|0x2000, NV_20, 0}, -{0x0201, "GeForce3 Ti 200", NV20_TCL_PRIMITIVE_3D|0x2000, NV_20, 0}, -{0x0202, "GeForce3 Ti 500", NV20_TCL_PRIMITIVE_3D|0x2000, NV_20, 0}, -{0x0203, "Quadro DCC", NV20_TCL_PRIMITIVE_3D|0x2000, NV_20, 0}, +{0x0200, "GeForce3", NV20_TCL_PRIMITIVE_3D, NV_20, 0}, +{0x0201, "GeForce3 Ti 200", NV20_TCL_PRIMITIVE_3D, NV_20, 0}, +{0x0202, "GeForce3 Ti 500", NV20_TCL_PRIMITIVE_3D, NV_20, 0}, +{0x0203, "Quadro DCC", NV20_TCL_PRIMITIVE_3D, NV_20, 0}, {0x0211, "GeForce 6800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x0212, "GeForce 6800 LE", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x0215, "GeForce 6800 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, @@ -132,21 +133,21 @@ static nouveau_card nouveau_card_list[]={ {0x0221, "GeForce 6200", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, {0x0240, "GeForce 6150", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, {0x0242, "GeForce 6100", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, -{0x0244, "GeForce 6150 Go", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, -{0x0250, "GeForce4 Ti 4600", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, -{0x0251, "GeForce4 Ti 4400", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, -{0x0252, "GeForce4 Ti", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, -{0x0253, "GeForce4 Ti 4200", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, -{0x0258, "Quadro4 900 XGL", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, -{0x0259, "Quadro4 750 XGL", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, -{0x025B, "Quadro4 700 XGL", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, -{0x0280, "GeForce4 Ti 4800", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, -{0x0281, "GeForce4 Ti 4200 AGP 8x", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, -{0x0282, "GeForce4 Ti 4800 SE", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, -{0x0286, "GeForce4 Ti 4200 Go AGP 8x", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, -{0x0288, "Quadro4 980 XGL", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, -{0x0289, "Quadro4 780 XGL", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, -{0x028C, "Quadro4 700 GoGL", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, +{0x0244, "Geforce 6150 Go", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, +{0x0250, "GeForce4 Ti 4600", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0251, "GeForce4 Ti 4400", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0252, "GeForce4 Ti", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0253, "GeForce4 Ti 4200", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0258, "Quadro4 900 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0259, "Quadro4 750 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x025B, "Quadro4 700 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0280, "GeForce4 Ti 4800", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0281, "GeForce4 Ti 4200 AGP 8x", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0282, "GeForce4 Ti 4800 SE", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0286, "GeForce4 Ti 4200 Go AGP 8x", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0288, "Quadro4 980 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0289, "Quadro4 780 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x028C, "Quadro4 700 GoGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, {0x0290, "GeForce 7900 GTX", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x0291, "GeForce 7900 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x0292, "GeForce 7900 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, @@ -158,58 +159,59 @@ static nouveau_card nouveau_card_list[]={ {0x029D, "Quadro FX 3500", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x029E, "Quadro FX 1500", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x029F, "Quadro FX 4500 X2", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, -{0x02A0, "XGPU", NV20_TCL_PRIMITIVE_3D|0x2000, NV_20, 0}, +{0x02A0, "XGPU", NV20_TCL_PRIMITIVE_3D, NV_20, 0}, {0x02E1, "GeForce 7600 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, -{0x0300, "GeForce FX", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0301, "GeForce FX 5800 Ultra", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0302, "GeForce FX 5800", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0308, "Quadro FX 2000", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0309, "Quadro FX 1000", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0311, "GeForce FX 5600 Ultra", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0312, "GeForce FX 5600", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0313, "NV31", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0314, "GeForce FX 5600XT", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0316, "NV31M", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0317, "NV31M Pro", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x031A, "GeForce FX Go5600", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x031B, "GeForce FX Go5650", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x031D, "NV31GLM", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x031E, "NV31GLM Pro", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x031F, "NV31GLM Pro", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0320, "GeForce FX 5200", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, -{0x0321, "GeForce FX 5200 Ultra", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, -{0x0322, "GeForce FX 5200", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, -{0x0323, "GeForce FX 5200LE", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, -{0x0324, "GeForce FX Go5200", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, -{0x0325, "GeForce FX Go5250", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, -{0x0326, "GeForce FX 5500", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, -{0x0327, "GeForce FX 5100", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, -{0x0328, "GeForce FX Go5200 32M/64M", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, -{0x0329, "GeForce FX Go5200", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, -{0x032A, "Quadro NVS 280 PCI", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, -{0x032B, "Quadro FX 500/600 PCI", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, -{0x032C, "GeForce FX Go 5300", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, -{0x032D, "GeForce FX Go5100", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, -{0x032F, "NV34GL", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, +{0x0300, "GeForce FX", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0301, "GeForce FX 5800 Ultra", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0302, "GeForce FX 5800", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0308, "Quadro FX 2000", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0309, "Quadro FX 1000", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0311, "GeForce FX 5600 Ultra", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0312, "GeForce FX 5600", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0313, "NV31", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0314, "GeForce FX 5600XT", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0316, "NV31M", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0317, "NV31M Pro", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x031A, "GeForce FX Go5600", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x031B, "GeForce FX Go5650", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x031C, "NVIDIA Quadro FX Go700", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x031D, "NV31GLM", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x031E, "NV31GLM Pro", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x031F, "NV31GLM Pro", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0320, "GeForce FX 5200", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x0321, "GeForce FX 5200 Ultra", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x0322, "GeForce FX 5200", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x0323, "GeForce FX 5200LE", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x0324, "GeForce FX Go5200", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x0325, "GeForce FX Go5250", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x0326, "GeForce FX 5500", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x0327, "GeForce FX 5100", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x0328, "GeForce FX Go5200 32M/64M", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x0329, "GeForce FX Go5200", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x032A, "Quadro NVS 280 PCI", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x032B, "Quadro FX 500/600 PCI", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x032C, "GeForce FX Go 5300", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x032D, "GeForce FX Go5100", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x032F, "NV34GL", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, {0x0330, "GeForce FX 5900 Ultra", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, {0x0331, "GeForce FX 5900", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, {0x0332, "GeForce FX 5900XT", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, -{0x0333, "GeForce FX 5950 Ultra", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, +{0x0333, "GeForce FX 5950 Ultra", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, {0x0334, "GeForce FX 5900ZT", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, -{0x0338, "Quadro FX 3000", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x033F, "Quadro FX 700", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0341, "GeForce FX 5700 Ultra", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0342, "GeForce FX 5700", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0343, "GeForce FX 5700LE", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0344, "GeForce FX 5700VE", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0345, "NV36.5", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0347, "GeForce FX Go5700", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0348, "GeForce FX Go5700", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0349, "NV36M Pro", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x034B, "NV36MAP", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x034C, "Quadro FX Go1000", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x034E, "Quadro FX 1100", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x034F, "NV36GL", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, +{0x0338, "Quadro FX 3000", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x033F, "Quadro FX 700", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0341, "GeForce FX 5700 Ultra", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0342, "GeForce FX 5700", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0343, "GeForce FX 5700LE", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0344, "GeForce FX 5700VE", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0345, "NV36.5", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0347, "GeForce FX Go5700", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0348, "GeForce FX Go5700", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0349, "NV36M Pro", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x034B, "NV36MAP", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x034C, "Quadro FX Go1000", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x034E, "Quadro FX 1100", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x034F, "NV36GL", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, {0x0391, "GeForce 7600 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x0392, "GeForce 7600 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x0393, "GeForce 7300 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, @@ -222,9 +224,9 @@ static nouveau_card nouveau_card_list[]={ {0x0009, "DAC64", 0, NV_03, 0}, {0x0018, "Riva128", 0, NV_03, 0}, {0x0019, "Riva128ZX", 0, NV_03, 0}, -{0x0020, "TNT", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, -{0x0028, "TNT2", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, -{0x0029, "UTNT2", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, -{0x002C, "VTNT2", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, -{0x00A0, "ITNT2", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, +{0x0020, "TNT", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x0028, "TNT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x0029, "UTNT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x002C, "VTNT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x00A0, "ITNT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, }; -- cgit v1.2.3 From 747c9129c0b592941b14c290ff3d8ab22ad66acb Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Wed, 17 Jan 2007 10:39:50 +0800 Subject: I965: fix bug#9625-get the correct PV for quardstrip The order of vertices in payload for quardstrip is (0, 1, 3, 2), so the PV for quardstrip is c->reg.vertex[2]. --- src/mesa/drivers/dri/i965/brw_gs.c | 5 ++++- src/mesa/drivers/dri/i965/brw_gs.h | 1 + src/mesa/drivers/dri/i965/brw_gs_emit.c | 10 ++++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_gs.c b/src/mesa/drivers/dri/i965/brw_gs.c index 9066e42252..73263a5fff 100644 --- a/src/mesa/drivers/dri/i965/brw_gs.c +++ b/src/mesa/drivers/dri/i965/brw_gs.c @@ -82,6 +82,9 @@ static void compile_gs_prog( struct brw_context *brw, case GL_QUADS: brw_gs_quads( &c ); break; + case GL_QUAD_STRIP: + brw_gs_quad_strip( &c ); + break; case GL_LINE_LOOP: brw_gs_lines( &c ); break; @@ -145,7 +148,7 @@ static const GLenum gs_prim[GL_POLYGON+1] = { GL_TRIANGLES, GL_TRIANGLES, GL_QUADS, - GL_QUADS, + GL_QUAD_STRIP, GL_TRIANGLES }; diff --git a/src/mesa/drivers/dri/i965/brw_gs.h b/src/mesa/drivers/dri/i965/brw_gs.h index f9aa71d919..29a4e80ce1 100644 --- a/src/mesa/drivers/dri/i965/brw_gs.h +++ b/src/mesa/drivers/dri/i965/brw_gs.h @@ -67,6 +67,7 @@ struct brw_gs_compile { #define ATTR_SIZE (4*4) void brw_gs_quads( struct brw_gs_compile *c ); +void brw_gs_quad_strip( struct brw_gs_compile *c ); void brw_gs_tris( struct brw_gs_compile *c ); void brw_gs_lines( struct brw_gs_compile *c ); void brw_gs_points( struct brw_gs_compile *c ); diff --git a/src/mesa/drivers/dri/i965/brw_gs_emit.c b/src/mesa/drivers/dri/i965/brw_gs_emit.c index e4eed36a46..9abb94d82e 100644 --- a/src/mesa/drivers/dri/i965/brw_gs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_gs_emit.c @@ -116,6 +116,16 @@ void brw_gs_quads( struct brw_gs_compile *c ) brw_gs_emit_vue(c, c->reg.vertex[2], 1, ((_3DPRIM_POLYGON << 2) | R02_PRIM_END)); } +void brw_gs_quad_strip( struct brw_gs_compile *c ) +{ + brw_gs_alloc_regs(c, 4); + + brw_gs_emit_vue(c, c->reg.vertex[2], 0, ((_3DPRIM_POLYGON << 2) | R02_PRIM_START)); + brw_gs_emit_vue(c, c->reg.vertex[3], 0, (_3DPRIM_POLYGON << 2)); + brw_gs_emit_vue(c, c->reg.vertex[0], 0, (_3DPRIM_POLYGON << 2)); + brw_gs_emit_vue(c, c->reg.vertex[1], 1, ((_3DPRIM_POLYGON << 2) | R02_PRIM_END)); +} + void brw_gs_tris( struct brw_gs_compile *c ) { brw_gs_alloc_regs(c, 3); -- cgit v1.2.3 From 2cb3594af9cd1434aa2c408cd6f8d51bcd12e8ea Mon Sep 17 00:00:00 2001 From: Aapo Tahkola Date: Thu, 18 Jan 2007 04:17:56 +0200 Subject: Fix invalid enums passed to MapBuffer --- src/mesa/vbo/vbo_exec_array.c | 2 +- src/mesa/vbo/vbo_save_api.c | 2 +- src/mesa/vbo/vbo_split_copy.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index cec353cf43..e0a6240c2a 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -334,7 +334,7 @@ vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *ind if (ctx->Array.ElementArrayBufferObj->Name) { const GLvoid *map = ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, - GL_DYNAMIC_READ_ARB, + GL_READ_ONLY, ctx->Array.ElementArrayBufferObj); max_index = get_max_index(count, type, ADD_POINTERS(map, indices)); diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c index f718cdd91a..c08fd1fe55 100644 --- a/src/mesa/vbo/vbo_save_api.c +++ b/src/mesa/vbo/vbo_save_api.c @@ -198,7 +198,7 @@ static GLfloat *map_vertex_store( GLcontext *ctx, struct vbo_save_vertex_store * assert(!vertex_store->buffer); vertex_store->buffer = (GLfloat *)ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER_ARB, /* not used */ - GL_STATIC_DRAW_ARB, /* not used */ + GL_WRITE_ONLY, /* not used */ vertex_store->bufferobj); assert(vertex_store->buffer); diff --git a/src/mesa/vbo/vbo_split_copy.c b/src/mesa/vbo/vbo_split_copy.c index 08eae2db40..fff733ccb5 100644 --- a/src/mesa/vbo/vbo_split_copy.c +++ b/src/mesa/vbo/vbo_split_copy.c @@ -382,7 +382,7 @@ static void replay_init( struct copy_context *copy ) if (vbo->Name && !vbo->Pointer) ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER_ARB, - GL_DYNAMIC_DRAW_ARB, /* XXX */ + GL_WRITE_ONLY, /* XXX */ vbo); copy->varying[j].src_ptr = ADD_POINTERS(vbo->Pointer, @@ -399,7 +399,7 @@ static void replay_init( struct copy_context *copy ) if (copy->ib->obj->Name && !copy->ib->obj->Pointer) ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER_ARB, /* XXX */ - GL_DYNAMIC_DRAW_ARB, /* XXX */ + GL_WRITE_ONLY, /* XXX */ copy->ib->obj); switch (copy->ib->type) { -- cgit v1.2.3 From a3b4b1173950599785e4f05278e868180a2bf387 Mon Sep 17 00:00:00 2001 From: Aapo Tahkola Date: Thu, 18 Jan 2007 04:46:04 +0200 Subject: Fix invalid enums passed to MapBuffer --- src/mesa/vbo/vbo_save_draw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c index daa686072e..a50d1cd904 100644 --- a/src/mesa/vbo/vbo_save_draw.c +++ b/src/mesa/vbo/vbo_save_draw.c @@ -152,7 +152,7 @@ static void vbo_save_loopback_vertex_list( GLcontext *ctx, { const char *buffer = ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER_ARB, - GL_DYNAMIC_READ_ARB, /* ? */ + GL_READ_ONLY, /* ? */ list->vertex_store->bufferobj); vbo_loopback_vertex_list( ctx, -- cgit v1.2.3 From feeed10dfd1495eb15924868fec3b795fb4b1ba3 Mon Sep 17 00:00:00 2001 From: Aapo Tahkola Date: Thu, 18 Jan 2007 05:30:20 +0200 Subject: typo fix. this case still fails. --- src/mesa/vbo/vbo_split.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/vbo/vbo_split.c b/src/mesa/vbo/vbo_split.c index 171859a18e..ef205a3bb1 100644 --- a/src/mesa/vbo/vbo_split.c +++ b/src/mesa/vbo/vbo_split.c @@ -121,7 +121,7 @@ void vbo_split_prims( GLcontext *ctx, */ assert(0); } - else if (max_index - min_index > limits->max_verts) { + else if (max_index - min_index >= limits->max_verts) { /* The vertex buffers are too large for hardware (or the * swtnl module). Traverse the indices, re-emitting vertices * in turn. Use a vertex cache to preserve some of the -- cgit v1.2.3 From 62efc4ba3eb53ca75abbe9b52feabe49a5fd56b5 Mon Sep 17 00:00:00 2001 From: Aapo Tahkola Date: Thu, 18 Jan 2007 05:56:13 +0200 Subject: support as much of GL_EXT_stencil_two_side as we can. untested. --- src/mesa/drivers/dri/r300/r300_context.c | 8 ++++++++ src/mesa/drivers/dri/r300/r300_render.c | 4 ++++ src/mesa/drivers/dri/r300/r300_state.c | 27 +++++++++++++++++++-------- src/mesa/drivers/dri/radeon/radeon_screen.c | 8 +++++++- 4 files changed, 38 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index 54eb081d05..71402761ae 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -73,6 +73,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. int future_hw_tcl_on=1; int hw_tcl_on=1; +#define need_GL_EXT_stencil_two_side #define need_GL_ARB_multisample #define need_GL_ARB_texture_compression #define need_GL_ARB_vertex_buffer_object @@ -126,6 +127,10 @@ const struct dri_extension card_extensions[] = { {NULL, NULL} }; +const struct dri_extension stencil_two_side[] = { + {"GL_EXT_stencil_two_side", GL_EXT_stencil_two_side_functions}, +}; + extern struct tnl_pipeline_stage _r300_render_stage; extern const struct tnl_pipeline_stage _r300_tcl_stage; extern const struct tnl_pipeline_stage _r300_texrect_stage; @@ -331,6 +336,9 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, driInitExtensions(ctx, card_extensions, GL_TRUE); + if (driQueryOptionb(&r300->radeon.optionCache, "disable_stencil_two_side") == 0) + driInitSingleExtension(ctx, stencil_two_side); + if (r300->radeon.glCtx->Mesa_DXTn && !driQueryOptionb (&r300->radeon.optionCache, "disable_s3tc")) { _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); _mesa_enable_extension( ctx, "GL_S3_s3tc" ); diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index 03f168365d..91305cb5a2 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -406,6 +406,10 @@ int r300Fallback(GLcontext *ctx) */ FALLBACK_IF(ctx->Fog.Enabled); #endif + FALLBACK_IF(ctx->Stencil._TestTwoSide && + (ctx->Stencil.Ref[0] != ctx->Stencil.Ref[1] || + ctx->Stencil.ValueMask[0] != ctx->Stencil.ValueMask[1] || + ctx->Stencil.WriteMask[0] != ctx->Stencil.WriteMask[1])); if(!r300->disable_lowimpact_fallback){ /* GL_POLYGON_OFFSET_POINT */ diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 72255066d5..6a22ccad2f 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -509,7 +509,6 @@ static void r300Enable(GLcontext* ctx, GLenum cap, GLboolean state) if (r300->state.stencil.hw_stencil) { R300_STATECHANGE(r300, zs); if (state) { - WARN_ONCE("TODO - double side stencil !\n"); r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_RB3D_STENCIL_ENABLE; } else { @@ -863,9 +862,12 @@ static void r300StencilFuncSeparate(GLcontext * ctx, GLenum face, (R300_RB3D_ZS2_STENCIL_MASK << R300_RB3D_ZS2_STENCIL_MASK_SHIFT)); flag = translate_func(ctx->Stencil.Function[0]); - - rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= (flag << R300_RB3D_ZS1_FRONT_FUNC_SHIFT) - | (flag << R300_RB3D_ZS1_BACK_FUNC_SHIFT); + rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= (flag << R300_RB3D_ZS1_FRONT_FUNC_SHIFT); + + if (ctx->Stencil._TestTwoSide) + flag = translate_func(ctx->Stencil.Function[1]); + + rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= (flag << R300_RB3D_ZS1_BACK_FUNC_SHIFT); rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |= refmask; } @@ -894,10 +896,19 @@ static void r300StencilOpSeparate(GLcontext * ctx, GLenum face, GLenum fail, rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= (translate_stencil_op(ctx->Stencil.FailFunc[0]) << R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT) |(translate_stencil_op(ctx->Stencil.ZFailFunc[0]) << R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT) - |(translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT) - |(translate_stencil_op(ctx->Stencil.FailFunc[0]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT) - |(translate_stencil_op(ctx->Stencil.ZFailFunc[0]) << R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT) - |(translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT); + |(translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT); + + if (ctx->Stencil._TestTwoSide) { + rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= + (translate_stencil_op(ctx->Stencil.FailFunc[1]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT) + |(translate_stencil_op(ctx->Stencil.ZFailFunc[1]) << R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT) + |(translate_stencil_op(ctx->Stencil.ZPassFunc[1]) << R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT); + } else { + rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= + (translate_stencil_op(ctx->Stencil.FailFunc[0]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT) + |(translate_stencil_op(ctx->Stencil.ZFailFunc[0]) << R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT) + |(translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT); + } } static void r300ClearStencil(GLcontext * ctx, GLint s) diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 279357ab59..cee1f7e2f9 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -163,6 +163,11 @@ DRI_CONF_OPT_BEGIN(disable_lowimpact_fallback,bool,def) \ DRI_CONF_DESC(en,"Disable Low-impact fallback") \ DRI_CONF_OPT_END +#define DRI_CONF_DISABLE_DOUBLE_SIDE_STENCIL(def) \ +DRI_CONF_OPT_BEGIN(disable_stencil_two_side,bool,def) \ + DRI_CONF_DESC(en,"Disable GL_EXT_stencil_two_side") \ +DRI_CONF_OPT_END + const char __driConfigOptions[] = DRI_CONF_BEGIN @@ -174,6 +179,7 @@ DRI_CONF_BEGIN DRI_CONF_MAX_TEXTURE_COORD_UNITS(8, 2, 8) DRI_CONF_COMMAND_BUFFER_SIZE(8, 8, 32) DRI_CONF_DISABLE_FALLBACK(false) + DRI_CONF_DISABLE_DOUBLE_SIDE_STENCIL(false) DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB) @@ -189,7 +195,7 @@ DRI_CONF_BEGIN DRI_CONF_NO_RAST(false) DRI_CONF_SECTION_END DRI_CONF_END; -static const GLuint __driNConfigOptions = 16; +static const GLuint __driNConfigOptions = 17; #ifndef RADEON_DEBUG int RADEON_DEBUG = 0; -- cgit v1.2.3 From 3c59483ed7c5700a58f47ca9b4a61214d02c9307 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Thu, 18 Jan 2007 22:07:17 +0100 Subject: nouveau: preliminary nv50 state --- src/mesa/drivers/dri/nouveau/Makefile | 1 + src/mesa/drivers/dri/nouveau/nv50_state.c | 567 ++++++++++++++++++++++++++++++ 2 files changed, 568 insertions(+) create mode 100644 src/mesa/drivers/dri/nouveau/nv50_state.c (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile index 9eb40fb9c1..7ffba27bac 100644 --- a/src/mesa/drivers/dri/nouveau/Makefile +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -31,6 +31,7 @@ DRIVER_SOURCES = \ nv10_state.c \ nv20_state.c \ nv30_state.c \ + nv50_state.c \ nouveau_state_cache.c \ nv20_vertprog.c \ nv30_fragprog.c \ diff --git a/src/mesa/drivers/dri/nouveau/nv50_state.c b/src/mesa/drivers/dri/nouveau/nv50_state.c new file mode 100644 index 0000000000..d03c6bf6f2 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv50_state.c @@ -0,0 +1,567 @@ +/************************************************************************** + +Copyright 2006 Nouveau +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 +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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. + +**************************************************************************/ + +#include "nouveau_context.h" +#include "nouveau_object.h" +#include "nouveau_fifo.h" +#include "nouveau_reg.h" +#include "nouveau_state.h" + +#include "tnl/t_pipeline.h" + +#include "mtypes.h" +#include "colormac.h" + +static void nv50AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte ubRef; + CLAMPED_FLOAT_TO_UBYTE(ubRef, ref); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF, 2); + OUT_RING_CACHE(ubRef); + OUT_RING_CACHE(func); +} + +static void nv50BlendColor(GLcontext *ctx, const GLfloat color[4]) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_BLEND_COLOR_R, 4); + OUT_RING_CACHEf(color[0]); + OUT_RING_CACHEf(color[1]); + OUT_RING_CACHEf(color[2]); + OUT_RING_CACHEf(color[3]); +} + +static void nv50BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_BLEND_EQUATION_RGB, 1); + OUT_RING_CACHE(modeRGB); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_BLEND_EQUATION_ALPHA, 1); + OUT_RING_CACHE(modeA); +} + + +static void nv50BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC_RGB, 2); + OUT_RING_CACHE(sfactorRGB); /* FIXME, sometimes has |0x4000 */ + OUT_RING_CACHE(dfactorRGB); /* FIXME, sometimes has |0x4000 */ + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC_ALPHA, 2); + OUT_RING_CACHE(sfactorA); /* FIXME, sometimes has |0x4000 */ + OUT_RING_CACHE(dfactorA); /* FIXME, sometimes has |0x4000 */ +} + +static void nv50Clear(GLcontext *ctx, GLbitfield mask) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLuint hw_bufs = 0; + + if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT)) + hw_bufs |= 0x3c; + if (mask & (BUFFER_BIT_STENCIL)) + hw_bufs |= 0x02; + if (mask & (BUFFER_BIT_DEPTH)) + hw_bufs |= 0x01; + + if (hw_bufs) { + BEGIN_RING_SIZE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CLEAR_BUFFERS, 1); + OUT_RING(hw_bufs); + } +} + +static void nv50ClearColor(GLcontext *ctx, const GLfloat color[4]) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CLEAR_COLOR_R, 4); + OUT_RING_CACHEf(color[0]); + OUT_RING_CACHEf(color[1]); + OUT_RING_CACHEf(color[2]); + OUT_RING_CACHEf(color[3]); +} + +static void nv50ClearDepth(GLcontext *ctx, GLclampd d) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CLEAR_DEPTH, 1); + OUT_RING_CACHEf(d); +} + +/* we're don't support indexed buffers + void (*ClearIndex)(GLcontext *ctx, GLuint index) + */ + +static void nv50ClearStencil(GLcontext *ctx, GLint s) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CLEAR_STENCIL, 1); + OUT_RING_CACHE(s); +} + +static void nv50ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) +{ + /* Only using shaders */ +} + +static void nv50ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, + GLboolean bmask, GLboolean amask ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + int i; + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_COLOR_MASK(0), 8); + for (i=0; i<8; i++) { + OUT_RING_CACHE(((amask && 0x01) << 12) | ((bmask && 0x01) << 8) | ((gmask && 0x01)<< 4) | ((rmask && 0x01) << 0)); + } +} + +static void nv50ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode) +{ + // TODO I need love +} + +static void nv50CullFace(GLcontext *ctx, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CULL_FACE, 1); + OUT_RING_CACHE(mode); +} + +static void nv50FrontFace(GLcontext *ctx, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_FRONT_FACE, 1); + OUT_RING_CACHE(mode); +} + +static void nv50DepthFunc(GLcontext *ctx, GLenum func) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1); + OUT_RING_CACHE(func); +} + +static void nv50DepthMask(GLcontext *ctx, GLboolean flag) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1); + OUT_RING_CACHE(flag); +} + +static void nv50DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2); + OUT_RING_CACHEf(nearval); + OUT_RING_CACHEf(farval); +} + +/** Specify the current buffer for writing */ +//void (*DrawBuffer)( GLcontext *ctx, GLenum buffer ); +/** Specify the buffers for writing for fragment programs*/ +//void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers ); + +static void nv50Enable(GLcontext *ctx, GLenum cap, GLboolean state) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + switch(cap) + { + case GL_ALPHA_TEST: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_AUTO_NORMAL: +// case GL_BLEND: +// case GL_CLIP_PLANE0: +// case GL_CLIP_PLANE1: +// case GL_CLIP_PLANE2: +// case GL_CLIP_PLANE3: +// case GL_CLIP_PLANE4: +// case GL_CLIP_PLANE5: + case GL_COLOR_LOGIC_OP: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LOGIC_OP_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_COLOR_MATERIAL: +// case GL_COLOR_SUM_EXT: +// case GL_COLOR_TABLE: +// case GL_CONVOLUTION_1D: +// case GL_CONVOLUTION_2D: + case GL_CULL_FACE: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_DEPTH_TEST: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_DITHER: +// case GL_FOG: +// case GL_HISTOGRAM: +// case GL_INDEX_LOGIC_OP: +// case GL_LIGHT0: +// case GL_LIGHT1: +// case GL_LIGHT2: +// case GL_LIGHT3: +// case GL_LIGHT4: +// case GL_LIGHT5: +// case GL_LIGHT6: +// case GL_LIGHT7: +// case GL_LIGHTING: + case GL_LINE_SMOOTH: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_LINE_STIPPLE: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LINE_STIPPLE_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_MAP1_COLOR_4: +// case GL_MAP1_INDEX: +// case GL_MAP1_NORMAL: +// case GL_MAP1_TEXTURE_COORD_1: +// case GL_MAP1_TEXTURE_COORD_2: +// case GL_MAP1_TEXTURE_COORD_3: +// case GL_MAP1_TEXTURE_COORD_4: +// case GL_MAP1_VERTEX_3: +// case GL_MAP1_VERTEX_4: +// case GL_MAP2_COLOR_4: +// case GL_MAP2_INDEX: +// case GL_MAP2_NORMAL: +// case GL_MAP2_TEXTURE_COORD_1: +// case GL_MAP2_TEXTURE_COORD_2: +// case GL_MAP2_TEXTURE_COORD_3: +// case GL_MAP2_TEXTURE_COORD_4: +// case GL_MAP2_VERTEX_3: +// case GL_MAP2_VERTEX_4: +// case GL_MINMAX: +// case GL_NORMALIZE: +// case GL_POINT_SMOOTH: + case GL_POLYGON_OFFSET_POINT: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_POLYGON_OFFSET_LINE: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_POLYGON_OFFSET_FILL: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_POLYGON_SMOOTH: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_POLYGON_STIPPLE: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_POST_COLOR_MATRIX_COLOR_TABLE: +// case GL_POST_CONVOLUTION_COLOR_TABLE: +// case GL_RESCALE_NORMAL: +// case GL_SCISSOR_TEST: +// case GL_SEPARABLE_2D: + case GL_STENCIL_TEST: + // TODO BACK and FRONT ? + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_ENABLE, 1); + OUT_RING_CACHE(state); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_TEXTURE_GEN_Q: +// case GL_TEXTURE_GEN_R: +// case GL_TEXTURE_GEN_S: +// case GL_TEXTURE_GEN_T: +// case GL_TEXTURE_1D: +// case GL_TEXTURE_2D: +// case GL_TEXTURE_3D: + } +} + +static void nv50Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + /* Only using shaders */ +} + +static void nv50Hint(GLcontext *ctx, GLenum target, GLenum mode) +{ + // TODO I need love (fog and line_smooth hints) +} + +// void (*IndexMask)(GLcontext *ctx, GLuint mask); + +static void nv50Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params ) +{ + /* Only with shaders */ +} + +/** Set the lighting model parameters */ +void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params); + + +static void nv50LineStipple(GLcontext *ctx, GLint factor, GLushort pattern ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN, 1); + OUT_RING_CACHE((pattern << 8) | factor); +} + +static void nv50LineWidth(GLcontext *ctx, GLfloat width) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LINE_WIDTH, 1); + OUT_RING_CACHEf(width); +} + +static void nv50LogicOpcode(GLcontext *ctx, GLenum opcode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LOGIC_OP_OP, 1); + OUT_RING_CACHE(opcode); +} + +static void nv50PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + /*TODO: not sure what goes here. */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + +} + +/** Specify the diameter of rasterized points */ +static void nv50PointSize(GLcontext *ctx, GLfloat size) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POINT_SIZE, 1); + OUT_RING_CACHEf(size); +} + +/** Select a polygon rasterization mode */ +static void nv50PolygonMode(GLcontext *ctx, GLenum face, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 1); + OUT_RING_CACHE(mode); + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK, 1); + OUT_RING_CACHE(mode); + } +} + +/** Set the scale and units used to calculate depth values */ +static void nv50PolygonOffset(GLcontext *ctx, GLfloat factor, GLfloat units) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR, 1); + OUT_RING_CACHEf(factor); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_UNITS, 1); + OUT_RING_CACHEf(units); +} + +/** Set the polygon stippling pattern */ +static void nv50PolygonStipple(GLcontext *ctx, const GLubyte *mask ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(0), 32); + OUT_RING_CACHEp(mask, 32); +} + +/* Specifies the current buffer for reading */ +void (*ReadBuffer)( GLcontext *ctx, GLenum buffer ); +/** Set rasterization mode */ +void (*RenderMode)(GLcontext *ctx, GLenum mode ); + +/** Define the scissor box */ +static void nv50Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); +} + +/** Select flat or smooth shading */ +static void nv50ShadeModel(GLcontext *ctx, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_SHADE_MODEL, 1); + OUT_RING_CACHE(mode); +} + +/** OpenGL 2.0 two-sided StencilFunc */ +static void nv50StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, + GLint ref, GLuint mask) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_FUNC, 1); + OUT_RING_CACHE(func); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_REF, 1); + OUT_RING_CACHE(ref); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_MASK, 1); + OUT_RING_CACHE(mask); + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_FUNC, 2); + OUT_RING_CACHE(func); + OUT_RING_CACHE(ref); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_MASK, 1); + OUT_RING_CACHE(mask); + } +} + +/** OpenGL 2.0 two-sided StencilMask */ +static void nv50StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_MASK, 1); + OUT_RING_CACHE(mask); + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_MASK, 1); + OUT_RING_CACHE(mask); + } +} + +/** OpenGL 2.0 two-sided StencilOp */ +static void nv50StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, + GLenum zfail, GLenum zpass) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_FAIL, 3); + OUT_RING_CACHE(fail); + OUT_RING_CACHE(zfail); + OUT_RING_CACHE(zpass); + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_FAIL, 3); + OUT_RING_CACHE(fail); + OUT_RING_CACHE(zfail); + OUT_RING_CACHE(zpass); + } +} + +/** Control the generation of texture coordinates */ +void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname, + const GLfloat *params); +/** Set texture environment parameters */ +void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname, + const GLfloat *param); +/** Set texture parameters */ +void (*TexParameter)(GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj, + GLenum pname, const GLfloat *params); + +static void nv50TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) +{ + /* Only with shaders */ +} + +static void nv50WindowMoved(nouveauContextPtr nmesa) +{ +} + +static GLboolean nv50InitCard(nouveauContextPtr nmesa) +{ + return GL_FALSE; +} + +static GLboolean nv50BindBuffers(nouveauContextPtr nmesa, int num_color, + nouveau_renderbuffer **color, + nouveau_renderbuffer *depth) +{ + return GL_FALSE; +} + +void nv50InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + func->AlphaFunc = nv50AlphaFunc; + func->BlendColor = nv50BlendColor; + func->BlendEquationSeparate = nv50BlendEquationSeparate; + func->BlendFuncSeparate = nv50BlendFuncSeparate; + func->Clear = nv50Clear; + func->ClearColor = nv50ClearColor; + func->ClearDepth = nv50ClearDepth; + func->ClearStencil = nv50ClearStencil; + func->ClipPlane = nv50ClipPlane; + func->ColorMask = nv50ColorMask; + func->ColorMaterial = nv50ColorMaterial; + func->CullFace = nv50CullFace; + func->FrontFace = nv50FrontFace; + func->DepthFunc = nv50DepthFunc; + func->DepthMask = nv50DepthMask; + func->DepthRange = nv50DepthRange; + func->Enable = nv50Enable; + func->Fogfv = nv50Fogfv; + func->Hint = nv50Hint; + func->Lightfv = nv50Lightfv; +/* func->LightModelfv = nv50LightModelfv; */ + func->LineStipple = nv50LineStipple; + func->LineWidth = nv50LineWidth; + func->LogicOpcode = nv50LogicOpcode; + func->PointParameterfv = nv50PointParameterfv; + func->PointSize = nv50PointSize; + func->PolygonMode = nv50PolygonMode; + func->PolygonOffset = nv50PolygonOffset; + func->PolygonStipple = nv50PolygonStipple; +/* func->ReadBuffer = nv50ReadBuffer; */ +/* func->RenderMode = nv50RenderMode; */ + func->Scissor = nv50Scissor; + func->ShadeModel = nv50ShadeModel; + func->StencilFuncSeparate = nv50StencilFuncSeparate; + func->StencilMaskSeparate = nv50StencilMaskSeparate; + func->StencilOpSeparate = nv50StencilOpSeparate; +/* func->TexGen = nv50TexGen; */ +/* func->TexParameter = nv50TexParameter; */ + func->TextureMatrix = nv50TextureMatrix; + + nmesa->hw_func.InitCard = nv50InitCard; + nmesa->hw_func.BindBuffers = nv50BindBuffers; + nmesa->hw_func.WindowMoved = nv50WindowMoved; +} -- cgit v1.2.3 From 669fefd3da55e3946b4b65a5d1104540c04717cb Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 19 Jan 2007 15:39:36 +1100 Subject: nouveau: bump drm patchlevel --- src/mesa/drivers/dri/nouveau/nouveau_screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c index ab7742df14..781ba0113f 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -327,7 +327,7 @@ void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIsc __DRIscreenPrivate *psp; static const __DRIversion ddx_expected = { 1, 2, 0 }; static const __DRIversion dri_expected = { 4, 0, 0 }; - static const __DRIversion drm_expected = { 0, 0, 2 }; + static const __DRIversion drm_expected = { 0, 0, 3 }; dri_interface = interface; -- cgit v1.2.3 From ee3d0617f923cd4bcc8bfdc1ce878648480c2679 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 21 Jan 2007 09:13:27 +1100 Subject: nouveau: shader backend branching support for all cards that support it. --- src/mesa/drivers/dri/nouveau/nouveau_shader.h | 5 +++ src/mesa/drivers/dri/nouveau/nv30_vertprog.c | 7 +++++ src/mesa/drivers/dri/nouveau/nv40_fragprog.c | 45 +++++++++++++++++++++++++++ src/mesa/drivers/dri/nouveau/nv40_vertprog.c | 10 ++++++ 4 files changed, 67 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h index 08cb7817cf..dfa53cad95 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -275,6 +275,11 @@ struct _nvsFunc { void (*SetSaturate) (nvsFunc *); void (*SetLastInst) (nvsFunc *); + void (*SetBranchTarget) (nvsFunc *, int addr); + void (*SetBranchElse) (nvsFunc *, int addr); + void (*SetBranchEnd) (nvsFunc *, int addr); + void (*SetLoopParams) (nvsFunc *, int cnt, int init, int inc); + int (*HasMergedInst) (nvsFunc *); int (*IsLastInst) (nvsFunc *); int (*GetOffsetNext) (nvsFunc *); diff --git a/src/mesa/drivers/dri/nouveau/nv30_vertprog.c b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c index 6ba8e35d55..0b7678f55d 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_vertprog.c +++ b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c @@ -48,6 +48,12 @@ NV30VPUpdateConst(GLcontext *ctx, nouveauShader *nvs, int id) /***************************************************************************** * Assembly routines */ +static void +NV30VPSetBranchTarget(nvsFunc *shader, int addr) +{ + shader->inst[2] &= ~NV30_VP_INST_IADDR_MASK; + shader->inst[2] |= (addr << NV30_VP_INST_IADDR_SHIFT); +} /***************************************************************************** * Disassembly routines @@ -349,5 +355,6 @@ NV30VPInitShaderFuncs(nvsFunc * shader) shader->GetCondRegID = NV30VPGetCondRegID; shader->GetBranch = NV30VPGetBranch; + shader->SetBranchTarget = NV30VPSetBranchTarget; } diff --git a/src/mesa/drivers/dri/nouveau/nv40_fragprog.c b/src/mesa/drivers/dri/nouveau/nv40_fragprog.c index 3d58d6b666..8bca6ae938 100644 --- a/src/mesa/drivers/dri/nouveau/nv40_fragprog.c +++ b/src/mesa/drivers/dri/nouveau/nv40_fragprog.c @@ -5,6 +5,47 @@ unsigned int NVFP_TX_BOP_COUNT = 5; struct _op_xlat NVFP_TX_BOP[64]; + +/***************************************************************************** + * Assembly routines + * - These extend the NV30 routines, which are almost identical. NV40 + * just has branching hacked into the instruction set. + */ +static void +NV40FPSetBranchTarget(nvsFunc *shader, int addr) +{ + shader->inst[2] &= ~NV40_FP_OP_IADDR_MASK; + shader->inst[2] |= (addr << NV40_FP_OP_IADDR_SHIFT); +} + +static void +NV40FPSetBranchElse(nvsFunc *shader, int addr) +{ + shader->inst[2] &= ~NV40_FP_OP_ELSE_ID_MASK; + shader->inst[2] |= (addr << NV40_FP_OP_ELSE_ID_SHIFT); +} + +static void +NV40FPSetBranchEnd(nvsFunc *shader, int addr) +{ + shader->inst[3] &= ~NV40_FP_OP_END_ID_MASK; + shader->inst[3] |= (addr << NV40_FP_OP_END_ID_SHIFT); +} + +static void +NV40FPSetLoopParams(nvsFunc *shader, int count, int initial, int increment) +{ + shader->inst[2] &= ~(NV40_FP_OP_LOOP_COUNT_MASK | + NV40_FP_OP_LOOP_INDEX_MASK | + NV40_FP_OP_LOOP_INCR_MASK); + shader->inst[2] |= ((count << NV40_FP_OP_LOOP_COUNT_SHIFT) | + (initial << NV40_FP_OP_LOOP_INDEX_SHIFT) | + (increment << NV40_FP_OP_LOOP_INCR_SHIFT)); +} + +/***************************************************************************** + * Disassembly routines + */ static struct _op_xlat * NV40FPGetOPTXRec(nvsFunc * shader, int merged) { @@ -149,4 +190,8 @@ NV40FPInitShaderFuncs(nvsFunc * shader) shader->GetLoopCount = NV40FPGetLoopCount; shader->GetLoopInitial = NV40FPGetLoopInitial; shader->GetLoopIncrement = NV40FPGetLoopIncrement; + shader->SetBranchTarget = NV40FPSetBranchTarget; + shader->SetBranchElse = NV40FPSetBranchElse; + shader->SetBranchEnd = NV40FPSetBranchEnd; + shader->SetLoopParams = NV40FPSetLoopParams; } diff --git a/src/mesa/drivers/dri/nouveau/nv40_vertprog.c b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c index 0493e18403..1ba1cfd155 100644 --- a/src/mesa/drivers/dri/nouveau/nv40_vertprog.c +++ b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c @@ -227,6 +227,15 @@ NV40VPSetSource(nvsFunc *shader, nvsRegister * src, int pos) } } +static void +NV40VPSetBranchTarget(nvsFunc *shader, int addr) +{ + shader->inst[2] &= ~NV40_VP_INST_IADDRH_MASK; + shader->inst[2] |= ((addr & 0xf8) >> 3) << NV40_VP_INST_IADDRH_SHIFT; + shader->inst[3] &= ~NV40_VP_INST_IADDRL_MASK; + shader->inst[3] |= ((addr & 0x07) << NV40_VP_INST_IADDRL_SHIFT); +} + static void NV40VPInitInstruction(nvsFunc *shader) { @@ -657,6 +666,7 @@ NV40VPInitShaderFuncs(nvsFunc * shader) shader->SetResult = NV40VPSetResult; shader->SetSource = NV40VPSetSource; shader->SetLastInst = NV40VPSetLastInst; + shader->SetBranchTarget = NV40VPSetBranchTarget; shader->HasMergedInst = NV40VPHasMergedInst; shader->GetOpcodeHW = NV40VPGetOpcodeHW; -- cgit v1.2.3 From 029b81742ad474245e18e0b629d669afe588111c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 21 Jan 2007 09:31:00 +1100 Subject: nouveau: kill off shader pass1. It sucks, and we have someone who can do a much better job than I can starting work on it soon. alloc_temp/free_temp is left in pass2 to workaround fragprog temps/outputs overlapping, but this all belongs in the optimiser. --- src/mesa/drivers/dri/nouveau/nouveau_shader.h | 4 - src/mesa/drivers/dri/nouveau/nouveau_shader_1.c | 304 ------------------------ src/mesa/drivers/dri/nouveau/nouveau_shader_2.c | 16 +- 3 files changed, 1 insertion(+), 323 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h index dfa53cad95..4b94625286 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -56,10 +56,6 @@ typedef struct _nouveauShader { int hw_index_cnt; } params[NVS_MAX_CONSTS]; - struct { - int last_use; - } temps[NVS_MAX_TEMPS]; - /* Pass-private data */ void *pass_rec; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_1.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_1.c index 5de9017f58..90c57d3807 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_1.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_1.c @@ -1,316 +1,12 @@ -/* - * Copyright (C) 2006 Ben Skeggs. - * - * 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 (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 NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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: - * Ben Skeggs - */ - #include "glheader.h" #include "macros.h" #include "enums.h" #include "nouveau_shader.h" -#define PASS1_OK 0 -#define PASS1_KILL 1 -#define PASS1_FAIL 2 - -struct pass1_rec { - unsigned int temp[NVS_MAX_TEMPS]; - unsigned int result[NVS_MAX_ATTRIBS]; - unsigned int address[NVS_MAX_ADDRESS]; - unsigned int cc[2]; -}; - -static void -pass1_remove_fragment(nvsPtr nvs, nvsFragmentList *item) -{ - if (item->prev) item->prev->next = item->next; - if (item->next) item->next->prev = item->prev; - if (nvs->list_head == item) nvs->list_head = item->next; - if (nvs->list_tail == item) nvs->list_tail = item->prev; - - nvs->inst_count--; -} - -static int -pass1_result_needed(struct pass1_rec *rec, nvsInstruction *inst) -{ - if (inst->cond_update && rec->cc[inst->cond_reg]) - return 1; - /* Only write components that are read later */ - if (inst->dest.file == NVS_FILE_TEMP) - return (inst->mask & rec->temp[inst->dest.index]); - if (inst->dest.file == NVS_FILE_ADDRESS) - return (inst->mask & rec->address[inst->dest.index]); - /* No point writing result components that are written later */ - if (inst->dest.file == NVS_FILE_RESULT) - return (inst->mask & ~rec->result[inst->dest.index]); - assert(0); -} - -static void -pass1_track_result(struct pass1_rec *rec, nvsInstruction *inst) -{ - if (inst->cond_test) - rec->cc[inst->cond_reg] = 1; - if (inst->dest.file == NVS_FILE_TEMP) { - inst->mask &= rec->temp[inst->dest.index]; - } else if (inst->dest.file == NVS_FILE_RESULT) { - inst->mask &= ~rec->result[inst->dest.index]; - rec->result[inst->dest.index] |= inst->mask; - } else if (inst->dest.file == NVS_FILE_ADDRESS) { - inst->mask &= rec->address[inst->dest.index]; - } -} - -static void -pass1_track_source(nouveauShader *nvs, nvsInstruction *inst, int pos, - unsigned int read) -{ - struct pass1_rec *rec = nvs->pass_rec; - nvsRegister *src = &inst->src[pos]; - unsigned int really_read = 0; - int i,sc; - - /* Account for swizzling */ - for (i=0; i<4; i++) - if (read & (1<swizzle[i]); - - /* Track register reads */ - if (src->file == NVS_FILE_TEMP) { - if (nvs->temps[src->index].last_use == -1) - nvs->temps[src->index].last_use = inst->header.position; - rec->temp [src->index] |= really_read; - } else if (src->indexed) { - rec->address[src->addr_reg] |= (1<addr_comp); - } - - /* Modify swizzle to only access read components */ - /* Find a component that is used.. */ - for (sc=0;sc<4;sc++) - if (really_read & (1<swizzle[i] = sc; -} - -static int -pass1_check_instruction(nouveauShader *nvs, nvsInstruction *inst) -{ - struct pass1_rec *rec = nvs->pass_rec; - unsigned int read0, read1, read2; - - if (inst->op != NVS_OP_KIL) { - if (!pass1_result_needed(rec, inst)) - return PASS1_KILL; - } - pass1_track_result(rec, inst); - - read0 = read1 = read2 = 0; - - switch (inst->op) { - case NVS_OP_FLR: - case NVS_OP_FRC: - case NVS_OP_MOV: - case NVS_OP_SSG: - case NVS_OP_ARL: - read0 = inst->mask; - break; - case NVS_OP_ADD: - case NVS_OP_MAX: - case NVS_OP_MIN: - case NVS_OP_MUL: - case NVS_OP_SEQ: - case NVS_OP_SFL: - case NVS_OP_SGE: - case NVS_OP_SGT: - case NVS_OP_SLE: - case NVS_OP_SLT: - case NVS_OP_SNE: - case NVS_OP_STR: - case NVS_OP_SUB: - read0 = inst->mask; - read1 = inst->mask; - break; - case NVS_OP_CMP: - case NVS_OP_LRP: - case NVS_OP_MAD: - read0 = inst->mask; - read1 = inst->mask; - read2 = inst->mask; - break; - case NVS_OP_XPD: - if (inst->mask & SMASK_X) read0 |= SMASK_Y|SMASK_Z; - if (inst->mask & SMASK_Y) read0 |= SMASK_X|SMASK_Z; - if (inst->mask & SMASK_Z) read0 |= SMASK_X|SMASK_Y; - read1 = read0; - break; - case NVS_OP_COS: - case NVS_OP_EX2: - case NVS_OP_EXP: - case NVS_OP_LG2: - case NVS_OP_LOG: - case NVS_OP_RCC: - case NVS_OP_RCP: - case NVS_OP_RSQ: - case NVS_OP_SCS: - case NVS_OP_SIN: - read0 = SMASK_X; - break; - case NVS_OP_POW: - read0 = SMASK_X; - read1 = SMASK_X; - break; - case NVS_OP_DIV: - read0 = inst->mask; - read1 = SMASK_X; - break; - case NVS_OP_DP2: - read0 = SMASK_X|SMASK_Y; - read1 = SMASK_X|SMASK_Y; - break; - case NVS_OP_DP3: - case NVS_OP_RFL: - read0 = SMASK_X|SMASK_Y|SMASK_Z; - read1 = SMASK_X|SMASK_Y|SMASK_Z; - break; - case NVS_OP_DP4: - read0 = SMASK_ALL; - read1 = SMASK_ALL; - break; - case NVS_OP_DPH: - read0 = SMASK_X|SMASK_Y|SMASK_Z; - read1 = SMASK_ALL; - break; - case NVS_OP_DST: - if (inst->mask & SMASK_Y) read0 = read1 = SMASK_Y; - if (inst->mask & SMASK_Z) read0 |= SMASK_Z; - if (inst->mask & SMASK_W) read1 |= SMASK_W; - break; - case NVS_OP_NRM: - read0 = SMASK_X|SMASK_Y|SMASK_Z; - break; - case NVS_OP_PK2H: - case NVS_OP_PK2US: - read0 = SMASK_X|SMASK_Y; - break; - case NVS_OP_DDX: - case NVS_OP_DDY: - case NVS_OP_UP2H: - case NVS_OP_UP2US: - case NVS_OP_PK4B: - case NVS_OP_PK4UB: - case NVS_OP_UP4B: - case NVS_OP_UP4UB: - read0 = SMASK_ALL; - break; - case NVS_OP_X2D: - read1 = SMASK_X|SMASK_Y; - if (inst->mask & (SMASK_X|SMASK_Z)) { - read0 |= SMASK_X; - read2 |= SMASK_X|SMASK_Y; - } - if (inst->mask & (SMASK_Y|SMASK_W)) { - read0 |= SMASK_Y; - read2 |= SMASK_Z|SMASK_W; - } - break; - case NVS_OP_LIT: - read0 |= SMASK_X|SMASK_Y|SMASK_W; - break; - case NVS_OP_TEX: - case NVS_OP_TXP: - case NVS_OP_TXL: - case NVS_OP_TXB: - read0 = SMASK_ALL; - break; - case NVS_OP_TXD: - read0 = SMASK_ALL; - read1 = SMASK_ALL; - read2 = SMASK_ALL; - break; - case NVS_OP_KIL: - break; - default: - fprintf(stderr, "Unknown sop=%d", inst->op); - return PASS1_FAIL; - } - - /* Any values that are written by this inst can't have been read further up */ - if (inst->dest.file == NVS_FILE_TEMP) - rec->temp[inst->dest.index] &= ~inst->mask; - - if (read0) pass1_track_source(nvs, inst, 0, read0); - if (read1) pass1_track_source(nvs, inst, 1, read1); - if (read2) pass1_track_source(nvs, inst, 2, read2); - - return PASS1_OK; -} - -/* Some basic dead code elimination - * - Remove unused instructions - * - Don't write unused register components - * - Modify swizzles to not reference unneeded components. - */ GLboolean nouveau_shader_pass1(nvsPtr nvs) { - nvsFragmentList *list = nvs->list_tail; - int i; - - for (i=0; itemps[i].last_use = -1; - - nvs->pass_rec = calloc(1, sizeof(struct pass1_rec)); - - while (list) { - assert(list->fragment->type == NVS_INSTRUCTION); - - switch(pass1_check_instruction(nvs, (nvsInstruction *)list->fragment)) { - case PASS1_OK: - break; - case PASS1_KILL: - pass1_remove_fragment(nvs, list); - break; - case PASS1_FAIL: - default: - free(nvs->pass_rec); - nvs->pass_rec = NULL; - return GL_FALSE; - } - - list = list->prev; - } - - free(nvs->pass_rec); - nvs->pass_rec = NULL; return GL_TRUE; } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c index 2177413b66..0476b05f58 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c @@ -68,29 +68,15 @@ pass2_alloc_hw_temp(nvsPtr nvs) return -1; } -static void -pass2_free_hw_temp(nvsPtr nvs, int reg) -{ - struct pass2_rec *rec = nvs->pass_rec; - rec->hw_temps[reg] = 0; -} - static nvsRegister pass2_mangle_reg(nvsPtr nvs, nvsInstruction *inst, nvsRegister reg) { struct pass2_rec *rec = nvs->pass_rec; if (reg.file == NVS_FILE_TEMP) { - int hwidx; - if (rec->temps[reg.index] == -1) rec->temps[reg.index] = pass2_alloc_hw_temp(nvs); - hwidx = rec->temps[reg.index]; - - if (nvs->temps[reg.index].last_use <= inst->header.position) - pass2_free_hw_temp(nvs, hwidx); - - reg.index = hwidx; + reg.index = rec->temps[reg.index]; } return reg; -- cgit v1.2.3 From 4f800c5bacb9734d3030fe11144c8003ec4f169a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 21 Jan 2007 09:48:33 +1100 Subject: nouveau: rename pass0_arb to pass0. I was expecting to have 2 frontends for the shader code (asm, glsl). With Brian's work on GLSL this is unnecessary :) --- src/mesa/drivers/dri/nouveau/Makefile | 2 +- src/mesa/drivers/dri/nouveau/nouveau_shader.c | 4 +- src/mesa/drivers/dri/nouveau/nouveau_shader.h | 3 +- src/mesa/drivers/dri/nouveau/nouveau_shader_0.c | 710 +++++++++++++++++++++ .../drivers/dri/nouveau/nouveau_shader_0_arb.c | 710 --------------------- 5 files changed, 714 insertions(+), 715 deletions(-) create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_shader_0.c delete mode 100644 src/mesa/drivers/dri/nouveau/nouveau_shader_0_arb.c (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile index 7ffba27bac..9718f3bf46 100644 --- a/src/mesa/drivers/dri/nouveau/Makefile +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -20,7 +20,7 @@ DRIVER_SOURCES = \ nouveau_span.c \ nouveau_state.c \ nouveau_shader.c \ - nouveau_shader_0_arb.c \ + nouveau_shader_0.c \ nouveau_shader_1.c \ nouveau_shader_2.c \ nouveau_tex.c \ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.c b/src/mesa/drivers/dri/nouveau/nouveau_shader.c index dc366b36c0..e4db115362 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.c @@ -111,7 +111,7 @@ nvsUpdateShader(GLcontext *ctx, nouveauShader *nvs) /* Translate to HW format now if necessary */ if (!nvs->translated) { /* Mesa ASM shader -> nouveauShader */ - if (!nouveau_shader_pass0_arb(ctx, nvs)) + if (!nouveau_shader_pass0(ctx, nvs)) return GL_FALSE; /* Basic dead code elimination + register usage info */ if (!nouveau_shader_pass1(nvs)) @@ -187,7 +187,7 @@ nvsBuildTextShader(GLcontext *ctx, GLenum target, const char *text) &nvs->mesa.fp); } - nouveau_shader_pass0_arb(ctx, nvs); + nouveau_shader_pass0(ctx, nvs); nouveau_shader_pass1(nvs); nouveau_shader_pass2(nvs); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h index 4b94625286..1a971e56bf 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -366,8 +366,7 @@ extern void NV40FPInitShaderFuncs(nvsFunc *); extern void nouveauShaderInitFuncs(GLcontext *ctx); -extern GLboolean nouveau_shader_pass0_arb(GLcontext *ctx, nouveauShader *nvs); -extern GLboolean nouveau_shader_pass0_slang(GLcontext *ctx, nouveauShader *nvs); +extern GLboolean nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs); extern GLboolean nouveau_shader_pass1(nvsPtr nvs); extern GLboolean nouveau_shader_pass2(nvsPtr nvs); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c new file mode 100644 index 0000000000..34475cad03 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -0,0 +1,710 @@ +/* + * Copyright (C) 2006 Ben Skeggs. + * + * 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 (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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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: + * Ben Skeggs + */ + +#include "glheader.h" +#include "macros.h" +#include "enums.h" + +#include "program.h" +#include "programopt.h" +#include "program_instruction.h" + +#include "nouveau_context.h" +#include "nouveau_shader.h" + +static nvsFixedReg _tx_mesa_vp_dst_reg[VERT_RESULT_MAX] = { + NVS_FR_POSITION, NVS_FR_COL0, NVS_FR_COL1, NVS_FR_FOGCOORD, + NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, + NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7, + NVS_FR_POINTSZ, NVS_FR_BFC0, NVS_FR_BFC1, NVS_FR_UNKNOWN /* EDGE */ +}; + +static nvsFixedReg _tx_mesa_fp_dst_reg[FRAG_RESULT_MAX] = { + NVS_FR_FRAGDATA0 /* COLR */, NVS_FR_FRAGDATA0 /* COLH */, + NVS_FR_UNKNOWN /* DEPR */ +}; + +static nvsFixedReg _tx_mesa_vp_src_reg[VERT_ATTRIB_MAX] = { + NVS_FR_POSITION, NVS_FR_WEIGHT, NVS_FR_NORMAL, NVS_FR_COL0, NVS_FR_COL1, + NVS_FR_FOGCOORD, NVS_FR_UNKNOWN /* COLOR_INDEX */, NVS_FR_UNKNOWN, + NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, + NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7, +/* Generic attribs 0-15, aliased to the above */ + NVS_FR_POSITION, NVS_FR_WEIGHT, NVS_FR_NORMAL, NVS_FR_COL0, NVS_FR_COL1, + NVS_FR_FOGCOORD, NVS_FR_UNKNOWN /* COLOR_INDEX */, NVS_FR_UNKNOWN, + NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, + NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7 +}; + +static nvsFixedReg _tx_mesa_fp_src_reg[FRAG_ATTRIB_MAX] = { + NVS_FR_POSITION, NVS_FR_COL0, NVS_FR_COL1, NVS_FR_FOGCOORD, + NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, + NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7 +}; + +static nvsSwzComp _tx_mesa_swizzle[4] = { + NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W +}; + +static nvsOpcode _tx_mesa_opcode[] = { + [OPCODE_ABS] = NVS_OP_ABS, [OPCODE_ADD] = NVS_OP_ADD, + [OPCODE_ARA] = NVS_OP_ARA, [OPCODE_ARL] = NVS_OP_ARL, + [OPCODE_ARL_NV] = NVS_OP_ARL, [OPCODE_ARR] = NVS_OP_ARR, + [OPCODE_CMP] = NVS_OP_CMP, [OPCODE_COS] = NVS_OP_COS, + [OPCODE_DDX] = NVS_OP_DDX, [OPCODE_DDY] = NVS_OP_DDY, + [OPCODE_DP3] = NVS_OP_DP3, [OPCODE_DP4] = NVS_OP_DP4, + [OPCODE_DPH] = NVS_OP_DPH, [OPCODE_DST] = NVS_OP_DST, + [OPCODE_EX2] = NVS_OP_EX2, [OPCODE_EXP] = NVS_OP_EXP, + [OPCODE_FLR] = NVS_OP_FLR, [OPCODE_FRC] = NVS_OP_FRC, + [OPCODE_KIL] = NVS_OP_EMUL, [OPCODE_KIL_NV] = NVS_OP_KIL, + [OPCODE_LG2] = NVS_OP_LG2, [OPCODE_LIT] = NVS_OP_LIT, + [OPCODE_LOG] = NVS_OP_LOG, + [OPCODE_LRP] = NVS_OP_LRP, + [OPCODE_MAD] = NVS_OP_MAD, [OPCODE_MAX] = NVS_OP_MAX, + [OPCODE_MIN] = NVS_OP_MIN, [OPCODE_MOV] = NVS_OP_MOV, + [OPCODE_MUL] = NVS_OP_MUL, + [OPCODE_PK2H] = NVS_OP_PK2H, [OPCODE_PK2US] = NVS_OP_PK2US, + [OPCODE_PK4B] = NVS_OP_PK4B, [OPCODE_PK4UB] = NVS_OP_PK4UB, + [OPCODE_POW] = NVS_OP_POW, [OPCODE_POPA] = NVS_OP_POPA, + [OPCODE_PUSHA] = NVS_OP_PUSHA, + [OPCODE_RCC] = NVS_OP_RCC, [OPCODE_RCP] = NVS_OP_RCP, + [OPCODE_RFL] = NVS_OP_RFL, [OPCODE_RSQ] = NVS_OP_RSQ, + [OPCODE_SCS] = NVS_OP_SCS, [OPCODE_SEQ] = NVS_OP_SEQ, + [OPCODE_SFL] = NVS_OP_SFL, [OPCODE_SGE] = NVS_OP_SGE, + [OPCODE_SGT] = NVS_OP_SGT, [OPCODE_SIN] = NVS_OP_SIN, + [OPCODE_SLE] = NVS_OP_SLE, [OPCODE_SLT] = NVS_OP_SLT, + [OPCODE_SNE] = NVS_OP_SNE, [OPCODE_SSG] = NVS_OP_SSG, + [OPCODE_STR] = NVS_OP_STR, [OPCODE_SUB] = NVS_OP_SUB, + [OPCODE_SWZ] = NVS_OP_MOV, + [OPCODE_TEX] = NVS_OP_TEX, [OPCODE_TXB] = NVS_OP_TXB, + [OPCODE_TXD] = NVS_OP_TXD, + [OPCODE_TXL] = NVS_OP_TXL, [OPCODE_TXP] = NVS_OP_TXP, + [OPCODE_TXP_NV] = NVS_OP_TXP, + [OPCODE_UP2H] = NVS_OP_UP2H, [OPCODE_UP2US] = NVS_OP_UP2US, + [OPCODE_UP4B] = NVS_OP_UP4B, [OPCODE_UP4UB] = NVS_OP_UP4UB, + [OPCODE_X2D] = NVS_OP_X2D, + [OPCODE_XPD] = NVS_OP_XPD +}; + +static nvsCond _tx_mesa_condmask[] = { + NVS_COND_UNKNOWN, NVS_COND_GT, NVS_COND_LT, NVS_COND_UN, NVS_COND_GE, + NVS_COND_LE, NVS_COND_NE, NVS_COND_NE, NVS_COND_TR, NVS_COND_FL +}; + +struct pass0_rec { + int nvs_ipos; + int next_temp; + int swzconst_done; + int swzconst_id; + nvsRegister const_half; +}; + +#define X NVS_SWZ_X +#define Y NVS_SWZ_Y +#define Z NVS_SWZ_Z +#define W NVS_SWZ_W + +static void +pass0_append_fragment(nouveauShader *nvs, nvsFragmentHeader *fragment) +{ + nvsFragmentList *list = calloc(1, sizeof(nvsFragmentList)); + if (!list) + return; + + list->fragment = fragment; + list->prev = nvs->list_tail; + if ( nvs->list_tail) + nvs->list_tail->next = list; + if (!nvs->list_head) + nvs->list_head = list; + nvs->list_tail = list; + + nvs->inst_count++; +} + +static void +pass0_make_reg(nouveauShader *nvs, nvsRegister *reg, + nvsRegFile file, unsigned int index) +{ + struct pass0_rec *rec = nvs->pass_rec; + + /* defaults */ + *reg = nvr_unused; + /* -1 == quick-and-dirty temp alloc */ + if (file == NVS_FILE_TEMP && index == -1) { + index = rec->next_temp++; + assert(index < NVS_MAX_TEMPS); + } + reg->file = file; + reg->index = index; +} + +static void +pass0_make_swizzle(nvsSwzComp *swz, unsigned int mesa) +{ + int i; + + for (i=0;i<4;i++) + swz[i] = _tx_mesa_swizzle[GET_SWZ(mesa, i)]; +} + +static nvsOpcode +pass0_make_opcode(enum prog_opcode op) +{ + if (op > MAX_OPCODE) + return NVS_OP_UNKNOWN; + return _tx_mesa_opcode[op]; +} + +static nvsCond +pass0_make_condmask(GLuint mesa) +{ + if (mesa > COND_FL) + return NVS_COND_UNKNOWN; + return _tx_mesa_condmask[mesa]; +} + +static unsigned int +pass0_make_mask(GLuint mesa_mask) +{ + unsigned int mask = 0; + + if (mesa_mask & WRITEMASK_X) mask |= SMASK_X; + if (mesa_mask & WRITEMASK_Y) mask |= SMASK_Y; + if (mesa_mask & WRITEMASK_Z) mask |= SMASK_Z; + if (mesa_mask & WRITEMASK_W) mask |= SMASK_W; + + return mask; +} + +static nvsTexTarget +pass0_make_tex_target(GLuint mesa) +{ + switch (mesa) { + case TEXTURE_1D_INDEX: return NVS_TEX_TARGET_1D; + case TEXTURE_2D_INDEX: return NVS_TEX_TARGET_2D; + case TEXTURE_3D_INDEX: return NVS_TEX_TARGET_3D; + case TEXTURE_CUBE_INDEX: return NVS_TEX_TARGET_CUBE; + case TEXTURE_RECT_INDEX: return NVS_TEX_TARGET_RECT; + default: + return NVS_TEX_TARGET_UNKNOWN; + } +} + +static void +pass0_make_dst_reg(nvsPtr nvs, nvsRegister *reg, + struct prog_dst_register *dst) +{ + struct gl_program *mesa = (struct gl_program*)&nvs->mesa.vp; + nvsFixedReg sfr; + + switch (dst->File) { + case PROGRAM_OUTPUT: + if (mesa->Target == GL_VERTEX_PROGRAM_ARB) { + sfr = (dst->Index < VERT_RESULT_MAX) ? + _tx_mesa_vp_dst_reg[dst->Index] : NVS_FR_UNKNOWN; + } else { + sfr = (dst->Index < FRAG_RESULT_MAX) ? + _tx_mesa_fp_dst_reg[dst->Index] : NVS_FR_UNKNOWN; + } + pass0_make_reg(nvs, reg, NVS_FILE_RESULT, sfr); + break; + case PROGRAM_TEMPORARY: + pass0_make_reg(nvs, reg, NVS_FILE_TEMP, dst->Index); + break; + case PROGRAM_ADDRESS: + pass0_make_reg(nvs, reg, NVS_FILE_ADDRESS, dst->Index); + break; + default: + fprintf(stderr, "Unknown dest file %d\n", dst->File); + assert(0); + } +} + +static void +pass0_make_src_reg(nvsPtr nvs, nvsRegister *reg, struct prog_src_register *src) +{ + struct gl_program *mesa = (struct gl_program *)&nvs->mesa.vp.Base; + struct gl_program_parameter_list *p = mesa->Parameters; + + *reg = nvr_unused; + + switch (src->File) { + case PROGRAM_INPUT: + reg->file = NVS_FILE_ATTRIB; + if (mesa->Target == GL_VERTEX_PROGRAM_ARB) { + reg->index = (src->Index < VERT_ATTRIB_MAX) ? + _tx_mesa_vp_src_reg[src->Index] : NVS_FR_UNKNOWN; + } else { + reg->index = (src->Index < FRAG_ATTRIB_MAX) ? + _tx_mesa_fp_src_reg[src->Index] : NVS_FR_UNKNOWN; + } + break; + /* All const types seem to get shoved into here, not really sure why */ + case PROGRAM_STATE_VAR: + switch (p->Parameters[src->Index].Type) { + case PROGRAM_NAMED_PARAM: + case PROGRAM_CONSTANT: + nvs->params[src->Index].source_val = NULL; + COPY_4V(nvs->params[src->Index].val, p->ParameterValues[src->Index]); + break; + case PROGRAM_STATE_VAR: + nvs->params[src->Index].source_val = p->ParameterValues[src->Index]; + break; + default: + fprintf(stderr, "Unknown parameter type %d\n", + p->Parameters[src->Index].Type); + assert(0); + break; + } + + if (src->RelAddr) { + reg->indexed = 1; + reg->addr_reg = 0; + reg->addr_comp = NVS_SWZ_X; + } else + reg->indexed = 0; + reg->file = NVS_FILE_CONST; + reg->index = src->Index; + break; + case PROGRAM_TEMPORARY: + reg->file = NVS_FILE_TEMP; + reg->index = src->Index; + break; + default: + fprintf(stderr, "Unknown source type %d\n", src->File); + assert(0); + } + + /* per-component negate handled elsewhere */ + reg->negate = src->NegateBase != 0; + reg->abs = src->Abs; + pass0_make_swizzle(reg->swizzle, src->Swizzle); +} + +static nvsInstruction * +pass0_emit(nouveauShader *nvs, nvsOpcode op, nvsRegister dst, + unsigned int mask, int saturate, + nvsRegister src0, nvsRegister src1, nvsRegister src2) +{ + struct pass0_rec *rec = nvs->pass_rec; + nvsInstruction *sif = NULL; + + /* Seems mesa doesn't explicitly 0 this.. */ + if (nvs->mesa.vp.Base.Target == GL_VERTEX_PROGRAM_ARB) + saturate = 0; + + sif = calloc(1, sizeof(nvsInstruction)); + if (sif) { + sif->header.type = NVS_INSTRUCTION; + sif->header.position = rec->nvs_ipos++; + sif->op = op; + sif->saturate = saturate; + sif->dest = dst; + sif->mask = mask; + sif->src[0] = src0; + sif->src[1] = src1; + sif->src[2] = src2; + sif->cond = COND_TR; + sif->cond_reg = 0; + sif->cond_test = 0; + sif->cond_update = 0; + pass0_make_swizzle(sif->cond_swizzle, SWIZZLE_NOOP); + pass0_append_fragment(nvs, (nvsFragmentHeader *)sif); + } + + return sif; +} + +static void +pass0_fixup_swizzle(nvsPtr nvs, + struct prog_src_register *src, + unsigned int sm1, + unsigned int sm2) +{ + static const float sc[4] = { 1.0, 0.0, -1.0, 0.0 }; + struct pass0_rec *rec = nvs->pass_rec; + int fixup_1, fixup_2; + nvsRegister sr, dr = nvr_unused; + nvsRegister sm1const, sm2const; + + if (!rec->swzconst_done) { + struct gl_program *prog = &nvs->mesa.vp.Base; + rec->swzconst_id = _mesa_add_unnamed_constant(prog->Parameters, sc, 4); + rec->swzconst_done = 1; + COPY_4V(nvs->params[rec->swzconst_id].val, sc); + } + + fixup_1 = (sm1 != MAKE_SWIZZLE4(0,0,0,0) && sm2 != MAKE_SWIZZLE4(2,2,2,2)); + fixup_2 = (sm2 != MAKE_SWIZZLE4(2,2,2,2)); + + if (src->File != PROGRAM_TEMPORARY && src->File != PROGRAM_INPUT) { + /* We can't use more than one const in an instruction, so move the const + * into a temp, and swizzle from there. + *TODO: should just emit the swizzled const, instead of swizzling it + * in the shader.. would need to reswizzle any state params when they + * change however.. + */ + pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); + pass0_make_src_reg(nvs, &sr, src); + pass0_emit(nvs, NVS_OP_MOV, dr, SMASK_ALL, 0, sr, nvr_unused, nvr_unused); + pass0_make_reg(nvs, &sr, NVS_FILE_TEMP, dr.index); + } else { + if (fixup_1) + src->NegateBase = 0; + pass0_make_src_reg(nvs, &sr, src); + pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); + } + + pass0_make_reg(nvs, &sm1const, NVS_FILE_CONST, rec->swzconst_id); + pass0_make_swizzle(sm1const.swizzle, sm1); + if (fixup_1 && fixup_2) { + /* Any combination with SWIZZLE_ONE */ + pass0_make_reg(nvs, &sm2const, NVS_FILE_CONST, rec->swzconst_id); + pass0_make_swizzle(sm2const.swizzle, sm2); + pass0_emit(nvs, NVS_OP_MAD, dr, SMASK_ALL, 0, sr, sm1const, sm2const); + } else { + /* SWIZZLE_ZERO || arbitrary negate */ + pass0_emit(nvs, NVS_OP_MUL, dr, SMASK_ALL, 0, sr, sm1const, nvr_unused); + } + + src->File = PROGRAM_TEMPORARY; + src->Index = dr.index; + src->Swizzle = SWIZZLE_NOOP; +} + +#define SET_SWZ(fs, cp, c) fs = (fs & ~(0x7<<(cp*3))) | (c<<(cp*3)) +static void +pass0_check_sources(nvsPtr nvs, struct prog_instruction *inst) +{ + unsigned int insrc = -1, constsrc = -1; + int i; + + for (i=0;i<_mesa_num_inst_src_regs(inst->Opcode);i++) { + struct prog_src_register *src = &inst->SrcReg[i]; + unsigned int sm_1 = 0, sm_2 = 0; + nvsRegister sr, dr; + int do_mov = 0, c; + + /* Build up swizzle masks as if we were going to use + * "MAD new, src, const1, const2" to support arbitrary negation + * and SWIZZLE_ZERO/SWIZZLE_ONE. + */ + for (c=0;c<4;c++) { + if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ZERO) { + SET_SWZ(sm_1, c, SWIZZLE_Y); /* 0.0 */ + SET_SWZ(sm_2, c, SWIZZLE_Y); + SET_SWZ(src->Swizzle, c, SWIZZLE_X); + } else if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ONE) { + SET_SWZ(sm_1, c, SWIZZLE_Y); + if (src->NegateBase & (1<Swizzle, c, SWIZZLE_X); + } else { + if (src->NegateBase & (1<File) { + case PROGRAM_INPUT: + if (insrc != -1 && insrc != src->Index) + do_mov = 1; + else insrc = src->Index; + break; + case PROGRAM_STATE_VAR: + if (constsrc != -1 && constsrc != src->Index) + do_mov = 1; + else constsrc = src->Index; + break; + default: + break; + } + + /* Emit any extra ATTRIB/CONST to a temp, and modify the Mesa instruction + * to point at the temp. + */ + if (do_mov) { + pass0_make_src_reg(nvs, &sr, src); + pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); + pass0_emit(nvs, NVS_OP_MOV, dr, SMASK_ALL, 0, + sr, nvr_unused, nvr_unused); + + src->File = PROGRAM_TEMPORARY; + src->Index = dr.index; + src->Swizzle= SWIZZLE_NOOP; + } + } +} + +static GLboolean +pass0_emulate_instruction(nouveauShader *nvs, struct prog_instruction *inst) +{ + nvsFunc *shader = nvs->func; + nvsRegister src[3], dest, temp; + nvsInstruction *nvsinst; + struct pass0_rec *rec = nvs->pass_rec; + unsigned int mask = pass0_make_mask(inst->DstReg.WriteMask); + int i, sat; + + sat = (inst->SaturateMode == SATURATE_ZERO_ONE); + + /* Build all the "real" regs for the instruction */ + for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++) + pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]); + if (inst->Opcode != OPCODE_KIL) + pass0_make_dst_reg(nvs, &dest, &inst->DstReg); + + switch (inst->Opcode) { + case OPCODE_ABS: + if (shader->caps & SCAP_SRC_ABS) + pass0_emit(nvs, NVS_OP_MOV, dest, mask, sat, + nvsAbs(src[0]), nvr_unused, nvr_unused); + else + pass0_emit(nvs, NVS_OP_MAX, dest, mask, sat, + src[0], nvsNegate(src[0]), nvr_unused); + break; + case OPCODE_KIL: + /* This is only in ARB shaders, so we don't have to worry + * about clobbering a CC reg as they aren't supported anyway. + */ + /* MOVC0 temp, src */ + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + nvsinst = pass0_emit(nvs, NVS_OP_MOV, temp, SMASK_ALL, 0, + src[0], nvr_unused, nvr_unused); + nvsinst->cond_update = 1; + nvsinst->cond_reg = 0; + /* KIL_NV (LT0.xyzw) temp */ + nvsinst = pass0_emit(nvs, NVS_OP_KIL, nvr_unused, 0, 0, + nvr_unused, nvr_unused, nvr_unused); + nvsinst->cond = COND_LT; + nvsinst->cond_reg = 0; + nvsinst->cond_test = 1; + pass0_make_swizzle(nvsinst->cond_swizzle, MAKE_SWIZZLE4(0,1,2,3)); + break; + case OPCODE_LIT: + break; + case OPCODE_LRP: + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + pass0_emit(nvs, NVS_OP_MAD, temp, mask, 0, + nvsNegate(src[0]), src[2], src[2]); + pass0_emit(nvs, NVS_OP_MAD, dest, mask, sat, + src[0], src[1], temp); + break; + case OPCODE_POW: + if (shader->SupportsOpcode(shader, NVS_OP_LG2) && + shader->SupportsOpcode(shader, NVS_OP_EX2)) { + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + /* LG2 temp.x, src0.c */ + pass0_emit(nvs, NVS_OP_LG2, temp, SMASK_X, 0, + nvsSwizzle(src[0], X, X, X, X), + nvr_unused, + nvr_unused); + /* MUL temp.x, temp.x, src1.c */ + pass0_emit(nvs, NVS_OP_MUL, temp, SMASK_X, 0, + nvsSwizzle(temp, X, X, X, X), + nvsSwizzle(src[1], X, X, X, X), + nvr_unused); + /* EX2 dest, temp.x */ + pass0_emit(nvs, NVS_OP_EX2, dest, mask, sat, + nvsSwizzle(temp, X, X, X, X), + nvr_unused, + nvr_unused); + } else { + /* can we use EXP/LOG instead of EX2/LG2?? */ + fprintf(stderr, "Implement POW for NV20 vtxprog!\n"); + return GL_FALSE; + } + break; + case OPCODE_RSQ: + if (rec->const_half.file != NVS_FILE_CONST) { + GLfloat const_half[4] = { 0.5, 0.0, 0.0, 0.0 }; + pass0_make_reg(nvs, &rec->const_half, NVS_FILE_CONST, + _mesa_add_unnamed_constant(nvs->mesa.vp.Base.Parameters, + const_half, 4)); + COPY_4V(nvs->params[rec->const_half.index].val, const_half); + } + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + pass0_emit(nvs, NVS_OP_LG2, temp, SMASK_X, 0, + nvsAbs(nvsSwizzle(src[0], X, X, X, X)), + nvr_unused, + nvr_unused); + pass0_emit(nvs, NVS_OP_MUL, temp, SMASK_X, 0, + nvsSwizzle(temp, X, X, X, X), + nvsNegate(rec->const_half), + nvr_unused); + pass0_emit(nvs, NVS_OP_EX2, dest, mask, sat, + nvsSwizzle(temp, X, X, X, X), + nvr_unused, + nvr_unused); + break; + case OPCODE_SCS: + if (mask & SMASK_X) + pass0_emit(nvs, NVS_OP_COS, dest, SMASK_X, sat, + nvsSwizzle(src[0], X, X, X, X), + nvr_unused, + nvr_unused); + if (mask & SMASK_Y) + pass0_emit(nvs, NVS_OP_SIN, dest, SMASK_Y, sat, + nvsSwizzle(src[0], X, X, X, X), + nvr_unused, + nvr_unused); + break; + case OPCODE_SUB: + pass0_emit(nvs, NVS_OP_ADD, dest, mask, sat, + src[0], nvsNegate(src[1]), nvr_unused); + break; + case OPCODE_XPD: + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + pass0_emit(nvs, NVS_OP_MUL, temp, SMASK_ALL, 0, + nvsSwizzle(src[0], Z, X, Y, Y), + nvsSwizzle(src[1], Y, Z, X, X), + nvr_unused); + pass0_emit(nvs, NVS_OP_MAD, dest, (mask & ~SMASK_W), sat, + nvsSwizzle(src[0], Y, Z, X, X), + nvsSwizzle(src[1], Z, X, Y, Y), + nvsNegate(temp)); + break; + default: + fprintf(stderr, "hw doesn't support opcode \"%s\", and no emulation found\n", + _mesa_opcode_string(inst->Opcode)); + return GL_FALSE; + } + + return GL_TRUE; +} + +static GLboolean +pass0_translate_instructions(nouveauShader *nvs) +{ + struct gl_program *prog = (struct gl_program *)&nvs->mesa.vp; + nvsFunc *shader = nvs->func; + int ipos; + + for (ipos=0; iposNumInstructions; ipos++) { + struct prog_instruction *inst = &prog->Instructions[ipos]; + + if (inst->Opcode == OPCODE_END) + break; + + /* Deal with multiple ATTRIB/PARAM in a single instruction */ + pass0_check_sources(nvs, inst); + + /* Now it's safe to do the prog_instruction->nvsInstruction conversion */ + if (shader->SupportsOpcode(shader, pass0_make_opcode(inst->Opcode))) { + nvsInstruction *nvsinst; + nvsRegister src[3], dest; + int i; + + for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++) + pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]); + pass0_make_dst_reg(nvs, &dest, &inst->DstReg); + + nvsinst = pass0_emit(nvs, + pass0_make_opcode(inst->Opcode), + dest, + pass0_make_mask(inst->DstReg.WriteMask), + (inst->SaturateMode != SATURATE_OFF), + src[0], src[1], src[2]); + nvsinst->tex_unit = inst->TexSrcUnit; + nvsinst->tex_target = pass0_make_tex_target(inst->TexSrcTarget); + /* TODO when NV_fp/vp is implemented */ + nvsinst->cond = COND_TR; + } else { + if (!pass0_emulate_instruction(nvs, inst)) + return GL_FALSE; + } + } + + return GL_TRUE; +} + +GLboolean +nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + struct gl_program *prog = (struct gl_program*)nvs; + struct gl_vertex_program *vp = (struct gl_vertex_program *)prog; + struct gl_fragment_program *fp = (struct gl_fragment_program *)prog; + struct pass0_rec *rec; + int ret; + + switch (prog->Target) { + case GL_VERTEX_PROGRAM_ARB: + nvs->func = &nmesa->VPfunc; + if (vp->IsPositionInvariant) + _mesa_insert_mvp_code(ctx, vp); +#if 0 + if (IS_FIXEDFUNCTION_PROG && CLIP_PLANES_USED) + pass0_insert_ff_clip_planes(); +#endif + break; + case GL_FRAGMENT_PROGRAM_ARB: + nvs->func = &nmesa->FPfunc; + if (fp->FogOption != GL_NONE) + _mesa_append_fog_code(ctx, fp); + break; + default: + fprintf(stderr, "Unknown program type %d", prog->Target); + return GL_FALSE; + } + + rec = calloc(1, sizeof(struct pass0_rec)); + rec->next_temp = prog->NumTemporaries; + nvs->pass_rec = rec; + + ret = pass0_translate_instructions(nvs); + if (!ret) { + /* DESTROY list */ + } + + free(nvs->pass_rec); + return ret; +} + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0_arb.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0_arb.c deleted file mode 100644 index afb889d421..0000000000 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0_arb.c +++ /dev/null @@ -1,710 +0,0 @@ -/* - * Copyright (C) 2006 Ben Skeggs. - * - * 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 (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 NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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: - * Ben Skeggs - */ - -#include "glheader.h" -#include "macros.h" -#include "enums.h" - -#include "program.h" -#include "programopt.h" -#include "program_instruction.h" - -#include "nouveau_context.h" -#include "nouveau_shader.h" - -static nvsFixedReg _tx_mesa_vp_dst_reg[VERT_RESULT_MAX] = { - NVS_FR_POSITION, NVS_FR_COL0, NVS_FR_COL1, NVS_FR_FOGCOORD, - NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, - NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7, - NVS_FR_POINTSZ, NVS_FR_BFC0, NVS_FR_BFC1, NVS_FR_UNKNOWN /* EDGE */ -}; - -static nvsFixedReg _tx_mesa_fp_dst_reg[FRAG_RESULT_MAX] = { - NVS_FR_FRAGDATA0 /* COLR */, NVS_FR_FRAGDATA0 /* COLH */, - NVS_FR_UNKNOWN /* DEPR */ -}; - -static nvsFixedReg _tx_mesa_vp_src_reg[VERT_ATTRIB_MAX] = { - NVS_FR_POSITION, NVS_FR_WEIGHT, NVS_FR_NORMAL, NVS_FR_COL0, NVS_FR_COL1, - NVS_FR_FOGCOORD, NVS_FR_UNKNOWN /* COLOR_INDEX */, NVS_FR_UNKNOWN, - NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, - NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7, -/* Generic attribs 0-15, aliased to the above */ - NVS_FR_POSITION, NVS_FR_WEIGHT, NVS_FR_NORMAL, NVS_FR_COL0, NVS_FR_COL1, - NVS_FR_FOGCOORD, NVS_FR_UNKNOWN /* COLOR_INDEX */, NVS_FR_UNKNOWN, - NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, - NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7 -}; - -static nvsFixedReg _tx_mesa_fp_src_reg[FRAG_ATTRIB_MAX] = { - NVS_FR_POSITION, NVS_FR_COL0, NVS_FR_COL1, NVS_FR_FOGCOORD, - NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, - NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7 -}; - -static nvsSwzComp _tx_mesa_swizzle[4] = { - NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W -}; - -static nvsOpcode _tx_mesa_opcode[] = { - [OPCODE_ABS] = NVS_OP_ABS, [OPCODE_ADD] = NVS_OP_ADD, - [OPCODE_ARA] = NVS_OP_ARA, [OPCODE_ARL] = NVS_OP_ARL, - [OPCODE_ARL_NV] = NVS_OP_ARL, [OPCODE_ARR] = NVS_OP_ARR, - [OPCODE_CMP] = NVS_OP_CMP, [OPCODE_COS] = NVS_OP_COS, - [OPCODE_DDX] = NVS_OP_DDX, [OPCODE_DDY] = NVS_OP_DDY, - [OPCODE_DP3] = NVS_OP_DP3, [OPCODE_DP4] = NVS_OP_DP4, - [OPCODE_DPH] = NVS_OP_DPH, [OPCODE_DST] = NVS_OP_DST, - [OPCODE_EX2] = NVS_OP_EX2, [OPCODE_EXP] = NVS_OP_EXP, - [OPCODE_FLR] = NVS_OP_FLR, [OPCODE_FRC] = NVS_OP_FRC, - [OPCODE_KIL] = NVS_OP_EMUL, [OPCODE_KIL_NV] = NVS_OP_KIL, - [OPCODE_LG2] = NVS_OP_LG2, [OPCODE_LIT] = NVS_OP_LIT, - [OPCODE_LOG] = NVS_OP_LOG, - [OPCODE_LRP] = NVS_OP_LRP, - [OPCODE_MAD] = NVS_OP_MAD, [OPCODE_MAX] = NVS_OP_MAX, - [OPCODE_MIN] = NVS_OP_MIN, [OPCODE_MOV] = NVS_OP_MOV, - [OPCODE_MUL] = NVS_OP_MUL, - [OPCODE_PK2H] = NVS_OP_PK2H, [OPCODE_PK2US] = NVS_OP_PK2US, - [OPCODE_PK4B] = NVS_OP_PK4B, [OPCODE_PK4UB] = NVS_OP_PK4UB, - [OPCODE_POW] = NVS_OP_POW, [OPCODE_POPA] = NVS_OP_POPA, - [OPCODE_PUSHA] = NVS_OP_PUSHA, - [OPCODE_RCC] = NVS_OP_RCC, [OPCODE_RCP] = NVS_OP_RCP, - [OPCODE_RFL] = NVS_OP_RFL, [OPCODE_RSQ] = NVS_OP_RSQ, - [OPCODE_SCS] = NVS_OP_SCS, [OPCODE_SEQ] = NVS_OP_SEQ, - [OPCODE_SFL] = NVS_OP_SFL, [OPCODE_SGE] = NVS_OP_SGE, - [OPCODE_SGT] = NVS_OP_SGT, [OPCODE_SIN] = NVS_OP_SIN, - [OPCODE_SLE] = NVS_OP_SLE, [OPCODE_SLT] = NVS_OP_SLT, - [OPCODE_SNE] = NVS_OP_SNE, [OPCODE_SSG] = NVS_OP_SSG, - [OPCODE_STR] = NVS_OP_STR, [OPCODE_SUB] = NVS_OP_SUB, - [OPCODE_SWZ] = NVS_OP_MOV, - [OPCODE_TEX] = NVS_OP_TEX, [OPCODE_TXB] = NVS_OP_TXB, - [OPCODE_TXD] = NVS_OP_TXD, - [OPCODE_TXL] = NVS_OP_TXL, [OPCODE_TXP] = NVS_OP_TXP, - [OPCODE_TXP_NV] = NVS_OP_TXP, - [OPCODE_UP2H] = NVS_OP_UP2H, [OPCODE_UP2US] = NVS_OP_UP2US, - [OPCODE_UP4B] = NVS_OP_UP4B, [OPCODE_UP4UB] = NVS_OP_UP4UB, - [OPCODE_X2D] = NVS_OP_X2D, - [OPCODE_XPD] = NVS_OP_XPD -}; - -static nvsCond _tx_mesa_condmask[] = { - NVS_COND_UNKNOWN, NVS_COND_GT, NVS_COND_LT, NVS_COND_UN, NVS_COND_GE, - NVS_COND_LE, NVS_COND_NE, NVS_COND_NE, NVS_COND_TR, NVS_COND_FL -}; - -struct pass0_rec { - int nvs_ipos; - int next_temp; - int swzconst_done; - int swzconst_id; - nvsRegister const_half; -}; - -#define X NVS_SWZ_X -#define Y NVS_SWZ_Y -#define Z NVS_SWZ_Z -#define W NVS_SWZ_W - -static void -pass0_append_fragment(nouveauShader *nvs, nvsFragmentHeader *fragment) -{ - nvsFragmentList *list = calloc(1, sizeof(nvsFragmentList)); - if (!list) - return; - - list->fragment = fragment; - list->prev = nvs->list_tail; - if ( nvs->list_tail) - nvs->list_tail->next = list; - if (!nvs->list_head) - nvs->list_head = list; - nvs->list_tail = list; - - nvs->inst_count++; -} - -static void -pass0_make_reg(nouveauShader *nvs, nvsRegister *reg, - nvsRegFile file, unsigned int index) -{ - struct pass0_rec *rec = nvs->pass_rec; - - /* defaults */ - *reg = nvr_unused; - /* -1 == quick-and-dirty temp alloc */ - if (file == NVS_FILE_TEMP && index == -1) { - index = rec->next_temp++; - assert(index < NVS_MAX_TEMPS); - } - reg->file = file; - reg->index = index; -} - -static void -pass0_make_swizzle(nvsSwzComp *swz, unsigned int mesa) -{ - int i; - - for (i=0;i<4;i++) - swz[i] = _tx_mesa_swizzle[GET_SWZ(mesa, i)]; -} - -static nvsOpcode -pass0_make_opcode(enum prog_opcode op) -{ - if (op > MAX_OPCODE) - return NVS_OP_UNKNOWN; - return _tx_mesa_opcode[op]; -} - -static nvsCond -pass0_make_condmask(GLuint mesa) -{ - if (mesa > COND_FL) - return NVS_COND_UNKNOWN; - return _tx_mesa_condmask[mesa]; -} - -static unsigned int -pass0_make_mask(GLuint mesa_mask) -{ - unsigned int mask = 0; - - if (mesa_mask & WRITEMASK_X) mask |= SMASK_X; - if (mesa_mask & WRITEMASK_Y) mask |= SMASK_Y; - if (mesa_mask & WRITEMASK_Z) mask |= SMASK_Z; - if (mesa_mask & WRITEMASK_W) mask |= SMASK_W; - - return mask; -} - -static nvsTexTarget -pass0_make_tex_target(GLuint mesa) -{ - switch (mesa) { - case TEXTURE_1D_INDEX: return NVS_TEX_TARGET_1D; - case TEXTURE_2D_INDEX: return NVS_TEX_TARGET_2D; - case TEXTURE_3D_INDEX: return NVS_TEX_TARGET_3D; - case TEXTURE_CUBE_INDEX: return NVS_TEX_TARGET_CUBE; - case TEXTURE_RECT_INDEX: return NVS_TEX_TARGET_RECT; - default: - return NVS_TEX_TARGET_UNKNOWN; - } -} - -static void -pass0_make_dst_reg(nvsPtr nvs, nvsRegister *reg, - struct prog_dst_register *dst) -{ - struct gl_program *mesa = (struct gl_program*)&nvs->mesa.vp; - nvsFixedReg sfr; - - switch (dst->File) { - case PROGRAM_OUTPUT: - if (mesa->Target == GL_VERTEX_PROGRAM_ARB) { - sfr = (dst->Index < VERT_RESULT_MAX) ? - _tx_mesa_vp_dst_reg[dst->Index] : NVS_FR_UNKNOWN; - } else { - sfr = (dst->Index < FRAG_RESULT_MAX) ? - _tx_mesa_fp_dst_reg[dst->Index] : NVS_FR_UNKNOWN; - } - pass0_make_reg(nvs, reg, NVS_FILE_RESULT, sfr); - break; - case PROGRAM_TEMPORARY: - pass0_make_reg(nvs, reg, NVS_FILE_TEMP, dst->Index); - break; - case PROGRAM_ADDRESS: - pass0_make_reg(nvs, reg, NVS_FILE_ADDRESS, dst->Index); - break; - default: - fprintf(stderr, "Unknown dest file %d\n", dst->File); - assert(0); - } -} - -static void -pass0_make_src_reg(nvsPtr nvs, nvsRegister *reg, struct prog_src_register *src) -{ - struct gl_program *mesa = (struct gl_program *)&nvs->mesa.vp.Base; - struct gl_program_parameter_list *p = mesa->Parameters; - - *reg = nvr_unused; - - switch (src->File) { - case PROGRAM_INPUT: - reg->file = NVS_FILE_ATTRIB; - if (mesa->Target == GL_VERTEX_PROGRAM_ARB) { - reg->index = (src->Index < VERT_ATTRIB_MAX) ? - _tx_mesa_vp_src_reg[src->Index] : NVS_FR_UNKNOWN; - } else { - reg->index = (src->Index < FRAG_ATTRIB_MAX) ? - _tx_mesa_fp_src_reg[src->Index] : NVS_FR_UNKNOWN; - } - break; - /* All const types seem to get shoved into here, not really sure why */ - case PROGRAM_STATE_VAR: - switch (p->Parameters[src->Index].Type) { - case PROGRAM_NAMED_PARAM: - case PROGRAM_CONSTANT: - nvs->params[src->Index].source_val = NULL; - COPY_4V(nvs->params[src->Index].val, p->ParameterValues[src->Index]); - break; - case PROGRAM_STATE_VAR: - nvs->params[src->Index].source_val = p->ParameterValues[src->Index]; - break; - default: - fprintf(stderr, "Unknown parameter type %d\n", - p->Parameters[src->Index].Type); - assert(0); - break; - } - - if (src->RelAddr) { - reg->indexed = 1; - reg->addr_reg = 0; - reg->addr_comp = NVS_SWZ_X; - } else - reg->indexed = 0; - reg->file = NVS_FILE_CONST; - reg->index = src->Index; - break; - case PROGRAM_TEMPORARY: - reg->file = NVS_FILE_TEMP; - reg->index = src->Index; - break; - default: - fprintf(stderr, "Unknown source type %d\n", src->File); - assert(0); - } - - /* per-component negate handled elsewhere */ - reg->negate = src->NegateBase != 0; - reg->abs = src->Abs; - pass0_make_swizzle(reg->swizzle, src->Swizzle); -} - -static nvsInstruction * -pass0_emit(nouveauShader *nvs, nvsOpcode op, nvsRegister dst, - unsigned int mask, int saturate, - nvsRegister src0, nvsRegister src1, nvsRegister src2) -{ - struct pass0_rec *rec = nvs->pass_rec; - nvsInstruction *sif = NULL; - - /* Seems mesa doesn't explicitly 0 this.. */ - if (nvs->mesa.vp.Base.Target == GL_VERTEX_PROGRAM_ARB) - saturate = 0; - - sif = calloc(1, sizeof(nvsInstruction)); - if (sif) { - sif->header.type = NVS_INSTRUCTION; - sif->header.position = rec->nvs_ipos++; - sif->op = op; - sif->saturate = saturate; - sif->dest = dst; - sif->mask = mask; - sif->src[0] = src0; - sif->src[1] = src1; - sif->src[2] = src2; - sif->cond = COND_TR; - sif->cond_reg = 0; - sif->cond_test = 0; - sif->cond_update = 0; - pass0_make_swizzle(sif->cond_swizzle, SWIZZLE_NOOP); - pass0_append_fragment(nvs, (nvsFragmentHeader *)sif); - } - - return sif; -} - -static void -pass0_fixup_swizzle(nvsPtr nvs, - struct prog_src_register *src, - unsigned int sm1, - unsigned int sm2) -{ - static const float sc[4] = { 1.0, 0.0, -1.0, 0.0 }; - struct pass0_rec *rec = nvs->pass_rec; - int fixup_1, fixup_2; - nvsRegister sr, dr = nvr_unused; - nvsRegister sm1const, sm2const; - - if (!rec->swzconst_done) { - struct gl_program *prog = &nvs->mesa.vp.Base; - rec->swzconst_id = _mesa_add_unnamed_constant(prog->Parameters, sc, 4); - rec->swzconst_done = 1; - COPY_4V(nvs->params[rec->swzconst_id].val, sc); - } - - fixup_1 = (sm1 != MAKE_SWIZZLE4(0,0,0,0) && sm2 != MAKE_SWIZZLE4(2,2,2,2)); - fixup_2 = (sm2 != MAKE_SWIZZLE4(2,2,2,2)); - - if (src->File != PROGRAM_TEMPORARY && src->File != PROGRAM_INPUT) { - /* We can't use more than one const in an instruction, so move the const - * into a temp, and swizzle from there. - *TODO: should just emit the swizzled const, instead of swizzling it - * in the shader.. would need to reswizzle any state params when they - * change however.. - */ - pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); - pass0_make_src_reg(nvs, &sr, src); - pass0_emit(nvs, NVS_OP_MOV, dr, SMASK_ALL, 0, sr, nvr_unused, nvr_unused); - pass0_make_reg(nvs, &sr, NVS_FILE_TEMP, dr.index); - } else { - if (fixup_1) - src->NegateBase = 0; - pass0_make_src_reg(nvs, &sr, src); - pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); - } - - pass0_make_reg(nvs, &sm1const, NVS_FILE_CONST, rec->swzconst_id); - pass0_make_swizzle(sm1const.swizzle, sm1); - if (fixup_1 && fixup_2) { - /* Any combination with SWIZZLE_ONE */ - pass0_make_reg(nvs, &sm2const, NVS_FILE_CONST, rec->swzconst_id); - pass0_make_swizzle(sm2const.swizzle, sm2); - pass0_emit(nvs, NVS_OP_MAD, dr, SMASK_ALL, 0, sr, sm1const, sm2const); - } else { - /* SWIZZLE_ZERO || arbitrary negate */ - pass0_emit(nvs, NVS_OP_MUL, dr, SMASK_ALL, 0, sr, sm1const, nvr_unused); - } - - src->File = PROGRAM_TEMPORARY; - src->Index = dr.index; - src->Swizzle = SWIZZLE_NOOP; -} - -#define SET_SWZ(fs, cp, c) fs = (fs & ~(0x7<<(cp*3))) | (c<<(cp*3)) -static void -pass0_check_sources(nvsPtr nvs, struct prog_instruction *inst) -{ - unsigned int insrc = -1, constsrc = -1; - int i; - - for (i=0;i<_mesa_num_inst_src_regs(inst->Opcode);i++) { - struct prog_src_register *src = &inst->SrcReg[i]; - unsigned int sm_1 = 0, sm_2 = 0; - nvsRegister sr, dr; - int do_mov = 0, c; - - /* Build up swizzle masks as if we were going to use - * "MAD new, src, const1, const2" to support arbitrary negation - * and SWIZZLE_ZERO/SWIZZLE_ONE. - */ - for (c=0;c<4;c++) { - if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ZERO) { - SET_SWZ(sm_1, c, SWIZZLE_Y); /* 0.0 */ - SET_SWZ(sm_2, c, SWIZZLE_Y); - SET_SWZ(src->Swizzle, c, SWIZZLE_X); - } else if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ONE) { - SET_SWZ(sm_1, c, SWIZZLE_Y); - if (src->NegateBase & (1<Swizzle, c, SWIZZLE_X); - } else { - if (src->NegateBase & (1<File) { - case PROGRAM_INPUT: - if (insrc != -1 && insrc != src->Index) - do_mov = 1; - else insrc = src->Index; - break; - case PROGRAM_STATE_VAR: - if (constsrc != -1 && constsrc != src->Index) - do_mov = 1; - else constsrc = src->Index; - break; - default: - break; - } - - /* Emit any extra ATTRIB/CONST to a temp, and modify the Mesa instruction - * to point at the temp. - */ - if (do_mov) { - pass0_make_src_reg(nvs, &sr, src); - pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); - pass0_emit(nvs, NVS_OP_MOV, dr, SMASK_ALL, 0, - sr, nvr_unused, nvr_unused); - - src->File = PROGRAM_TEMPORARY; - src->Index = dr.index; - src->Swizzle= SWIZZLE_NOOP; - } - } -} - -static GLboolean -pass0_emulate_instruction(nouveauShader *nvs, struct prog_instruction *inst) -{ - nvsFunc *shader = nvs->func; - nvsRegister src[3], dest, temp; - nvsInstruction *nvsinst; - struct pass0_rec *rec = nvs->pass_rec; - unsigned int mask = pass0_make_mask(inst->DstReg.WriteMask); - int i, sat; - - sat = (inst->SaturateMode == SATURATE_ZERO_ONE); - - /* Build all the "real" regs for the instruction */ - for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++) - pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]); - if (inst->Opcode != OPCODE_KIL) - pass0_make_dst_reg(nvs, &dest, &inst->DstReg); - - switch (inst->Opcode) { - case OPCODE_ABS: - if (shader->caps & SCAP_SRC_ABS) - pass0_emit(nvs, NVS_OP_MOV, dest, mask, sat, - nvsAbs(src[0]), nvr_unused, nvr_unused); - else - pass0_emit(nvs, NVS_OP_MAX, dest, mask, sat, - src[0], nvsNegate(src[0]), nvr_unused); - break; - case OPCODE_KIL: - /* This is only in ARB shaders, so we don't have to worry - * about clobbering a CC reg as they aren't supported anyway. - */ - /* MOVC0 temp, src */ - pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - nvsinst = pass0_emit(nvs, NVS_OP_MOV, temp, SMASK_ALL, 0, - src[0], nvr_unused, nvr_unused); - nvsinst->cond_update = 1; - nvsinst->cond_reg = 0; - /* KIL_NV (LT0.xyzw) temp */ - nvsinst = pass0_emit(nvs, NVS_OP_KIL, nvr_unused, 0, 0, - nvr_unused, nvr_unused, nvr_unused); - nvsinst->cond = COND_LT; - nvsinst->cond_reg = 0; - nvsinst->cond_test = 1; - pass0_make_swizzle(nvsinst->cond_swizzle, MAKE_SWIZZLE4(0,1,2,3)); - break; - case OPCODE_LIT: - break; - case OPCODE_LRP: - pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - pass0_emit(nvs, NVS_OP_MAD, temp, mask, 0, - nvsNegate(src[0]), src[2], src[2]); - pass0_emit(nvs, NVS_OP_MAD, dest, mask, sat, - src[0], src[1], temp); - break; - case OPCODE_POW: - if (shader->SupportsOpcode(shader, NVS_OP_LG2) && - shader->SupportsOpcode(shader, NVS_OP_EX2)) { - pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - /* LG2 temp.x, src0.c */ - pass0_emit(nvs, NVS_OP_LG2, temp, SMASK_X, 0, - nvsSwizzle(src[0], X, X, X, X), - nvr_unused, - nvr_unused); - /* MUL temp.x, temp.x, src1.c */ - pass0_emit(nvs, NVS_OP_MUL, temp, SMASK_X, 0, - nvsSwizzle(temp, X, X, X, X), - nvsSwizzle(src[1], X, X, X, X), - nvr_unused); - /* EX2 dest, temp.x */ - pass0_emit(nvs, NVS_OP_EX2, dest, mask, sat, - nvsSwizzle(temp, X, X, X, X), - nvr_unused, - nvr_unused); - } else { - /* can we use EXP/LOG instead of EX2/LG2?? */ - fprintf(stderr, "Implement POW for NV20 vtxprog!\n"); - return GL_FALSE; - } - break; - case OPCODE_RSQ: - if (rec->const_half.file != NVS_FILE_CONST) { - GLfloat const_half[4] = { 0.5, 0.0, 0.0, 0.0 }; - pass0_make_reg(nvs, &rec->const_half, NVS_FILE_CONST, - _mesa_add_unnamed_constant(nvs->mesa.vp.Base.Parameters, - const_half, 4)); - COPY_4V(nvs->params[rec->const_half.index].val, const_half); - } - pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - pass0_emit(nvs, NVS_OP_LG2, temp, SMASK_X, 0, - nvsAbs(nvsSwizzle(src[0], X, X, X, X)), - nvr_unused, - nvr_unused); - pass0_emit(nvs, NVS_OP_MUL, temp, SMASK_X, 0, - nvsSwizzle(temp, X, X, X, X), - nvsNegate(rec->const_half), - nvr_unused); - pass0_emit(nvs, NVS_OP_EX2, dest, mask, sat, - nvsSwizzle(temp, X, X, X, X), - nvr_unused, - nvr_unused); - break; - case OPCODE_SCS: - if (mask & SMASK_X) - pass0_emit(nvs, NVS_OP_COS, dest, SMASK_X, sat, - nvsSwizzle(src[0], X, X, X, X), - nvr_unused, - nvr_unused); - if (mask & SMASK_Y) - pass0_emit(nvs, NVS_OP_SIN, dest, SMASK_Y, sat, - nvsSwizzle(src[0], X, X, X, X), - nvr_unused, - nvr_unused); - break; - case OPCODE_SUB: - pass0_emit(nvs, NVS_OP_ADD, dest, mask, sat, - src[0], nvsNegate(src[1]), nvr_unused); - break; - case OPCODE_XPD: - pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - pass0_emit(nvs, NVS_OP_MUL, temp, SMASK_ALL, 0, - nvsSwizzle(src[0], Z, X, Y, Y), - nvsSwizzle(src[1], Y, Z, X, X), - nvr_unused); - pass0_emit(nvs, NVS_OP_MAD, dest, (mask & ~SMASK_W), sat, - nvsSwizzle(src[0], Y, Z, X, X), - nvsSwizzle(src[1], Z, X, Y, Y), - nvsNegate(temp)); - break; - default: - fprintf(stderr, "hw doesn't support opcode \"%s\", and no emulation found\n", - _mesa_opcode_string(inst->Opcode)); - return GL_FALSE; - } - - return GL_TRUE; -} - -static GLboolean -pass0_translate_instructions(nouveauShader *nvs) -{ - struct gl_program *prog = (struct gl_program *)&nvs->mesa.vp; - nvsFunc *shader = nvs->func; - int ipos; - - for (ipos=0; iposNumInstructions; ipos++) { - struct prog_instruction *inst = &prog->Instructions[ipos]; - - if (inst->Opcode == OPCODE_END) - break; - - /* Deal with multiple ATTRIB/PARAM in a single instruction */ - pass0_check_sources(nvs, inst); - - /* Now it's safe to do the prog_instruction->nvsInstruction conversion */ - if (shader->SupportsOpcode(shader, pass0_make_opcode(inst->Opcode))) { - nvsInstruction *nvsinst; - nvsRegister src[3], dest; - int i; - - for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++) - pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]); - pass0_make_dst_reg(nvs, &dest, &inst->DstReg); - - nvsinst = pass0_emit(nvs, - pass0_make_opcode(inst->Opcode), - dest, - pass0_make_mask(inst->DstReg.WriteMask), - (inst->SaturateMode != SATURATE_OFF), - src[0], src[1], src[2]); - nvsinst->tex_unit = inst->TexSrcUnit; - nvsinst->tex_target = pass0_make_tex_target(inst->TexSrcTarget); - /* TODO when NV_fp/vp is implemented */ - nvsinst->cond = COND_TR; - } else { - if (!pass0_emulate_instruction(nvs, inst)) - return GL_FALSE; - } - } - - return GL_TRUE; -} - -GLboolean -nouveau_shader_pass0_arb(GLcontext *ctx, nouveauShader *nvs) -{ - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - struct gl_program *prog = (struct gl_program*)nvs; - struct gl_vertex_program *vp = (struct gl_vertex_program *)prog; - struct gl_fragment_program *fp = (struct gl_fragment_program *)prog; - struct pass0_rec *rec; - int ret; - - switch (prog->Target) { - case GL_VERTEX_PROGRAM_ARB: - nvs->func = &nmesa->VPfunc; - if (vp->IsPositionInvariant) - _mesa_insert_mvp_code(ctx, vp); -#if 0 - if (IS_FIXEDFUNCTION_PROG && CLIP_PLANES_USED) - pass0_insert_ff_clip_planes(); -#endif - break; - case GL_FRAGMENT_PROGRAM_ARB: - nvs->func = &nmesa->FPfunc; - if (fp->FogOption != GL_NONE) - _mesa_append_fog_code(ctx, fp); - break; - default: - fprintf(stderr, "Unknown program type %d", prog->Target); - return GL_FALSE; - } - - rec = calloc(1, sizeof(struct pass0_rec)); - rec->next_temp = prog->NumTemporaries; - nvs->pass_rec = rec; - - ret = pass0_translate_instructions(nvs); - if (!ret) { - /* DESTROY list */ - } - - free(nvs->pass_rec); - return ret; -} - -- cgit v1.2.3 From 3c0961d29993a2203323b4c308ae6d7e418ac5aa Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sun, 21 Jan 2007 04:06:57 +0100 Subject: nouveau: add nv04 state support, and small nv04 fixes. --- src/mesa/drivers/dri/nouveau/Makefile | 11 +- src/mesa/drivers/dri/nouveau/nouveau_context.c | 3 +- src/mesa/drivers/dri/nouveau/nouveau_context.h | 18 +- src/mesa/drivers/dri/nouveau/nouveau_object.c | 11 +- src/mesa/drivers/dri/nouveau/nouveau_state.c | 4 +- src/mesa/drivers/dri/nouveau/nouveau_state.h | 1 + src/mesa/drivers/dri/nouveau/nv04_state.c | 497 +++++++++++++++++++++++++ 7 files changed, 527 insertions(+), 18 deletions(-) create mode 100644 src/mesa/drivers/dri/nouveau/nv04_state.c (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile index 9718f3bf46..492e743360 100644 --- a/src/mesa/drivers/dri/nouveau/Makefile +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -19,6 +19,7 @@ DRIVER_SOURCES = \ nouveau_screen.c \ nouveau_span.c \ nouveau_state.c \ + nouveau_state_cache.c \ nouveau_shader.c \ nouveau_shader_0.c \ nouveau_shader_1.c \ @@ -26,18 +27,18 @@ DRIVER_SOURCES = \ nouveau_tex.c \ nouveau_swtcl.c \ nouveau_sync.c \ + nv04_state.c \ nv04_swtcl.c \ - nv10_swtcl.c \ nv10_state.c \ + nv10_swtcl.c \ nv20_state.c \ - nv30_state.c \ - nv50_state.c \ - nouveau_state_cache.c \ nv20_vertprog.c \ + nv30_state.c \ nv30_fragprog.c \ nv30_vertprog.c \ nv40_fragprog.c \ - nv40_vertprog.c + nv40_vertprog.c \ + nv50_state.c C_SOURCES = \ $(COMMON_SOURCES) \ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 79da46fc0b..5db93eb012 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -50,6 +50,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_msg.h" #include "nouveau_reg.h" #include "nouveau_lock.h" +#include "nv04_swtcl.h" #include "nv10_swtcl.h" #include "vblank.h" @@ -212,7 +213,7 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, break; case NV_04: case NV_05: - //nv04TriInitFunctions( ctx ); + nv04TriInitFunctions( ctx ); break; case NV_10: case NV_20: diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index c7bf387210..bcfbb9fb8d 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -170,15 +170,15 @@ typedef struct nouveau_context { /* Configuration cache */ driOptionCache optionCache; - /* vblank stuff */ - uint32_t vblank_flags; - uint32_t vblank_seq; - - GLuint new_state; - GLuint new_render_state; - GLuint render_index; - GLmatrix viewport; - GLfloat depth_scale; + /* vblank stuff */ + uint32_t vblank_flags; + uint32_t vblank_seq; + + GLuint new_state; + GLuint new_render_state; + GLuint render_index; + GLmatrix viewport; + GLfloat depth_scale; }nouveauContextRec, *nouveauContextPtr; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.c b/src/mesa/drivers/dri/nouveau/nouveau_object.c index 1558f2963d..26086e16e4 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.c @@ -62,10 +62,17 @@ void nouveauObjectInit(nouveauContextPtr nmesa) nouveauCreateContextObject(nmesa, Nv3D, nmesa->screen->card->class_3d, 0, 0, 0, 0); - nouveauCreateContextObject(nmesa, NvCtxSurf2D, NV10_CONTEXT_SURFACES_2D, + if (nmesa->screen->card->type>=NV_10) { + nouveauCreateContextObject(nmesa, NvCtxSurf2D, NV10_CONTEXT_SURFACES_2D, 0, 0, 0, 0); - nouveauCreateContextObject(nmesa, NvImageBlit, NV10_IMAGE_BLIT, + nouveauCreateContextObject(nmesa, NvImageBlit, NV10_IMAGE_BLIT, NV_DMA_CONTEXT_FLAGS_PATCH_SRCCOPY, 0, 0, 0); + } else { + nouveauCreateContextObject(nmesa, NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D, + 0, 0, 0, 0); + nouveauCreateContextObject(nmesa, NvImageBlit, NV_IMAGE_BLIT, + NV_DMA_CONTEXT_FLAGS_PATCH_SRCCOPY, 0, 0, 0); + } nouveauCreateContextObject(nmesa, NvMemFormat, NV_MEMORY_TO_MEMORY_FORMAT, 0, 0, 0, 0); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c index 1ff881f054..18f6ffb2ad 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -156,9 +156,11 @@ void nouveauDDInitState(nouveauContextPtr nmesa) switch(type) { case NV_03: + /* Unimplemented */ + break; case NV_04: case NV_05: - /* No TCL engines for these ones */ + nv04InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver); break; case NV_10: nv10InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.h b/src/mesa/drivers/dri/nouveau/nouveau_state.h index 16d63a6ac2..5b85287445 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.h @@ -32,6 +32,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. extern void nouveauDDInitState(nouveauContextPtr nmesa); extern void nouveauDDInitStateFuncs(GLcontext *ctx); +extern void nv04InitStateFuncs(GLcontext *ctx, struct dd_function_table *func); extern void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func); extern void nv20InitStateFuncs(GLcontext *ctx, struct dd_function_table *func); extern void nv30InitStateFuncs(GLcontext *ctx, struct dd_function_table *func); diff --git a/src/mesa/drivers/dri/nouveau/nv04_state.c b/src/mesa/drivers/dri/nouveau/nv04_state.c new file mode 100644 index 0000000000..83ad8ae432 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_state.c @@ -0,0 +1,497 @@ +/************************************************************************** + +Copyright 2007 Stephane Marchesin +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 +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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. + +**************************************************************************/ + +#include "nouveau_context.h" +#include "nouveau_object.h" +#include "nouveau_fifo.h" +#include "nouveau_reg.h" +#include "nouveau_msg.h" + +#include "tnl/t_pipeline.h" + +#include "mtypes.h" +#include "colormac.h" + +static uint32_t nv04_compare_func(GLcontext *ctx,GLuint f) +{ + switch ( ctx->Color.AlphaFunc ) { + case GL_NEVER: return 1; + case GL_LESS: return 2; + case GL_EQUAL: return 3; + case GL_LEQUAL: return 4; + case GL_GREATER: return 5; + case GL_NOTEQUAL: return 6; + case GL_GEQUAL: return 7; + case GL_ALWAYS: return 8; + } + WARN_ONCE("Unable to find the function\n"); + return 0; +} + +static uint32_t nv04_blend_func(GLcontext *ctx,GLuint f) +{ + switch ( ctx->Color.AlphaFunc ) { + case GL_ZERO: return 0x1; + case GL_ONE: return 0x2; + case GL_SRC_COLOR: return 0x3; + case GL_ONE_MINUS_SRC_COLOR: return 0x4; + case GL_SRC_ALPHA: return 0x5; + case GL_ONE_MINUS_SRC_ALPHA: return 0x6; + case GL_DST_ALPHA: return 0x7; + case GL_ONE_MINUS_DST_ALPHA: return 0x8; + case GL_DST_COLOR: return 0x9; + case GL_ONE_MINUS_DST_COLOR: return 0xA; + case GL_SRC_ALPHA_SATURATE: return 0xB; + } + WARN_ONCE("Unable to find the function\n"); + return 0; +} + +static void nv04_emit_control(GLcontext *ctx) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + uint32_t control,cull; + GLubyte alpha_ref; + + CLAMPED_FLOAT_TO_UBYTE(alpha_ref, ctx->Color.AlphaRef); + control=alpha_ref; + control|=(nv04_compare_func(ctx,ctx->Color.AlphaFunc)<<8); + control|=(ctx->Color.AlphaEnabled<<12); + control|=(1<<13); + control|=(ctx->Depth.Test<<14); + control|=(nv04_compare_func(ctx,ctx->Depth.Func)<<16); + if ((ctx->Polygon.CullFlag)&&(ctx->Polygon.CullFaceMode!=GL_FRONT_AND_BACK)) + { + if ((ctx->Polygon.FrontFace==GL_CW)&&(ctx->Polygon.CullFaceMode==GL_FRONT)) + cull=2; + if ((ctx->Polygon.FrontFace==GL_CW)&&(ctx->Polygon.CullFaceMode==GL_BACK)) + cull=3; + if ((ctx->Polygon.FrontFace==GL_CCW)&&(ctx->Polygon.CullFaceMode==GL_FRONT)) + cull=3; + if ((ctx->Polygon.FrontFace==GL_CCW)&&(ctx->Polygon.CullFaceMode==GL_BACK)) + cull=2; + } + else + if (ctx->Polygon.CullFaceMode==GL_FRONT_AND_BACK) + cull=0; + else + cull=1; + control|=(cull<<20); + control|=(ctx->Color.DitherFlag<<22); + if ((ctx->Depth.Test)&&(ctx->Depth.Mask)) + control|=(1<<24); + + control|=(1<<30); // integer zbuffer format + + BEGIN_RING_CACHE(NvSub3D, NV04_DX5_TEXTURED_TRIANGLE_CONTROL, 1); + OUT_RING_CACHE(control); +} + +static void nv04_emit_blend(GLcontext *ctx) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + uint32_t blend; + + blend=0x4; // texture MODULATE_ALPHA + blend|=0x20; // alpha is MSB + switch(ctx->Light.ShadeModel) { + case GL_SMOOTH:blend|=(1<<6);break; + case GL_FLAT: blend|=(2<<6);break; + default:break; + } + if (ctx->Hint.PerspectiveCorrection!=GL_FASTEST) + blend|=(1<<8); + blend|=(ctx->Fog.Enabled<<16); + blend|=(ctx->Color.BlendEnabled<<20); + blend|=(nv04_blend_func(ctx,ctx->Color.BlendSrcRGB)<<24); + blend|=(nv04_blend_func(ctx,ctx->Color.BlendDstRGB)<<28); + + BEGIN_RING_CACHE(NvSub3D, NV04_DX5_TEXTURED_TRIANGLE_BLEND, 1); + OUT_RING_CACHE(blend); +} + +static void nv04_emit_fog_color(GLcontext *ctx) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte c[4]; + c[0] = FLOAT_TO_UBYTE( ctx->Fog.Color[0] ); + c[1] = FLOAT_TO_UBYTE( ctx->Fog.Color[1] ); + c[2] = FLOAT_TO_UBYTE( ctx->Fog.Color[2] ); + c[3] = FLOAT_TO_UBYTE( ctx->Fog.Color[3] ); + BEGIN_RING_CACHE(NvSub3D, NV04_DX5_TEXTURED_TRIANGLE_FOG_COLOR, 1); + OUT_RING_CACHE(PACK_COLOR_8888_REV(c[0],c[1],c[2],c[3])); +} + +static void nv04AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) +{ + nv04_emit_control(ctx); +} + +static void nv04BlendColor(GLcontext *ctx, const GLfloat color[4]) +{ + nv04_emit_blend(ctx); +} + +static void nv04BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA) +{ + nv04_emit_blend(ctx); +} + + +static void nv04BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA) +{ + nv04_emit_blend(ctx); +} + +static void nv04Clear(GLcontext *ctx, GLbitfield mask) +{ + /* TODO */ +} + +static void nv04ClearColor(GLcontext *ctx, const GLfloat color[4]) +{ + /* TODO */ +} + +static void nv04ClearDepth(GLcontext *ctx, GLclampd d) +{ + /* TODO */ +} + +static void nv04ClearStencil(GLcontext *ctx, GLint s) +{ + /* TODO */ +} + +static void nv04ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) +{ + /* TODO */ +} + +static void nv04ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, + GLboolean bmask, GLboolean amask ) +{ + /* TODO */ +} + +static void nv04ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode) +{ + /* TODO I need love */ +} + +static void nv04CullFace(GLcontext *ctx, GLenum mode) +{ + nv04_emit_control(ctx); +} + +static void nv04FrontFace(GLcontext *ctx, GLenum mode) +{ + /* TODO */ +} + +static void nv04DepthFunc(GLcontext *ctx, GLenum func) +{ + nv04_emit_control(ctx); +} + +static void nv04DepthMask(GLcontext *ctx, GLboolean flag) +{ + /* TODO */ +} + +static void nv04DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval) +{ + /* TODO */ +} + +/** Specify the current buffer for writing */ +//void (*DrawBuffer)( GLcontext *ctx, GLenum buffer ); +/** Specify the buffers for writing for fragment programs*/ +//void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers ); + +static void nv04Enable(GLcontext *ctx, GLenum cap, GLboolean state) +{ + switch(cap) + { + case GL_ALPHA_TEST: + nv04_emit_control(ctx); + break; +// case GL_AUTO_NORMAL: + case GL_BLEND: + nv04_emit_blend(ctx); + break; +// case GL_CLIP_PLANE0: +// case GL_CLIP_PLANE1: +// case GL_CLIP_PLANE2: +// case GL_CLIP_PLANE3: +// case GL_CLIP_PLANE4: +// case GL_CLIP_PLANE5: +// case GL_COLOR_LOGIC_OP: +// case GL_COLOR_MATERIAL: +// case GL_COLOR_SUM_EXT: +// case GL_COLOR_TABLE: +// case GL_CONVOLUTION_1D: +// case GL_CONVOLUTION_2D: + case GL_CULL_FACE: + nv04_emit_control(ctx); + break; + case GL_DEPTH_TEST: + nv04_emit_control(ctx); + break; + case GL_DITHER: + nv04_emit_control(ctx); + break; + case GL_FOG: + nv04_emit_blend(ctx); + break; +// case GL_HISTOGRAM: +// case GL_INDEX_LOGIC_OP: +// case GL_LIGHT0: +// case GL_LIGHT1: +// case GL_LIGHT2: +// case GL_LIGHT3: +// case GL_LIGHT4: +// case GL_LIGHT5: +// case GL_LIGHT6: +// case GL_LIGHT7: +// case GL_LIGHTING: +// case GL_LINE_SMOOTH: +// case GL_LINE_STIPPLE: +// case GL_MAP1_COLOR_4: +// case GL_MAP1_INDEX: +// case GL_MAP1_NORMAL: +// case GL_MAP1_TEXTURE_COORD_1: +// case GL_MAP1_TEXTURE_COORD_2: +// case GL_MAP1_TEXTURE_COORD_3: +// case GL_MAP1_TEXTURE_COORD_4: +// case GL_MAP1_VERTEX_3: +// case GL_MAP1_VERTEX_4: +// case GL_MAP2_COLOR_4: +// case GL_MAP2_INDEX: +// case GL_MAP2_NORMAL: +// case GL_MAP2_TEXTURE_COORD_1: +// case GL_MAP2_TEXTURE_COORD_2: +// case GL_MAP2_TEXTURE_COORD_3: +// case GL_MAP2_TEXTURE_COORD_4: +// case GL_MAP2_VERTEX_3: +// case GL_MAP2_VERTEX_4: +// case GL_MINMAX: +// case GL_NORMALIZE: +// case GL_POINT_SMOOTH: +// case GL_POLYGON_OFFSET_POINT: +// case GL_POLYGON_OFFSET_LINE: +// case GL_POLYGON_OFFSET_FILL: +// case GL_POLYGON_SMOOTH: +// case GL_POLYGON_STIPPLE: +// case GL_POST_COLOR_MATRIX_COLOR_TABLE: +// case GL_POST_CONVOLUTION_COLOR_TABLE: +// case GL_RESCALE_NORMAL: +// case GL_SCISSOR_TEST: +// case GL_SEPARABLE_2D: +// case GL_STENCIL_TEST: +// case GL_TEXTURE_GEN_Q: +// case GL_TEXTURE_GEN_R: +// case GL_TEXTURE_GEN_S: +// case GL_TEXTURE_GEN_T: +// case GL_TEXTURE_1D: +// case GL_TEXTURE_2D: +// case GL_TEXTURE_3D: + } +} + +static void nv04Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + nv04_emit_blend(ctx); + nv04_emit_fog_color(ctx); +} + +static void nv04Hint(GLcontext *ctx, GLenum target, GLenum mode) +{ + switch(target) + { + case GL_PERSPECTIVE_CORRECTION_HINT:nv04_emit_blend(ctx);break; + default:break; + } +} + +static void nv04LineStipple(GLcontext *ctx, GLint factor, GLushort pattern ) +{ + /* TODO not even in your dreams */ +} + +static void nv04LineWidth(GLcontext *ctx, GLfloat width) +{ + /* TODO */ +} + +static void nv04LogicOpcode(GLcontext *ctx, GLenum opcode) +{ + /* TODO */ +} + +static void nv04PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + /* TODO */ +} + +static void nv04PointSize(GLcontext *ctx, GLfloat size) +{ + /* TODO */ +} + +static void nv04PolygonMode(GLcontext *ctx, GLenum face, GLenum mode) +{ + /* TODO */ +} + +/** Set the scale and units used to calculate depth values */ +static void nv04PolygonOffset(GLcontext *ctx, GLfloat factor, GLfloat units) +{ + /* TODO */ +} + +/** Set the polygon stippling pattern */ +static void nv04PolygonStipple(GLcontext *ctx, const GLubyte *mask ) +{ + /* TODO */ +} + +/* Specifies the current buffer for reading */ +void (*ReadBuffer)( GLcontext *ctx, GLenum buffer ); +/** Set rasterization mode */ +void (*RenderMode)(GLcontext *ctx, GLenum mode ); + +/** Define the scissor box */ +static void nv04Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + /* TODO */ +} + +/** Select flat or smooth shading */ +static void nv04ShadeModel(GLcontext *ctx, GLenum mode) +{ + nv04_emit_blend(ctx); +} + +/** OpenGL 2.0 two-sided StencilFunc */ +static void nv04StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, + GLint ref, GLuint mask) +{ + /* TODO */ +} + +/** OpenGL 2.0 two-sided StencilMask */ +static void nv04StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask) +{ + /* TODO */ +} + +/** OpenGL 2.0 two-sided StencilOp */ +static void nv04StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, + GLenum zfail, GLenum zpass) +{ + /* TODO */ +} + +/** Control the generation of texture coordinates */ +void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname, + const GLfloat *params); +/** Set texture environment parameters */ +void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname, + const GLfloat *param); +/** Set texture parameters */ +void (*TexParameter)(GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj, + GLenum pname, const GLfloat *params); + +/* Update anything that depends on the window position/size */ +static void nv04WindowMoved(nouveauContextPtr nmesa) +{ +} + +/* Initialise any card-specific non-GL related state */ +static GLboolean nv04InitCard(nouveauContextPtr nmesa) +{ + return GL_TRUE; +} + +/* Update buffer offset/pitch/format */ +static GLboolean nv04BindBuffers(nouveauContextPtr nmesa, int num_color, + nouveau_renderbuffer **color, + nouveau_renderbuffer *depth) +{ + return GL_TRUE; +} + +void nv04InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + func->AlphaFunc = nv04AlphaFunc; + func->BlendColor = nv04BlendColor; + func->BlendEquationSeparate = nv04BlendEquationSeparate; + func->BlendFuncSeparate = nv04BlendFuncSeparate; + func->Clear = nv04Clear; + func->ClearColor = nv04ClearColor; + func->ClearDepth = nv04ClearDepth; + func->ClearStencil = nv04ClearStencil; + func->ClipPlane = nv04ClipPlane; + func->ColorMask = nv04ColorMask; + func->ColorMaterial = nv04ColorMaterial; + func->CullFace = nv04CullFace; + func->FrontFace = nv04FrontFace; + func->DepthFunc = nv04DepthFunc; + func->DepthMask = nv04DepthMask; + func->DepthRange = nv04DepthRange; + func->Enable = nv04Enable; + func->Fogfv = nv04Fogfv; + func->Hint = nv04Hint; +/* func->Lightfv = nv04Lightfv;*/ +/* func->LightModelfv = nv04LightModelfv; */ + func->LineStipple = nv04LineStipple; /* Not for NV04 */ + func->LineWidth = nv04LineWidth; + func->LogicOpcode = nv04LogicOpcode; + func->PointParameterfv = nv04PointParameterfv; + func->PointSize = nv04PointSize; + func->PolygonMode = nv04PolygonMode; + func->PolygonOffset = nv04PolygonOffset; + func->PolygonStipple = nv04PolygonStipple; /* Not for NV04 */ +/* func->ReadBuffer = nv04ReadBuffer;*/ +/* func->RenderMode = nv04RenderMode;*/ + func->Scissor = nv04Scissor; + func->ShadeModel = nv04ShadeModel; + func->StencilFuncSeparate = nv04StencilFuncSeparate; + func->StencilMaskSeparate = nv04StencilMaskSeparate; + func->StencilOpSeparate = nv04StencilOpSeparate; +/* func->TexGen = nv04TexGen;*/ +/* func->TexParameter = nv04TexParameter;*/ +/* func->TextureMatrix = nv04TextureMatrix;*/ + + nmesa->hw_func.InitCard = nv04InitCard; + nmesa->hw_func.BindBuffers = nv04BindBuffers; + nmesa->hw_func.WindowMoved = nv04WindowMoved; +} -- cgit v1.2.3 From d1f0a55af42c8a34c2d59ca003e7d7a8263665fb Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Mon, 22 Jan 2007 00:12:05 +0100 Subject: nouveau: fix some bugs in the nv10 swtcl. --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 12b277de45..f916912c7e 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -23,7 +23,7 @@ * DEALINGS IN THE SOFTWARE. */ -/* Software TCL for NV10, NV20, NV30, NV40, G70 */ +/* Software TCL for NV10, NV20, NV30, NV40, NV50 */ #include #include @@ -288,6 +288,20 @@ do { \ nmesa->vertex_attr_count++; \ } while (0) +static void nv10_render_clipped_line(GLcontext *ctx,GLuint ii,GLuint jj) +{ + +} + +static void nv10_render_clipped_poly(GLcontext *ctx,const GLuint *elts,GLuint n) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint *tmp = VB->Elts; + VB->Elts = (GLuint *)elts; + nv10_render_generic_primitive_elts( ctx, 0, n, PRIM_BEGIN|PRIM_END,GL_POLYGON ); + VB->Elts = tmp; +} static void nv10ChooseRenderState(GLcontext *ctx) { @@ -296,8 +310,8 @@ static void nv10ChooseRenderState(GLcontext *ctx) tnl->Driver.Render.PrimTabVerts = nv10_render_tab_verts; tnl->Driver.Render.PrimTabElts = nv10_render_tab_elts; - tnl->Driver.Render.ClippedLine = NULL; - tnl->Driver.Render.ClippedPolygon = NULL; + tnl->Driver.Render.ClippedLine = nv10_render_clipped_line; + tnl->Driver.Render.ClippedPolygon = nv10_render_clipped_poly; } @@ -323,6 +337,7 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa) 0.0, 0.0, 0.0, 1.0 }; + nmesa->vertex_attr_count = 0; RENDERINPUTS_COPY(index, nmesa->render_inputs_bitset); /* -- cgit v1.2.3 From ea441355d304ceff0d7eac4e112ed713ea08a43f Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Sun, 21 Jan 2007 20:30:31 -0500 Subject: nouveau: Fixes for nv30. --- src/mesa/drivers/dri/nouveau/nv30_state.c | 128 ++++++++++++++++++++++-------- 1 file changed, 96 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 4d79bb6127..e788a9235a 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -764,8 +764,66 @@ static void nv30WindowMoved(nouveauContextPtr nmesa) static GLboolean nv30InitCard(nouveauContextPtr nmesa) { - /* Need some love.. */ - return GL_FALSE; + int i; + nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); + + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT1, 3); + OUT_RING(NvDmaFB); + OUT_RING(NvDmaAGP); + OUT_RING(NvDmaFB); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT8, 1); + OUT_RING(NvDmaFB); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT4, 2); + OUT_RING(NvDmaFB); + OUT_RING(NvDmaFB); + BEGIN_RING_SIZE(NvSub3D, 0x1b0, 1); /* SET_OBJECT8B*/ + OUT_RING(NvDmaFB); + + for(i = 0x2c8; i <= 0x2fc; i += 4) + { + BEGIN_RING_SIZE(NvSub3D, i, 1); + OUT_RING(0x0); + } + + BEGIN_RING_SIZE(NvSub3D, 0x0220, 1); + OUT_RING(1); + + BEGIN_RING_SIZE(NvSub3D, 0x03b0, 1); + OUT_RING(0x00100000); + BEGIN_RING_SIZE(NvSub3D, 0x1454, 1); + OUT_RING(0); + BEGIN_RING_SIZE(NvSub3D, 0x1d80, 1); + OUT_RING(3); + BEGIN_RING_SIZE(NvSub3D, 0x1450, 1); + OUT_RING(0x00030004); + + /* NEW */ + BEGIN_RING_SIZE(NvSub3D, 0x1e98, 1); + OUT_RING(0); + BEGIN_RING_SIZE(NvSub3D, 0x17e0, 3); + OUT_RING(0); + OUT_RING(0); + OUT_RING(0x3f800000); + BEGIN_RING_SIZE(NvSub3D, 0x1f80, 16); + OUT_RING(0); OUT_RING(0); OUT_RING(0); OUT_RING(0); + OUT_RING(0); OUT_RING(0); OUT_RING(0); OUT_RING(0); + OUT_RING(0x0000ffff); + OUT_RING(0); OUT_RING(0); OUT_RING(0); OUT_RING(0); + OUT_RING(0); OUT_RING(0); OUT_RING(0); +/* + BEGIN_RING_SIZE(NvSub3D, 0x100, 2); + OUT_RING(0); + OUT_RING(0); +*/ + BEGIN_RING_SIZE(NvSub3D, 0x120, 3); + OUT_RING(0); + OUT_RING(1); + OUT_RING(2); + + BEGIN_RING_SIZE(NvSub3D, 0x1d88, 1); + OUT_RING(0x00001200); + + return GL_TRUE; } static GLboolean nv40InitCard(nouveauContextPtr nmesa) @@ -811,36 +869,41 @@ static GLboolean nv40InitCard(nouveauContextPtr nmesa) } static GLboolean nv30BindBuffers(nouveauContextPtr nmesa, int num_color, - nouveau_renderbuffer **color, - nouveau_renderbuffer *depth) -{ - GLuint x, y, w, h; - - w = color[0]->mesa.Width; - h = color[0]->mesa.Height; - x = nmesa->drawX; - y = nmesa->drawY; - - if (num_color != 1) - return GL_FALSE; - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_DIM0, 5); - OUT_RING (((w+x)<<16)|x); - OUT_RING (((h+y)<<16)|y); - if (color[0]->mesa._ActualFormat == GL_RGBA8) - OUT_RING (0x148); - else - OUT_RING (0x143); - OUT_RING (color[0]->pitch); - OUT_RING (color[0]->offset); - - if (depth) { - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_OFFSET, 1); - OUT_RING (depth->offset); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH, 1); - OUT_RING (depth->pitch); - } - - return GL_TRUE; + nouveau_renderbuffer **color, + nouveau_renderbuffer *depth) +{ + GLuint x, y, w, h; + + w = color[0]->mesa.Width; + h = color[0]->mesa.Height; + x = nmesa->drawX; + y = nmesa->drawY; + + if (num_color != 1) + return GL_FALSE; + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_DIM0, 5); + OUT_RING (((w+x)<<16)|x); + OUT_RING (((h+y)<<16)|y); + if (color[0]->mesa._ActualFormat == GL_RGBA8) + OUT_RING (0x148); + else + OUT_RING (0x143); + if (nmesa->screen->card->type >= NV_40) + OUT_RING (color[0]->pitch); + else + OUT_RING (color[0]->pitch | (depth ? (depth->pitch << 16): 0)); + OUT_RING (color[0]->offset); + + if (depth) { + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_OFFSET, 1); + OUT_RING (depth->offset); + if (nmesa->screen->card->type >= NV_40) { + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH, 1); + OUT_RING (depth->pitch >> 2); + } + } + + return GL_TRUE; } void nv30InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) @@ -862,6 +925,7 @@ void nv30InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) func->FrontFace = nv30FrontFace; func->DepthFunc = nv30DepthFunc; func->DepthMask = nv30DepthMask; + func->DepthRange = nv30DepthRange; func->Enable = nv30Enable; func->Fogfv = nv30Fogfv; func->Hint = nv30Hint; -- cgit v1.2.3 From c3ac2709967299481928dee175a124bf8a72fecd Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 21 Jan 2007 16:45:40 +1100 Subject: nouveau: start converting shaders into a tree format again.. No branching stuff implemented yet. Works enough for gears, probably other stuff broken. --- src/mesa/drivers/dri/nouveau/nouveau_shader.c | 6 +- src/mesa/drivers/dri/nouveau/nouveau_shader.h | 60 +++- src/mesa/drivers/dri/nouveau/nouveau_shader_0.c | 375 +++++++++++++++--------- src/mesa/drivers/dri/nouveau/nouveau_shader_2.c | 45 ++- 4 files changed, 315 insertions(+), 171 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.c b/src/mesa/drivers/dri/nouveau/nouveau_shader.c index e4db115362..f911347d62 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.c @@ -563,12 +563,12 @@ nvsDumpInstruction(nvsInstruction * inst, int slot, int lvl) } void -nvsDumpFragmentList(nvsFragmentList *f, int lvl) +nvsDumpFragmentList(nvsFragmentHeader *f, int lvl) { while (f) { - switch (f->fragment->type) { + switch (f->type) { case NVS_INSTRUCTION: - nvsDumpInstruction((nvsInstruction*)f->fragment, 0, lvl); + nvsDumpInstruction((nvsInstruction*)f, 0, lvl); break; default: fprintf(stderr, "%s: Only NVS_INSTRUCTION fragments can be in" diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h index 1a971e56bf..a3ab027142 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -12,19 +12,18 @@ typedef struct _nvsFunc nvsFunc; #define NVS_MAX_ADDRESS 2 #define NVS_MAX_INSNS 4096 -typedef struct { +typedef struct _nvs_fragment_header { + struct _nvs_fragment_header *parent; + struct _nvs_fragment_header *prev; + struct _nvs_fragment_header *next; enum { NVS_INSTRUCTION, + NVS_BRANCH, + NVS_LOOP, + NVS_SUBROUTINE } type; - int position; } nvsFragmentHeader; -typedef struct _nvs_fragment_list { - struct _nvs_fragment_list *prev; - struct _nvs_fragment_list *next; - nvsFragmentHeader *fragment; -} nvsFragmentList; - typedef struct _nouveauShader { union { struct gl_vertex_program vp; @@ -59,8 +58,7 @@ typedef struct _nouveauShader { /* Pass-private data */ void *pass_rec; - nvsFragmentList *list_head; - nvsFragmentList *list_tail; + nvsFragmentHeader *program_tree; } nouveauShader, *nvsPtr; typedef enum { @@ -186,7 +184,8 @@ typedef enum { NVS_TEX_TARGET_UNKNOWN = 0 } nvsTexTarget; -typedef struct { +/* Arith/TEX instructions */ +typedef struct nvs_instruction { nvsFragmentHeader header; nvsOpcode op; @@ -207,6 +206,43 @@ typedef struct { int cond_update; } nvsInstruction; +/* BRA, CAL, IF */ +typedef struct nvs_branch { + nvsFragmentHeader header; + + nvsOpcode op; + + nvsCond cond; + nvsSwzComp cond_swizzle[4]; + int cond_test; + + nvsFragmentHeader *target_head; + nvsFragmentHeader *target_tail; + nvsFragmentHeader *else_head; + nvsFragmentHeader *else_tail; +} nvsBranch; + +/* LOOP+ENDLOOP */ +typedef struct { + nvsFragmentHeader header; + + int count; + int initial; + int increment; + + nvsFragmentHeader *insn_head; + nvsFragmentHeader *insn_tail; +} nvsLoop; + +/* label+following instructions */ +typedef struct nvs_subroutine { + nvsFragmentHeader header; + + char * label; + nvsFragmentHeader *insn_head; + nvsFragmentHeader *insn_tail; +} nvsSubroutine; + #define SMASK_X (1<<0) #define SMASK_Y (1<<1) #define SMASK_Z (1<<2) @@ -353,7 +389,7 @@ nvsSwizzle(nvsRegister reg, nvsSwzComp x, nvsSwzComp y, extern GLboolean nvsUpdateShader(GLcontext *ctx, nouveauShader *nvs); extern void nvsDisasmHWShader(nvsPtr); -extern void nvsDumpFragmentList(nvsFragmentList *f, int lvl); +extern void nvsDumpFragmentList(nvsFragmentHeader *f, int lvl); extern nouveauShader *nvsBuildTextShader(GLcontext *ctx, GLenum target, const char *text); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c index 34475cad03..503eae36b7 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -40,6 +40,7 @@ #include "nouveau_context.h" #include "nouveau_shader.h" +#include "nouveau_msg.h" static nvsFixedReg _tx_mesa_vp_dst_reg[VERT_RESULT_MAX] = { NVS_FR_POSITION, NVS_FR_COL0, NVS_FR_COL1, NVS_FR_FOGCOORD, @@ -134,21 +135,63 @@ struct pass0_rec { #define W NVS_SWZ_W static void -pass0_append_fragment(nouveauShader *nvs, nvsFragmentHeader *fragment) +pass0_append_fragment(nvsFragmentHeader *parent, + nvsFragmentHeader *fragment, + int pos) { - nvsFragmentList *list = calloc(1, sizeof(nvsFragmentList)); - if (!list) - return; - - list->fragment = fragment; - list->prev = nvs->list_tail; - if ( nvs->list_tail) - nvs->list_tail->next = list; - if (!nvs->list_head) - nvs->list_head = list; - nvs->list_tail = list; - - nvs->inst_count++; + nvsFragmentHeader **head, **tail; + assert(parent && fragment); + + switch (parent->type) { + case NVS_BRANCH: + if (pos == 0) { + head = &((nvsBranch *)parent)->target_head; + tail = &((nvsBranch *)parent)->target_tail; + } else { + head = &((nvsBranch *)parent)->else_head; + tail = &((nvsBranch *)parent)->else_tail; + } + break; + case NVS_LOOP: + head = &((nvsLoop *)parent)->insn_head; + tail = &((nvsLoop *)parent)->insn_tail; + break; + case NVS_SUBROUTINE: + head = &((nvsSubroutine *)parent)->insn_head; + tail = &((nvsSubroutine *)parent)->insn_tail; + break; + default: + assert(0); + break; + } + + fragment->parent = parent; + fragment->prev = *tail; + fragment->next = NULL; + if (!(*head)) + *head = fragment; + else + (*tail)->next = fragment; + *tail = fragment; + +} + +static nvsSubroutine * +pass0_create_subroutine(nouveauShader *nvs, const char *label) +{ + nvsSubroutine *sub; + + sub = CALLOC_STRUCT(nvs_subroutine); + if (sub) { + sub->header.type = NVS_SUBROUTINE; + sub->label = strdup(label); + if (!nvs->program_tree) + nvs->program_tree = &sub->header; + else + pass0_append_fragment(nvs->program_tree, &sub->header, 0); + } + + return sub; } static void @@ -312,41 +355,40 @@ pass0_make_src_reg(nvsPtr nvs, nvsRegister *reg, struct prog_src_register *src) } static nvsInstruction * -pass0_emit(nouveauShader *nvs, nvsOpcode op, nvsRegister dst, - unsigned int mask, int saturate, +pass0_emit(nouveauShader *nvs, nvsFragmentHeader *parent, int fpos, + nvsOpcode op, nvsRegister dst, + unsigned int mask, int saturate, nvsRegister src0, nvsRegister src1, nvsRegister src2) { - struct pass0_rec *rec = nvs->pass_rec; - nvsInstruction *sif = NULL; - - /* Seems mesa doesn't explicitly 0 this.. */ - if (nvs->mesa.vp.Base.Target == GL_VERTEX_PROGRAM_ARB) - saturate = 0; - - sif = calloc(1, sizeof(nvsInstruction)); - if (sif) { - sif->header.type = NVS_INSTRUCTION; - sif->header.position = rec->nvs_ipos++; - sif->op = op; - sif->saturate = saturate; - sif->dest = dst; - sif->mask = mask; - sif->src[0] = src0; - sif->src[1] = src1; - sif->src[2] = src2; - sif->cond = COND_TR; - sif->cond_reg = 0; - sif->cond_test = 0; - sif->cond_update = 0; - pass0_make_swizzle(sif->cond_swizzle, SWIZZLE_NOOP); - pass0_append_fragment(nvs, (nvsFragmentHeader *)sif); - } - - return sif; + nvsInstruction *sif; + + sif = CALLOC_STRUCT(nvs_instruction); + if (!sif) + return NULL; + + /* Seems mesa doesn't explicitly 0 this.. */ + if (nvs->mesa.vp.Base.Target == GL_VERTEX_PROGRAM_ARB) + saturate = 0; + + sif->op = op; + sif->saturate = saturate; + sif->dest = dst; + sif->mask = mask; + sif->src[0] = src0; + sif->src[1] = src1; + sif->src[2] = src2; + sif->cond = COND_TR; + sif->cond_reg = 0; + sif->cond_test = 0; + sif->cond_update= 0; + pass0_make_swizzle(sif->cond_swizzle, SWIZZLE_NOOP); + pass0_append_fragment(parent, &sif->header, fpos); + + return sif; } static void -pass0_fixup_swizzle(nvsPtr nvs, +pass0_fixup_swizzle(nvsPtr nvs, nvsFragmentHeader *parent, int fpos, struct prog_src_register *src, unsigned int sm1, unsigned int sm2) @@ -376,7 +418,7 @@ pass0_fixup_swizzle(nvsPtr nvs, */ pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); pass0_make_src_reg(nvs, &sr, src); - pass0_emit(nvs, NVS_OP_MOV, dr, SMASK_ALL, 0, sr, nvr_unused, nvr_unused); + pass0_emit(nvs, parent, fpos, NVS_OP_MOV, dr, SMASK_ALL, 0, sr, nvr_unused, nvr_unused); pass0_make_reg(nvs, &sr, NVS_FILE_TEMP, dr.index); } else { if (fixup_1) @@ -391,10 +433,10 @@ pass0_fixup_swizzle(nvsPtr nvs, /* Any combination with SWIZZLE_ONE */ pass0_make_reg(nvs, &sm2const, NVS_FILE_CONST, rec->swzconst_id); pass0_make_swizzle(sm2const.swizzle, sm2); - pass0_emit(nvs, NVS_OP_MAD, dr, SMASK_ALL, 0, sr, sm1const, sm2const); + pass0_emit(nvs, parent, fpos, NVS_OP_MAD, dr, SMASK_ALL, 0, sr, sm1const, sm2const); } else { /* SWIZZLE_ZERO || arbitrary negate */ - pass0_emit(nvs, NVS_OP_MUL, dr, SMASK_ALL, 0, sr, sm1const, nvr_unused); + pass0_emit(nvs, parent, fpos, NVS_OP_MUL, dr, SMASK_ALL, 0, sr, sm1const, nvr_unused); } src->File = PROGRAM_TEMPORARY; @@ -404,7 +446,8 @@ pass0_fixup_swizzle(nvsPtr nvs, #define SET_SWZ(fs, cp, c) fs = (fs & ~(0x7<<(cp*3))) | (c<<(cp*3)) static void -pass0_check_sources(nvsPtr nvs, struct prog_instruction *inst) +pass0_check_sources(nvsPtr nvs, nvsFragmentHeader *parent, int fpos, + struct prog_instruction *inst) { unsigned int insrc = -1, constsrc = -1; int i; @@ -444,7 +487,7 @@ pass0_check_sources(nvsPtr nvs, struct prog_instruction *inst) */ if ((sm_1 != MAKE_SWIZZLE4(0,0,0,0) && sm_1 != MAKE_SWIZZLE4(2,2,2,2)) || sm_2 != MAKE_SWIZZLE4(1,1,1,1)) { - pass0_fixup_swizzle(nvs, src, sm_1, sm_2); + pass0_fixup_swizzle(nvs, parent, fpos, src, sm_1, sm_2); /* The source is definitely in a temp now, so don't bother checking * for multiple ATTRIB/CONST regs. */ @@ -473,7 +516,7 @@ pass0_check_sources(nvsPtr nvs, struct prog_instruction *inst) if (do_mov) { pass0_make_src_reg(nvs, &sr, src); pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); - pass0_emit(nvs, NVS_OP_MOV, dr, SMASK_ALL, 0, + pass0_emit(nvs, parent, fpos, NVS_OP_MOV, dr, SMASK_ALL, 0, sr, nvr_unused, nvr_unused); src->File = PROGRAM_TEMPORARY; @@ -484,7 +527,9 @@ pass0_check_sources(nvsPtr nvs, struct prog_instruction *inst) } static GLboolean -pass0_emulate_instruction(nouveauShader *nvs, struct prog_instruction *inst) +pass0_emulate_instruction(nouveauShader *nvs, + nvsFragmentHeader *parent, int fpos, + struct prog_instruction *inst) { nvsFunc *shader = nvs->func; nvsRegister src[3], dest, temp; @@ -504,10 +549,10 @@ pass0_emulate_instruction(nouveauShader *nvs, struct prog_instruction *inst) switch (inst->Opcode) { case OPCODE_ABS: if (shader->caps & SCAP_SRC_ABS) - pass0_emit(nvs, NVS_OP_MOV, dest, mask, sat, + pass0_emit(nvs, parent, fpos, NVS_OP_MOV, dest, mask, sat, nvsAbs(src[0]), nvr_unused, nvr_unused); else - pass0_emit(nvs, NVS_OP_MAX, dest, mask, sat, + pass0_emit(nvs, parent, fpos, NVS_OP_MAX, dest, mask, sat, src[0], nvsNegate(src[0]), nvr_unused); break; case OPCODE_KIL: @@ -516,12 +561,12 @@ pass0_emulate_instruction(nouveauShader *nvs, struct prog_instruction *inst) */ /* MOVC0 temp, src */ pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - nvsinst = pass0_emit(nvs, NVS_OP_MOV, temp, SMASK_ALL, 0, + nvsinst = pass0_emit(nvs, parent, fpos, NVS_OP_MOV, temp, SMASK_ALL, 0, src[0], nvr_unused, nvr_unused); nvsinst->cond_update = 1; nvsinst->cond_reg = 0; /* KIL_NV (LT0.xyzw) temp */ - nvsinst = pass0_emit(nvs, NVS_OP_KIL, nvr_unused, 0, 0, + nvsinst = pass0_emit(nvs, parent, fpos, NVS_OP_KIL, nvr_unused, 0, 0, nvr_unused, nvr_unused, nvr_unused); nvsinst->cond = COND_LT; nvsinst->cond_reg = 0; @@ -532,9 +577,9 @@ pass0_emulate_instruction(nouveauShader *nvs, struct prog_instruction *inst) break; case OPCODE_LRP: pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - pass0_emit(nvs, NVS_OP_MAD, temp, mask, 0, + pass0_emit(nvs, parent, fpos, NVS_OP_MAD, temp, mask, 0, nvsNegate(src[0]), src[2], src[2]); - pass0_emit(nvs, NVS_OP_MAD, dest, mask, sat, + pass0_emit(nvs, parent, fpos, NVS_OP_MAD, dest, mask, sat, src[0], src[1], temp); break; case OPCODE_POW: @@ -542,17 +587,17 @@ pass0_emulate_instruction(nouveauShader *nvs, struct prog_instruction *inst) shader->SupportsOpcode(shader, NVS_OP_EX2)) { pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); /* LG2 temp.x, src0.c */ - pass0_emit(nvs, NVS_OP_LG2, temp, SMASK_X, 0, + pass0_emit(nvs, parent, fpos, NVS_OP_LG2, temp, SMASK_X, 0, nvsSwizzle(src[0], X, X, X, X), nvr_unused, nvr_unused); /* MUL temp.x, temp.x, src1.c */ - pass0_emit(nvs, NVS_OP_MUL, temp, SMASK_X, 0, + pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_X, 0, nvsSwizzle(temp, X, X, X, X), nvsSwizzle(src[1], X, X, X, X), nvr_unused); /* EX2 dest, temp.x */ - pass0_emit(nvs, NVS_OP_EX2, dest, mask, sat, + pass0_emit(nvs, parent, fpos, NVS_OP_EX2, dest, mask, sat, nvsSwizzle(temp, X, X, X, X), nvr_unused, nvr_unused); @@ -571,42 +616,42 @@ pass0_emulate_instruction(nouveauShader *nvs, struct prog_instruction *inst) COPY_4V(nvs->params[rec->const_half.index].val, const_half); } pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - pass0_emit(nvs, NVS_OP_LG2, temp, SMASK_X, 0, + pass0_emit(nvs, parent, fpos, NVS_OP_LG2, temp, SMASK_X, 0, nvsAbs(nvsSwizzle(src[0], X, X, X, X)), nvr_unused, nvr_unused); - pass0_emit(nvs, NVS_OP_MUL, temp, SMASK_X, 0, + pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_X, 0, nvsSwizzle(temp, X, X, X, X), nvsNegate(rec->const_half), nvr_unused); - pass0_emit(nvs, NVS_OP_EX2, dest, mask, sat, + pass0_emit(nvs, parent, fpos, NVS_OP_EX2, dest, mask, sat, nvsSwizzle(temp, X, X, X, X), nvr_unused, nvr_unused); break; case OPCODE_SCS: if (mask & SMASK_X) - pass0_emit(nvs, NVS_OP_COS, dest, SMASK_X, sat, + pass0_emit(nvs, parent, fpos, NVS_OP_COS, dest, SMASK_X, sat, nvsSwizzle(src[0], X, X, X, X), nvr_unused, nvr_unused); if (mask & SMASK_Y) - pass0_emit(nvs, NVS_OP_SIN, dest, SMASK_Y, sat, + pass0_emit(nvs, parent, fpos, NVS_OP_SIN, dest, SMASK_Y, sat, nvsSwizzle(src[0], X, X, X, X), nvr_unused, nvr_unused); break; case OPCODE_SUB: - pass0_emit(nvs, NVS_OP_ADD, dest, mask, sat, + pass0_emit(nvs, parent, fpos, NVS_OP_ADD, dest, mask, sat, src[0], nvsNegate(src[1]), nvr_unused); break; case OPCODE_XPD: pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - pass0_emit(nvs, NVS_OP_MUL, temp, SMASK_ALL, 0, + pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_ALL, 0, nvsSwizzle(src[0], Z, X, Y, Y), nvsSwizzle(src[1], Y, Z, X, X), nvr_unused); - pass0_emit(nvs, NVS_OP_MAD, dest, (mask & ~SMASK_W), sat, + pass0_emit(nvs, parent, fpos, NVS_OP_MAD, dest, (mask & ~SMASK_W), sat, nvsSwizzle(src[0], Y, Z, X, X), nvsSwizzle(src[1], Z, X, Y, Y), nvsNegate(temp)); @@ -621,90 +666,132 @@ pass0_emulate_instruction(nouveauShader *nvs, struct prog_instruction *inst) } static GLboolean -pass0_translate_instructions(nouveauShader *nvs) +pass0_translate_arith(nouveauShader *nvs, struct gl_program *prog, + int ipos, int fpos, + nvsFragmentHeader *parent) { - struct gl_program *prog = (struct gl_program *)&nvs->mesa.vp; - nvsFunc *shader = nvs->func; - int ipos; - - for (ipos=0; iposNumInstructions; ipos++) { - struct prog_instruction *inst = &prog->Instructions[ipos]; - - if (inst->Opcode == OPCODE_END) - break; - - /* Deal with multiple ATTRIB/PARAM in a single instruction */ - pass0_check_sources(nvs, inst); - - /* Now it's safe to do the prog_instruction->nvsInstruction conversion */ - if (shader->SupportsOpcode(shader, pass0_make_opcode(inst->Opcode))) { - nvsInstruction *nvsinst; - nvsRegister src[3], dest; - int i; - - for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++) - pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]); - pass0_make_dst_reg(nvs, &dest, &inst->DstReg); - - nvsinst = pass0_emit(nvs, - pass0_make_opcode(inst->Opcode), - dest, - pass0_make_mask(inst->DstReg.WriteMask), - (inst->SaturateMode != SATURATE_OFF), - src[0], src[1], src[2]); - nvsinst->tex_unit = inst->TexSrcUnit; - nvsinst->tex_target = pass0_make_tex_target(inst->TexSrcTarget); - /* TODO when NV_fp/vp is implemented */ - nvsinst->cond = COND_TR; - } else { - if (!pass0_emulate_instruction(nvs, inst)) - return GL_FALSE; - } - } + struct prog_instruction *inst = &prog->Instructions[ipos]; + nvsFunc *shader = nvs->func; + nvsInstruction *nvsinst; + GLboolean ret; + + /* Deal with multiple ATTRIB/PARAM in a single instruction */ + pass0_check_sources(nvs, parent, fpos, inst); + + /* Now it's safe to do the prog_instruction->nvsInstruction + * conversion + */ + if (shader->SupportsOpcode(shader, + pass0_make_opcode(inst->Opcode))) { + nvsRegister src[3], dest; + int i; + + for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++) + pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]); + pass0_make_dst_reg(nvs, &dest, &inst->DstReg); + + nvsinst = pass0_emit(nvs, parent, fpos, + pass0_make_opcode(inst->Opcode), + dest, + pass0_make_mask(inst->DstReg.WriteMask), + (inst->SaturateMode != SATURATE_OFF), + src[0], src[1], src[2]); + nvsinst->tex_unit = inst->TexSrcUnit; + nvsinst->tex_target = pass0_make_tex_target(inst->TexSrcTarget); + /* TODO when NV_fp/vp is implemented */ + nvsinst->cond = COND_TR; + + ret = GL_TRUE; + } else + ret = pass0_emulate_instruction(nvs, parent, fpos, inst); + + return ret; +} - return GL_TRUE; +static GLboolean +pass0_translate_instructions(nouveauShader *nvs, int ipos, int fpos, + nvsFragmentHeader *parent) +{ + struct gl_program *prog = (struct gl_program *)&nvs->mesa.vp; + + while (1) { + struct prog_instruction *inst = &prog->Instructions[ipos]; + + switch (inst->Opcode) { + case OPCODE_END: + return GL_TRUE; + case OPCODE_BRA: + case OPCODE_CAL: + //case OPCDOE_RET: + //case OPCODE_LOOP: + //case OPCODE_ENDLOOP: + //case OPCODE_IF: + //case OPCODE_ELSE: + //case OPCODE_ENDIF: + WARN_ONCE("branch ops unimplemented\n"); + return GL_FALSE; + break; + default: + if (!pass0_translate_arith(nvs, prog, + ipos, fpos, parent)) + return GL_FALSE; + break; + } + + ipos++; + } + + return GL_TRUE; } GLboolean nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - struct gl_program *prog = (struct gl_program*)nvs; - struct gl_vertex_program *vp = (struct gl_vertex_program *)prog; - struct gl_fragment_program *fp = (struct gl_fragment_program *)prog; - struct pass0_rec *rec; - int ret; - - switch (prog->Target) { - case GL_VERTEX_PROGRAM_ARB: - nvs->func = &nmesa->VPfunc; - if (vp->IsPositionInvariant) - _mesa_insert_mvp_code(ctx, vp); + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + struct gl_program *prog = (struct gl_program*)nvs; + struct gl_vertex_program *vp = (struct gl_vertex_program *)prog; + struct gl_fragment_program *fp = (struct gl_fragment_program *)prog; + struct pass0_rec *rec; + int ret = GL_FALSE; + + switch (prog->Target) { + case GL_VERTEX_PROGRAM_ARB: + nvs->func = &nmesa->VPfunc; + + if (vp->IsPositionInvariant) + _mesa_insert_mvp_code(ctx, vp); #if 0 - if (IS_FIXEDFUNCTION_PROG && CLIP_PLANES_USED) - pass0_insert_ff_clip_planes(); + if (IS_FIXEDFUNCTION_PROG && CLIP_PLANES_USED) + pass0_insert_ff_clip_planes(); #endif - break; - case GL_FRAGMENT_PROGRAM_ARB: - nvs->func = &nmesa->FPfunc; - if (fp->FogOption != GL_NONE) - _mesa_append_fog_code(ctx, fp); - break; - default: - fprintf(stderr, "Unknown program type %d", prog->Target); - return GL_FALSE; - } - - rec = calloc(1, sizeof(struct pass0_rec)); - rec->next_temp = prog->NumTemporaries; - nvs->pass_rec = rec; - - ret = pass0_translate_instructions(nvs); - if (!ret) { - /* DESTROY list */ - } - - free(nvs->pass_rec); - return ret; + break; + case GL_FRAGMENT_PROGRAM_ARB: + nvs->func = &nmesa->FPfunc; + + if (fp->FogOption != GL_NONE) + _mesa_append_fog_code(ctx, fp); + break; + default: + fprintf(stderr, "Unknown program type %d", prog->Target); + return GL_FALSE; + } + + rec = CALLOC_STRUCT(pass0_rec); + if (rec) { + rec->next_temp = prog->NumTemporaries; + nvs->pass_rec = rec; + + nvs->program_tree = (nvsFragmentHeader*) + pass0_create_subroutine(nvs, "program body"); + if (nvs->program_tree) { + ret = pass0_translate_instructions(nvs, + 0, 0, + nvs->program_tree); + /*XXX: if (!ret) DESTROY TREE!!! */ + } + FREE(rec); + } + + return ret; } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c index 0476b05f58..b9b87ccf91 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c @@ -38,6 +38,7 @@ #include "nouveau_context.h" #include "nouveau_shader.h" +#include "nouveau_msg.h" struct pass2_rec { /* Map nvsRegister temp ID onto hw temp ID */ @@ -166,11 +167,37 @@ pass2_assemble_instruction(nvsPtr nvs, nvsInstruction *inst, int last) return 1; } +static GLboolean +pass2_translate(nvsPtr nvs, nvsFragmentHeader *f) +{ + nvsFunc *shader = nvs->func; + GLboolean last; + + while (f) { + last = (f == ((nvsSubroutine*)nvs->program_tree)->insn_tail); + + switch (f->type) { + case NVS_INSTRUCTION: + if (!pass2_assemble_instruction(nvs, + (nvsInstruction *)f, + last)) + return GL_FALSE; + break; + default: + WARN_ONCE("Unimplemented fragment type\n"); + return GL_FALSE; + } + + f = f->next; + } + + return GL_TRUE; +} + /* Translate program into hardware format */ GLboolean nouveau_shader_pass2(nvsPtr nvs) { - nvsFragmentList *list = nvs->list_head; struct pass2_rec *rec; int i; @@ -182,21 +209,15 @@ nouveau_shader_pass2(nvsPtr nvs) /* Start off with allocating 4 uint32_t's for each inst, will be grown * if necessary.. */ - nvs->program_alloc_size = nvs->inst_count * 4; + nvs->program_alloc_size = nvs->mesa.vp.Base.NumInstructions * 4; nvs->program = calloc(nvs->program_alloc_size, sizeof(uint32_t)); nvs->program_size = 0; nvs->program_current = 0; - while (list) { - assert(list->fragment->type == NVS_INSTRUCTION); - - if (!pass2_assemble_instruction(nvs, (nvsInstruction *)list->fragment, list->next ? 0 : 1)) { - free(nvs->program); - nvs->program = NULL; - return GL_FALSE; - } - - list = list->next; + if (!pass2_translate(nvs, ((nvsSubroutine*)nvs->program_tree)->insn_head)) { + free(nvs->program); + nvs->program = NULL; + return GL_FALSE; } /* Shrink allocated memory to only what we need */ -- cgit v1.2.3 From 50227f6fd23f3a4737dada1a98d26f6d0141af47 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 21 Jan 2007 17:16:39 +1100 Subject: nouveau: reindent shader pass0/pass2 if this gets rejected by the commit list, just ignore it.. nothing interesting to see here :) --- src/mesa/drivers/dri/nouveau/nouveau_shader_0.c | 779 ++++++++++++------------ src/mesa/drivers/dri/nouveau/nouveau_shader_2.c | 311 +++++----- 2 files changed, 566 insertions(+), 524 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c index 503eae36b7..d6ea42573a 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -188,7 +188,8 @@ pass0_create_subroutine(nouveauShader *nvs, const char *label) if (!nvs->program_tree) nvs->program_tree = &sub->header; else - pass0_append_fragment(nvs->program_tree, &sub->header, 0); + pass0_append_fragment(nvs->program_tree, + &sub->header, 0); } return sub; @@ -196,162 +197,168 @@ pass0_create_subroutine(nouveauShader *nvs, const char *label) static void pass0_make_reg(nouveauShader *nvs, nvsRegister *reg, - nvsRegFile file, unsigned int index) + nvsRegFile file, unsigned int index) { - struct pass0_rec *rec = nvs->pass_rec; - - /* defaults */ - *reg = nvr_unused; - /* -1 == quick-and-dirty temp alloc */ - if (file == NVS_FILE_TEMP && index == -1) { - index = rec->next_temp++; - assert(index < NVS_MAX_TEMPS); - } - reg->file = file; - reg->index = index; + struct pass0_rec *rec = nvs->pass_rec; + + /* defaults */ + *reg = nvr_unused; + /* -1 == quick-and-dirty temp alloc */ + if (file == NVS_FILE_TEMP && index == -1) { + index = rec->next_temp++; + assert(index < NVS_MAX_TEMPS); + } + reg->file = file; + reg->index = index; } static void pass0_make_swizzle(nvsSwzComp *swz, unsigned int mesa) { - int i; + int i; - for (i=0;i<4;i++) - swz[i] = _tx_mesa_swizzle[GET_SWZ(mesa, i)]; + for (i=0;i<4;i++) + swz[i] = _tx_mesa_swizzle[GET_SWZ(mesa, i)]; } static nvsOpcode pass0_make_opcode(enum prog_opcode op) { - if (op > MAX_OPCODE) - return NVS_OP_UNKNOWN; - return _tx_mesa_opcode[op]; + if (op > MAX_OPCODE) + return NVS_OP_UNKNOWN; + return _tx_mesa_opcode[op]; } static nvsCond pass0_make_condmask(GLuint mesa) { - if (mesa > COND_FL) - return NVS_COND_UNKNOWN; - return _tx_mesa_condmask[mesa]; + if (mesa > COND_FL) + return NVS_COND_UNKNOWN; + return _tx_mesa_condmask[mesa]; } static unsigned int pass0_make_mask(GLuint mesa_mask) { - unsigned int mask = 0; + unsigned int mask = 0; - if (mesa_mask & WRITEMASK_X) mask |= SMASK_X; - if (mesa_mask & WRITEMASK_Y) mask |= SMASK_Y; - if (mesa_mask & WRITEMASK_Z) mask |= SMASK_Z; - if (mesa_mask & WRITEMASK_W) mask |= SMASK_W; + if (mesa_mask & WRITEMASK_X) mask |= SMASK_X; + if (mesa_mask & WRITEMASK_Y) mask |= SMASK_Y; + if (mesa_mask & WRITEMASK_Z) mask |= SMASK_Z; + if (mesa_mask & WRITEMASK_W) mask |= SMASK_W; - return mask; + return mask; } static nvsTexTarget pass0_make_tex_target(GLuint mesa) { - switch (mesa) { - case TEXTURE_1D_INDEX: return NVS_TEX_TARGET_1D; - case TEXTURE_2D_INDEX: return NVS_TEX_TARGET_2D; - case TEXTURE_3D_INDEX: return NVS_TEX_TARGET_3D; - case TEXTURE_CUBE_INDEX: return NVS_TEX_TARGET_CUBE; - case TEXTURE_RECT_INDEX: return NVS_TEX_TARGET_RECT; - default: - return NVS_TEX_TARGET_UNKNOWN; - } + switch (mesa) { + case TEXTURE_1D_INDEX: return NVS_TEX_TARGET_1D; + case TEXTURE_2D_INDEX: return NVS_TEX_TARGET_2D; + case TEXTURE_3D_INDEX: return NVS_TEX_TARGET_3D; + case TEXTURE_CUBE_INDEX: return NVS_TEX_TARGET_CUBE; + case TEXTURE_RECT_INDEX: return NVS_TEX_TARGET_RECT; + default: + return NVS_TEX_TARGET_UNKNOWN; + } } static void pass0_make_dst_reg(nvsPtr nvs, nvsRegister *reg, struct prog_dst_register *dst) { - struct gl_program *mesa = (struct gl_program*)&nvs->mesa.vp; - nvsFixedReg sfr; - - switch (dst->File) { - case PROGRAM_OUTPUT: - if (mesa->Target == GL_VERTEX_PROGRAM_ARB) { - sfr = (dst->Index < VERT_RESULT_MAX) ? - _tx_mesa_vp_dst_reg[dst->Index] : NVS_FR_UNKNOWN; - } else { - sfr = (dst->Index < FRAG_RESULT_MAX) ? - _tx_mesa_fp_dst_reg[dst->Index] : NVS_FR_UNKNOWN; - } - pass0_make_reg(nvs, reg, NVS_FILE_RESULT, sfr); - break; - case PROGRAM_TEMPORARY: - pass0_make_reg(nvs, reg, NVS_FILE_TEMP, dst->Index); - break; - case PROGRAM_ADDRESS: - pass0_make_reg(nvs, reg, NVS_FILE_ADDRESS, dst->Index); - break; - default: - fprintf(stderr, "Unknown dest file %d\n", dst->File); - assert(0); - } + struct gl_program *mesa = (struct gl_program*)&nvs->mesa.vp; + nvsFixedReg sfr; + + switch (dst->File) { + case PROGRAM_OUTPUT: + if (mesa->Target == GL_VERTEX_PROGRAM_ARB) { + sfr = (dst->Index < VERT_RESULT_MAX) ? + _tx_mesa_vp_dst_reg[dst->Index] : + NVS_FR_UNKNOWN; + } else { + sfr = (dst->Index < FRAG_RESULT_MAX) ? + _tx_mesa_fp_dst_reg[dst->Index] : + NVS_FR_UNKNOWN; + } + pass0_make_reg(nvs, reg, NVS_FILE_RESULT, sfr); + break; + case PROGRAM_TEMPORARY: + pass0_make_reg(nvs, reg, NVS_FILE_TEMP, dst->Index); + break; + case PROGRAM_ADDRESS: + pass0_make_reg(nvs, reg, NVS_FILE_ADDRESS, dst->Index); + break; + default: + fprintf(stderr, "Unknown dest file %d\n", dst->File); + assert(0); + } } static void pass0_make_src_reg(nvsPtr nvs, nvsRegister *reg, struct prog_src_register *src) { - struct gl_program *mesa = (struct gl_program *)&nvs->mesa.vp.Base; - struct gl_program_parameter_list *p = mesa->Parameters; - - *reg = nvr_unused; - - switch (src->File) { - case PROGRAM_INPUT: - reg->file = NVS_FILE_ATTRIB; - if (mesa->Target == GL_VERTEX_PROGRAM_ARB) { - reg->index = (src->Index < VERT_ATTRIB_MAX) ? - _tx_mesa_vp_src_reg[src->Index] : NVS_FR_UNKNOWN; - } else { - reg->index = (src->Index < FRAG_ATTRIB_MAX) ? - _tx_mesa_fp_src_reg[src->Index] : NVS_FR_UNKNOWN; - } - break; - /* All const types seem to get shoved into here, not really sure why */ - case PROGRAM_STATE_VAR: - switch (p->Parameters[src->Index].Type) { - case PROGRAM_NAMED_PARAM: - case PROGRAM_CONSTANT: - nvs->params[src->Index].source_val = NULL; - COPY_4V(nvs->params[src->Index].val, p->ParameterValues[src->Index]); - break; - case PROGRAM_STATE_VAR: - nvs->params[src->Index].source_val = p->ParameterValues[src->Index]; - break; - default: - fprintf(stderr, "Unknown parameter type %d\n", - p->Parameters[src->Index].Type); - assert(0); - break; - } - - if (src->RelAddr) { - reg->indexed = 1; - reg->addr_reg = 0; - reg->addr_comp = NVS_SWZ_X; - } else - reg->indexed = 0; - reg->file = NVS_FILE_CONST; - reg->index = src->Index; - break; - case PROGRAM_TEMPORARY: - reg->file = NVS_FILE_TEMP; - reg->index = src->Index; - break; - default: - fprintf(stderr, "Unknown source type %d\n", src->File); - assert(0); - } - - /* per-component negate handled elsewhere */ - reg->negate = src->NegateBase != 0; - reg->abs = src->Abs; - pass0_make_swizzle(reg->swizzle, src->Swizzle); + struct gl_program *mesa = (struct gl_program *)&nvs->mesa.vp.Base; + struct gl_program_parameter_list *p = mesa->Parameters; + + *reg = nvr_unused; + + switch (src->File) { + case PROGRAM_INPUT: + reg->file = NVS_FILE_ATTRIB; + if (mesa->Target == GL_VERTEX_PROGRAM_ARB) { + reg->index = (src->Index < VERT_ATTRIB_MAX) ? + _tx_mesa_vp_src_reg[src->Index] : + NVS_FR_UNKNOWN; + } else { + reg->index = (src->Index < FRAG_ATTRIB_MAX) ? + _tx_mesa_fp_src_reg[src->Index] : + NVS_FR_UNKNOWN; + } + break; + /* All const types seem to get shoved into here, not really sure why */ + case PROGRAM_STATE_VAR: + switch (p->Parameters[src->Index].Type) { + case PROGRAM_NAMED_PARAM: + case PROGRAM_CONSTANT: + nvs->params[src->Index].source_val = NULL; + COPY_4V(nvs->params[src->Index].val, + p->ParameterValues[src->Index]); + break; + case PROGRAM_STATE_VAR: + nvs->params[src->Index].source_val = + p->ParameterValues[src->Index]; + break; + default: + fprintf(stderr, "Unknown parameter type %d\n", + p->Parameters[src->Index].Type); + assert(0); + break; + } + + if (src->RelAddr) { + reg->indexed = 1; + reg->addr_reg = 0; + reg->addr_comp = NVS_SWZ_X; + } else + reg->indexed = 0; + reg->file = NVS_FILE_CONST; + reg->index = src->Index; + break; + case PROGRAM_TEMPORARY: + reg->file = NVS_FILE_TEMP; + reg->index = src->Index; + break; + default: + fprintf(stderr, "Unknown source type %d\n", src->File); + assert(0); + } + + /* per-component negate handled elsewhere */ + reg->negate = src->NegateBase != 0; + reg->abs = src->Abs; + pass0_make_swizzle(reg->swizzle, src->Swizzle); } static nvsInstruction * @@ -389,59 +396,66 @@ pass0_emit(nouveauShader *nvs, nvsFragmentHeader *parent, int fpos, static void pass0_fixup_swizzle(nvsPtr nvs, nvsFragmentHeader *parent, int fpos, - struct prog_src_register *src, + struct prog_src_register *src, unsigned int sm1, unsigned int sm2) { - static const float sc[4] = { 1.0, 0.0, -1.0, 0.0 }; - struct pass0_rec *rec = nvs->pass_rec; - int fixup_1, fixup_2; - nvsRegister sr, dr = nvr_unused; - nvsRegister sm1const, sm2const; - - if (!rec->swzconst_done) { - struct gl_program *prog = &nvs->mesa.vp.Base; - rec->swzconst_id = _mesa_add_unnamed_constant(prog->Parameters, sc, 4); - rec->swzconst_done = 1; - COPY_4V(nvs->params[rec->swzconst_id].val, sc); - } - - fixup_1 = (sm1 != MAKE_SWIZZLE4(0,0,0,0) && sm2 != MAKE_SWIZZLE4(2,2,2,2)); - fixup_2 = (sm2 != MAKE_SWIZZLE4(2,2,2,2)); - - if (src->File != PROGRAM_TEMPORARY && src->File != PROGRAM_INPUT) { - /* We can't use more than one const in an instruction, so move the const - * into a temp, and swizzle from there. - *TODO: should just emit the swizzled const, instead of swizzling it - * in the shader.. would need to reswizzle any state params when they - * change however.. - */ - pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); - pass0_make_src_reg(nvs, &sr, src); - pass0_emit(nvs, parent, fpos, NVS_OP_MOV, dr, SMASK_ALL, 0, sr, nvr_unused, nvr_unused); - pass0_make_reg(nvs, &sr, NVS_FILE_TEMP, dr.index); - } else { - if (fixup_1) - src->NegateBase = 0; - pass0_make_src_reg(nvs, &sr, src); - pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); - } - - pass0_make_reg(nvs, &sm1const, NVS_FILE_CONST, rec->swzconst_id); - pass0_make_swizzle(sm1const.swizzle, sm1); - if (fixup_1 && fixup_2) { - /* Any combination with SWIZZLE_ONE */ - pass0_make_reg(nvs, &sm2const, NVS_FILE_CONST, rec->swzconst_id); - pass0_make_swizzle(sm2const.swizzle, sm2); - pass0_emit(nvs, parent, fpos, NVS_OP_MAD, dr, SMASK_ALL, 0, sr, sm1const, sm2const); - } else { - /* SWIZZLE_ZERO || arbitrary negate */ - pass0_emit(nvs, parent, fpos, NVS_OP_MUL, dr, SMASK_ALL, 0, sr, sm1const, nvr_unused); - } - - src->File = PROGRAM_TEMPORARY; - src->Index = dr.index; - src->Swizzle = SWIZZLE_NOOP; + static const float sc[4] = { 1.0, 0.0, -1.0, 0.0 }; + struct pass0_rec *rec = nvs->pass_rec; + int fixup_1, fixup_2; + nvsRegister sr, dr = nvr_unused; + nvsRegister sm1const, sm2const; + + if (!rec->swzconst_done) { + struct gl_program *prog = &nvs->mesa.vp.Base; + rec->swzconst_id = _mesa_add_unnamed_constant(prog->Parameters, + sc, 4); + rec->swzconst_done = 1; + COPY_4V(nvs->params[rec->swzconst_id].val, sc); + } + + fixup_1 = (sm1 != MAKE_SWIZZLE4(0,0,0,0) && + sm2 != MAKE_SWIZZLE4(2,2,2,2)); + fixup_2 = (sm2 != MAKE_SWIZZLE4(2,2,2,2)); + + if (src->File != PROGRAM_TEMPORARY && src->File != PROGRAM_INPUT) { + /* We can't use more than one const in an instruction, + * so move the const into a temp, and swizzle from there. + * + * TODO: should just emit the swizzled const, instead of + * swizzling it in the shader.. would need to reswizzle + * any state params when they change however.. + */ + pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); + pass0_make_src_reg(nvs, &sr, src); + pass0_emit(nvs, parent, fpos, NVS_OP_MOV, + dr, SMASK_ALL, 0, sr, nvr_unused, nvr_unused); + pass0_make_reg(nvs, &sr, NVS_FILE_TEMP, dr.index); + } else { + if (fixup_1) + src->NegateBase = 0; + pass0_make_src_reg(nvs, &sr, src); + pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); + } + + pass0_make_reg(nvs, &sm1const, NVS_FILE_CONST, rec->swzconst_id); + pass0_make_swizzle(sm1const.swizzle, sm1); + if (fixup_1 && fixup_2) { + /* Any combination with SWIZZLE_ONE */ + pass0_make_reg(nvs, &sm2const, + NVS_FILE_CONST, rec->swzconst_id); + pass0_make_swizzle(sm2const.swizzle, sm2); + pass0_emit(nvs, parent, fpos, NVS_OP_MAD, + dr, SMASK_ALL, 0, sr, sm1const, sm2const); + } else { + /* SWIZZLE_ZERO || arbitrary negate */ + pass0_emit(nvs, parent, fpos, NVS_OP_MUL, + dr, SMASK_ALL, 0, sr, sm1const, nvr_unused); + } + + src->File = PROGRAM_TEMPORARY; + src->Index = dr.index; + src->Swizzle = SWIZZLE_NOOP; } #define SET_SWZ(fs, cp, c) fs = (fs & ~(0x7<<(cp*3))) | (c<<(cp*3)) @@ -449,81 +463,86 @@ static void pass0_check_sources(nvsPtr nvs, nvsFragmentHeader *parent, int fpos, struct prog_instruction *inst) { - unsigned int insrc = -1, constsrc = -1; - int i; - - for (i=0;i<_mesa_num_inst_src_regs(inst->Opcode);i++) { - struct prog_src_register *src = &inst->SrcReg[i]; - unsigned int sm_1 = 0, sm_2 = 0; - nvsRegister sr, dr; - int do_mov = 0, c; - - /* Build up swizzle masks as if we were going to use - * "MAD new, src, const1, const2" to support arbitrary negation - * and SWIZZLE_ZERO/SWIZZLE_ONE. - */ - for (c=0;c<4;c++) { - if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ZERO) { - SET_SWZ(sm_1, c, SWIZZLE_Y); /* 0.0 */ - SET_SWZ(sm_2, c, SWIZZLE_Y); - SET_SWZ(src->Swizzle, c, SWIZZLE_X); - } else if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ONE) { - SET_SWZ(sm_1, c, SWIZZLE_Y); - if (src->NegateBase & (1<Swizzle, c, SWIZZLE_X); - } else { - if (src->NegateBase & (1<File) { - case PROGRAM_INPUT: - if (insrc != -1 && insrc != src->Index) - do_mov = 1; - else insrc = src->Index; - break; - case PROGRAM_STATE_VAR: - if (constsrc != -1 && constsrc != src->Index) - do_mov = 1; - else constsrc = src->Index; - break; - default: - break; - } - - /* Emit any extra ATTRIB/CONST to a temp, and modify the Mesa instruction - * to point at the temp. - */ - if (do_mov) { - pass0_make_src_reg(nvs, &sr, src); - pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); - pass0_emit(nvs, parent, fpos, NVS_OP_MOV, dr, SMASK_ALL, 0, - sr, nvr_unused, nvr_unused); - - src->File = PROGRAM_TEMPORARY; - src->Index = dr.index; - src->Swizzle= SWIZZLE_NOOP; - } - } + unsigned int insrc = -1, constsrc = -1; + int i; + + for (i=0;i<_mesa_num_inst_src_regs(inst->Opcode);i++) { + struct prog_src_register *src = &inst->SrcReg[i]; + unsigned int sm_1 = 0, sm_2 = 0; + nvsRegister sr, dr; + int do_mov = 0, c; + + /* Build up swizzle masks as if we were going to use + * "MAD new, src, const1, const2" to support arbitrary negation + * and SWIZZLE_ZERO/SWIZZLE_ONE. + */ + for (c=0;c<4;c++) { + if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ZERO) { + SET_SWZ(sm_1, c, SWIZZLE_Y); /* 0.0 */ + SET_SWZ(sm_2, c, SWIZZLE_Y); + SET_SWZ(src->Swizzle, c, SWIZZLE_X); + } else if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ONE) { + SET_SWZ(sm_1, c, SWIZZLE_Y); + if (src->NegateBase & (1<Swizzle, c, SWIZZLE_X); + } else { + if (src->NegateBase & (1<File) { + case PROGRAM_INPUT: + if (insrc != -1 && insrc != src->Index) + do_mov = 1; + else insrc = src->Index; + break; + case PROGRAM_STATE_VAR: + if (constsrc != -1 && constsrc != src->Index) + do_mov = 1; + else constsrc = src->Index; + break; + default: + break; + } + + /* Emit any extra ATTRIB/CONST to a temp, and modify the Mesa + * instruction to point at the temp. + */ + if (do_mov) { + pass0_make_src_reg(nvs, &sr, src); + pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); + pass0_emit(nvs, parent, fpos, NVS_OP_MOV, + dr, SMASK_ALL, 0, + sr, nvr_unused, nvr_unused); + + src->File = PROGRAM_TEMPORARY; + src->Index = dr.index; + src->Swizzle= SWIZZLE_NOOP; + } + } } static GLboolean @@ -531,138 +550,150 @@ pass0_emulate_instruction(nouveauShader *nvs, nvsFragmentHeader *parent, int fpos, struct prog_instruction *inst) { - nvsFunc *shader = nvs->func; - nvsRegister src[3], dest, temp; - nvsInstruction *nvsinst; - struct pass0_rec *rec = nvs->pass_rec; - unsigned int mask = pass0_make_mask(inst->DstReg.WriteMask); - int i, sat; - - sat = (inst->SaturateMode == SATURATE_ZERO_ONE); - - /* Build all the "real" regs for the instruction */ - for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++) - pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]); - if (inst->Opcode != OPCODE_KIL) - pass0_make_dst_reg(nvs, &dest, &inst->DstReg); - - switch (inst->Opcode) { - case OPCODE_ABS: - if (shader->caps & SCAP_SRC_ABS) - pass0_emit(nvs, parent, fpos, NVS_OP_MOV, dest, mask, sat, - nvsAbs(src[0]), nvr_unused, nvr_unused); - else - pass0_emit(nvs, parent, fpos, NVS_OP_MAX, dest, mask, sat, - src[0], nvsNegate(src[0]), nvr_unused); - break; - case OPCODE_KIL: - /* This is only in ARB shaders, so we don't have to worry - * about clobbering a CC reg as they aren't supported anyway. - */ - /* MOVC0 temp, src */ - pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - nvsinst = pass0_emit(nvs, parent, fpos, NVS_OP_MOV, temp, SMASK_ALL, 0, - src[0], nvr_unused, nvr_unused); - nvsinst->cond_update = 1; - nvsinst->cond_reg = 0; - /* KIL_NV (LT0.xyzw) temp */ - nvsinst = pass0_emit(nvs, parent, fpos, NVS_OP_KIL, nvr_unused, 0, 0, - nvr_unused, nvr_unused, nvr_unused); - nvsinst->cond = COND_LT; - nvsinst->cond_reg = 0; - nvsinst->cond_test = 1; - pass0_make_swizzle(nvsinst->cond_swizzle, MAKE_SWIZZLE4(0,1,2,3)); - break; - case OPCODE_LIT: - break; - case OPCODE_LRP: - pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - pass0_emit(nvs, parent, fpos, NVS_OP_MAD, temp, mask, 0, - nvsNegate(src[0]), src[2], src[2]); - pass0_emit(nvs, parent, fpos, NVS_OP_MAD, dest, mask, sat, - src[0], src[1], temp); - break; - case OPCODE_POW: - if (shader->SupportsOpcode(shader, NVS_OP_LG2) && - shader->SupportsOpcode(shader, NVS_OP_EX2)) { - pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - /* LG2 temp.x, src0.c */ - pass0_emit(nvs, parent, fpos, NVS_OP_LG2, temp, SMASK_X, 0, - nvsSwizzle(src[0], X, X, X, X), - nvr_unused, - nvr_unused); - /* MUL temp.x, temp.x, src1.c */ - pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_X, 0, - nvsSwizzle(temp, X, X, X, X), - nvsSwizzle(src[1], X, X, X, X), - nvr_unused); - /* EX2 dest, temp.x */ - pass0_emit(nvs, parent, fpos, NVS_OP_EX2, dest, mask, sat, - nvsSwizzle(temp, X, X, X, X), - nvr_unused, - nvr_unused); - } else { - /* can we use EXP/LOG instead of EX2/LG2?? */ - fprintf(stderr, "Implement POW for NV20 vtxprog!\n"); - return GL_FALSE; - } - break; - case OPCODE_RSQ: - if (rec->const_half.file != NVS_FILE_CONST) { - GLfloat const_half[4] = { 0.5, 0.0, 0.0, 0.0 }; - pass0_make_reg(nvs, &rec->const_half, NVS_FILE_CONST, - _mesa_add_unnamed_constant(nvs->mesa.vp.Base.Parameters, - const_half, 4)); - COPY_4V(nvs->params[rec->const_half.index].val, const_half); - } - pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - pass0_emit(nvs, parent, fpos, NVS_OP_LG2, temp, SMASK_X, 0, - nvsAbs(nvsSwizzle(src[0], X, X, X, X)), - nvr_unused, - nvr_unused); - pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_X, 0, - nvsSwizzle(temp, X, X, X, X), - nvsNegate(rec->const_half), - nvr_unused); - pass0_emit(nvs, parent, fpos, NVS_OP_EX2, dest, mask, sat, - nvsSwizzle(temp, X, X, X, X), - nvr_unused, - nvr_unused); - break; - case OPCODE_SCS: - if (mask & SMASK_X) - pass0_emit(nvs, parent, fpos, NVS_OP_COS, dest, SMASK_X, sat, - nvsSwizzle(src[0], X, X, X, X), - nvr_unused, - nvr_unused); - if (mask & SMASK_Y) - pass0_emit(nvs, parent, fpos, NVS_OP_SIN, dest, SMASK_Y, sat, - nvsSwizzle(src[0], X, X, X, X), - nvr_unused, - nvr_unused); - break; - case OPCODE_SUB: - pass0_emit(nvs, parent, fpos, NVS_OP_ADD, dest, mask, sat, - src[0], nvsNegate(src[1]), nvr_unused); - break; - case OPCODE_XPD: - pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_ALL, 0, - nvsSwizzle(src[0], Z, X, Y, Y), - nvsSwizzle(src[1], Y, Z, X, X), - nvr_unused); - pass0_emit(nvs, parent, fpos, NVS_OP_MAD, dest, (mask & ~SMASK_W), sat, - nvsSwizzle(src[0], Y, Z, X, X), - nvsSwizzle(src[1], Z, X, Y, Y), - nvsNegate(temp)); - break; - default: - fprintf(stderr, "hw doesn't support opcode \"%s\", and no emulation found\n", - _mesa_opcode_string(inst->Opcode)); - return GL_FALSE; - } - - return GL_TRUE; + nvsFunc *shader = nvs->func; + nvsRegister src[3], dest, temp; + nvsInstruction *nvsinst; + struct pass0_rec *rec = nvs->pass_rec; + unsigned int mask = pass0_make_mask(inst->DstReg.WriteMask); + int i, sat; + + sat = (inst->SaturateMode == SATURATE_ZERO_ONE); + + /* Build all the "real" regs for the instruction */ + for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++) + pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]); + if (inst->Opcode != OPCODE_KIL) + pass0_make_dst_reg(nvs, &dest, &inst->DstReg); + + switch (inst->Opcode) { + case OPCODE_ABS: + if (shader->caps & SCAP_SRC_ABS) + pass0_emit(nvs, parent, fpos, NVS_OP_MOV, + dest, mask, sat, + nvsAbs(src[0]), nvr_unused, nvr_unused); + else + pass0_emit(nvs, parent, fpos, NVS_OP_MAX, + dest, mask, sat, + src[0], nvsNegate(src[0]), nvr_unused); + break; + case OPCODE_KIL: + /* This is only in ARB shaders, so we don't have to worry + * about clobbering a CC reg as they aren't supported anyway. + */ + /* MOVC0 temp, src */ + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + nvsinst = pass0_emit(nvs, parent, fpos, NVS_OP_MOV, + temp, SMASK_ALL, 0, + src[0], nvr_unused, nvr_unused); + nvsinst->cond_update = 1; + nvsinst->cond_reg = 0; + /* KIL_NV (LT0.xyzw) temp */ + nvsinst = pass0_emit(nvs, parent, fpos, NVS_OP_KIL, + nvr_unused, 0, 0, + nvr_unused, nvr_unused, nvr_unused); + nvsinst->cond = COND_LT; + nvsinst->cond_reg = 0; + nvsinst->cond_test = 1; + pass0_make_swizzle(nvsinst->cond_swizzle, + MAKE_SWIZZLE4(0,1,2,3)); + break; + case OPCODE_LRP: + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + pass0_emit(nvs, parent, fpos, NVS_OP_MAD, temp, mask, 0, + nvsNegate(src[0]), src[2], src[2]); + pass0_emit(nvs, parent, fpos, NVS_OP_MAD, dest, mask, sat, + src[0], src[1], temp); + break; + case OPCODE_POW: + if (shader->SupportsOpcode(shader, NVS_OP_LG2) && + shader->SupportsOpcode(shader, NVS_OP_EX2)) { + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + /* LG2 temp.x, src0.c */ + pass0_emit(nvs, parent, fpos, NVS_OP_LG2, + temp, SMASK_X, 0, + nvsSwizzle(src[0], X, X, X, X), + nvr_unused, + nvr_unused); + /* MUL temp.x, temp.x, src1.c */ + pass0_emit(nvs, parent, fpos, NVS_OP_MUL, + temp, SMASK_X, 0, + nvsSwizzle(temp, X, X, X, X), + nvsSwizzle(src[1], X, X, X, X), + nvr_unused); + /* EX2 dest, temp.x */ + pass0_emit(nvs, parent, fpos, NVS_OP_EX2, + dest, mask, sat, + nvsSwizzle(temp, X, X, X, X), + nvr_unused, + nvr_unused); + } else { + /* can we use EXP/LOG instead of EX2/LG2?? */ + fprintf(stderr, "Implement POW for NV20 vtxprog!\n"); + return GL_FALSE; + } + break; + case OPCODE_RSQ: + if (rec->const_half.file != NVS_FILE_CONST) { + GLfloat const_half[4] = { 0.5, 0.0, 0.0, 0.0 }; + pass0_make_reg(nvs, &rec->const_half, NVS_FILE_CONST, + _mesa_add_unnamed_constant( + nvs->mesa.vp.Base.Parameters, + const_half, 4)); + COPY_4V(nvs->params[rec->const_half.index].val, + const_half); + } + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + pass0_emit(nvs, parent, fpos, NVS_OP_LG2, temp, SMASK_X, 0, + nvsAbs(nvsSwizzle(src[0], X, X, X, X)), + nvr_unused, + nvr_unused); + pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_X, 0, + nvsSwizzle(temp, X, X, X, X), + nvsNegate(rec->const_half), + nvr_unused); + pass0_emit(nvs, parent, fpos, NVS_OP_EX2, dest, mask, sat, + nvsSwizzle(temp, X, X, X, X), + nvr_unused, + nvr_unused); + break; + case OPCODE_SCS: + if (mask & SMASK_X) + pass0_emit(nvs, parent, fpos, NVS_OP_COS, + dest, SMASK_X, sat, + nvsSwizzle(src[0], X, X, X, X), + nvr_unused, + nvr_unused); + if (mask & SMASK_Y) + pass0_emit(nvs, parent, fpos, NVS_OP_SIN, + dest, SMASK_Y, sat, + nvsSwizzle(src[0], X, X, X, X), + nvr_unused, + nvr_unused); + break; + case OPCODE_SUB: + pass0_emit(nvs, parent, fpos, NVS_OP_ADD, dest, mask, sat, + src[0], nvsNegate(src[1]), nvr_unused); + break; + case OPCODE_XPD: + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_ALL, 0, + nvsSwizzle(src[0], Z, X, Y, Y), + nvsSwizzle(src[1], Y, Z, X, X), + nvr_unused); + pass0_emit(nvs, parent, fpos, NVS_OP_MAD, + dest, (mask & ~SMASK_W), sat, + nvsSwizzle(src[0], Y, Z, X, X), + nvsSwizzle(src[1], Z, X, Y, Y), + nvsNegate(temp)); + break; + default: + WARN_ONCE("hw doesn't support opcode \"%s\"," + "and no emulation found\n", + _mesa_opcode_string(inst->Opcode)); + return GL_FALSE; + } + + return GL_TRUE; } static GLboolean diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c index b9b87ccf91..6fb36c1daf 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c @@ -41,130 +41,138 @@ #include "nouveau_msg.h" struct pass2_rec { - /* Map nvsRegister temp ID onto hw temp ID */ - unsigned int temps[NVS_MAX_TEMPS]; - /* Track free hw registers */ - unsigned int hw_temps[NVS_MAX_TEMPS]; + /* Map nvsRegister temp ID onto hw temp ID */ + unsigned int temps[NVS_MAX_TEMPS]; + /* Track free hw registers */ + unsigned int hw_temps[NVS_MAX_TEMPS]; }; static int pass2_alloc_hw_temp(nvsPtr nvs) { - struct pass2_rec *rec = nvs->pass_rec; - int i; - - for (i=0; ifunc->MaxTemp; i++) { - /* This is a *horrible* hack.. R0 is both temp0 and result.color - * in NV30/40 fragprogs, we can use R0 as a temp before result is - * written however.. - */ - if (nvs->mesa.vp.Base.Target == GL_FRAGMENT_PROGRAM_ARB && i==0) - continue; - - if (rec->hw_temps[i] == 0) { - rec->hw_temps[i] = 1; - return i; - } - } - return -1; + struct pass2_rec *rec = nvs->pass_rec; + int i; + + for (i=0; ifunc->MaxTemp; i++) { + /* This is a *horrible* hack.. R0 is both temp0 and result.color + * in NV30/40 fragprogs, we can use R0 as a temp before result + * is written however.. + */ + if (nvs->mesa.vp.Base.Target == GL_FRAGMENT_PROGRAM_ARB && i==0) + continue; + if (rec->hw_temps[i] == 0) { + rec->hw_temps[i] = 1; + return i; + } + } + + return -1; } static nvsRegister pass2_mangle_reg(nvsPtr nvs, nvsInstruction *inst, nvsRegister reg) { - struct pass2_rec *rec = nvs->pass_rec; + struct pass2_rec *rec = nvs->pass_rec; - if (reg.file == NVS_FILE_TEMP) { - if (rec->temps[reg.index] == -1) - rec->temps[reg.index] = pass2_alloc_hw_temp(nvs); - reg.index = rec->temps[reg.index]; - } + if (reg.file == NVS_FILE_TEMP) { + if (rec->temps[reg.index] == -1) + rec->temps[reg.index] = pass2_alloc_hw_temp(nvs); + reg.index = rec->temps[reg.index]; + } - return reg; + return reg; } static void pass2_add_instruction(nvsPtr nvs, nvsInstruction *inst, - struct _op_xlat *op, int slot) + struct _op_xlat *op, int slot) { - nvsSwzComp default_swz[4] = { NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W }; - nvsFunc *shader = nvs->func; - nvsRegister reg; - int i; - - shader->SetOpcode(shader, op->NV, slot); - if (inst->saturate ) shader->SetSaturate(shader); - if (inst->cond_update) shader->SetCCUpdate(shader); - if (inst->cond_test ) shader->SetCondition(shader, 1, inst->cond, - inst->cond_reg, - inst->cond_swizzle); - else shader->SetCondition(shader, 0, NVS_COND_TR, - 0, - default_swz); - switch (inst->op) { - case NVS_OP_TEX: - case NVS_OP_TXB: - case NVS_OP_TXL: - case NVS_OP_TXP: - case NVS_OP_TXD: - shader->SetTexImageUnit(shader, inst->tex_unit); - break; - default: - break; - } - - for (i = 0; i < 3; i++) { - if (op->srcpos[i] != -1) { - reg = pass2_mangle_reg(nvs, inst, inst->src[i]); - if (reg.file == NVS_FILE_ATTRIB) - nvs->inputs_read |= (1 << reg.index); - shader->SetSource(shader, ®, op->srcpos[i]); - if (reg.file == NVS_FILE_CONST && shader->GetSourceConstVal) { - int idx_slot = nvs->params[reg.index].hw_index_cnt++; - nvs->params[reg.index].hw_index = realloc( - nvs->params[reg.index].hw_index, sizeof(int) * idx_slot+1); - nvs->params[reg.index].hw_index[idx_slot] = nvs->program_current + 4; - } - } - } - - reg = pass2_mangle_reg(nvs, inst, inst->dest); - if (reg.file == NVS_FILE_RESULT) - nvs->outputs_written |= (1 << reg.index); - shader->SetResult(shader, ®, inst->mask, slot); + nvsSwzComp default_swz[4] = { NVS_SWZ_X, NVS_SWZ_Y, + NVS_SWZ_Z, NVS_SWZ_W }; + nvsFunc *shader = nvs->func; + nvsRegister reg; + int i; + + shader->SetOpcode(shader, op->NV, slot); + if (inst->saturate ) shader->SetSaturate(shader); + if (inst->cond_update ) shader->SetCCUpdate(shader); + if (inst->cond_test ) shader->SetCondition(shader, 1, inst->cond, + inst->cond_reg, + inst->cond_swizzle); + else shader->SetCondition(shader, 0, NVS_COND_TR, + 0, + default_swz); + switch (inst->op) { + case NVS_OP_TEX: + case NVS_OP_TXB: + case NVS_OP_TXL: + case NVS_OP_TXP: + case NVS_OP_TXD: + shader->SetTexImageUnit(shader, inst->tex_unit); + break; + default: + break; + } + + for (i = 0; i < 3; i++) { + if (op->srcpos[i] != -1) { + reg = pass2_mangle_reg(nvs, inst, inst->src[i]); + + if (reg.file == NVS_FILE_ATTRIB) + nvs->inputs_read |= (1 << reg.index); + shader->SetSource(shader, ®, op->srcpos[i]); + + if (reg.file == NVS_FILE_CONST && + shader->GetSourceConstVal) { + int idx_slot = + nvs->params[reg.index].hw_index_cnt++; + nvs->params[reg.index].hw_index = realloc( + nvs->params[reg.index].hw_index, + sizeof(int) * idx_slot+1); + nvs->params[reg.index].hw_index[idx_slot] = + nvs->program_current + 4; + } + } + } + + reg = pass2_mangle_reg(nvs, inst, inst->dest); + if (reg.file == NVS_FILE_RESULT) + nvs->outputs_written |= (1 << reg.index); + shader->SetResult(shader, ®, inst->mask, slot); } static int pass2_assemble_instruction(nvsPtr nvs, nvsInstruction *inst, int last) { - nvsFunc *shader = nvs->func; - struct _op_xlat *op; - unsigned int hw_inst[8]; - int slot; - int instsz; - int i; - - shader->inst = hw_inst; - - /* Assemble this instruction */ - if (!(op = shader->GetOPTXFromSOP(inst->op, &slot))) - return 0; - shader->InitInstruction(shader); - pass2_add_instruction(nvs, inst, op, slot); - if (last) - shader->SetLastInst(shader); - - instsz = shader->GetOffsetNext(nvs->func); - if (nvs->program_size + instsz >= nvs->program_alloc_size) { - nvs->program_alloc_size *= 2; - nvs->program = realloc(nvs->program, - nvs->program_alloc_size * sizeof(uint32_t)); - } - - for (i=0; iprogram[nvs->program_current++] = hw_inst[i]; - nvs->program_size = nvs->program_current; - return 1; + nvsFunc *shader = nvs->func; + struct _op_xlat *op; + unsigned int hw_inst[8]; + int slot; + int instsz; + int i; + + shader->inst = hw_inst; + + /* Assemble this instruction */ + if (!(op = shader->GetOPTXFromSOP(inst->op, &slot))) + return 0; + shader->InitInstruction(shader); + pass2_add_instruction(nvs, inst, op, slot); + if (last) + shader->SetLastInst(shader); + + instsz = shader->GetOffsetNext(nvs->func); + if (nvs->program_size + instsz >= nvs->program_alloc_size) { + nvs->program_alloc_size *= 2; + nvs->program = realloc(nvs->program, + nvs->program_alloc_size * + sizeof(uint32_t)); + } + + for (i=0; iprogram[nvs->program_current++] = hw_inst[i]; + nvs->program_size = nvs->program_current; + return 1; } static GLboolean @@ -198,53 +206,56 @@ pass2_translate(nvsPtr nvs, nvsFragmentHeader *f) GLboolean nouveau_shader_pass2(nvsPtr nvs) { - struct pass2_rec *rec; - int i; - - rec = calloc(1, sizeof(struct pass2_rec)); - for (i=0; itemps[i] = -1; - nvs->pass_rec = rec; - - /* Start off with allocating 4 uint32_t's for each inst, will be grown - * if necessary.. - */ - nvs->program_alloc_size = nvs->mesa.vp.Base.NumInstructions * 4; - nvs->program = calloc(nvs->program_alloc_size, sizeof(uint32_t)); - nvs->program_size = 0; - nvs->program_current = 0; - - if (!pass2_translate(nvs, ((nvsSubroutine*)nvs->program_tree)->insn_head)) { - free(nvs->program); - nvs->program = NULL; - return GL_FALSE; - } - - /* Shrink allocated memory to only what we need */ - nvs->program = realloc(nvs->program, nvs->program_size * sizeof(uint32_t)); - nvs->program_alloc_size = nvs->program_size; - - nvs->translated = 1; - nvs->on_hardware = 0; - - if (NOUVEAU_DEBUG & DEBUG_SHADERS) { - fflush(stdout); fflush(stderr); - fprintf(stderr, "----------------MESA PROGRAM target=%s, id=0x%x\n", - _mesa_lookup_enum_by_nr(nvs->mesa.vp.Base.Target), - nvs->mesa.vp.Base.Id); - fflush(stdout); fflush(stderr); - _mesa_print_program(&nvs->mesa.vp.Base); - fflush(stdout); fflush(stderr); - fprintf(stderr, "^^^^^^^^^^^^^^^^MESA PROGRAM\n"); - fflush(stdout); fflush(stderr); - fprintf(stderr, "----------------NV PROGRAM\n"); - fflush(stdout); fflush(stderr); - nvsDisasmHWShader(nvs); - fflush(stdout); fflush(stderr); - fprintf(stderr, "^^^^^^^^^^^^^^^^NV PROGRAM\n"); - fflush(stdout); fflush(stderr); - } - - return GL_TRUE; + struct pass2_rec *rec; + int i; + + rec = calloc(1, sizeof(struct pass2_rec)); + for (i=0; itemps[i] = -1; + nvs->pass_rec = rec; + + /* Start off with allocating 4 uint32_t's for each inst, will be grown + * if necessary.. + */ + nvs->program_alloc_size = nvs->mesa.vp.Base.NumInstructions * 4; + nvs->program = calloc(nvs->program_alloc_size, sizeof(uint32_t)); + nvs->program_size = 0; + nvs->program_current = 0; + + if (!pass2_translate(nvs, + ((nvsSubroutine*)nvs->program_tree)->insn_head)) { + free(nvs->program); + nvs->program = NULL; + return GL_FALSE; + } + + /* Shrink allocated memory to only what we need */ + nvs->program = realloc(nvs->program, + nvs->program_size * sizeof(uint32_t)); + nvs->program_alloc_size = nvs->program_size; + + nvs->translated = 1; + nvs->on_hardware = 0; + + if (NOUVEAU_DEBUG & DEBUG_SHADERS) { + fflush(stdout); fflush(stderr); + fprintf(stderr, "-----------MESA PROGRAM target=%s, id=0x%x\n", + _mesa_lookup_enum_by_nr( + nvs->mesa.vp.Base.Target), + nvs->mesa.vp.Base.Id); + fflush(stdout); fflush(stderr); + _mesa_print_program(&nvs->mesa.vp.Base); + fflush(stdout); fflush(stderr); + fprintf(stderr, "^^^^^^^^^^^^^^^^MESA PROGRAM\n"); + fflush(stdout); fflush(stderr); + fprintf(stderr, "----------------NV PROGRAM\n"); + fflush(stdout); fflush(stderr); + nvsDisasmHWShader(nvs); + fflush(stdout); fflush(stderr); + fprintf(stderr, "^^^^^^^^^^^^^^^^NV PROGRAM\n"); + fflush(stdout); fflush(stderr); + } + + return GL_TRUE; } -- cgit v1.2.3 From ed69205684a0c3c69d27a9e2d13213997aaa5b93 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 23 Jan 2007 11:06:16 +1100 Subject: nouveau: unbreak nv40 --- src/mesa/drivers/dri/nouveau/nv30_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index e788a9235a..9bb4f14909 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -899,7 +899,7 @@ static GLboolean nv30BindBuffers(nouveauContextPtr nmesa, int num_color, OUT_RING (depth->offset); if (nmesa->screen->card->type >= NV_40) { BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH, 1); - OUT_RING (depth->pitch >> 2); + OUT_RING (depth->pitch); } } -- cgit v1.2.3 From a8b9d13f745405e370353cfb4aca680314a42d46 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 23 Jan 2007 13:36:45 +1100 Subject: nouveau: fill in condition info for instructions --- src/mesa/drivers/dri/nouveau/nouveau_shader_0.c | 153 ++++++++++++------------ 1 file changed, 76 insertions(+), 77 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c index d6ea42573a..5845d4f63a 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -117,7 +117,8 @@ static nvsOpcode _tx_mesa_opcode[] = { }; static nvsCond _tx_mesa_condmask[] = { - NVS_COND_UNKNOWN, NVS_COND_GT, NVS_COND_LT, NVS_COND_UN, NVS_COND_GE, + NVS_COND_TR, /* workaround mesa not filling a valid value */ + NVS_COND_GT, NVS_COND_LT, NVS_COND_UN, NVS_COND_GE, NVS_COND_LE, NVS_COND_NE, NVS_COND_NE, NVS_COND_TR, NVS_COND_FL }; @@ -134,6 +135,26 @@ struct pass0_rec { #define Z NVS_SWZ_Z #define W NVS_SWZ_W +#define FILL_CONDITION_FLAGS(fragment) do { \ + (fragment)->cond = \ + pass0_make_condmask(inst->DstReg.CondMask); \ + if ((fragment)->cond != NVS_COND_TR) \ + (fragment)->cond_test = 1; \ + (fragment)->cond_reg = inst->CondDst; \ + pass0_make_swizzle((fragment)->cond_swizzle, inst->DstReg.CondSwizzle);\ +} while(0) + +#define ARITH(op,dest,mask,sat,s0,s1,s2) do { \ + nvsinst = pass0_emit(nvs, parent, fpos, (op), \ + (dest), (mask), (sat), (s0), (s1), (s2));\ + FILL_CONDITION_FLAGS(nvsinst); \ +} while(0) + +#define ARITHu(op,dest,mask,sat,s0,s1,s2) do { \ + nvsinst = pass0_emit(nvs, parent, fpos, (op), \ + (dest), (mask), (sat), (s0), (s1), (s2));\ +} while(0) + static void pass0_append_fragment(nvsFragmentHeader *parent, nvsFragmentHeader *fragment, @@ -403,6 +424,7 @@ pass0_fixup_swizzle(nvsPtr nvs, nvsFragmentHeader *parent, int fpos, static const float sc[4] = { 1.0, 0.0, -1.0, 0.0 }; struct pass0_rec *rec = nvs->pass_rec; int fixup_1, fixup_2; + nvsInstruction *nvsinst; nvsRegister sr, dr = nvr_unused; nvsRegister sm1const, sm2const; @@ -428,8 +450,8 @@ pass0_fixup_swizzle(nvsPtr nvs, nvsFragmentHeader *parent, int fpos, */ pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); pass0_make_src_reg(nvs, &sr, src); - pass0_emit(nvs, parent, fpos, NVS_OP_MOV, - dr, SMASK_ALL, 0, sr, nvr_unused, nvr_unused); + ARITHu(NVS_OP_MOV, dr, SMASK_ALL, 0, + sr, nvr_unused, nvr_unused); pass0_make_reg(nvs, &sr, NVS_FILE_TEMP, dr.index); } else { if (fixup_1) @@ -445,12 +467,10 @@ pass0_fixup_swizzle(nvsPtr nvs, nvsFragmentHeader *parent, int fpos, pass0_make_reg(nvs, &sm2const, NVS_FILE_CONST, rec->swzconst_id); pass0_make_swizzle(sm2const.swizzle, sm2); - pass0_emit(nvs, parent, fpos, NVS_OP_MAD, - dr, SMASK_ALL, 0, sr, sm1const, sm2const); + ARITHu(NVS_OP_MAD, dr, SMASK_ALL, 0, sr, sm1const, sm2const); } else { /* SWIZZLE_ZERO || arbitrary negate */ - pass0_emit(nvs, parent, fpos, NVS_OP_MUL, - dr, SMASK_ALL, 0, sr, sm1const, nvr_unused); + ARITHu(NVS_OP_MUL, dr, SMASK_ALL, 0, sr, sm1const, nvr_unused); } src->File = PROGRAM_TEMPORARY; @@ -568,64 +588,54 @@ pass0_emulate_instruction(nouveauShader *nvs, switch (inst->Opcode) { case OPCODE_ABS: if (shader->caps & SCAP_SRC_ABS) - pass0_emit(nvs, parent, fpos, NVS_OP_MOV, - dest, mask, sat, + ARITH(NVS_OP_MOV, dest, mask, sat, nvsAbs(src[0]), nvr_unused, nvr_unused); else - pass0_emit(nvs, parent, fpos, NVS_OP_MAX, - dest, mask, sat, + ARITH(NVS_OP_MAX, dest, mask, sat, src[0], nvsNegate(src[0]), nvr_unused); break; case OPCODE_KIL: /* This is only in ARB shaders, so we don't have to worry * about clobbering a CC reg as they aren't supported anyway. + *XXX: might have to worry with GLSL however... */ /* MOVC0 temp, src */ pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - nvsinst = pass0_emit(nvs, parent, fpos, NVS_OP_MOV, - temp, SMASK_ALL, 0, - src[0], nvr_unused, nvr_unused); + ARITHu(NVS_OP_MOV, temp, SMASK_ALL, 0, + src[0], nvr_unused, nvr_unused); nvsinst->cond_update = 1; nvsinst->cond_reg = 0; /* KIL_NV (LT0.xyzw) temp */ - nvsinst = pass0_emit(nvs, parent, fpos, NVS_OP_KIL, - nvr_unused, 0, 0, - nvr_unused, nvr_unused, nvr_unused); + ARITHu(NVS_OP_KIL, nvr_unused, 0, 0, + nvr_unused, nvr_unused, nvr_unused); nvsinst->cond = COND_LT; nvsinst->cond_reg = 0; nvsinst->cond_test = 1; - pass0_make_swizzle(nvsinst->cond_swizzle, - MAKE_SWIZZLE4(0,1,2,3)); + pass0_make_swizzle(nvsinst->cond_swizzle, SWIZZLE_NOOP); break; case OPCODE_LRP: pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - pass0_emit(nvs, parent, fpos, NVS_OP_MAD, temp, mask, 0, - nvsNegate(src[0]), src[2], src[2]); - pass0_emit(nvs, parent, fpos, NVS_OP_MAD, dest, mask, sat, - src[0], src[1], temp); + ARITHu(NVS_OP_MAD, temp, mask, 0, + nvsNegate(src[0]), src[2], src[2]); + ARITH (NVS_OP_MAD, dest, mask, sat, src[0], src[1], temp); break; case OPCODE_POW: if (shader->SupportsOpcode(shader, NVS_OP_LG2) && shader->SupportsOpcode(shader, NVS_OP_EX2)) { pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); /* LG2 temp.x, src0.c */ - pass0_emit(nvs, parent, fpos, NVS_OP_LG2, - temp, SMASK_X, 0, - nvsSwizzle(src[0], X, X, X, X), - nvr_unused, - nvr_unused); + ARITHu(NVS_OP_LG2, temp, SMASK_X, 0, + nvsSwizzle(src[0], X, X, X, X), + nvr_unused, nvr_unused); /* MUL temp.x, temp.x, src1.c */ - pass0_emit(nvs, parent, fpos, NVS_OP_MUL, - temp, SMASK_X, 0, - nvsSwizzle(temp, X, X, X, X), - nvsSwizzle(src[1], X, X, X, X), - nvr_unused); + ARITHu(NVS_OP_MUL, temp, SMASK_X, 0, + nvsSwizzle(temp, X, X, X, X), + nvsSwizzle(src[1], X, X, X, X), + nvr_unused); /* EX2 dest, temp.x */ - pass0_emit(nvs, parent, fpos, NVS_OP_EX2, - dest, mask, sat, - nvsSwizzle(temp, X, X, X, X), - nvr_unused, - nvr_unused); + ARITH (NVS_OP_EX2, dest, mask, sat, + nvsSwizzle(temp, X, X, X, X), + nvr_unused, nvr_unused); } else { /* can we use EXP/LOG instead of EX2/LG2?? */ fprintf(stderr, "Implement POW for NV20 vtxprog!\n"); @@ -643,48 +653,41 @@ pass0_emulate_instruction(nouveauShader *nvs, const_half); } pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - pass0_emit(nvs, parent, fpos, NVS_OP_LG2, temp, SMASK_X, 0, - nvsAbs(nvsSwizzle(src[0], X, X, X, X)), - nvr_unused, - nvr_unused); - pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_X, 0, - nvsSwizzle(temp, X, X, X, X), - nvsNegate(rec->const_half), - nvr_unused); - pass0_emit(nvs, parent, fpos, NVS_OP_EX2, dest, mask, sat, - nvsSwizzle(temp, X, X, X, X), - nvr_unused, - nvr_unused); + ARITHu(NVS_OP_LG2, temp, SMASK_X, 0, + nvsAbs(nvsSwizzle(src[0], X, X, X, X)), + nvr_unused, nvr_unused); + ARITHu(NVS_OP_MUL, temp, SMASK_X, 0, + nvsSwizzle(temp, X, X, X, X), + nvsNegate(rec->const_half), + nvr_unused); + ARITH (NVS_OP_EX2, dest, mask, sat, + nvsSwizzle(temp, X, X, X, X), + nvr_unused, nvr_unused); break; case OPCODE_SCS: if (mask & SMASK_X) - pass0_emit(nvs, parent, fpos, NVS_OP_COS, - dest, SMASK_X, sat, + ARITH(NVS_OP_COS, dest, SMASK_X, sat, nvsSwizzle(src[0], X, X, X, X), - nvr_unused, - nvr_unused); + nvr_unused, nvr_unused); if (mask & SMASK_Y) - pass0_emit(nvs, parent, fpos, NVS_OP_SIN, - dest, SMASK_Y, sat, + ARITH(NVS_OP_SIN, dest, SMASK_Y, sat, nvsSwizzle(src[0], X, X, X, X), - nvr_unused, - nvr_unused); + nvr_unused, nvr_unused); break; case OPCODE_SUB: - pass0_emit(nvs, parent, fpos, NVS_OP_ADD, dest, mask, sat, + ARITH(NVS_OP_ADD, dest, mask, sat, src[0], nvsNegate(src[1]), nvr_unused); break; case OPCODE_XPD: pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_ALL, 0, - nvsSwizzle(src[0], Z, X, Y, Y), - nvsSwizzle(src[1], Y, Z, X, X), - nvr_unused); - pass0_emit(nvs, parent, fpos, NVS_OP_MAD, - dest, (mask & ~SMASK_W), sat, - nvsSwizzle(src[0], Y, Z, X, X), - nvsSwizzle(src[1], Z, X, Y, Y), - nvsNegate(temp)); + ARITHu(NVS_OP_MUL, temp, SMASK_ALL, 0, + nvsSwizzle(src[0], Z, X, Y, Y), + nvsSwizzle(src[1], Y, Z, X, X), + nvr_unused); + ARITH (NVS_OP_MAD, dest, (mask & ~SMASK_W), sat, + nvsSwizzle(src[0], Y, Z, X, X), + nvsSwizzle(src[1], Z, X, Y, Y), + nvsNegate(temp)); break; default: WARN_ONCE("hw doesn't support opcode \"%s\"," @@ -721,16 +724,12 @@ pass0_translate_arith(nouveauShader *nvs, struct gl_program *prog, pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]); pass0_make_dst_reg(nvs, &dest, &inst->DstReg); - nvsinst = pass0_emit(nvs, parent, fpos, - pass0_make_opcode(inst->Opcode), - dest, - pass0_make_mask(inst->DstReg.WriteMask), - (inst->SaturateMode != SATURATE_OFF), - src[0], src[1], src[2]); + ARITH(pass0_make_opcode(inst->Opcode), dest, + pass0_make_mask(inst->DstReg.WriteMask), + (inst->SaturateMode != SATURATE_OFF), + src[0], src[1], src[2]); nvsinst->tex_unit = inst->TexSrcUnit; nvsinst->tex_target = pass0_make_tex_target(inst->TexSrcTarget); - /* TODO when NV_fp/vp is implemented */ - nvsinst->cond = COND_TR; ret = GL_TRUE; } else @@ -753,7 +752,7 @@ pass0_translate_instructions(nouveauShader *nvs, int ipos, int fpos, return GL_TRUE; case OPCODE_BRA: case OPCODE_CAL: - //case OPCDOE_RET: + case OPCODE_RET: //case OPCODE_LOOP: //case OPCODE_ENDLOOP: //case OPCODE_IF: -- cgit v1.2.3 From cf33bcf0b246f75094673beaa989034fa27c4b9f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 23 Jan 2007 16:07:12 +1100 Subject: nouveau: allow for card-specific shader infos to be kept NV30/40 fragprog: build FP_CONTROL per-shader, still some hardcoded bits for this reg.. It looks like it has to do with the number of temps used, but needs more looking at. NV40 vtxprog : build VP_IN_REG/VP_OUT_REG during shader compile --- src/mesa/drivers/dri/nouveau/nouveau_shader.h | 74 ++++++++------- src/mesa/drivers/dri/nouveau/nouveau_shader_0.c | 1 + src/mesa/drivers/dri/nouveau/nouveau_shader_2.c | 4 - src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 3 - src/mesa/drivers/dri/nouveau/nv30_fragprog.c | 4 + src/mesa/drivers/dri/nouveau/nv30_state.c | 3 - src/mesa/drivers/dri/nouveau/nv30_vertprog.c | 4 + src/mesa/drivers/dri/nouveau/nv40_vertprog.c | 118 +++++++++++++++++++----- 8 files changed, 149 insertions(+), 62 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h index a3ab027142..8b4be9dfe7 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -24,6 +24,16 @@ typedef struct _nvs_fragment_header { } type; } nvsFragmentHeader; +typedef union { + struct { + uint32_t fp_control; + } NV30FP; + struct { + uint32_t vp_in_reg; + uint32_t vp_out_reg; + } NV30VP; +} nvsCardPriv; + typedef struct _nouveauShader { union { struct gl_vertex_program vp; @@ -41,10 +51,10 @@ typedef struct _nouveauShader { unsigned int program_start_id; unsigned int program_current; struct gl_buffer_object *program_buffer; - unsigned int inputs_read; - unsigned int outputs_written; int inst_count; + nvsCardPriv card_priv; + struct { GLfloat *source_val; /* NULL if invariant */ float val[4]; @@ -113,35 +123,35 @@ typedef enum { } nvsSwzComp; typedef enum { - NVS_FR_POSITION, - NVS_FR_WEIGHT, - NVS_FR_NORMAL, - NVS_FR_COL0, - NVS_FR_COL1, - NVS_FR_BFC0, - NVS_FR_BFC1, - NVS_FR_FOGCOORD, - NVS_FR_POINTSZ, - NVS_FR_TEXCOORD0, - NVS_FR_TEXCOORD1, - NVS_FR_TEXCOORD2, - NVS_FR_TEXCOORD3, - NVS_FR_TEXCOORD4, - NVS_FR_TEXCOORD5, - NVS_FR_TEXCOORD6, - NVS_FR_TEXCOORD7, - NVS_FR_FRAGDATA0, - NVS_FR_FRAGDATA1, - NVS_FR_FRAGDATA2, - NVS_FR_FRAGDATA3, - NVS_FR_CLIP0, - NVS_FR_CLIP1, - NVS_FR_CLIP2, - NVS_FR_CLIP3, - NVS_FR_CLIP4, - NVS_FR_CLIP5, - NVS_FR_CLIP6, - NVS_FR_FACING, + NVS_FR_POSITION = 0, + NVS_FR_WEIGHT = 1, + NVS_FR_NORMAL = 2, + NVS_FR_COL0 = 3, + NVS_FR_COL1 = 4, + NVS_FR_FOGCOORD = 5, + NVS_FR_TEXCOORD0 = 8, + NVS_FR_TEXCOORD1 = 9, + NVS_FR_TEXCOORD2 = 10, + NVS_FR_TEXCOORD3 = 11, + NVS_FR_TEXCOORD4 = 12, + NVS_FR_TEXCOORD5 = 13, + NVS_FR_TEXCOORD6 = 14, + NVS_FR_TEXCOORD7 = 15, + NVS_FR_BFC0 = 16, + NVS_FR_BFC1 = 17, + NVS_FR_POINTSZ = 18, + NVS_FR_FRAGDATA0 = 19, + NVS_FR_FRAGDATA1 = 20, + NVS_FR_FRAGDATA2 = 21, + NVS_FR_FRAGDATA3 = 22, + NVS_FR_CLIP0 = 23, + NVS_FR_CLIP1 = 24, + NVS_FR_CLIP2 = 25, + NVS_FR_CLIP3 = 26, + NVS_FR_CLIP4 = 27, + NVS_FR_CLIP5 = 28, + NVS_FR_CLIP6 = 29, + NVS_FR_FACING = 30, NVS_FR_UNKNOWN } nvsFixedReg; @@ -279,6 +289,8 @@ extern nvsSwzComp NV20VP_TX_SWIZZLE[4]; #define SCAP_SRC_ABS (1<<0) struct _nvsFunc { + nvsCardPriv *card_priv; + unsigned int MaxInst; unsigned int MaxAttrib; unsigned int MaxTemp; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c index 5845d4f63a..3e542ea9c0 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -805,6 +805,7 @@ nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) fprintf(stderr, "Unknown program type %d", prog->Target); return GL_FALSE; } + nvs->func->card_priv = &nvs->card_priv; rec = CALLOC_STRUCT(pass0_rec); if (rec) { diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c index 6fb36c1daf..c106fd2d94 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c @@ -118,8 +118,6 @@ pass2_add_instruction(nvsPtr nvs, nvsInstruction *inst, if (op->srcpos[i] != -1) { reg = pass2_mangle_reg(nvs, inst, inst->src[i]); - if (reg.file == NVS_FILE_ATTRIB) - nvs->inputs_read |= (1 << reg.index); shader->SetSource(shader, ®, op->srcpos[i]); if (reg.file == NVS_FILE_CONST && @@ -136,8 +134,6 @@ pass2_add_instruction(nvsPtr nvs, nvsInstruction *inst, } reg = pass2_mangle_reg(nvs, inst, inst->dest); - if (reg.file == NVS_FILE_RESULT) - nvs->outputs_written |= (1 << reg.index); shader->SetResult(shader, ®, inst->mask, slot); } diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index f916912c7e..c9bfac8c4a 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -476,9 +476,6 @@ static void nv10ChooseVertexState( GLcontext *ctx ) * is up to date */ nvsUpdateShader(ctx, nmesa->passthrough_vp); - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_IN_REG, 2); - OUT_RING_CACHE (0xff09); /*IN : POS, COL, TC0-7 */ - OUT_RING_CACHE (0x3fc001); /*OUT: COL, TC0-7, POS implied */ /* Update texenv shader / user fragprog */ nvsUpdateShader(ctx, (nouveauShader*)ctx->FragmentProgram._Current); diff --git a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c index cd7c955c9e..3c7501dd62 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c +++ b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c @@ -46,6 +46,8 @@ NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs) */ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM, 1); OUT_RING (offset | 1); + BEGIN_RING_SIZE(NvSub3D, 0x1d60, 1); + OUT_RING (nvs->card_priv.NV30FP.fp_control | 0x03000000); } static void @@ -92,6 +94,8 @@ NV30FPSupportsOpcode(nvsFunc *shader, nvsOpcode op) static void NV30FPSetOpcode(nvsFunc *shader, unsigned int opcode, int slot) { + if (opcode == NV30_FP_OP_OPCODE_KIL) + shader->card_priv->NV30FP.fp_control |= (1<<7); shader->inst[0] &= ~NV30_FP_OP_OPCODE_MASK; shader->inst[0] |= (opcode << NV30_FP_OP_OPCODE_SHIFT); } diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 9bb4f14909..9b0d7425c8 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -862,9 +862,6 @@ static GLboolean nv40InitCard(nouveauContextPtr nmesa) BEGIN_RING_SIZE(NvSub3D, 0x1e94, 1); OUT_RING(0x00000001); - BEGIN_RING_SIZE(NvSub3D, 0x1d60, 1); - OUT_RING(0x03008000); - return GL_TRUE; } diff --git a/src/mesa/drivers/dri/nouveau/nv30_vertprog.c b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c index 0b7678f55d..afcacf36c2 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_vertprog.c +++ b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c @@ -29,6 +29,10 @@ NV30VPUploadToHW(GLcontext *ctx, nouveauShader *nvs) } BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_PROGRAM_START_ID, 1); OUT_RING(0); + + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_IN_REG, 2); + OUT_RING(nvs->card_priv.NV30VP.vp_in_reg); + OUT_RING(nvs->card_priv.NV30VP.vp_out_reg); } static void diff --git a/src/mesa/drivers/dri/nouveau/nv40_vertprog.c b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c index 1ba1cfd155..6cb7e1cfd6 100644 --- a/src/mesa/drivers/dri/nouveau/nv40_vertprog.c +++ b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c @@ -66,6 +66,96 @@ NV40VPSetCondition(nvsFunc *shader, int on, nvsCond cond, int reg, shader->inst[0] |= (swizzle[NVS_SWZ_W] << NV40_VP_INST_COND_SWZ_W_SHIFT); } +/* these just exist here until nouveau_reg.h has them. */ +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_COL0 (1<<0) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_COL1 (1<<1) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_BFC0 (1<<2) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_BFC1 (1<<3) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_FOGC (1<<4) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_PSZ (1<<5) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP0 (1<<6) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP1 (1<<7) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP2 (1<<8) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP3 (1<<9) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP4 (1<<10) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP5 (1<<11) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_TEX0 (1<<14) + +static unsigned int +NV40VPTranslateResultReg(nvsFunc *shader, nvsFixedReg result, + unsigned int *mask_ret) +{ + unsigned int *out_reg = &shader->card_priv->NV30VP.vp_out_reg; + + *mask_ret = 0xf; + + switch (result) { + case NVS_FR_POSITION: + /* out_reg POS implied */ + return NV40_VP_INST_DEST_POS; + case NVS_FR_COL0: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_COL0; + return NV40_VP_INST_DEST_COL0; + case NVS_FR_COL1: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_COL1; + return NV40_VP_INST_DEST_COL1; + case NVS_FR_BFC0: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_BFC0; + return NV40_VP_INST_DEST_BFC0; + case NVS_FR_BFC1: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_BFC1; + return NV40_VP_INST_DEST_BFC1; + case NVS_FR_FOGCOORD: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_FOGC; + *mask_ret = 0x8; + return NV40_VP_INST_DEST_FOGC; + case NVS_FR_CLIP0: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP0; + *mask_ret = 0x4; + return NV40_VP_INST_DEST_FOGC; + case NVS_FR_CLIP1: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP1; + *mask_ret = 0x2; + return NV40_VP_INST_DEST_FOGC; + case NVS_FR_CLIP2: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP2; + *mask_ret = 0x1; + return NV40_VP_INST_DEST_FOGC; + case NVS_FR_POINTSZ: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_PSZ; + *mask_ret = 0x8; + return NV40_VP_INST_DEST_PSZ; + case NVS_FR_CLIP3: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP3; + *mask_ret = 0x4; + return NV40_VP_INST_DEST_PSZ; + case NVS_FR_CLIP4: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP4; + *mask_ret = 0x2; + return NV40_VP_INST_DEST_PSZ; + case NVS_FR_CLIP5: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP5; + *mask_ret = 0x1; + return NV40_VP_INST_DEST_PSZ; + case NVS_FR_TEXCOORD0: + case NVS_FR_TEXCOORD1: + case NVS_FR_TEXCOORD2: + case NVS_FR_TEXCOORD3: + case NVS_FR_TEXCOORD4: + case NVS_FR_TEXCOORD5: + case NVS_FR_TEXCOORD6: + case NVS_FR_TEXCOORD7: + { + int unit = result - NVS_FR_TEXCOORD0; + (*out_reg) |= (NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_TEX0 << unit); + return NV40_VP_INST_DEST_TC(unit); + } + default: + WARN_ONCE("unknown vp output %d\n", result); + return NV40_VP_INST_DEST_POS; + } +} + static void NV40VPSetResult(nvsFunc *shader, nvsRegister * dest, unsigned int mask, int slot) @@ -78,29 +168,14 @@ NV40VPSetResult(nvsFunc *shader, nvsRegister * dest, unsigned int mask, if (mask & SMASK_W) hwmask |= (1 << 0); if (dest->file == NVS_FILE_RESULT) { + unsigned int valid_mask; int hwidx; - switch (dest->index) { - case NVS_FR_POSITION : hwidx = NV40_VP_INST_DEST_POS; break; - case NVS_FR_COL0 : hwidx = NV40_VP_INST_DEST_COL0; break; - case NVS_FR_COL1 : hwidx = NV40_VP_INST_DEST_COL1; break; - case NVS_FR_BFC0 : hwidx = NV40_VP_INST_DEST_BFC0; break; - case NVS_FR_BFC1 : hwidx = NV40_VP_INST_DEST_BFC1; break; - case NVS_FR_FOGCOORD : hwidx = NV40_VP_INST_DEST_FOGC; break; - case NVS_FR_POINTSZ : hwidx = NV40_VP_INST_DEST_PSZ; break; - case NVS_FR_TEXCOORD0: hwidx = NV40_VP_INST_DEST_TC(0); break; - case NVS_FR_TEXCOORD1: hwidx = NV40_VP_INST_DEST_TC(1); break; - case NVS_FR_TEXCOORD2: hwidx = NV40_VP_INST_DEST_TC(2); break; - case NVS_FR_TEXCOORD3: hwidx = NV40_VP_INST_DEST_TC(3); break; - case NVS_FR_TEXCOORD4: hwidx = NV40_VP_INST_DEST_TC(4); break; - case NVS_FR_TEXCOORD5: hwidx = NV40_VP_INST_DEST_TC(5); break; - case NVS_FR_TEXCOORD6: hwidx = NV40_VP_INST_DEST_TC(6); break; - case NVS_FR_TEXCOORD7: hwidx = NV40_VP_INST_DEST_TC(7); break; - default: - WARN_ONCE("unknown vtxprog output %d\n", dest->index); - hwidx = 0; - break; - } + hwidx = NV40VPTranslateResultReg(shader, dest->index, &valid_mask); + if (hwmask & ~valid_mask) + WARN_ONCE("writing invalid components of result reg\n"); + hwmask &= valid_mask; + shader->inst[3] &= ~NV40_VP_INST_DEST_MASK; shader->inst[3] |= (hwidx << NV40_VP_INST_DEST_SHIFT); @@ -174,6 +249,7 @@ NV40VPSetSource(nvsFunc *shader, nvsRegister * src, int pos) shader->inst[1] &= ~NV40_VP_INST_INPUT_SRC_MASK; shader->inst[1] |= (src->index << NV40_VP_INST_INPUT_SRC_SHIFT); + shader->card_priv->NV30VP.vp_in_reg |= (1 << src->index); if (src->indexed) { shader->inst[0] |= NV40_VP_INST_INDEX_INPUT; if (src->addr_reg) -- cgit v1.2.3 From 60c28739aa4afe543e0293c15a7aaf84ec2183ea Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 23 Jan 2007 16:25:25 +1100 Subject: nouveau: DPH and CMP for NV40 which doesn't do it natively. --- src/mesa/drivers/dri/nouveau/nouveau_shader_0.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c index 3e542ea9c0..28c6ad803b 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -594,6 +594,30 @@ pass0_emulate_instruction(nouveauShader *nvs, ARITH(NVS_OP_MAX, dest, mask, sat, src[0], nvsNegate(src[0]), nvr_unused); break; + case OPCODE_CMP: + /*XXX: this will clobber CC0... */ + ARITH (NVS_OP_MOV, dest, mask, sat, + src[2], nvr_unused, nvr_unused); + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + ARITHu(NVS_OP_MOV, temp, SMASK_ALL, 0, + src[0], nvr_unused, nvr_unused); + nvsinst->cond_update = 1; + nvsinst->cond_reg = 0; + ARITH (NVS_OP_MOV, dest, mask, sat, + src[1], nvr_unused, nvr_unused); + nvsinst->cond = COND_LT; + nvsinst->cond_reg = 0; + nvsinst->cond_test = 1; + break; + case OPCODE_DPH: + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + ARITHu(NVS_OP_DP3, temp, SMASK_X, 0, + src[0], src[1], nvr_unused); + ARITH (NVS_OP_ADD, dest, mask, sat, + nvsSwizzle(temp, X, X, X, X), + nvsSwizzle(src[1], W, W, W, W), + nvr_unused); + break; case OPCODE_KIL: /* This is only in ARB shaders, so we don't have to worry * about clobbering a CC reg as they aren't supported anyway. -- cgit v1.2.3 From fe9fef2cec2f9ed13370612a9a58df04b0075f15 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 23 Jan 2007 08:57:38 +0100 Subject: i915tex: Fix randr resizing. Rotation still broken. --- src/mesa/drivers/dri/i915tex/intel_context.c | 22 ++++++++++++++++++++-- src/mesa/drivers/dri/i915tex/intel_context.h | 9 +++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c b/src/mesa/drivers/dri/i915tex/intel_context.c index c77d365360..c7ab621919 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.c +++ b/src/mesa/drivers/dri/i915tex/intel_context.c @@ -357,6 +357,10 @@ intelInitContext(struct intel_context *intel, intel->driScreen = sPriv; intel->sarea = saPriv; + intel->width = intelScreen->width; + intel->height = intelScreen->height; + intel->current_rotation = intelScreen->current_rotation; + if (!lockMutexInit) { lockMutexInit = GL_TRUE; _glthread_INIT_MUTEX(lockMutex); @@ -635,12 +639,22 @@ intelContendedLock(struct intel_context *intel, GLuint flags) sarea->rotation != intelScreen->current_rotation) { intelUpdateScreenRotation(sPriv, sarea); + } + + if (sarea->width != intel->width || + sarea->height != intel->height || + sarea->rotation != intel->current_rotation) { - /* + /* + * FIXME: Really only need to do this when drawing to a + * common back- or front buffer. + */ + + /* * This will drop the outstanding batchbuffer on the floor - * FIXME: This should be done for all contexts? */ + driBOUnmap(intel->batch->buffer); intel_batchbuffer_reset(intel->batch); /* lose all primitives */ @@ -653,6 +667,10 @@ intelContendedLock(struct intel_context *intel, GLuint flags) /* force window update */ intel->lastStamp = 0; + + intel->width = sarea->width; + intel->height = sarea->height; + intel->current_rotation = sarea->rotation; } diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h b/src/mesa/drivers/dri/i915tex/intel_context.h index 7654e4ecd5..96b911501f 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.h +++ b/src/mesa/drivers/dri/i915tex/intel_context.h @@ -286,6 +286,15 @@ struct intel_context GLuint swap_missed_count; GLuint swap_scheduled; + + /* Rotation. Need to match that of the + * current screen. + */ + + int width; + int height; + int current_rotation; + }; /* These are functions now: -- cgit v1.2.3 From d46093b8d56f6d89b341d7437c5185ca6be597af Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 23 Jan 2007 09:04:58 +0100 Subject: i915tex: Relocation fixes: Increase the number of allowed relocations per batchbuffer. Fix an assert to avoid an array index overflow. (Reported by Steve Wilkins) --- src/mesa/drivers/dri/i915tex/intel_batchbuffer.c | 2 +- src/mesa/drivers/dri/i915tex/intel_batchbuffer.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c index be2750d041..c92b83bcb3 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c @@ -311,7 +311,7 @@ intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, struct _DriBufferObject *buffer, GLuint flags, GLuint mask, GLuint delta) { - assert(batch->nr_relocs <= MAX_RELOCS); + assert(batch->nr_relocs < MAX_RELOCS); driBOAddListItem(&batch->list, buffer, flags, mask); diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h index a83dbf423d..59261f7274 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h @@ -9,7 +9,7 @@ struct intel_context; #define BATCH_SZ 16384 #define BATCH_RESERVED 16 -#define MAX_RELOCS 100 +#define MAX_RELOCS 400 #define INTEL_BATCH_NO_CLIPRECTS 0x1 #define INTEL_BATCH_CLIPRECTS 0x2 -- cgit v1.2.3 From 18d1fdebebcb52e7fcf50e62c4c02862d173af51 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 23 Jan 2007 11:46:02 -0700 Subject: fixes for C++ warnings/errors --- src/mesa/drivers/x11/glxapi.c | 2 +- src/mesa/main/colortab.c | 4 ++-- src/mesa/main/dlist.c | 4 ++-- src/mesa/main/texcompress_s3tc.c | 2 +- src/mesa/main/texenvprogram.c | 5 +++-- src/mesa/main/texobj.c | 6 +++--- src/mesa/shader/arbprogram.c | 4 ++-- src/mesa/shader/program.c | 2 +- src/mesa/shader/slang/slang_execute.c | 2 +- src/mesa/swrast/s_copypix.c | 4 ++-- src/mesa/swrast/s_depth.c | 4 ++-- src/mesa/swrast/s_drawpix.c | 16 ++++++++++------ src/mesa/swrast/s_readpix.c | 23 +++++++++++++---------- src/mesa/swrast/s_span.c | 8 +++++--- src/mesa/tnl/t_array_api.c | 2 +- src/mesa/tnl/t_vb_arbprogram.c | 3 ++- 16 files changed, 51 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/x11/glxapi.c b/src/mesa/drivers/x11/glxapi.c index 7945f1c5b0..973f394045 100644 --- a/src/mesa/drivers/x11/glxapi.c +++ b/src/mesa/drivers/x11/glxapi.c @@ -241,7 +241,7 @@ glXGetCurrentContext(void) #if defined(GLX_USE_TLS) return CurrentContext; #elif defined(THREADS) - return _glthread_GetTSD(&ContextTSD); + return (GLXContext) _glthread_GetTSD(&ContextTSD); #else return CurrentContext; #endif diff --git a/src/mesa/main/colortab.c b/src/mesa/main/colortab.c index e9349516eb..9fb0baf4a7 100644 --- a/src/mesa/main/colortab.c +++ b/src/mesa/main/colortab.c @@ -472,8 +472,8 @@ _mesa_ColorTable( GLenum target, GLenum internalFormat, _mesa_free_colortable_data(table); if (width > 0) { - table->TableF = _mesa_malloc(comps * width * sizeof(GLfloat)); - table->TableUB = _mesa_malloc(comps * width * sizeof(GLubyte)); + table->TableF = (GLfloat *) _mesa_malloc(comps * width * sizeof(GLfloat)); + table->TableUB = (GLubyte *) _mesa_malloc(comps * width * sizeof(GLubyte)); if (!table->TableF || !table->TableUB) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glColorTable"); diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index dca6ede6cb..ca48403482 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -4476,7 +4476,7 @@ save_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count, ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); if (count > 0) { - unsigned i; + GLint i; const GLfloat * p = params; for (i = 0 ; i < count ; i++) { @@ -4710,7 +4710,7 @@ save_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count, ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); if (count > 0) { - unsigned i; + GLint i; const GLfloat * p = params; for (i = 0 ; i < count ; i++) { diff --git a/src/mesa/main/texcompress_s3tc.c b/src/mesa/main/texcompress_s3tc.c index 99b703de4a..c823967b7a 100644 --- a/src/mesa/main/texcompress_s3tc.c +++ b/src/mesa/main/texcompress_s3tc.c @@ -91,7 +91,7 @@ _mesa_dlopen(const char *libname, int flags) return dlopen(libname, flags); #endif #else - return (GenericFunc) NULL; + return NULL; #endif /* USE_EXTERNAL_DXTN_LIB */ } diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c index 5329719cbb..5038b9b0c3 100644 --- a/src/mesa/main/texenvprogram.c +++ b/src/mesa/main/texenvprogram.c @@ -1184,13 +1184,14 @@ static void cache_item( struct texenvprog_cache *cache, const struct state_key *key, void *data ) { - struct texenvprog_cache_item *c = MALLOC(sizeof(*c)); + struct texenvprog_cache_item *c + = (struct texenvprog_cache_item *) MALLOC(sizeof(*c)); c->hash = hash; c->key = _mesa_malloc(sizeof(*key)); memcpy(c->key, key, sizeof(*key)); - c->data = data; + c->data = (struct gl_fragment_program *) data; if (cache->n_items > cache->size * 1.5) { if (cache->size < 1000) diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c index 1d27cd3f7c..3cfbfa5eb5 100644 --- a/src/mesa/main/texobj.c +++ b/src/mesa/main/texobj.c @@ -699,7 +699,7 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures) = _mesa_lookup_texture(ctx, textures[i]); if (delObj) { - GLboolean delete; + GLboolean deleted; _mesa_lock_texture(ctx, delObj); @@ -728,14 +728,14 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures) * XXX all RefCount accesses should be protected by a mutex. */ delObj->RefCount--; - delete = (delObj->RefCount == 0); + deleted = (delObj->RefCount == 0); _mesa_unlock_texture(ctx, delObj); /* We know that refcount went to zero above, so this is * the only pointer left to delObj, so we don't have to * worry about locking any more: */ - if (delete) { + if (deleted) { ASSERT(delObj->Name != 0); /* Never delete default tex objs */ ASSERT(ctx->Driver.DeleteTexture); (*ctx->Driver.DeleteTexture)(ctx, delObj); diff --git a/src/mesa/shader/arbprogram.c b/src/mesa/shader/arbprogram.c index bff80d7ee3..91f3a5e8ee 100644 --- a/src/mesa/shader/arbprogram.c +++ b/src/mesa/shader/arbprogram.c @@ -312,7 +312,7 @@ _mesa_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count, const GLfloat *params) { GET_CURRENT_CONTEXT(ctx); - unsigned i; + GLint i; GLfloat * dest; ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -464,7 +464,7 @@ _mesa_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count, { GET_CURRENT_CONTEXT(ctx); struct gl_program *prog; - unsigned i; + GLint i; ASSERT_OUTSIDE_BEGIN_END(ctx); FLUSH_VERTICES(ctx, _NEW_PROGRAM); diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index 8442ba3248..d301f19090 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -1810,7 +1810,7 @@ _mesa_print_program(const struct gl_program *prog) void _mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog) { - GLint i; + GLuint i; _mesa_printf("NumInstructions=%d\n", prog->NumInstructions); _mesa_printf("NumTemporaries=%d\n", prog->NumTemporaries); diff --git a/src/mesa/shader/slang/slang_execute.c b/src/mesa/shader/slang/slang_execute.c index e469de0207..3ffa4b88bf 100644 --- a/src/mesa/shader/slang/slang_execute.c +++ b/src/mesa/shader/slang/slang_execute.c @@ -328,7 +328,7 @@ static GLvoid ensure_infolog_created(slang_info_log ** infolog) { if (*infolog == NULL) { - *infolog = slang_alloc_malloc(sizeof(slang_info_log)); + *infolog = (slang_info_log *) slang_alloc_malloc(sizeof(slang_info_log)); if (*infolog == NULL) return; slang_info_log_construct(*infolog); diff --git a/src/mesa/swrast/s_copypix.c b/src/mesa/swrast/s_copypix.c index 761ab724e9..7e8ebb4477 100644 --- a/src/mesa/swrast/s_copypix.c +++ b/src/mesa/swrast/s_copypix.c @@ -860,8 +860,8 @@ fast_copy_pixels(GLcontext *ctx, } /* clipping not supported */ - if (srcX < 0 || srcX + width > srcFb->Width || - srcY < 0 || srcY + height > srcFb->Height || + if (srcX < 0 || srcX + width > (GLint) srcFb->Width || + srcY < 0 || srcY + height > (GLint) srcFb->Height || dstX < dstFb->_Xmin || dstX + width > dstFb->_Xmax || dstY < dstFb->_Ymin || dstY + height > dstFb->_Ymax) { return GL_FALSE; diff --git a/src/mesa/swrast/s_depth.c b/src/mesa/swrast/s_depth.c index cb584b5de8..408174c990 100644 --- a/src/mesa/swrast/s_depth.c +++ b/src/mesa/swrast/s_depth.c @@ -1289,7 +1289,7 @@ _swrast_read_depth_span_uint( GLcontext *ctx, struct gl_renderbuffer *rb, GLint dx = -x; GLint i; for (i = 0; i < dx; i++) - depth[i] = 0.0; + depth[i] = 0; x = 0; n -= dx; depth += dx; @@ -1298,7 +1298,7 @@ _swrast_read_depth_span_uint( GLcontext *ctx, struct gl_renderbuffer *rb, GLint dx = x + n - (GLint) rb->Width; GLint i; for (i = 0; i < dx; i++) - depth[n - i - 1] = 0.0; + depth[n - i - 1] = 0; n -= dx; } if (n <= 0) { diff --git a/src/mesa/swrast/s_drawpix.c b/src/mesa/swrast/s_drawpix.c index bdb2558351..d945a871ae 100644 --- a/src/mesa/swrast/s_drawpix.c +++ b/src/mesa/swrast/s_drawpix.c @@ -110,8 +110,9 @@ fast_draw_rgba_pixels(GLcontext *ctx, GLint x, GLint y, */ if (format == GL_RGBA && type == rbType) { - const GLubyte *src = _mesa_image_address2d(&unpack, pixels, width, - height, format, type, 0, 0); + const GLubyte *src + = (const GLubyte *) _mesa_image_address2d(&unpack, pixels, width, + height, format, type, 0, 0); const GLint srcStride = _mesa_image_row_stride(&unpack, width, format, type); if (simpleZoom) { @@ -139,8 +140,9 @@ fast_draw_rgba_pixels(GLcontext *ctx, GLint x, GLint y, } if (format == GL_RGB && type == rbType) { - const GLubyte *src = _mesa_image_address2d(&unpack, pixels, width, - height, format, type, 0, 0); + const GLubyte *src + = (const GLubyte *) _mesa_image_address2d(&unpack, pixels, width, + height, format, type, 0, 0); const GLint srcStride = _mesa_image_row_stride(&unpack, width, format, type); if (simpleZoom) { @@ -640,8 +642,10 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y, /* if the span is wider than MAX_WIDTH we have to do it in chunks */ while (skipPixels < width) { const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH); - const GLubyte *source = _mesa_image_address2d(unpack, pixels, - width, height, format, type, 0, skipPixels); + const GLubyte *source + = (const GLubyte *) _mesa_image_address2d(unpack, pixels, + width, height, format, + type, 0, skipPixels); GLint row; for (row = 0; row < height; row++) { diff --git a/src/mesa/swrast/s_readpix.c b/src/mesa/swrast/s_readpix.c index 128ce0afb3..27f4736c39 100644 --- a/src/mesa/swrast/s_readpix.c +++ b/src/mesa/swrast/s_readpix.c @@ -94,8 +94,8 @@ read_depth_pixels( GLcontext *ctx, /* clipping should have been done already */ ASSERT(x >= 0); ASSERT(y >= 0); - ASSERT(x + width <= rb->Width); - ASSERT(y + height <= rb->Height); + ASSERT(x + width <= (GLint) rb->Width); + ASSERT(y + height <= (GLint) rb->Height); /* width should never be > MAX_WIDTH since we did clipping earlier */ ASSERT(width <= MAX_WIDTH); @@ -210,8 +210,8 @@ fast_read_rgba_pixels( GLcontext *ctx, ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB); /* clipping should have already been done */ - ASSERT(x + width <= rb->Width); - ASSERT(y + height <= rb->Height); + ASSERT(x + width <= (GLint) rb->Width); + ASSERT(y + height <= (GLint) rb->Height); /* check for things we can't handle here */ if (transferOps || @@ -223,8 +223,9 @@ fast_read_rgba_pixels( GLcontext *ctx, if (format == GL_RGBA && rb->DataType == type) { const GLint dstStride = _mesa_image_row_stride(packing, width, format, type); - GLubyte *dest = _mesa_image_address2d(packing, pixels, width, height, - format, type, 0, 0); + GLubyte *dest + = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height, + format, type, 0, 0); GLint row; ASSERT(rb->GetRow); for (row = 0; row < height; row++) { @@ -239,8 +240,9 @@ fast_read_rgba_pixels( GLcontext *ctx, type == GL_UNSIGNED_BYTE) { const GLint dstStride = _mesa_image_row_stride(packing, width, format, type); - GLubyte *dest = _mesa_image_address2d(packing, pixels, width, height, - format, type, 0, 0); + GLubyte *dest + = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height, + format, type, 0, 0); GLint row; ASSERT(rb->GetRow); for (row = 0; row < height; row++) { @@ -396,8 +398,9 @@ read_rgba_pixels( GLcontext *ctx, = _mesa_image_row_stride(packing, width, format, type); GLfloat (*rgba)[4] = swrast->SpanArrays->color.sz4.rgba; GLint row; - GLubyte *dst = _mesa_image_address2d(packing, pixels, width, height, - format, type, 0, 0); + GLubyte *dst + = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height, + format, type, 0, 0); for (row = 0; row < height; row++, y++) { diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index c74b98facf..cca1864ea4 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -1814,7 +1814,9 @@ _swrast_get_values(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint i, inCount = 0, inStart = 0; for (i = 0; i < count; i++) { - if (x[i] >= 0 && y[i] >= 0 && x[i] < rb->Width && y[i] < rb->Height) { + if (x[i] >= 0 && y[i] >= 0 && + x[i] < (GLint) rb->Width && + y[i] < (GLint) rb->Height) { /* inside */ if (inCount == 0) inStart = i; @@ -1848,10 +1850,10 @@ _swrast_put_row(GLcontext *ctx, struct gl_renderbuffer *rb, { GLint skip = 0; - if (y < 0 || y >= rb->Height) + if (y < 0 || (GLint) y >= rb->Height) return; /* above or below */ - if (x + (GLint) count <= 0 || x >= rb->Width) + if (x + (GLint) count <= 0 || x >= (GLint) rb->Width) return; /* entirely left or right */ if (x + count > rb->Width) { diff --git a/src/mesa/tnl/t_array_api.c b/src/mesa/tnl/t_array_api.c index 6826cf7e24..087f6af08c 100644 --- a/src/mesa/tnl/t_array_api.c +++ b/src/mesa/tnl/t_array_api.c @@ -298,7 +298,7 @@ _tnl_DrawRangeElements(GLenum mode, #ifdef DEBUG /* check that array indices really fall inside [start, end] range */ { - GLuint i; + GLint i; for (i = 0; i < count; i++) { if (ui_indices[i] < start || ui_indices[i] > end) { _mesa_warning(ctx, "Invalid array index in " diff --git a/src/mesa/tnl/t_vb_arbprogram.c b/src/mesa/tnl/t_vb_arbprogram.c index bf4c1d5223..524472a777 100644 --- a/src/mesa/tnl/t_vb_arbprogram.c +++ b/src/mesa/tnl/t_vb_arbprogram.c @@ -1056,7 +1056,7 @@ static void compile_vertex_program( struct gl_vertex_program *program, { struct compilation cp; struct tnl_compiled_program *p = CALLOC_STRUCT(tnl_compiled_program); - GLuint i; + GLint i; if (program->TnlData) free_tnl_data( program ); @@ -1290,6 +1290,7 @@ run_arb_vertex_program(GLcontext *ctx, struct tnl_pipeline_stage *stage) call_func( p, m ); } else { + GLint j; for (j = 0; j < p->nr_instructions; j++) { union instruction inst = p->instructions[j]; opcode_func[inst.alu.opcode]( m, inst ); -- cgit v1.2.3 From 7e85b0a025a82c3ffed060a757a3b4adae03d269 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 23 Jan 2007 12:50:08 -0700 Subject: silence C++ warnings --- src/mesa/main/bufferobj.c | 4 ++-- src/mesa/swrast/s_atifragshader.c | 5 +++-- src/mesa/swrast/s_buffers.c | 5 ++++- src/mesa/swrast/s_context.c | 4 ++-- src/mesa/swrast/s_stencil.c | 12 +++++++----- src/mesa/swrast/s_zoom.c | 16 ++++++++-------- 6 files changed, 26 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c index 3f9f798546..009055a6ab 100644 --- a/src/mesa/main/bufferobj.c +++ b/src/mesa/main/bufferobj.c @@ -119,7 +119,7 @@ buffer_object_subdata_range_good( GLcontext * ctx, GLenum target, _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller); return NULL; } - if ((GLuint) (offset + size) > bufObj->Size) { + if (offset + size > bufObj->Size) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(size + offset > buffer size)", caller); return NULL; @@ -297,7 +297,7 @@ _mesa_buffer_subdata( GLcontext *ctx, GLenum target, GLintptrARB offset, (void) ctx; (void) target; /* this should have been caught in _mesa_BufferSubData() */ - ASSERT((GLuint) (size + offset) <= bufObj->Size); + ASSERT(size + offset <= bufObj->Size); if (bufObj->Data) { _mesa_memcpy( (GLubyte *) bufObj->Data + offset, data, size ); diff --git a/src/mesa/swrast/s_atifragshader.c b/src/mesa/swrast/s_atifragshader.c index 75df50b0ba..467b8652d8 100644 --- a/src/mesa/swrast/s_atifragshader.c +++ b/src/mesa/swrast/s_atifragshader.c @@ -325,7 +325,8 @@ execute_shader(GLcontext *ctx, const struct ati_fragment_shader *shader, struct atifs_instruction *inst; struct atifs_setupinst *texinst; GLint optype; - GLint i, j, pass; + GLuint i; + GLint j, pass; GLint dstreg; GLfloat src[2][3][4]; GLfloat zeros[4] = { 0.0, 0.0, 0.0, 0.0 }; @@ -348,7 +349,7 @@ execute_shader(GLcontext *ctx, const struct ati_fragment_shader *shader, /* setup the source registers for color and alpha ops */ for (optype = 0; optype < 2; optype++) { - for (i = 0; i < inst->ArgCount[optype]; i++) { + for (i = 0; i < inst->ArgCount[optype]; i++) { GLint index = inst->SrcReg[optype][i].Index; if (index >= GL_REG_0_ATI && index <= GL_REG_5_ATI) diff --git a/src/mesa/swrast/s_buffers.c b/src/mesa/swrast/s_buffers.c index 284ea2b517..35f2dd6490 100644 --- a/src/mesa/swrast/s_buffers.c +++ b/src/mesa/swrast/s_buffers.c @@ -80,7 +80,10 @@ clear_rgba_buffer_with_masking(GLcontext *ctx, struct gl_renderbuffer *rb) else { ASSERT(span.array->ChanType == GL_FLOAT); for (i = 0; i < width; i++) { - COPY_4V(span.array->rgba[i], ctx->Color.ClearColor); + CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][0], ctx->Color.ClearColor[0]); + CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][1], ctx->Color.ClearColor[1]); + CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][2], ctx->Color.ClearColor[2]); + CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][3], ctx->Color.ClearColor[3]); } } diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c index d4b8080ddc..1c9a098a2d 100644 --- a/src/mesa/swrast/s_context.c +++ b/src/mesa/swrast/s_context.c @@ -401,7 +401,7 @@ _swrast_validate_texture_images(GLcontext *ctx) GLuint numFaces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; GLuint face; for (face = 0; face < numFaces; face++) { - GLuint lvl; + GLint lvl; for (lvl = texObj->BaseLevel; lvl <= texObj->_MaxLevel; lvl++) { struct gl_texture_image *texImg = texObj->Image[face][lvl]; if (texImg && !texImg->Data) { @@ -439,7 +439,7 @@ _swrast_eject_texture_images(GLcontext *ctx) GLuint numFaces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; GLuint face; for (face = 0; face < numFaces; face++) { - GLuint lvl; + GLint lvl; for (lvl = texObj->BaseLevel; lvl <= texObj->_MaxLevel; lvl++) { struct gl_texture_image *texImg = texObj->Image[face][lvl]; if (texImg && texImg->Data) { diff --git a/src/mesa/swrast/s_stencil.c b/src/mesa/swrast/s_stencil.c index dbab6b3c20..a8aa1d4b6d 100644 --- a/src/mesa/swrast/s_stencil.c +++ b/src/mesa/swrast/s_stencil.c @@ -1062,7 +1062,8 @@ void _swrast_read_stencil_span(GLcontext *ctx, struct gl_renderbuffer *rb, GLint n, GLint x, GLint y, GLstencil stencil[]) { - if (y < 0 || y >= rb->Height || x + n <= 0 || x >= rb->Width) { + if (y < 0 || y >= (GLint) rb->Height || + x + n <= 0 || x >= (GLint) rb->Width) { /* span is completely outside framebuffer */ return; /* undefined values OK */ } @@ -1073,7 +1074,7 @@ _swrast_read_stencil_span(GLcontext *ctx, struct gl_renderbuffer *rb, n -= dx; stencil += dx; } - if (x + n > rb->Width) { + if (x + n > (GLint) rb->Width) { GLint dx = x + n - rb->Width; n -= dx; } @@ -1103,7 +1104,8 @@ _swrast_write_stencil_span(GLcontext *ctx, GLint n, GLint x, GLint y, const GLuint stencilMax = (1 << fb->Visual.stencilBits) - 1; const GLuint stencilMask = ctx->Stencil.WriteMask[0]; - if (y < 0 || y >= rb->Height || x + n <= 0 || x >= rb->Width) { + if (y < 0 || y >= (GLint) rb->Height || + x + n <= 0 || x >= (GLint) rb->Width) { /* span is completely outside framebuffer */ return; /* undefined values OK */ } @@ -1113,7 +1115,7 @@ _swrast_write_stencil_span(GLcontext *ctx, GLint n, GLint x, GLint y, n -= dx; stencil += dx; } - if (x + n > rb->Width) { + if (x + n > (GLint) rb->Width) { GLint dx = x + n - rb->Width; n -= dx; } @@ -1191,7 +1193,7 @@ _swrast_clear_stencil_buffer( GLcontext *ctx, struct gl_renderbuffer *rb ) } else { /* no bit masking */ - if (width == rb->Width && rb->DataType == GL_UNSIGNED_BYTE) { + if (width == (GLint) rb->Width && rb->DataType == GL_UNSIGNED_BYTE) { /* optimized case */ /* Note: bottom-to-top raster assumed! */ GLubyte *stencil = (GLubyte *) rb->GetPointer(ctx, rb, x, y); diff --git a/src/mesa/swrast/s_zoom.c b/src/mesa/swrast/s_zoom.c index 29b8df41b7..036a6084dc 100644 --- a/src/mesa/swrast/s_zoom.c +++ b/src/mesa/swrast/s_zoom.c @@ -209,7 +209,7 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span, for (i = 0; i < zoomedWidth; i++) { GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; ASSERT(j >= 0); - ASSERT(j < span->end); + ASSERT(j < (GLint) span->end); COPY_4UBV(zoomed.array->color.sz1.rgba[i], rgba[j]); } } @@ -219,7 +219,7 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span, for (i = 0; i < zoomedWidth; i++) { GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; ASSERT(j >= 0); - ASSERT(j < span->end); + ASSERT(j < (GLint) span->end); COPY_4V(zoomed.array->color.sz2.rgba[i], rgba[j]); } } @@ -229,7 +229,7 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span, for (i = 0; i < zoomedWidth; i++) { GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; ASSERT(j >= 0); - ASSERT(j < span->end); + ASSERT(j < (GLint) span->end); COPY_4V(zoomed.array->color.sz4.rgba[i], rgba[j]); } } @@ -241,7 +241,7 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span, for (i = 0; i < zoomedWidth; i++) { GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; ASSERT(j >= 0); - ASSERT(j < span->end); + ASSERT(j < (GLint) span->end); zoomed.array->color.sz1.rgba[i][0] = rgb[j][0]; zoomed.array->color.sz1.rgba[i][1] = rgb[j][1]; zoomed.array->color.sz1.rgba[i][2] = rgb[j][2]; @@ -254,7 +254,7 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span, for (i = 0; i < zoomedWidth; i++) { GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; ASSERT(j >= 0); - ASSERT(j < span->end); + ASSERT(j < (GLint) span->end); zoomed.array->color.sz2.rgba[i][0] = rgb[j][0]; zoomed.array->color.sz2.rgba[i][1] = rgb[j][1]; zoomed.array->color.sz2.rgba[i][2] = rgb[j][2]; @@ -267,7 +267,7 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span, for (i = 0; i < zoomedWidth; i++) { GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; ASSERT(j >= 0); - ASSERT(j < span->end); + ASSERT(j < (GLint) span->end); zoomed.array->color.sz4.rgba[i][0] = rgb[j][0]; zoomed.array->color.sz4.rgba[i][1] = rgb[j][1]; zoomed.array->color.sz4.rgba[i][2] = rgb[j][2]; @@ -281,7 +281,7 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span, for (i = 0; i < zoomedWidth; i++) { GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; ASSERT(j >= 0); - ASSERT(j < span->end); + ASSERT(j < (GLint) span->end); zoomed.array->index[i] = indexes[j]; } } @@ -291,7 +291,7 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span, for (i = 0; i < zoomedWidth; i++) { GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; ASSERT(j >= 0); - ASSERT(j < span->end); + ASSERT(j < (GLint) span->end); zoomed.array->z[i] = zValues[j]; } /* Now, fall into either the RGB or COLOR_INDEX path below */ -- cgit v1.2.3 From bdc5394d22d7bc1215c9a38f735a419c9063ab05 Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Wed, 24 Jan 2007 15:47:15 +0800 Subject: 965 ARB_Occlusion_query fix --- src/mesa/drivers/dri/i965/intel_context.c | 27 ++++++++++++++++----------- src/mesa/drivers/dri/i965/intel_context.h | 2 +- src/mesa/drivers/dri/i965/intel_screen.c | 6 ++---- 3 files changed, 19 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 459ed109ed..388600dbbe 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -184,9 +184,17 @@ const struct dri_extension card_extensions[] = { NULL, NULL } }; -static const struct dri_extension arb_oc_extension = +const struct dri_extension arb_oc_extension = { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions}; +void intelInitExtensions(GLcontext *ctx, GLboolean enable_imaging) +{ + struct intel_context *intel = ctx?intel_context(ctx):NULL; + driInitExtensions(ctx, card_extensions, enable_imaging); + if (!ctx || intel->intelScreen->drmMinor >= 8) + driInitSingleExtension (ctx, &arb_oc_extension); +} + static const struct dri_debug_control debug_control[] = { { "fall", DEBUG_FALLBACKS }, @@ -248,28 +256,29 @@ static void intelBeginQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) { struct intel_context *intel = intel_context( ctx ); - GLuint64EXT tmp = 0; drmI830MMIO io = { .read_write = MMIO_WRITE, .reg = MMIO_REGS_PS_DEPTH_COUNT, - .data = &tmp + .data = &q->Result }; intel->stats_wm = GL_TRUE; intelFinish(&intel->ctx); - drmCommandWrite(intel->driFd, DRM_I830_MMIO, &io, sizeof(io)); + drmCommandRead(intel->driFd, DRM_I830_MMIO, &io, sizeof(io)); } static void intelEndQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) { struct intel_context *intel = intel_context( ctx ); + GLuint64EXT tmp; drmI830MMIO io = { .read_write = MMIO_READ, .reg = MMIO_REGS_PS_DEPTH_COUNT, - .data = &q->Result + .data = &tmp }; intelFinish(&intel->ctx); drmCommandRead(intel->driFd, DRM_I830_MMIO, &io, sizeof(io)); + q->Result = tmp - q->Result; q->Ready = GL_TRUE; intel->stats_wm = GL_FALSE; } @@ -409,12 +418,7 @@ GLboolean intelInitContext( struct intel_context *intel, _mesa_printf("IRQs not active. Exiting\n"); exit(1); } - - driInitExtensions( ctx, card_extensions, - GL_TRUE ); - - if (intel->intelScreen->drmMinor >= 8) - driInitSingleExtension (ctx, &arb_oc_extension); + intelInitExtensions(ctx, GL_TRUE); INTEL_DEBUG = driParseDebugString( getenv( "INTEL_DEBUG" ), debug_control ); @@ -693,3 +697,4 @@ void UNLOCK_HARDWARE( struct intel_context *intel ) _glthread_UNLOCK_MUTEX(lockMutex); } + diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h index fe7ee382a1..d51536c3fe 100644 --- a/src/mesa/drivers/dri/i965/intel_context.h +++ b/src/mesa/drivers/dri/i965/intel_context.h @@ -500,6 +500,7 @@ void intelBitmap(GLcontext * ctx, const struct gl_pixelstore_attrib *unpack, const GLubyte * pixels); +void intelInitExtensions(GLcontext *ctx, GLboolean enable_imaging); #define _NEW_WINDOW_POS 0x40000000 @@ -522,6 +523,5 @@ static inline struct intel_texture_image *intel_texture_image( struct gl_texture return (struct intel_texture_image *)img; } - #endif diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c index 8269deba66..08f0bb340f 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.c +++ b/src/mesa/drivers/dri/i965/intel_screen.c @@ -38,6 +38,7 @@ #include "intel_screen.h" +#include "intel_context.h" #include "intel_tex.h" #include "intel_span.h" #include "intel_ioctl.h" @@ -61,8 +62,6 @@ const GLuint __driNConfigOptions = 4; static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; #endif /*USE_NEW_INTERFACE*/ -extern const struct dri_extension card_extensions[]; - /** * Map all the memory regions described by the screen. * \return GL_TRUE if success, GL_FALSE if error. @@ -687,7 +686,6 @@ void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIsc (dri_priv->cpp == 2) ? 16 : 24, (dri_priv->cpp == 2) ? 0 : 8, GL_TRUE ); - /* Calling driInitExtensions here, with a NULL context pointer, does not actually * enable the extensions. It just makes sure that all the dispatch offsets for all * the extensions that *might* be enables are known. This is needed because the @@ -696,7 +694,7 @@ void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIsc * * Hello chicken. Hello egg. How are you two today? */ - driInitExtensions( NULL, card_extensions, GL_FALSE ); + intelInitExtensions(NULL, GL_FALSE); } return (void *) psp; -- cgit v1.2.3 From 844e5610de6ffe6966072d120b50db541ea85104 Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Wed, 24 Jan 2007 16:07:43 +0800 Subject: 965 glxswapcontrol fix --- src/mesa/drivers/dri/i965/intel_context.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 388600dbbe..f7ab7d3b7d 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -61,6 +61,7 @@ #include "bufmgr.h" #include "utils.h" +#include "vblank.h" #ifndef INTEL_DEBUG int INTEL_DEBUG = (0); #endif @@ -336,6 +337,11 @@ GLboolean intelInitContext( struct intel_context *intel, intel->driScreen = sPriv; intel->sarea = saPriv; + driParseConfigFiles (&intel->optionCache, &intelScreen->optionCache, + intel->driScreen->myNum, "i965"); + + intel->vblank_flags = (intel->intelScreen->irq_active != 0) + ? driGetDefaultVBlankFlags(&intel->optionCache) : VBLANK_FLAG_NO_IRQ; ctx->Const.MaxTextureMaxAnisotropy = 2.0; @@ -563,6 +569,9 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv, if ( intel->driDrawable != driDrawPriv ) { /* Shouldn't the readbuffer be stored also? */ + driDrawableInitVBlank( driDrawPriv, intel->vblank_flags, + &intel->vbl_seq ); + intel->driDrawable = driDrawPriv; intelWindowMoved( intel ); } -- cgit v1.2.3 From 42bd32dad7f2bd9b4c4df8a7394328d31748f1f5 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 25 Jan 2007 11:56:45 +1100 Subject: nouveau: some extra debug output --- src/mesa/drivers/dri/nouveau/nouveau_screen.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c index 781ba0113f..2d14a9d84d 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -339,8 +339,11 @@ void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIsc } // temporary lock step versioning - if (drm_expected.patch!=drm_version->patch) + if (drm_expected.patch!=drm_version->patch) { + __driUtilMessage("%s: wrong DRM version, expected %d, got %d\n", + drm_expected.patch, drm_version->patch); return NULL; + } psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, ddx_version, dri_version, drm_version, -- cgit v1.2.3 From 2d7687865e8831e365756f1270c03ee70298ba4c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 25 Jan 2007 12:08:49 +1100 Subject: nouveau: and here's the "oops, I suck" commit :) --- src/mesa/drivers/dri/nouveau/nouveau_screen.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c index 2d14a9d84d..881b20149f 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -341,6 +341,7 @@ void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIsc // temporary lock step versioning if (drm_expected.patch!=drm_version->patch) { __driUtilMessage("%s: wrong DRM version, expected %d, got %d\n", + __func__, drm_expected.patch, drm_version->patch); return NULL; } -- cgit v1.2.3 From 86996dfe32fccd5777dd0e410b5dbe964fb206d1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 25 Jan 2007 13:40:51 +1100 Subject: nouveau: add result scaling to shader backend, use it in RSQ emul for NV40. --- src/mesa/drivers/dri/nouveau/nouveau_shader.c | 2 +- src/mesa/drivers/dri/nouveau/nouveau_shader.h | 13 ++++++++++++ src/mesa/drivers/dri/nouveau/nouveau_shader_0.c | 17 +++------------- src/mesa/drivers/dri/nouveau/nouveau_shader_2.c | 4 ++++ src/mesa/drivers/dri/nouveau/nv40_fragprog.c | 27 +++++++++++++++++++++++++ src/mesa/drivers/dri/nouveau/nv40_shader.h | 4 ++-- 6 files changed, 50 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.c b/src/mesa/drivers/dri/nouveau/nouveau_shader.c index f911347d62..cdb79fca1e 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.c @@ -179,7 +179,7 @@ nvsBuildTextShader(GLcontext *ctx, GLenum target, const char *text) strlen(text), &nvs->mesa.vp); } else if (target == GL_FRAGMENT_PROGRAM_ARB) { - _mesa_init_fragment_program(ctx, &nvs->mesa.fp, GL_VERTEX_PROGRAM_ARB, 0); + _mesa_init_fragment_program(ctx, &nvs->mesa.fp, GL_FRAGMENT_PROGRAM_ARB, 0); _mesa_parse_arb_fragment_program(ctx, GL_FRAGMENT_PROGRAM_ARB, text, diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h index 8b4be9dfe7..7329ccd9ea 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -194,6 +194,16 @@ typedef enum { NVS_TEX_TARGET_UNKNOWN = 0 } nvsTexTarget; +typedef enum { + NVS_SCALE_1X = 0, + NVS_SCALE_2X = 1, + NVS_SCALE_4X = 2, + NVS_SCALE_8X = 3, + NVS_SCALE_INV_2X = 5, + NVS_SCALE_INV_4X = 6, + NVS_SCALE_INV_8X = 7, +} nvsScale; + /* Arith/TEX instructions */ typedef struct nvs_instruction { nvsFragmentHeader header; @@ -203,6 +213,7 @@ typedef struct nvs_instruction { nvsRegister dest; unsigned int mask; + nvsScale dest_scale; nvsRegister src[3]; @@ -307,6 +318,7 @@ struct _nvsFunc { void (*InitInstruction) (nvsFunc *); int (*SupportsOpcode) (nvsFunc *, nvsOpcode); + int (*SupportsResultScale) (nvsFunc *, nvsScale); void (*SetOpcode) (nvsFunc *, unsigned int opcode, int slot); void (*SetCCUpdate) (nvsFunc *); @@ -314,6 +326,7 @@ struct _nvsFunc { nvsSwzComp *swizzle); void (*SetResult) (nvsFunc *, nvsRegister *, unsigned int mask, int slot); + void (*SetResultScale) (nvsFunc *, nvsScale); void (*SetSource) (nvsFunc *, nvsRegister *, int pos); void (*SetTexImageUnit) (nvsFunc *, int unit); void (*SetSaturate) (nvsFunc *); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c index 28c6ad803b..3bcc2ba755 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -402,6 +402,7 @@ pass0_emit(nouveauShader *nvs, nvsFragmentHeader *parent, int fpos, sif->saturate = saturate; sif->dest = dst; sif->mask = mask; + sif->dest_scale = NVS_SCALE_1X; sif->src[0] = src0; sif->src[1] = src1; sif->src[2] = src2; @@ -667,25 +668,13 @@ pass0_emulate_instruction(nouveauShader *nvs, } break; case OPCODE_RSQ: - if (rec->const_half.file != NVS_FILE_CONST) { - GLfloat const_half[4] = { 0.5, 0.0, 0.0, 0.0 }; - pass0_make_reg(nvs, &rec->const_half, NVS_FILE_CONST, - _mesa_add_unnamed_constant( - nvs->mesa.vp.Base.Parameters, - const_half, 4)); - COPY_4V(nvs->params[rec->const_half.index].val, - const_half); - } pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); ARITHu(NVS_OP_LG2, temp, SMASK_X, 0, nvsAbs(nvsSwizzle(src[0], X, X, X, X)), nvr_unused, nvr_unused); - ARITHu(NVS_OP_MUL, temp, SMASK_X, 0, - nvsSwizzle(temp, X, X, X, X), - nvsNegate(rec->const_half), - nvr_unused); + nvsinst->dest_scale = NVS_SCALE_INV_2X; ARITH (NVS_OP_EX2, dest, mask, sat, - nvsSwizzle(temp, X, X, X, X), + nvsNegate(nvsSwizzle(temp, X, X, X, X)), nvr_unused, nvr_unused); break; case OPCODE_SCS: diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c index c106fd2d94..b043f877e4 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c @@ -135,6 +135,10 @@ pass2_add_instruction(nvsPtr nvs, nvsInstruction *inst, reg = pass2_mangle_reg(nvs, inst, inst->dest); shader->SetResult(shader, ®, inst->mask, slot); + + if (inst->dest_scale != NVS_SCALE_1X) { + shader->SetResultScale(shader, inst->dest_scale); + } } static int diff --git a/src/mesa/drivers/dri/nouveau/nv40_fragprog.c b/src/mesa/drivers/dri/nouveau/nv40_fragprog.c index 8bca6ae938..3e4ae0496e 100644 --- a/src/mesa/drivers/dri/nouveau/nv40_fragprog.c +++ b/src/mesa/drivers/dri/nouveau/nv40_fragprog.c @@ -11,6 +11,30 @@ struct _op_xlat NVFP_TX_BOP[64]; * - These extend the NV30 routines, which are almost identical. NV40 * just has branching hacked into the instruction set. */ +static int +NV40FPSupportsResultScale(nvsFunc *shader, nvsScale scale) +{ + switch (scale) { + case NVS_SCALE_1X: + case NVS_SCALE_2X: + case NVS_SCALE_4X: + case NVS_SCALE_8X: + case NVS_SCALE_INV_2X: + case NVS_SCALE_INV_4X: + case NVS_SCALE_INV_8X: + return 1; + default: + return 0; + } +} + +static void +NV40FPSetResultScale(nvsFunc *shader, nvsScale scale) +{ + shader->inst[2] &= ~NV40_FP_OP_DST_SCALE_MASK; + shader->inst[2] |= ((unsigned int)scale << NV40_FP_OP_DST_SCALE_SHIFT); +} + static void NV40FPSetBranchTarget(nvsFunc *shader, int addr) { @@ -179,6 +203,9 @@ NV40FPInitShaderFuncs(nvsFunc * shader) MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_REP , NVS_OP_REP , -1, -1, -1); MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_RET , NVS_OP_RET , -1, -1, -1); + shader->SupportsResultScale = NV40FPSupportsResultScale; + shader->SetResultScale = NV40FPSetResultScale; + /* fragment.facing */ shader->GetSourceID = NV40FPGetSourceID; diff --git a/src/mesa/drivers/dri/nouveau/nv40_shader.h b/src/mesa/drivers/dri/nouveau/nv40_shader.h index 2a2b5639b6..584f4c23e0 100644 --- a/src/mesa/drivers/dri/nouveau/nv40_shader.h +++ b/src/mesa/drivers/dri/nouveau/nv40_shader.h @@ -399,8 +399,8 @@ /* high order bits of SRC1 */ #define NV40_FP_OP_OPCODE_IS_BRANCH (1<<31) -#define NV40_FP_OP_SRC_SCALE_SHIFT 28 -#define NV40_FP_OP_SRC_SCALE_MASK (3 << 28) +#define NV40_FP_OP_DST_SCALE_SHIFT 28 +#define NV40_FP_OP_DST_SCALE_MASK (3 << 28) /* SRC1 LOOP */ #define NV40_FP_OP_LOOP_INCR_SHIFT 19 -- cgit v1.2.3 From d5db167c2cf9243c3153efb29582df72d819e7ac Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 25 Jan 2007 15:12:49 +1100 Subject: nouveau: unbreak NOUVEAU_RING_DEBUG --- src/mesa/drivers/dri/nouveau/nouveau_sync.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.c b/src/mesa/drivers/dri/nouveau/nouveau_sync.c index 0bf20e723b..e7bc4fcd5e 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_sync.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.c @@ -14,6 +14,10 @@ nouveau_notifier_new(GLcontext *ctx, GLuint handle) nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); nouveau_notifier *notifier; +#ifdef NOUVEAU_RING_DEBUG + return NULL; +#endif + notifier = CALLOC_STRUCT(nouveau_notifier_t); if (!notifier) return NULL; @@ -53,6 +57,10 @@ nouveau_notifier_reset(nouveau_notifier *notifier) { volatile GLuint *n = notifier->mem->map; +#ifdef NOUVEAU_RING_DEBUG + return; +#endif + n[NV_NOTIFY_TIME_0 /4] = 0x00000000; n[NV_NOTIFY_TIME_1 /4] = 0x00000000; n[NV_NOTIFY_RETURN_VALUE/4] = 0x00000000; @@ -67,6 +75,10 @@ nouveau_notifier_wait_status(nouveau_notifier *notifier, GLuint status, volatile GLuint *n = notifier->mem->map; unsigned int time = 0; +#ifdef NOUVEAU_RING_DEBUG + return GL_TRUE; +#endif + while (time <= timeout) { if (n[NV_NOTIFY_STATE/4] & NV_NOTIFY_STATE_ERROR_CODE_MASK) { MESSAGE("Notifier returned error: 0x%04x\n", @@ -114,6 +126,10 @@ GLboolean nouveauSyncInitFuncs(GLcontext *ctx) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); +#ifdef NOUVEAU_RING_DEBUG + return GL_TRUE; +#endif + nmesa->syncNotifier = nouveau_notifier_new(ctx, NvSyncNotify); if (!nmesa->syncNotifier) { MESSAGE("Failed to create channel sync notifier\n"); -- cgit v1.2.3 From 5970400476c5c0a1223a49e9ec2eb511ae94b246 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Thu, 25 Jan 2007 12:11:03 +0100 Subject: re-fix bug 9062 in vbo code --- src/mesa/vbo/vbo_exec_draw.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c index 846d5dc196..2b52d7a1ff 100644 --- a/src/mesa/vbo/vbo_exec_draw.c +++ b/src/mesa/vbo/vbo_exec_draw.c @@ -114,6 +114,11 @@ static GLuint vbo_copy_vertices( struct vbo_exec_context *exec ) return 2; } case GL_TRIANGLE_STRIP: + /* no parity issue, but need to make sure the tri is not drawn twice */ + if (nr & 1) { + exec->vtx.prim[exec->vtx.prim_count-1].count--; + } + /* fallthrough */ case GL_QUAD_STRIP: switch (nr) { case 0: ovf = 0; break; -- cgit v1.2.3 From 327462d901cc1ff8e98bcbeba18ad54c77926390 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Thu, 25 Jan 2007 12:12:54 +0100 Subject: remove tnl/t_vtx_x86_gcc.S file from sources as it no longer exists --- src/mesa/sources | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/sources b/src/mesa/sources index a32ecaf027..fd6e8b40e5 100644 --- a/src/mesa/sources +++ b/src/mesa/sources @@ -243,8 +243,7 @@ X86_SOURCES = \ x86/sse_xform3.S \ x86/sse_xform4.S \ x86/sse_normal.S \ - x86/read_rgba_span_x86.S \ - tnl/t_vtx_x86_gcc.S + x86/read_rgba_span_x86.S X86_API = \ x86/glapi_x86.S -- cgit v1.2.3 From db79d7dea03d5129a05d48af19049cb740799669 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Thu, 25 Jan 2007 14:32:06 +0100 Subject: fix dstelt memory allocation to avoid hash corruption --- src/mesa/vbo/vbo_split_copy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/vbo/vbo_split_copy.c b/src/mesa/vbo/vbo_split_copy.c index fff733ccb5..df69e4ca28 100644 --- a/src/mesa/vbo/vbo_split_copy.c +++ b/src/mesa/vbo/vbo_split_copy.c @@ -469,7 +469,7 @@ static void replay_init( struct copy_context *copy ) copy->ib->count * 2); copy->dstelt_size = MIN2(copy->dstelt_size, copy->limits->max_indices); - copy->dstelt = _mesa_malloc(copy->dstelt_size); + copy->dstelt = _mesa_malloc(sizeof(GLuint) * copy->dstelt_size); copy->dstelt_nr = 0; /* Setup the new index buffer to point to the allocated element -- cgit v1.2.3 From 78b64d911b4b50ab744f250522a88b3952859f98 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Thu, 25 Jan 2007 16:39:02 +0100 Subject: allocate larger minimum dstelt buffer increase the minimum dstelt buffer size to avoid triggering an assertion later because the split is triggered before the buffer is full. This fixes cases where the vbo_split_copy path is hit because of maximum index limit, where the dstelt buffer size needed could be very small (doom3 hit that assertion with a vertex count of just 3) --- src/mesa/vbo/vbo_split_copy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/vbo/vbo_split_copy.c b/src/mesa/vbo/vbo_split_copy.c index df69e4ca28..d9c5853782 100644 --- a/src/mesa/vbo/vbo_split_copy.c +++ b/src/mesa/vbo/vbo_split_copy.c @@ -466,7 +466,7 @@ static void replay_init( struct copy_context *copy ) /* Allocate an output element list: */ copy->dstelt_size = MIN2(65536, - copy->ib->count * 2); + copy->ib->count * 2 + 3); copy->dstelt_size = MIN2(copy->dstelt_size, copy->limits->max_indices); copy->dstelt = _mesa_malloc(sizeof(GLuint) * copy->dstelt_size); -- cgit v1.2.3 From 38e9f8b6f297bafba639ce192fc9926c8e890271 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Thu, 25 Jan 2007 18:52:40 +0100 Subject: do not rebase index buffers as it does not work currently (tested with r200 and sw mesa) --- src/mesa/vbo/vbo_exec_array.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index e0a6240c2a..5a3a7488ed 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -302,11 +302,12 @@ vbo_exec_DrawRangeElements(GLenum mode, * worry about performance implications of start > 0. * * XXX: consider passing start as min_index to draw_prims instead. + * XXX: don't rebase because it didn't work. */ ib.rebase = 0; } else { - ib.rebase = start; + ib.rebase = /*start*/ 0; } prim[0].begin = 1; @@ -318,7 +319,7 @@ vbo_exec_DrawRangeElements(GLenum mode, prim[0].count = count; prim[0].indexed = 1; - vbo->draw_prims( ctx, exec->array.inputs, prim, 1, &ib, ib.rebase, end+1 ); + vbo->draw_prims( ctx, exec->array.inputs, prim, 1, &ib, /*ib.rebase*/ start, end+1 ); } -- cgit v1.2.3 From 6aa62ba43f64f617c608e52b63c7eaa7aae16fb4 Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Fri, 26 Jan 2007 07:04:15 +0800 Subject: ARB_Occlusion_query should support multiple query at same time --- src/mesa/drivers/dri/i965/intel_context.c | 6 +++--- src/mesa/drivers/dri/i965/intel_context.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index f7ab7d3b7d..3f8c2c0890 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -258,11 +258,11 @@ intelBeginQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) { struct intel_context *intel = intel_context( ctx ); drmI830MMIO io = { - .read_write = MMIO_WRITE, + .read_write = MMIO_READ, .reg = MMIO_REGS_PS_DEPTH_COUNT, .data = &q->Result }; - intel->stats_wm = GL_TRUE; + intel->stats_wm++; intelFinish(&intel->ctx); drmCommandRead(intel->driFd, DRM_I830_MMIO, &io, sizeof(io)); } @@ -281,7 +281,7 @@ intelEndQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) drmCommandRead(intel->driFd, DRM_I830_MMIO, &io, sizeof(io)); q->Result = tmp - q->Result; q->Ready = GL_TRUE; - intel->stats_wm = GL_FALSE; + intel->stats_wm--; } diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h index d51536c3fe..a0f392f935 100644 --- a/src/mesa/drivers/dri/i965/intel_context.h +++ b/src/mesa/drivers/dri/i965/intel_context.h @@ -177,7 +177,7 @@ struct intel_context GLuint second_last_swap_fence; GLboolean aub_wrap; - GLboolean stats_wm; + GLuint stats_wm; struct intel_batchbuffer *batch; -- cgit v1.2.3 From c9b33ecd7c07cace0a6553ccfdaf7b021959c934 Mon Sep 17 00:00:00 2001 From: George Sapountzis Date: Wed, 6 Dec 2006 06:43:23 +0200 Subject: Drop old (pre-AIGLX) GLcore interface. The old GLcore interface was replaced in Xorg 7.1 with the addition of AIGLX, it is only used by DDX's which are known not to work with the new DIX glx code. --- Bug 9285: misc glcore, xmesa cleanups ACKed by Ian Romanick. --- include/GL/internal/glcore.h | 257 +------------------------------------------ src/mesa/main/context.c | 7 +- src/mesa/main/imports.c | 13 +-- 3 files changed, 5 insertions(+), 272 deletions(-) (limited to 'src') diff --git a/include/GL/internal/glcore.h b/include/GL/internal/glcore.h index ca3cf5be57..3cb792f393 100644 --- a/include/GL/internal/glcore.h +++ b/include/GL/internal/glcore.h @@ -189,259 +189,6 @@ typedef struct __GLcontextModesRec { /************************************************************************/ -/* -** Structure used for allocating and freeing drawable private memory. -** (like software buffers, for example). -** -** The memory allocation routines are provided by the surrounding -** "operating system" code, and they are to be used for allocating -** software buffers and things which are associated with the drawable, -** and used by any context which draws to that drawable. There are -** separate memory allocation functions for drawables and contexts -** since drawables and contexts can be created and destroyed independently -** of one another, and the "operating system" may want to use separate -** allocation arenas for each. -** -** The freePrivate function is filled in by the core routines when they -** allocates software buffers, and stick them in "private". The freePrivate -** function will destroy anything allocated to this drawable (to be called -** when the drawable is destroyed). -*/ -typedef struct __GLdrawableRegionRec __GLdrawableRegion; -typedef struct __GLdrawableBufferRec __GLdrawableBuffer; -typedef struct __GLdrawablePrivateRec __GLdrawablePrivate; - -typedef struct __GLregionRectRec { - /* lower left (inside the rectangle) */ - GLint x0, y0; - /* upper right (outside the rectangle) */ - GLint x1, y1; -} __GLregionRect; - -struct __GLdrawableRegionRec { - GLint numRects; - __GLregionRect *rects; - __GLregionRect boundingRect; -}; - -/************************************************************************/ - -/* masks for the buffers */ -#define __GL_FRONT_BUFFER_MASK 0x00000001 -#define __GL_FRONT_LEFT_BUFFER_MASK 0x00000001 -#define __GL_FRONT_RIGHT_BUFFER_MASK 0x00000002 -#define __GL_BACK_BUFFER_MASK 0x00000004 -#define __GL_BACK_LEFT_BUFFER_MASK 0x00000004 -#define __GL_BACK_RIGHT_BUFFER_MASK 0x00000008 -#define __GL_ACCUM_BUFFER_MASK 0x00000010 -#define __GL_DEPTH_BUFFER_MASK 0x00000020 -#define __GL_STENCIL_BUFFER_MASK 0x00000040 -#define __GL_AUX_BUFFER_MASK(i) (0x0000080 << (i)) - -#define __GL_ALL_BUFFER_MASK 0xffffffff - -/* what Resize routines return if resize resorted to fallback case */ -#define __GL_BUFFER_FALLBACK 0x10 - -typedef void (*__GLbufFallbackInitFn)(__GLdrawableBuffer *buf, - __GLdrawablePrivate *glPriv, GLint bits); -typedef void (*__GLbufMainInitFn)(__GLdrawableBuffer *buf, - __GLdrawablePrivate *glPriv, GLint bits, - __GLbufFallbackInitFn back); - -/* -** A drawable buffer -** -** This data structure describes the context side of a drawable. -** -** According to the spec there could be multiple contexts bound to the same -** drawable at the same time (from different threads). In order to avoid -** multiple-access conflicts, locks are used to serialize access. When a -** thread needs to access (read or write) a member of the drawable, it takes -** a lock first. Some of the entries in the drawable are treated "mostly -** constant", so we take the freedom of allowing access to them without -** taking a lock (for optimization reasons). -** -** For more details regarding locking, see buffers.h in the GL core -*/ -struct __GLdrawableBufferRec { - /* - ** Buffer dimensions - */ - GLint width, height, depth; - - /* - ** Framebuffer base address - */ - void *base; - - /* - ** Framebuffer size (in bytes) - */ - GLuint size; - - /* - ** Size (in bytes) of each element in the framebuffer - */ - GLuint elementSize; - GLuint elementSizeLog2; - - /* - ** Element skip from one scanline to the next. - ** If the buffer is part of another buffer (for example, fullscreen - ** front buffer), outerWidth is the width of that buffer. - */ - GLint outerWidth; - - /* - ** outerWidth * elementSize - */ - GLint byteWidth; - - /* - ** Allocation/deallocation is done based on this handle. A handle - ** is conceptually different from the framebuffer 'base'. - */ - void *handle; - - /* imported */ - GLboolean (*resize)(__GLdrawableBuffer *buf, - GLint x, GLint y, GLuint width, GLuint height, - __GLdrawablePrivate *glPriv, GLuint bufferMask); - void (*lock)(__GLdrawableBuffer *buf, __GLdrawablePrivate *glPriv); - void (*unlock)(__GLdrawableBuffer *buf, __GLdrawablePrivate *glPriv); - void (*fill)(__GLdrawableBuffer *buf, __GLdrawablePrivate *glPriv, - GLuint val, GLint x, GLint y, GLint w, GLint h); - void (*free)(__GLdrawableBuffer *buf, __GLdrawablePrivate *glPriv); - - /* exported */ - void (*freePrivate)(__GLdrawableBuffer *buf, __GLdrawablePrivate *glPriv); -#ifdef __cplusplus - void *privatePtr; -#else - void *private; -#endif - - /* private */ - void *other; /* implementation private data */ - __GLbufMainInitFn mainInit; - __GLbufFallbackInitFn fallbackInit; -}; - -/* -** The context side of the drawable private -*/ -struct __GLdrawablePrivateRec { - /* - ** Drawable Modes - */ - __GLcontextModes *modes; - - /* - ** Drawable size - */ - GLuint width, height; - - /* - ** Origin in screen coordinates of the drawable - */ - GLint xOrigin, yOrigin; -#ifdef __GL_ALIGNED_BUFFERS - /* - ** Drawable offset from screen origin - */ - GLint xOffset, yOffset; - - /* - ** Alignment restriction - */ - GLint xAlignment, yAlignment; -#endif - /* - ** Should we invert the y axis? - */ - GLint yInverted; - - /* - ** Mask specifying which buffers are renderable by the hw - */ - GLuint accelBufferMask; - - /* - ** the buffers themselves - */ - __GLdrawableBuffer frontBuffer; - __GLdrawableBuffer backBuffer; - __GLdrawableBuffer accumBuffer; - __GLdrawableBuffer depthBuffer; - __GLdrawableBuffer stencilBuffer; -#if defined(__GL_NUMBER_OF_AUX_BUFFERS) && (__GL_NUMBER_OF_AUX_BUFFERS > 0) - __GLdrawableBuffer *auxBuffer; -#endif - - __GLdrawableRegion ownershipRegion; - - /* - ** Lock for the drawable private structure - */ - void *lock; -#ifdef DEBUG - /* lock debugging info */ - int lockRefCount; - int lockLine[10]; - char *lockFile[10]; -#endif - - /* imported */ - void *(*malloc)(size_t size); - void *(*calloc)(size_t numElem, size_t elemSize); - void *(*realloc)(void *oldAddr, size_t newSize); - void (*free)(void *addr); - - GLboolean (*addSwapRect)(__GLdrawablePrivate *glPriv, - GLint x, GLint y, GLsizei width, GLsizei height); - void (*setClipRect)(__GLdrawablePrivate *glPriv, - GLint x, GLint y, GLsizei width, GLsizei height); - void (*updateClipRegion)(__GLdrawablePrivate *glPriv); - GLboolean (*resize)(__GLdrawablePrivate *glPriv); - void (*getDrawableSize)(__GLdrawablePrivate *glPriv, - GLint *x, GLint *y, GLuint *width, GLuint *height); - - void (*lockDP)(__GLdrawablePrivate *glPriv, __GLcontext *gc); - void (*unlockDP)(__GLdrawablePrivate *glPriv); - - /* exported */ -#ifdef __cplusplus - void *privatePtr; -#else - void *private; -#endif - void (*freePrivate)(__GLdrawablePrivate *); - - /* client data */ - void *other; -}; - -/* -** Macros to lock/unlock the drawable private -*/ -#if defined(DEBUG) -#define __GL_LOCK_DP(glPriv,gc) \ - (*(glPriv)->lockDP)(glPriv,gc); \ - (glPriv)->lockLine[(glPriv)->lockRefCount] = __LINE__; \ - (glPriv)->lockFile[(glPriv)->lockRefCount] = __FILE__; \ - (glPriv)->lockRefCount++ -#define __GL_UNLOCK_DP(glPriv) \ - (glPriv)->lockRefCount--; \ - (glPriv)->lockLine[(glPriv)->lockRefCount] = 0; \ - (glPriv)->lockFile[(glPriv)->lockRefCount] = NULL; \ - (*(glPriv)->unlockDP)(glPriv) -#else /* DEBUG */ -#define __GL_LOCK_DP(glPriv,gc) (*(glPriv)->lockDP)(glPriv,gc) -#define __GL_UNLOCK_DP(glPriv) (*(glPriv)->unlockDP)(glPriv) -#endif /* DEBUG */ - - /* ** Procedures which are imported by the GL from the surrounding ** "operating system". Math functions are not considered part of the @@ -467,8 +214,8 @@ typedef struct __GLimportsRec { int (CAPI *fprintf)(__GLcontext *gc, void *stream, const char *fmt, ...); /* Drawing surface management */ - __GLdrawablePrivate *(*getDrawablePrivate)(__GLcontext *gc); - __GLdrawablePrivate *(*getReadablePrivate)(__GLcontext *gc); + void *(*getDrawablePrivate)(__GLcontext *gc); + void *(*getReadablePrivate)(__GLcontext *gc); /* Operating system dependent data goes here */ void *other; diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 7ff45cffe8..b2bd1d8a8e 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -292,13 +292,8 @@ _mesa_forceCurrent(__GLcontext *gc) GLboolean _mesa_notifyResize(__GLcontext *gc) { - GLint x, y; - GLuint width, height; - __GLdrawablePrivate *d = gc->imports.getDrawablePrivate(gc); - if (!d || !d->getDrawableSize) - return GL_FALSE; - d->getDrawableSize( d, &x, &y, &width, &height ); /* update viewport, resize software buffers, etc. */ + (void) gc; return GL_TRUE; } diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c index ed809acbe2..996839a20e 100644 --- a/src/mesa/main/imports.c +++ b/src/mesa/main/imports.c @@ -1176,16 +1176,6 @@ default_fprintf(__GLcontext *gc, void *stream, const char *fmt, ...) return r; } -/** - * \todo this really is driver-specific and can't be here - */ -static __GLdrawablePrivate * -default_GetDrawablePrivate(__GLcontext *gc) -{ - (void) gc; - return NULL; -} - /*@}*/ @@ -1222,6 +1212,7 @@ _mesa_init_default_imports(__GLimports *imports, void *driverCtx) imports->fopen = default_fopen; imports->fclose = default_fclose; imports->fprintf = default_fprintf; - imports->getDrawablePrivate = default_GetDrawablePrivate; + imports->getDrawablePrivate = NULL; /* driver-specific */ + imports->getReadablePrivate = NULL; /* driver-specific */ imports->other = driverCtx; } -- cgit v1.2.3 From 507167d7e2cf3bc64d1c112d927efeb1baa3b495 Mon Sep 17 00:00:00 2001 From: George Sapountzis Date: Wed, 6 Dec 2006 06:54:13 +0200 Subject: Override Const.CheckArrayBounds for Xserver in XMesaCreateContext(). This leaves one last XFree86Server ifdef in Mesa core. --- Bug 9285: misc glcore, xmesa cleanups ACKed by Ian Romanick. --- src/mesa/drivers/x11/xm_api.c | 7 +++++++ src/mesa/main/context.c | 8 +------- 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c index b50c4757af..510fbd5849 100644 --- a/src/mesa/drivers/x11/xm_api.c +++ b/src/mesa/drivers/x11/xm_api.c @@ -1545,6 +1545,13 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) _mesa_enable_extension(mesaCtx, "GL_EXT_timer_query"); #endif +#ifdef XFree86Server + /* If we're running in the X server, do bounds checking to prevent + * segfaults and server crashes! + */ + mesaCtx->Const.CheckArrayBounds = GL_TRUE; +#endif + /* finish up xmesa context initializations */ c->swapbytes = CHECK_BYTE_ORDER(v) ? GL_FALSE : GL_TRUE; c->xm_visual = v; diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index b2bd1d8a8e..99f4dc9dfd 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1078,14 +1078,8 @@ _mesa_init_constants( GLcontext *ctx ) ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES; ctx->Const.MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH; - /* If we're running in the X server, do bounds checking to prevent - * segfaults and server crashes! - */ -#if defined(XFree86Server) - ctx->Const.CheckArrayBounds = GL_TRUE; -#else + /* CheckArrayBounds is overriden by drivers/x11 for X server */ ctx->Const.CheckArrayBounds = GL_FALSE; -#endif /* GL_ARB_draw_buffers */ ctx->Const.MaxDrawBuffers = MAX_DRAW_BUFFERS; -- cgit v1.2.3 From dbb54b234cd919b8ef7e36e0603ec69f3ed3fc7f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 20 Jan 2007 17:59:08 -0800 Subject: Remove dead code causing a warning. --- src/mesa/drivers/dri/i965/intel_context.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 3f8c2c0890..63809e0aa8 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -87,11 +87,6 @@ int INTEL_DEBUG = (0); int VERBOSE = 0; #endif -#if DEBUG_LOCKING -char *prevLockFile; -int prevLockLine; -#endif - /*************************************** * Mesa's Driver Functions ***************************************/ -- cgit v1.2.3 From 869b8ad499717eda4a1be04de4e516134123402c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 20 Jan 2007 18:06:38 -0800 Subject: Add _mesa_ffsll() for compatibility on OSes without ffsll(), and use it. --- src/mesa/drivers/dri/i965/brw_draw_upload.c | 2 +- src/mesa/main/imports.c | 21 +++++++++++++++++++++ src/mesa/main/imports.h | 3 +++ 3 files changed, 25 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 57ee294f0c..08741ad90f 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -414,7 +414,7 @@ GLboolean brw_upload_vertices( struct brw_context *brw, */ while (tmp) { - GLuint i = ffsll(tmp)-1; + GLuint i = _mesa_ffsll(tmp)-1; struct brw_vertex_element *input = &brw->vb.inputs[i]; tmp &= ~((GLuint64EXT)1<> 32); + if (bit != 0) + return 32 + bit; + + return 0; +#endif +} /** * Return number of bits set in given GLuint. diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h index 19a9478f76..d9885dbeec 100644 --- a/src/mesa/main/imports.h +++ b/src/mesa/main/imports.h @@ -688,6 +688,9 @@ _mesa_pow(double x, double y); extern int _mesa_ffs(int i); +extern int +_mesa_ffsll(long long i); + extern unsigned int _mesa_bitcount(unsigned int n); -- cgit v1.2.3 From 5a3d9853958993174f13c8cff6bcf11993a48f65 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 20 Jan 2007 18:09:32 -0800 Subject: Bug #9604: Fix a static buffer allocation failure. The pool that the static buffer got allocated from was sized by pitch * height, but the buffer generated from it had its size aligned to a tile boundary, so allocation failed if pitch * height wasn't aligned. However, the 2d driver ensures that the size ends at a tile boundary, so just pass the 2d driver's buffer size rather than calculating it. --- src/mesa/drivers/dri/i965/intel_context.c | 6 ++++-- src/mesa/drivers/dri/i965/intel_regions.c | 2 +- src/mesa/drivers/dri/i965/intel_regions.h | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 63809e0aa8..4486a28adc 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -446,8 +446,8 @@ GLboolean intelInitContext( struct intel_context *intel, intelScreen->cpp, intelScreen->front.pitch / intelScreen->cpp, intelScreen->height, - intelScreen->front.tiled != 0); /* 0: LINEAR */ - + intelScreen->front.size, + intelScreen->front.tiled != 0); intel->back_region = intel_region_create_static(intel, @@ -457,6 +457,7 @@ GLboolean intelInitContext( struct intel_context *intel, intelScreen->cpp, intelScreen->back.pitch / intelScreen->cpp, intelScreen->height, + intelScreen->back.size, intelScreen->back.tiled != 0); /* Still assuming front.cpp == depth.cpp @@ -473,6 +474,7 @@ GLboolean intelInitContext( struct intel_context *intel, intelScreen->cpp, intelScreen->depth.pitch / intelScreen->cpp, intelScreen->height, + intelScreen->depth.size, intelScreen->depth.tiled != 0); intel_bufferobj_init( intel ); diff --git a/src/mesa/drivers/dri/i965/intel_regions.c b/src/mesa/drivers/dri/i965/intel_regions.c index 398b0a0a3b..835ecdd725 100644 --- a/src/mesa/drivers/dri/i965/intel_regions.c +++ b/src/mesa/drivers/dri/i965/intel_regions.c @@ -122,10 +122,10 @@ struct intel_region *intel_region_create_static( struct intel_context *intel, GLuint cpp, GLuint pitch, GLuint height, + GLuint size, GLboolean tiled ) { struct intel_region *region = calloc(sizeof(*region), 1); - GLuint size = cpp * pitch * height; GLint pool; DBG("%s\n", __FUNCTION__); diff --git a/src/mesa/drivers/dri/i965/intel_regions.h b/src/mesa/drivers/dri/i965/intel_regions.h index 2413f0de33..d2235f1275 100644 --- a/src/mesa/drivers/dri/i965/intel_regions.h +++ b/src/mesa/drivers/dri/i965/intel_regions.h @@ -78,6 +78,7 @@ struct intel_region *intel_region_create_static( struct intel_context *intel, GLuint cpp, GLuint pitch, GLuint height, + GLuint size, GLboolean tiled ); /* Map/unmap regions. This is refcounted also: -- cgit v1.2.3 From 99c9bc386f54964eea0ed93f6b036477076dae57 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 26 Jan 2007 19:01:55 -0700 Subject: document, re-indent _mesa_ffsll() --- src/mesa/main/imports.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c index ad77373075..be2f04c188 100644 --- a/src/mesa/main/imports.c +++ b/src/mesa/main/imports.c @@ -574,28 +574,36 @@ _mesa_ffs(int i) #endif } + +/** + * Find position of first bit set in given value. + * XXX Warning: this function can only be used on 64-bit systems! + * \return position of lest significant bit set, starting at 1, return zero + * if no bits set. + */ int _mesa_ffsll(long long val) { #ifdef ffsll - return ffsll(val); + return ffsll(val); #else - int bit; + int bit; - assert(sizeof(val) == 8); + assert(sizeof(val) == 8); - bit = ffs(val); - if (bit != 0) - return bit; + bit = ffs(val); + if (bit != 0) + return bit; - bit = ffs(val >> 32); - if (bit != 0) - return 32 + bit; + bit = ffs(val >> 32); + if (bit != 0) + return 32 + bit; - return 0; + return 0; #endif } + /** * Return number of bits set in given GLuint. */ -- cgit v1.2.3 From 0931e21eb62af217564f450e9e56bc7b6f0e15c7 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sat, 27 Jan 2007 03:03:25 +0100 Subject: nouveau: more work on nv04, this time buffer format/pitches/... --- src/mesa/drivers/dri/nouveau/nouveau_object.c | 2 ++ src/mesa/drivers/dri/nouveau/nouveau_object.h | 2 ++ src/mesa/drivers/dri/nouveau/nv04_state.c | 45 +++++++++++++++++++++++++-- 3 files changed, 47 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.c b/src/mesa/drivers/dri/nouveau/nouveau_object.c index 26086e16e4..302009c8b1 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.c @@ -70,6 +70,8 @@ void nouveauObjectInit(nouveauContextPtr nmesa) } else { nouveauCreateContextObject(nmesa, NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D, 0, 0, 0, 0); + nouveauCreateContextObject(nmesa, NvCtxSurf3D, NV04_CONTEXT_SURFACES_3D, + 0, 0, 0, 0); nouveauCreateContextObject(nmesa, NvImageBlit, NV_IMAGE_BLIT, NV_DMA_CONTEXT_FLAGS_PATCH_SRCCOPY, 0, 0, 0); } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.h b/src/mesa/drivers/dri/nouveau/nouveau_object.h index b1ff5a5d0d..e154e0acff 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.h @@ -12,6 +12,7 @@ enum DMAObjects { NvCtxSurf2D = 0x80000020, NvImageBlit = 0x80000021, NvMemFormat = 0x80000022, + NvCtxSurf3D = 0x80000023, NvDmaFB = 0xD0FB0001, NvDmaAGP = 0xD0AA0001, NvSyncNotify = 0xD0000001 @@ -21,6 +22,7 @@ enum DMASubchannel { NvSubCtxSurf2D = 0, NvSubImageBlit = 1, NvSubMemFormat = 2, + NvSubCtxSurf3D = 3, NvSub3D = 7, }; diff --git a/src/mesa/drivers/dri/nouveau/nv04_state.c b/src/mesa/drivers/dri/nouveau/nv04_state.c index 83ad8ae432..ec4cd40d87 100644 --- a/src/mesa/drivers/dri/nouveau/nv04_state.c +++ b/src/mesa/drivers/dri/nouveau/nv04_state.c @@ -267,6 +267,7 @@ static void nv04Enable(GLcontext *ctx, GLenum cap, GLboolean state) break; case GL_FOG: nv04_emit_blend(ctx); + nv04_emit_fog_color(ctx); break; // case GL_HISTOGRAM: // case GL_INDEX_LOGIC_OP: @@ -436,14 +437,54 @@ static void nv04WindowMoved(nouveauContextPtr nmesa) /* Initialise any card-specific non-GL related state */ static GLboolean nv04InitCard(nouveauContextPtr nmesa) { + nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); + nouveauObjectOnSubchannel(nmesa, NvSubCtxSurf3D, NvCtxSurf3D); + + BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_DMA_NOTIFY, 3); + OUT_RING(NvDmaFB); + OUT_RING(NvDmaFB); + OUT_RING(NvDmaFB); + BEGIN_RING_SIZE(NvSub3D, NV04_DX5_TEXTURED_TRIANGLE_SURFACE, 1); + OUT_RING(NvCtxSurf3D); return GL_TRUE; } /* Update buffer offset/pitch/format */ static GLboolean nv04BindBuffers(nouveauContextPtr nmesa, int num_color, - nouveau_renderbuffer **color, - nouveau_renderbuffer *depth) + nouveau_renderbuffer **color, + nouveau_renderbuffer *depth) { + GLuint x, y, w, h; + + w = color[0]->mesa.Width; + h = color[0]->mesa.Height; + x = nmesa->drawX; + y = nmesa->drawY; + + /* FIXME pitches have to be aligned ! */ + BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_PITCH, 2); + OUT_RING(color[0]->pitch|(depth->pitch<<16)); + OUT_RING(color[0]->offset); + + if (depth) { + BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1); + OUT_RING(depth->offset); + } + + BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_CLIP_HORIZONTAL, 2); + OUT_RING((w<<16)|x); + OUT_RING((h<<16)|y); + + /* FIXME not sure... */ + BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_CLIP_SIZE, 1); + OUT_RING((h<<16)|w); + + BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_FORMAT, 1); + if (color[0]->mesa._ActualFormat == GL_RGBA8) + OUT_RING(108/*A8R8G8B8*/); + else + OUT_RING(103/*R5G6B5*/); + return GL_TRUE; } -- cgit v1.2.3 From 1b62353dd868a37ee20c20d66b2123e2020cc59f Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 26 Jan 2007 19:08:34 -0700 Subject: fix typo --- src/mesa/main/imports.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c index be2f04c188..890d1a4e32 100644 --- a/src/mesa/main/imports.c +++ b/src/mesa/main/imports.c @@ -578,7 +578,7 @@ _mesa_ffs(int i) /** * Find position of first bit set in given value. * XXX Warning: this function can only be used on 64-bit systems! - * \return position of lest significant bit set, starting at 1, return zero + * \return position of least-significant bit set, starting at 1, return zero * if no bits set. */ int -- cgit v1.2.3 From c00169fd25336c1425c5457fcd925ba10464f3cf Mon Sep 17 00:00:00 2001 From: George Sapountzis Date: Sat, 27 Jan 2007 08:16:10 +0200 Subject: Bug 9628: no entry for GetVertexAttribPointerv This is because (in glX_API.xml) GetVertexAttribPointerv is aliased to GetVertexAttribPointervARB which is then aliased to GetVertexAttribPointervNV. Make GetVertexAttribPointerv alias GetVertexAttribPointervNV directly. Patch by Ian Romanick and regenerate. --- src/mesa/drivers/dri/common/extension_helper.h | 22 ++++++++-------------- src/mesa/glapi/gl_API.xml | 2 +- src/mesa/glapi/glapitemp.h | 6 ++++++ src/mesa/glapi/glprocs.h | 12 +++++++----- src/mesa/main/enums.c | 2 +- src/mesa/sparc/glapi_sparc.S | 1 + src/mesa/x86-64/glapi_x86-64.S | 1 + src/mesa/x86/glapi_x86.S | 1 + 8 files changed, 26 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/common/extension_helper.h b/src/mesa/drivers/dri/common/extension_helper.h index d6d51cdd16..c798496425 100644 --- a/src/mesa/drivers/dri/common/extension_helper.h +++ b/src/mesa/drivers/dri/common/extension_helper.h @@ -2466,10 +2466,10 @@ static const char MultiTexCoord4ivARB_names[] = ""; #endif -#if defined(need_GL_VERSION_2_0) -static const char GetVertexAttribPointervARB_names[] = - "iip\0" /* Parameter signature */ - "glGetVertexAttribPointerv\0" +#if defined(need_GL_EXT_gpu_program_parameters) +static const char ProgramLocalParameters4fvEXT_names[] = + "iiip\0" /* Parameter signature */ + "glProgramLocalParameters4fvEXT\0" ""; #endif @@ -3152,13 +3152,6 @@ static const char VertexAttribPointerNV_names[] = ""; #endif -#if defined(need_GL_EXT_gpu_program_parameters) -static const char ProgramLocalParameters4fvEXT_names[] = - "iiip\0" /* Parameter signature */ - "glProgramLocalParameters4fvEXT\0" - ""; -#endif - #if defined(need_GL_EXT_framebuffer_object) static const char GetFramebufferAttachmentParameterivEXT_names[] = "iiip\0" /* Parameter signature */ @@ -3781,9 +3774,10 @@ static const char ReplacementCodeuiColor3fVertex3fSUN_names[] = ""; #endif -#if defined(need_GL_ARB_vertex_program) || defined(need_GL_NV_vertex_program) +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) || defined(need_GL_NV_vertex_program) static const char GetVertexAttribPointervNV_names[] = "iip\0" /* Parameter signature */ + "glGetVertexAttribPointerv\0" "glGetVertexAttribPointervARB\0" "glGetVertexAttribPointervNV\0" ""; @@ -5343,8 +5337,8 @@ static const struct dri_extension_function GL_EXT_framebuffer_object_functions[] #if defined(need_GL_EXT_gpu_program_parameters) static const struct dri_extension_function GL_EXT_gpu_program_parameters_functions[] = { - { ProgramEnvParameters4fvEXT_names, ProgramEnvParameters4fvEXT_remap_index, -1 }, { ProgramLocalParameters4fvEXT_names, ProgramLocalParameters4fvEXT_remap_index, -1 }, + { ProgramEnvParameters4fvEXT_names, ProgramEnvParameters4fvEXT_remap_index, -1 }, { NULL, 0, 0 } }; #endif @@ -6263,7 +6257,6 @@ static const struct dri_extension_function GL_VERSION_2_0_functions[] = { { GetVertexAttribfvARB_names, GetVertexAttribfvARB_remap_index, -1 }, { GetAttribLocationARB_names, GetAttribLocationARB_remap_index, -1 }, { Uniform3ivARB_names, Uniform3ivARB_remap_index, -1 }, - { GetVertexAttribPointervARB_names, GetVertexAttribPointervARB_remap_index, -1 }, { VertexAttrib4sARB_names, VertexAttrib4sARB_remap_index, -1 }, { VertexAttrib2dvARB_names, VertexAttrib2dvARB_remap_index, -1 }, { VertexAttrib2fvARB_names, VertexAttrib2fvARB_remap_index, -1 }, @@ -6295,6 +6288,7 @@ static const struct dri_extension_function GL_VERSION_2_0_functions[] = { { Uniform4iARB_names, Uniform4iARB_remap_index, -1 }, { UseProgramObjectARB_names, UseProgramObjectARB_remap_index, -1 }, { DeleteProgram_names, DeleteProgram_remap_index, -1 }, + { GetVertexAttribPointervNV_names, GetVertexAttribPointervNV_remap_index, -1 }, { Uniform2iARB_names, Uniform2iARB_remap_index, -1 }, { VertexAttrib4dARB_names, VertexAttrib4dARB_remap_index, -1 }, { GetUniformLocationARB_names, GetUniformLocationARB_remap_index, -1 }, diff --git a/src/mesa/glapi/gl_API.xml b/src/mesa/glapi/gl_API.xml index 905c4a03a6..687dffbcac 100644 --- a/src/mesa/glapi/gl_API.xml +++ b/src/mesa/glapi/gl_API.xml @@ -5318,7 +5318,7 @@ - + diff --git a/src/mesa/glapi/glapitemp.h b/src/mesa/glapi/glapitemp.h index 340a4f6a04..f67611abb4 100644 --- a/src/mesa/glapi/glapitemp.h +++ b/src/mesa/glapi/glapitemp.h @@ -4865,6 +4865,11 @@ KEYWORD1 void KEYWORD2 NAME(GetTrackMatrixivNV)(GLenum target, GLuint address, G DISPATCH(GetTrackMatrixivNV, (target, address, pname, params), (F, "glGetTrackMatrixivNV(0x%x, %d, 0x%x, %p);\n", target, address, pname, (const void *) params)); } +KEYWORD1 void KEYWORD2 NAME(GetVertexAttribPointerv)(GLuint index, GLenum pname, GLvoid ** pointer) +{ + DISPATCH(GetVertexAttribPointervNV, (index, pname, params), (F, "glGetVertexAttribPointerv(%d, 0x%x, %p);\n", index, pname, (const void *) params)); +} + KEYWORD1 void KEYWORD2 NAME(GetVertexAttribPointervARB)(GLuint index, GLenum pname, GLvoid ** params) { DISPATCH(GetVertexAttribPointervNV, (index, pname, params), (F, "glGetVertexAttribPointervARB(%d, 0x%x, %p);\n", index, pname, (const void *) params)); @@ -6577,6 +6582,7 @@ static _glapi_proc UNUSED_TABLE_NAME[] = { TABLE_ENTRY(BindProgramARB), TABLE_ENTRY(DeleteProgramsARB), TABLE_ENTRY(GenProgramsARB), + TABLE_ENTRY(GetVertexAttribPointerv), TABLE_ENTRY(GetVertexAttribPointervARB), TABLE_ENTRY(IsProgramARB), TABLE_ENTRY(PointParameteri), diff --git a/src/mesa/glapi/glprocs.h b/src/mesa/glapi/glprocs.h index 905c65862d..190d9ed149 100644 --- a/src/mesa/glapi/glprocs.h +++ b/src/mesa/glapi/glprocs.h @@ -1086,6 +1086,7 @@ static const char gl_string_table[] = "glBindProgramARB\0" "glDeleteProgramsARB\0" "glGenProgramsARB\0" + "glGetVertexAttribPointerv\0" "glGetVertexAttribPointervARB\0" "glIsProgramARB\0" "glPointParameteri\0" @@ -2229,11 +2230,12 @@ static const glprocs_table_t static_functions[] = { NAME_FUNC_OFFSET(18432, glDeleteProgramsNV, glDeleteProgramsNV, NULL, _gloffset_DeleteProgramsNV), NAME_FUNC_OFFSET(18452, glGenProgramsNV, glGenProgramsNV, NULL, _gloffset_GenProgramsNV), NAME_FUNC_OFFSET(18469, glGetVertexAttribPointervNV, glGetVertexAttribPointervNV, NULL, _gloffset_GetVertexAttribPointervNV), - NAME_FUNC_OFFSET(18498, glIsProgramNV, glIsProgramNV, NULL, _gloffset_IsProgramNV), - NAME_FUNC_OFFSET(18513, glPointParameteriNV, glPointParameteriNV, NULL, _gloffset_PointParameteriNV), - NAME_FUNC_OFFSET(18531, glPointParameterivNV, glPointParameterivNV, NULL, _gloffset_PointParameterivNV), - NAME_FUNC_OFFSET(18550, gl_dispatch_stub_749, gl_dispatch_stub_749, NULL, _gloffset_BlendEquationSeparateEXT), - NAME_FUNC_OFFSET(18574, gl_dispatch_stub_749, gl_dispatch_stub_749, NULL, _gloffset_BlendEquationSeparateEXT), + NAME_FUNC_OFFSET(18495, glGetVertexAttribPointervNV, glGetVertexAttribPointervNV, NULL, _gloffset_GetVertexAttribPointervNV), + NAME_FUNC_OFFSET(18524, glIsProgramNV, glIsProgramNV, NULL, _gloffset_IsProgramNV), + NAME_FUNC_OFFSET(18539, glPointParameteriNV, glPointParameteriNV, NULL, _gloffset_PointParameteriNV), + NAME_FUNC_OFFSET(18557, glPointParameterivNV, glPointParameterivNV, NULL, _gloffset_PointParameterivNV), + NAME_FUNC_OFFSET(18576, gl_dispatch_stub_749, gl_dispatch_stub_749, NULL, _gloffset_BlendEquationSeparateEXT), + NAME_FUNC_OFFSET(18600, gl_dispatch_stub_749, gl_dispatch_stub_749, NULL, _gloffset_BlendEquationSeparateEXT), NAME_FUNC_OFFSET(-1, NULL, NULL, NULL, 0) }; diff --git a/src/mesa/main/enums.c b/src/mesa/main/enums.c index fc56809e97..8c1b785aab 100644 --- a/src/mesa/main/enums.c +++ b/src/mesa/main/enums.c @@ -3517,7 +3517,6 @@ static const enum_elt all_enums[1737] = static const unsigned reduced_enums[1277] = { - 30, /* GL_ALL_CLIENT_ATTRIB_BITS */ 435, /* GL_FALSE */ 643, /* GL_LINES */ 645, /* GL_LINE_LOOP */ @@ -4794,6 +4793,7 @@ static const unsigned reduced_enums[1277] = 1314, /* GL_SCISSOR_BIT */ 29, /* GL_ALL_ATTRIB_BITS */ 938, /* GL_MULTISAMPLE_BIT */ + 30, /* GL_ALL_CLIENT_ATTRIB_BITS */ }; #define Elements(x) sizeof(x)/sizeof(*x) diff --git a/src/mesa/sparc/glapi_sparc.S b/src/mesa/sparc/glapi_sparc.S index c2a8ca6154..86c9f30e14 100644 --- a/src/mesa/sparc/glapi_sparc.S +++ b/src/mesa/sparc/glapi_sparc.S @@ -1855,6 +1855,7 @@ _mesa_sparc_glapi_end: .globl glBindProgramARB ; .type glBindProgramARB,#function ; glBindProgramARB = glBindProgramNV .globl glDeleteProgramsARB ; .type glDeleteProgramsARB,#function ; glDeleteProgramsARB = glDeleteProgramsNV .globl glGenProgramsARB ; .type glGenProgramsARB,#function ; glGenProgramsARB = glGenProgramsNV + .globl glGetVertexAttribPointerv ; .type glGetVertexAttribPointerv,#function ; glGetVertexAttribPointerv = glGetVertexAttribPointervNV .globl glGetVertexAttribPointervARB ; .type glGetVertexAttribPointervARB,#function ; glGetVertexAttribPointervARB = glGetVertexAttribPointervNV .globl glIsProgramARB ; .type glIsProgramARB,#function ; glIsProgramARB = glIsProgramNV .globl glPointParameteri ; .type glPointParameteri,#function ; glPointParameteri = glPointParameteriNV diff --git a/src/mesa/x86-64/glapi_x86-64.S b/src/mesa/x86-64/glapi_x86-64.S index d8ef5eae09..eb54ba4848 100644 --- a/src/mesa/x86-64/glapi_x86-64.S +++ b/src/mesa/x86-64/glapi_x86-64.S @@ -29477,6 +29477,7 @@ GL_PREFIX(_dispatch_stub_771): .globl GL_PREFIX(BindProgramARB) ; .set GL_PREFIX(BindProgramARB), GL_PREFIX(BindProgramNV) .globl GL_PREFIX(DeleteProgramsARB) ; .set GL_PREFIX(DeleteProgramsARB), GL_PREFIX(DeleteProgramsNV) .globl GL_PREFIX(GenProgramsARB) ; .set GL_PREFIX(GenProgramsARB), GL_PREFIX(GenProgramsNV) + .globl GL_PREFIX(GetVertexAttribPointerv) ; .set GL_PREFIX(GetVertexAttribPointerv), GL_PREFIX(GetVertexAttribPointervNV) .globl GL_PREFIX(GetVertexAttribPointervARB) ; .set GL_PREFIX(GetVertexAttribPointervARB), GL_PREFIX(GetVertexAttribPointervNV) .globl GL_PREFIX(IsProgramARB) ; .set GL_PREFIX(IsProgramARB), GL_PREFIX(IsProgramNV) .globl GL_PREFIX(PointParameteri) ; .set GL_PREFIX(PointParameteri), GL_PREFIX(PointParameteriNV) diff --git a/src/mesa/x86/glapi_x86.S b/src/mesa/x86/glapi_x86.S index 2c01b38aeb..1106eeede8 100644 --- a/src/mesa/x86/glapi_x86.S +++ b/src/mesa/x86/glapi_x86.S @@ -1246,6 +1246,7 @@ GLNAME(gl_dispatch_functions_start): GL_STUB_ALIAS(BindProgramARB, _gloffset_BindProgramNV, BindProgramARB@8, BindProgramNV, BindProgramNV@8) GL_STUB_ALIAS(DeleteProgramsARB, _gloffset_DeleteProgramsNV, DeleteProgramsARB@8, DeleteProgramsNV, DeleteProgramsNV@8) GL_STUB_ALIAS(GenProgramsARB, _gloffset_GenProgramsNV, GenProgramsARB@8, GenProgramsNV, GenProgramsNV@8) + GL_STUB_ALIAS(GetVertexAttribPointerv, _gloffset_GetVertexAttribPointervNV, GetVertexAttribPointerv@12, GetVertexAttribPointervNV, GetVertexAttribPointervNV@12) GL_STUB_ALIAS(GetVertexAttribPointervARB, _gloffset_GetVertexAttribPointervNV, GetVertexAttribPointervARB@12, GetVertexAttribPointervNV, GetVertexAttribPointervNV@12) GL_STUB_ALIAS(IsProgramARB, _gloffset_IsProgramNV, IsProgramARB@4, IsProgramNV, IsProgramNV@4) GL_STUB_ALIAS(PointParameteri, _gloffset_PointParameteriNV, PointParameteri@8, PointParameteriNV, PointParameteriNV@8) -- cgit v1.2.3 From ea55de3d654333b5615db4690cca6138b906b131 Mon Sep 17 00:00:00 2001 From: Claudio Ciccani Date: Sat, 27 Jan 2007 19:32:05 +0100 Subject: Updated copyright header. Switched to LGPL (GPL header was a cut-&-paste mistake). --- src/mesa/drivers/directfb/idirectfbgl_mesa.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/directfb/idirectfbgl_mesa.c b/src/mesa/drivers/directfb/idirectfbgl_mesa.c index 3c8c6c256e..ebcbfbcc65 100644 --- a/src/mesa/drivers/directfb/idirectfbgl_mesa.c +++ b/src/mesa/drivers/directfb/idirectfbgl_mesa.c @@ -1,18 +1,19 @@ /* - * Copyright (C) 2004-2006 Claudio Ciccani + * Copyright (C) 2004-2007 Claudio Ciccani * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * * Based on glfbdev.c, written by Brian Paul. -- cgit v1.2.3 From 1879069eab58a80a27ff1ee0e34b7940643539ab Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 28 Jan 2007 16:35:32 +1100 Subject: nouveau: extend notifier interface to allow multiple notifiers in a memory block. --- src/mesa/drivers/dri/nouveau/nouveau_sync.c | 36 +++++++++++++++++++++-------- src/mesa/drivers/dri/nouveau/nouveau_sync.h | 10 +++++--- 2 files changed, 33 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.c b/src/mesa/drivers/dri/nouveau/nouveau_sync.c index e7bc4fcd5e..5fb8dec7d8 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_sync.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.c @@ -9,7 +9,7 @@ #include "nouveau_sync.h" nouveau_notifier * -nouveau_notifier_new(GLcontext *ctx, GLuint handle) +nouveau_notifier_new(GLcontext *ctx, GLuint handle, GLuint count) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); nouveau_notifier *notifier; @@ -24,7 +24,7 @@ nouveau_notifier_new(GLcontext *ctx, GLuint handle) notifier->mem = nouveau_mem_alloc(ctx, NOUVEAU_MEM_FB | NOUVEAU_MEM_MAPPED, - 32, + count * NV_NOTIFIER_SIZE, 0); if (!notifier->mem) { FREE(notifier); @@ -53,9 +53,9 @@ nouveau_notifier_destroy(GLcontext *ctx, nouveau_notifier *notifier) } void -nouveau_notifier_reset(nouveau_notifier *notifier) +nouveau_notifier_reset(nouveau_notifier *notifier, GLuint id) { - volatile GLuint *n = notifier->mem->map; + volatile GLuint *n = notifier->mem->map + (id * NV_NOTIFIER_SIZE); #ifdef NOUVEAU_RING_DEBUG return; @@ -68,11 +68,27 @@ nouveau_notifier_reset(nouveau_notifier *notifier) NV_NOTIFY_STATE_STATUS_SHIFT); } +GLuint +nouveau_notifier_status(nouveau_notifier *notifier, GLuint id) +{ + volatile GLuint *n = notifier->mem->map + (id * NV_NOTIFIER_SIZE); + + return n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT; +} + +GLuint +nouveau_notifier_return_val(nouveau_notifier *notifier, GLuint id) +{ + volatile GLuint *n = notifier->mem->map + (id * NV_NOTIFIER_SIZE); + + return n[NV_NOTIFY_RETURN_VALUE/4]; +} + GLboolean -nouveau_notifier_wait_status(nouveau_notifier *notifier, GLuint status, - GLuint timeout) +nouveau_notifier_wait_status(nouveau_notifier *notifier, GLuint id, + GLuint status, GLuint timeout) { - volatile GLuint *n = notifier->mem->map; + volatile GLuint *n = notifier->mem->map + (id * NV_NOTIFIER_SIZE); unsigned int time = 0; #ifdef NOUVEAU_RING_DEBUG @@ -108,7 +124,7 @@ nouveau_notifier_wait_nop(GLcontext *ctx, nouveau_notifier *notifier, nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); GLboolean ret; - nouveau_notifier_reset(notifier); + nouveau_notifier_reset(notifier, 0); BEGIN_RING_SIZE(subc, NV_NOTIFY, 1); OUT_RING (NV_NOTIFY_STYLE_WRITE_ONLY); @@ -116,7 +132,7 @@ nouveau_notifier_wait_nop(GLcontext *ctx, nouveau_notifier *notifier, OUT_RING (0); FIRE_RING(); - ret = nouveau_notifier_wait_status(notifier, + ret = nouveau_notifier_wait_status(notifier, 0, NV_NOTIFY_STATE_STATUS_COMPLETED, 0 /* no timeout */); if (ret == GL_FALSE) MESSAGE("wait on notifier failed\n"); @@ -130,7 +146,7 @@ GLboolean nouveauSyncInitFuncs(GLcontext *ctx) return GL_TRUE; #endif - nmesa->syncNotifier = nouveau_notifier_new(ctx, NvSyncNotify); + nmesa->syncNotifier = nouveau_notifier_new(ctx, NvSyncNotify, 1); if (!nmesa->syncNotifier) { MESSAGE("Failed to create channel sync notifier\n"); return GL_FALSE; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.h b/src/mesa/drivers/dri/nouveau/nouveau_sync.h index d9e3d4b80c..5c941bbb1c 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_sync.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.h @@ -3,6 +3,7 @@ #include "nouveau_buffers.h" +#define NV_NOTIFIER_SIZE 32 #define NV_NOTIFY_TIME_0 0x00000000 #define NV_NOTIFY_TIME_1 0x00000004 #define NV_NOTIFY_RETURN_VALUE 0x00000008 @@ -24,10 +25,13 @@ typedef struct nouveau_notifier_t { nouveau_mem *mem; } nouveau_notifier; -extern nouveau_notifier *nouveau_notifier_new(GLcontext *, GLuint handle); +extern nouveau_notifier *nouveau_notifier_new(GLcontext *, GLuint handle, + GLuint count); extern void nouveau_notifier_destroy(GLcontext *, nouveau_notifier *); -extern void nouveau_notifier_reset(nouveau_notifier *); -extern GLboolean nouveau_notifier_wait_status(nouveau_notifier *r, +extern void nouveau_notifier_reset(nouveau_notifier *, GLuint id); +extern GLuint nouveau_notifier_status(nouveau_notifier *, GLuint id); +extern GLuint nouveau_notifier_return_val(nouveau_notifier *, GLuint id); +extern GLboolean nouveau_notifier_wait_status(nouveau_notifier *r, GLuint id, GLuint status, GLuint timeout); extern void nouveau_notifier_wait_nop(GLcontext *ctx, nouveau_notifier *, GLuint subc); -- cgit v1.2.3 From aacea5218199b6fb614c75d4f6ee14dd27af70b3 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 28 Jan 2007 17:02:40 +1100 Subject: nouveau: initial GL_ARB_occlusion_query support Only enabled on NV40, NV20/NV30 code is untested.. However, NV30 should be identical to NV40. --- src/mesa/drivers/dri/nouveau/Makefile | 1 + src/mesa/drivers/dri/nouveau/nouveau_context.c | 4 + src/mesa/drivers/dri/nouveau/nouveau_context.h | 5 + src/mesa/drivers/dri/nouveau/nouveau_object.h | 3 +- src/mesa/drivers/dri/nouveau/nouveau_query.c | 198 +++++++++++++++++++++++++ src/mesa/drivers/dri/nouveau/nouveau_query.h | 38 +++++ src/mesa/drivers/dri/nouveau/nouveau_sync.c | 27 ++++ src/mesa/drivers/dri/nouveau/nouveau_sync.h | 27 ++++ 8 files changed, 302 insertions(+), 1 deletion(-) create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_query.c create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_query.h (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile index 492e743360..20d2de5eef 100644 --- a/src/mesa/drivers/dri/nouveau/Makefile +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -27,6 +27,7 @@ DRIVER_SOURCES = \ nouveau_tex.c \ nouveau_swtcl.c \ nouveau_sync.c \ + nouveau_query.c \ nv04_state.c \ nv04_swtcl.c \ nv10_state.c \ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 5db93eb012..e18cebcd29 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -50,6 +50,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_msg.h" #include "nouveau_reg.h" #include "nouveau_lock.h" +#include "nouveau_query.h" #include "nv04_swtcl.h" #include "nv10_swtcl.h" @@ -71,6 +72,7 @@ static const struct dri_debug_control debug_control[] = }; #define need_GL_ARB_vertex_program +#define need_GL_ARB_occlusion_query #include "extension_helper.h" const struct dri_extension common_extensions[] = @@ -100,6 +102,7 @@ const struct dri_extension nv40_extensions[] = * written for those cards. */ { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions }, + { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions}, { NULL, 0 } }; @@ -229,6 +232,7 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, nouveauInitBufferObjects(ctx); if (!nouveauSyncInitFuncs(ctx)) return GL_FALSE; + nouveauQueryInitFuncs(ctx); nmesa->hw_func.InitCard(nmesa); nouveauInitState(ctx); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index bcfbb9fb8d..c1d06654ee 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -105,6 +105,11 @@ typedef struct nouveau_context { /* Channel synchronisation */ nouveau_notifier *syncNotifier; + /* ARB_occlusion_query / EXT_timer_query */ + GLuint query_object_max; + GLboolean * query_alloc; + nouveau_notifier *queryNotifier; + /* Additional hw-specific functions */ nouveau_hw_func hw_func; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.h b/src/mesa/drivers/dri/nouveau/nouveau_object.h index e154e0acff..daad281029 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.h @@ -15,7 +15,8 @@ enum DMAObjects { NvCtxSurf3D = 0x80000023, NvDmaFB = 0xD0FB0001, NvDmaAGP = 0xD0AA0001, - NvSyncNotify = 0xD0000001 + NvSyncNotify = 0xD0000001, + NvQueryNotify = 0xD0000002 }; enum DMASubchannel { diff --git a/src/mesa/drivers/dri/nouveau/nouveau_query.c b/src/mesa/drivers/dri/nouveau/nouveau_query.c new file mode 100644 index 0000000000..de3f5b0378 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_query.c @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2007 Ben Skeggs. + * + * 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 (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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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. + * + */ + +/* GL_ARB_occlusion_query support for NV20/30/40 */ + +#include "mtypes.h" + +#include "nouveau_fifo.h" +#include "nouveau_msg.h" +#include "nouveau_object.h" +#include "nouveau_reg.h" +#include "nouveau_sync.h" +#include "nouveau_query.h" + +static struct gl_query_object * +nouveauNewQueryObject(GLcontext *ctx, GLuint id) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_query_object *nq; + int i; + + for (i=0; iquery_object_max; i++) + if (nmesa->query_alloc[i] == GL_FALSE) + break; + if (i==nmesa->query_object_max) + return NULL; + + nq = CALLOC_STRUCT(nouveau_query_object_t); + if (nq) { + nq->notifier_id = i; + + nq->mesa.Id = id; + nq->mesa.Result = 0; + nq->mesa.Active = GL_FALSE; + nq->mesa.Ready = GL_TRUE; + } + + return (struct gl_query_object *)nq; +} + +static void +nouveauBeginQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_query_object *nq = (nouveau_query_object *)q; + + nouveau_notifier_reset(nmesa->queryNotifier, nq->notifier_id); + + switch (nmesa->screen->card->type) { + case NV_20: + BEGIN_RING_CACHE(NvSub3D, 0x17c8, 1); + OUT_RING_CACHE (1); + BEGIN_RING_CACHE(NvSub3D, 0x17cc, 1); + OUT_RING_CACHE (1); + break; + case NV_30: + case NV_40: + case NV_44: + /* I don't think this is OCC_QUERY enable, but it *is* needed to make + * the SET_OBJECT7 notifier block work with STORE_RESULT. + * + * Also, this appears to reset the pixel pass counter */ + BEGIN_RING_SIZE(NvSub3D, + NV30_TCL_PRIMITIVE_3D_OCC_QUERY_OR_COLOR_BUFF_ENABLE, + 1); + OUT_RING (1); + /* Probably OCC_QUERY_ENABLE */ + BEGIN_RING_CACHE(NvSub3D, 0x17cc, 1); + OUT_RING_CACHE (1); + break; + default: + WARN_ONCE("no support for this card\n"); + break; + } +} + +static void +nouveauUpdateQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_query_object *nq = (nouveau_query_object *)q; + int status; + + status = nouveau_notifier_status(nmesa->queryNotifier, + nq->notifier_id); + + q->Ready = (status == NV_NOTIFY_STATE_STATUS_COMPLETED); + if (q->Ready) + q->Result = nouveau_notifier_return_val(nmesa->queryNotifier, + nq->notifier_id); +} + +static void +nouveauWaitQueryResult(GLcontext *ctx, GLenum target, struct gl_query_object *q) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_query_object *nq = (nouveau_query_object *)q; + + nouveau_notifier_wait_status(nmesa->queryNotifier, nq->notifier_id, + NV_NOTIFY_STATE_STATUS_COMPLETED, 0); + nouveauUpdateQuery(ctx, target, q); +} + +static void +nouveauEndQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) +{ + nouveau_query_object *nq = (nouveau_query_object *)q; + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + switch (nmesa->screen->card->type) { + case NV_20: + BEGIN_RING_SIZE(NvSub3D, 0x17d0, 1); + OUT_RING (0x01000000 | nq->notifier_id*32); + break; + case NV_30: + case NV_40: + case NV_44: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STORE_RESULT, 1); + OUT_RING (0x01000000 | nq->notifier_id*32); + break; + default: + WARN_ONCE("no support for this card\n"); + break; + } + FIRE_RING(); + + /*XXX: wait for query to complete, mesa doesn't give the driver + * an interface to query the status of a query object so + * this has to stall the channel. + */ + nouveauWaitQueryResult(ctx, target, q); + + BEGIN_RING_CACHE(NvSub3D, 0x17cc, 1); + OUT_RING_CACHE (0); +} + +void +nouveauQueryInitFuncs(GLcontext *ctx) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (nmesa->screen->card->type < NV_20) + return; + + nmesa->query_object_max = (0x4000 / 32); + nmesa->queryNotifier = + nouveau_notifier_new(ctx, NvQueryNotify, + nmesa->query_object_max); + nmesa->query_alloc = calloc(nmesa->query_object_max, sizeof(GLboolean)); + + switch (nmesa->screen->card->type) { + case NV_20: + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SET_OBJECT8, 1); + OUT_RING_CACHE (NvQueryNotify); + break; + case NV_30: + case NV_40: + case NV_44: + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT7, 1); + OUT_RING_CACHE (NvQueryNotify); + break; + default: + break; + }; + + ctx->Driver.NewQueryObject = nouveauNewQueryObject; + ctx->Driver.BeginQuery = nouveauBeginQuery; + ctx->Driver.EndQuery = nouveauEndQuery; +#if 0 + ctx->Driver.UpdateQuery = nouveauUpdateQuery; + ctx->Driver.WaitQueryResult = nouveauWaitQueryResult; +#endif +} + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_query.h b/src/mesa/drivers/dri/nouveau/nouveau_query.h new file mode 100644 index 0000000000..3ded41417e --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_query.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2007 Ben Skeggs. + * + * 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 (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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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. + * + */ + +#ifndef __NOUVEAU_QUERY_H__ +#define __NOUVEAU_QUERY_H__ + +typedef struct nouveau_query_object_t { + struct gl_query_object mesa; + + int notifier_id; +} nouveau_query_object; + +extern void nouveauQueryInitFuncs(GLcontext *ctx); +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.c b/src/mesa/drivers/dri/nouveau/nouveau_sync.c index 5fb8dec7d8..c47ff3a985 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_sync.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.c @@ -1,3 +1,30 @@ +/* + * Copyright (C) 2007 Ben Skeggs. + * + * 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 (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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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. + * + */ + #include "vblank.h" /* for DO_USLEEP */ #include "nouveau_context.h" diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.h b/src/mesa/drivers/dri/nouveau/nouveau_sync.h index 5c941bbb1c..019d5f6629 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_sync.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.h @@ -1,3 +1,30 @@ +/* + * Copyright (C) 2007 Ben Skeggs. + * + * 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 (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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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. + * + */ + #ifndef __NOUVEAU_SYNC_H__ #define __NOUVEAU_SYNC_H__ -- cgit v1.2.3 From b0e86b2dbd11b3ff515172cf1741600c0879ad3f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 28 Jan 2007 22:55:35 +1100 Subject: nouveau: fix nv30 line width --- src/mesa/drivers/dri/nouveau/nv30_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 9b0d7425c8..55b6463781 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -559,7 +559,7 @@ static void nv30LineWidth(GLcontext *ctx, GLfloat width) nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); GLubyte ubWidth; - CLAMPED_FLOAT_TO_UBYTE(ubWidth, width); + ubWidth = (GLubyte)(width * 8.0) & 0xFF; BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_WIDTH_SMOOTH, 1); OUT_RING_CACHE(ubWidth); -- cgit v1.2.3 From c7c0a6ddcddc8d91fde0a7cb5a2bce85c708d438 Mon Sep 17 00:00:00 2001 From: Matthieu Castet Date: Sun, 28 Jan 2007 23:26:21 +0100 Subject: nouveau : nv10 mixing cached stuff with not cached stuff is bad. --- src/mesa/drivers/dri/nouveau/nv10_state.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 0e912e73ff..4e9bccb243 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -688,10 +688,10 @@ static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color, if (color[0]->mesa._ActualFormat != GL_RGBA8) { format = 0x103; /* R5G6B5 color buffer */ } - OUT_RING(format); - OUT_RING(pitch); - OUT_RING(color[0]->offset); - OUT_RING(depth ? depth->offset : color[0]->offset); + OUT_RING_CACHE(format); + OUT_RING_CACHE(pitch); + OUT_RING_CACHE(color[0]->offset); + OUT_RING_CACHE(depth ? depth->offset : color[0]->offset); return GL_TRUE; } -- cgit v1.2.3 From c97540065c6dce20dd6ace9a15d9872a3a66f71c Mon Sep 17 00:00:00 2001 From: Matthieu Castet Date: Mon, 29 Jan 2007 23:19:12 +0100 Subject: nouveau : nv10 comment icomplete command --- src/mesa/drivers/dri/nouveau/nv10_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 4e9bccb243..f6e47b7f48 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -322,7 +322,7 @@ static void nv10Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) switch(pname) { case GL_FOG_MODE: - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FOG_MODE, 1); + //BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FOG_MODE, 1); //OUT_RING_CACHE (params); break; /* TODO: unsure about the rest.*/ -- cgit v1.2.3 From aa397fe47212d7686efe423aedd10f2c57f2c2b9 Mon Sep 17 00:00:00 2001 From: Matthieu Castet Date: Mon, 29 Jan 2007 23:26:35 +0100 Subject: nouveau : NOUVEAU_RING_TRACE allow to print what we are really sending to the fifo. --- src/mesa/drivers/dri/nouveau/nouveau_fifo.h | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h index 9056bfb255..490089f71a 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h @@ -33,15 +33,30 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_ctrlreg.h" #include "nouveau_state_cache.h" +//#define NOUVEAU_RING_TRACE //#define NOUVEAU_RING_DEBUG //#define NOUVEAU_STATE_CACHE_DISABLE +#ifndef NOUVEAU_RING_TRACE +#define NOUVEAU_RING_TRACE 0 +#else +#undef NOUVEAU_RING_TRACE +#define NOUVEAU_RING_TRACE 1 +#endif + #define NV_READ(reg) *(volatile u_int32_t *)(nmesa->mmio + (reg)) #define NV_FIFO_READ(reg) *(volatile u_int32_t *)(nmesa->fifo.mmio + (reg/4)) #define NV_FIFO_WRITE(reg,value) *(volatile u_int32_t *)(nmesa->fifo.mmio + (reg/4)) = value; #define NV_FIFO_READ_GET() ((NV_FIFO_READ(NV03_FIFO_REGS_DMAGET) - nmesa->fifo.put_base) >> 2) -#define NV_FIFO_WRITE_PUT(val) NV_FIFO_WRITE(NV03_FIFO_REGS_DMAPUT, ((val)<<2) + nmesa->fifo.put_base) +#define NV_FIFO_WRITE_PUT(val) do { \ + if (NOUVEAU_RING_TRACE) {\ + printf("FIRE_RING : 0x%08x\n", nmesa->fifo.current << 2); \ + fflush(stdout); \ + sleep(1); \ + } \ + NV_FIFO_WRITE(NV03_FIFO_REGS_DMAPUT, ((val)<<2) + nmesa->fifo.put_base); \ +} while(0) /* * Ring/fifo interface @@ -75,15 +90,23 @@ int i; printf("OUT_RINGp: (size 0x%x dwords)\n",sz); for(i=0;ififo.current+i) << 2, *(p+i), *((float*)(p+i))); \ + } \ memcpy(nmesa->fifo.buffer+nmesa->fifo.current,ptr,(sz)*4); \ nmesa->fifo.current+=(sz); \ }while(0) #define OUT_RING(n) do { \ +if (NOUVEAU_RING_TRACE) \ + printf("OUT_RINGn: [0x%08x] 0x%08x (%s)\n", nmesa->fifo.current << 2, n, __func__); \ nmesa->fifo.buffer[nmesa->fifo.current++]=(n); \ }while(0) #define OUT_RINGf(n) do { \ +if (NOUVEAU_RING_TRACE) \ + printf("OUT_RINGf: [0x%08x] %.04f (%s)\n", nmesa->fifo.current << 2, n, __func__); \ *((float*)(nmesa->fifo.buffer+nmesa->fifo.current++))=(n); \ }while(0) -- cgit v1.2.3 From 0c5b42a99182be05a72c78fa9340b75f3be81220 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 29 Jan 2007 16:39:19 +1100 Subject: nouveau: unhardcode some more NV30TCL_FP_CONTROL values --- src/mesa/drivers/dri/nouveau/nouveau_shader.h | 3 ++- src/mesa/drivers/dri/nouveau/nv30_fragprog.c | 20 +++++++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h index 7329ccd9ea..82eb27b053 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -26,7 +26,8 @@ typedef struct _nvs_fragment_header { typedef union { struct { - uint32_t fp_control; + GLboolean uses_kil; + GLuint num_regs; } NV30FP; struct { uint32_t vp_in_reg; diff --git a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c index 3c7501dd62..02bd8014cc 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c +++ b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c @@ -24,6 +24,7 @@ static void NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nvsCardPriv *priv = &nvs->card_priv; uint32_t offset; if (!nvs->program_buffer) @@ -46,8 +47,9 @@ NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs) */ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM, 1); OUT_RING (offset | 1); - BEGIN_RING_SIZE(NvSub3D, 0x1d60, 1); - OUT_RING (nvs->card_priv.NV30FP.fp_control | 0x03000000); + BEGIN_RING_SIZE(NvSub3D, 0x1d60 /*NV30_TCL_PRIMITIVE_3D_FP_CONTROL*/, 1); + OUT_RING ((priv->NV30FP.uses_kil << 7) | + (priv->NV30FP.num_regs << 24)); } static void @@ -95,7 +97,7 @@ static void NV30FPSetOpcode(nvsFunc *shader, unsigned int opcode, int slot) { if (opcode == NV30_FP_OP_OPCODE_KIL) - shader->card_priv->NV30FP.fp_control |= (1<<7); + shader->card_priv->NV30FP.uses_kil = GL_TRUE; shader->inst[0] &= ~NV30_FP_OP_OPCODE_MASK; shader->inst[0] |= (opcode << NV30_FP_OP_OPCODE_SHIFT); } @@ -145,6 +147,16 @@ NV30FPSetCondition(nvsFunc *shader, int on, nvsCond cond, int reg, shader->inst[1] |= (swz[NVS_SWZ_W] << NV30_FP_OP_COND_SWZ_W_SHIFT); } +static void +NV30FPSetHighReg(nvsFunc *shader, int id) +{ + if (shader->card_priv->NV30FP.num_regs < (id+1)) { + if (id == 0) + id = 1; /* necessary? */ + shader->card_priv->NV30FP.num_regs = (id+1); + } +} + static void NV30FPSetResult(nvsFunc *shader, nvsRegister *reg, unsigned int mask, int slot) { @@ -163,6 +175,7 @@ NV30FPSetResult(nvsFunc *shader, nvsRegister *reg, unsigned int mask, int slot) shader->inst[0] &= ~NV30_FP_OP_UNK0_7; hwreg = reg->index; } + NV30FPSetHighReg(shader, hwreg); shader->inst[0] &= ~NV30_FP_OP_OUT_REG_SHIFT; shader->inst[0] |= (hwreg << NV30_FP_OP_OUT_REG_SHIFT); } @@ -176,6 +189,7 @@ NV30FPSetSource(nvsFunc *shader, nvsRegister *reg, int pos) case NVS_FILE_TEMP: hwsrc |= (NV30_FP_REG_TYPE_TEMP << NV30_FP_REG_TYPE_SHIFT); hwsrc |= (reg->index << NV30_FP_REG_SRC_SHIFT); + NV30FPSetHighReg(shader, reg->index); break; case NVS_FILE_ATTRIB: { -- cgit v1.2.3 From cafbc459f51ce6645e1fc4b6b2b7ec34efedd874 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 27 Jan 2007 18:36:01 +1100 Subject: nouveau: maintain a map of which vtxprog input corresponds to which array --- src/mesa/drivers/dri/nouveau/nouveau_shader.h | 1 + src/mesa/drivers/dri/nouveau/nouveau_shader_0.c | 46 +++++++++++++++++++++++++ 2 files changed, 47 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h index 82eb27b053..e2515c1c79 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -55,6 +55,7 @@ typedef struct _nouveauShader { int inst_count; nvsCardPriv card_priv; + int vp_attrib_map[NVS_MAX_ATTRIBS]; struct { GLfloat *source_val; /* NULL if invariant */ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c index 3bcc2ba755..81ed012c78 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -787,6 +787,50 @@ pass0_translate_instructions(nouveauShader *nvs, int ipos, int fpos, return GL_TRUE; } +static void +pass0_build_attrib_map(nouveauShader *nvs, struct gl_vertex_program *vp) +{ + GLuint inputs_read = vp->Base.InputsRead; + GLuint input_alloc = ~0xFFFF; + int i; + + for (i=0; ivp_attrib_map[i] = -1; + + while (inputs_read) { + int in = ffs(inputs_read) - 1; + int hw; + inputs_read &= ~(1<IsNVProgram) { + /* NVvp: must alias */ + if (in >= VERT_ATTRIB_GENERIC0) + hw = in - VERT_ATTRIB_GENERIC0; + else + hw = in; + } else { + /* ARBvp: may alias + * GL2.0: must not alias + */ + if (in >= VERT_ATTRIB_GENERIC0) + hw = ffs(~input_alloc) - 1; + else + hw = in; + input_alloc |= (1<vp_attrib_map[hw] = in; + } + + if (NOUVEAU_DEBUG & DEBUG_SHADERS) { + printf("vtxprog attrib map:\n"); + for (i=0; ivp_attrib_map[i]); + } + } +} + GLboolean nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) { @@ -801,6 +845,8 @@ nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) case GL_VERTEX_PROGRAM_ARB: nvs->func = &nmesa->VPfunc; + pass0_build_attrib_map(nvs, vp); + if (vp->IsPositionInvariant) _mesa_insert_mvp_code(ctx, vp); #if 0 -- cgit v1.2.3 From 7fbf8d3324868e6920243e3b1abdeb6e398ea715 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 27 Jan 2007 18:51:19 +1100 Subject: nouveau: oops --- src/mesa/drivers/dri/nouveau/nouveau_shader_0.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c index 81ed012c78..fc55056854 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -322,6 +322,7 @@ pass0_make_src_reg(nvsPtr nvs, nvsRegister *reg, struct prog_src_register *src) { struct gl_program *mesa = (struct gl_program *)&nvs->mesa.vp.Base; struct gl_program_parameter_list *p = mesa->Parameters; + int i; *reg = nvr_unused; @@ -329,9 +330,14 @@ pass0_make_src_reg(nvsPtr nvs, nvsRegister *reg, struct prog_src_register *src) case PROGRAM_INPUT: reg->file = NVS_FILE_ATTRIB; if (mesa->Target == GL_VERTEX_PROGRAM_ARB) { - reg->index = (src->Index < VERT_ATTRIB_MAX) ? - _tx_mesa_vp_src_reg[src->Index] : - NVS_FR_UNKNOWN; + for (i=0; ivp_attrib_map[i] == src->Index) { + reg->index = i; + break; + } + } + if (i==NVS_MAX_ATTRIBS) + reg->index = NVS_FR_UNKNOWN; } else { reg->index = (src->Index < FRAG_ATTRIB_MAX) ? _tx_mesa_fp_src_reg[src->Index] : -- cgit v1.2.3 From 2d8b31610917e5e14a242725b047a21f6d2c14e0 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 27 Jan 2007 18:54:42 +1100 Subject: nouveau: remove an unused table --- src/mesa/drivers/dri/nouveau/nouveau_shader_0.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c index fc55056854..b96cf95939 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -54,18 +54,6 @@ static nvsFixedReg _tx_mesa_fp_dst_reg[FRAG_RESULT_MAX] = { NVS_FR_UNKNOWN /* DEPR */ }; -static nvsFixedReg _tx_mesa_vp_src_reg[VERT_ATTRIB_MAX] = { - NVS_FR_POSITION, NVS_FR_WEIGHT, NVS_FR_NORMAL, NVS_FR_COL0, NVS_FR_COL1, - NVS_FR_FOGCOORD, NVS_FR_UNKNOWN /* COLOR_INDEX */, NVS_FR_UNKNOWN, - NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, - NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7, -/* Generic attribs 0-15, aliased to the above */ - NVS_FR_POSITION, NVS_FR_WEIGHT, NVS_FR_NORMAL, NVS_FR_COL0, NVS_FR_COL1, - NVS_FR_FOGCOORD, NVS_FR_UNKNOWN /* COLOR_INDEX */, NVS_FR_UNKNOWN, - NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, - NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7 -}; - static nvsFixedReg _tx_mesa_fp_src_reg[FRAG_ATTRIB_MAX] = { NVS_FR_POSITION, NVS_FR_COL0, NVS_FR_COL1, NVS_FR_FOGCOORD, NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, @@ -815,7 +803,7 @@ pass0_build_attrib_map(nouveauShader *nvs, struct gl_vertex_program *vp) else hw = in; } else { - /* ARBvp: may alias + /* ARBvp: may alias (but we won't) * GL2.0: must not alias */ if (in >= VERT_ATTRIB_GENERIC0) -- cgit v1.2.3 From de0cf18b096822cf8e113a46f12740ebeb10f8df Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 29 Jan 2007 17:08:45 +1100 Subject: nouveau: oops, build attrib map after we know how the final shader will look.. --- src/mesa/drivers/dri/nouveau/nouveau_shader_0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c index b96cf95939..9f32cd8c11 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -839,14 +839,14 @@ nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) case GL_VERTEX_PROGRAM_ARB: nvs->func = &nmesa->VPfunc; - pass0_build_attrib_map(nvs, vp); - if (vp->IsPositionInvariant) _mesa_insert_mvp_code(ctx, vp); #if 0 if (IS_FIXEDFUNCTION_PROG && CLIP_PLANES_USED) pass0_insert_ff_clip_planes(); #endif + + pass0_build_attrib_map(nvs, vp); break; case GL_FRAGMENT_PROGRAM_ARB: nvs->func = &nmesa->FPfunc; -- cgit v1.2.3 From ede8017d2c6c2f6da4c75c9ce0cc4d748e870973 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 30 Jan 2007 12:33:00 +1100 Subject: nouveau: rework shader param handling Conflicts: src/mesa/drivers/dri/nouveau/nouveau_shader_0.c --- src/mesa/drivers/dri/nouveau/nouveau_shader.c | 9 +- src/mesa/drivers/dri/nouveau/nouveau_shader.h | 3 + src/mesa/drivers/dri/nouveau/nouveau_shader_0.c | 145 +++++++++++++++++------- 3 files changed, 110 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.c b/src/mesa/drivers/dri/nouveau/nouveau_shader.c index cdb79fca1e..c78b72bd11 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.c @@ -126,15 +126,16 @@ nvsUpdateShader(GLcontext *ctx, nouveauShader *nvs) /* Update state parameters */ plist = nvs->mesa.vp.Base.Parameters; _mesa_load_state_parameters(ctx, plist); - for (i=0; iNumParameters; i++) { + for (i=0; iparam_high; i++) { + if (!nvs->params[i].in_use) + continue; + if (!nvs->on_hardware) { /* if we've been kicked off the hardware there's no guarantee our * consts are still there.. reupload them all */ nvs->func->UpdateConst(ctx, nvs, i); - } else if (plist->Parameters[i].Type == PROGRAM_STATE_VAR) { - if (!nvs->params[i].source_val) /* this is a workaround when consts aren't alloc'd from id=0.. */ - continue; + } else if (nvs->params[i].source_val) { /* update any changed state parameters */ if (!TEST_EQ_4V(nvs->params[i].val, nvs->params[i].source_val)) nvs->func->UpdateConst(ctx, nvs, i); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h index e2515c1c79..68007dd1ea 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -58,6 +58,8 @@ typedef struct _nouveauShader { int vp_attrib_map[NVS_MAX_ATTRIBS]; struct { + GLboolean in_use; + GLfloat *source_val; /* NULL if invariant */ float val[4]; /* Hardware-specific tracking, currently only nv30_fragprog @@ -66,6 +68,7 @@ typedef struct _nouveauShader { int *hw_index; int hw_index_cnt; } params[NVS_MAX_CONSTS]; + int param_high; /* Pass-private data */ void *pass_rec; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c index 9f32cd8c11..fb6e0b05c3 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -113,6 +113,10 @@ static nvsCond _tx_mesa_condmask[] = { struct pass0_rec { int nvs_ipos; int next_temp; + + int mesa_const_base; + int mesa_const_last; + int swzconst_done; int swzconst_id; nvsRegister const_half; @@ -308,8 +312,8 @@ pass0_make_dst_reg(nvsPtr nvs, nvsRegister *reg, static void pass0_make_src_reg(nvsPtr nvs, nvsRegister *reg, struct prog_src_register *src) { + struct pass0_rec *rec = nvs->pass_rec; struct gl_program *mesa = (struct gl_program *)&nvs->mesa.vp.Base; - struct gl_program_parameter_list *p = mesa->Parameters; int i; *reg = nvr_unused; @@ -332,34 +336,16 @@ pass0_make_src_reg(nvsPtr nvs, nvsRegister *reg, struct prog_src_register *src) NVS_FR_UNKNOWN; } break; - /* All const types seem to get shoved into here, not really sure why */ case PROGRAM_STATE_VAR: - switch (p->Parameters[src->Index].Type) { - case PROGRAM_NAMED_PARAM: - case PROGRAM_CONSTANT: - nvs->params[src->Index].source_val = NULL; - COPY_4V(nvs->params[src->Index].val, - p->ParameterValues[src->Index]); - break; - case PROGRAM_STATE_VAR: - nvs->params[src->Index].source_val = - p->ParameterValues[src->Index]; - break; - default: - fprintf(stderr, "Unknown parameter type %d\n", - p->Parameters[src->Index].Type); - assert(0); - break; + case PROGRAM_NAMED_PARAM: + case PROGRAM_CONSTANT: + reg->file = NVS_FILE_CONST; + reg->index = src->Index + rec->mesa_const_base; + reg->indexed = src->RelAddr; + if (reg->indexed) { + reg->addr_reg = 0; + reg->addr_comp = NVS_SWZ_X; } - - if (src->RelAddr) { - reg->indexed = 1; - reg->addr_reg = 0; - reg->addr_comp = NVS_SWZ_X; - } else - reg->indexed = 0; - reg->file = NVS_FILE_CONST; - reg->index = src->Index; break; case PROGRAM_TEMPORARY: reg->file = NVS_FILE_TEMP; @@ -568,7 +554,6 @@ pass0_emulate_instruction(nouveauShader *nvs, nvsFunc *shader = nvs->func; nvsRegister src[3], dest, temp; nvsInstruction *nvsinst; - struct pass0_rec *rec = nvs->pass_rec; unsigned int mask = pass0_make_mask(inst->DstReg.WriteMask); int i, sat; @@ -825,6 +810,73 @@ pass0_build_attrib_map(nouveauShader *nvs, struct gl_vertex_program *vp) } } +static void +pass0_prealloc_mesa_consts(nouveauShader *nvs) +{ + struct pass0_rec *rec = nvs->pass_rec; + struct gl_program *prog = &nvs->mesa.vp.Base; + struct prog_instruction *inst = prog->Instructions; + struct gl_program_parameter_list *plist = prog->Parameters; + int i; + + /*XXX: not a good idea, params->hw_index is malloc'd */ + memset(nvs->params, 0x00, sizeof(nvs->params)); + + /* When doing relative addressing on constants, the hardware needs us + * to fill the "const id" field with a positive value. Determine the + * most negative index that is used so that all accesses to a + * mesa-provided constant can be rebased to a positive index. + */ + while (inst->Opcode != OPCODE_END) { + for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++) { + struct prog_src_register *src = &inst->SrcReg[i]; + + switch (src->File) { + case PROGRAM_STATE_VAR: + case PROGRAM_CONSTANT: + case PROGRAM_NAMED_PARAM: + if (src->RelAddr && src->Index < 0) { + int base = src->Index * -1; + if (rec->mesa_const_base < base) + rec->mesa_const_base = base; + } + break; + default: + break; + } + } + + inst++; + } + + /* Init all const tracking/alloc info from the parameter list, rather + * than doing it as we translate the program. Otherwise we can't get + * at the correct constant info when relative addressing is being used. + */ + rec->mesa_const_last = plist->NumParameters + rec->mesa_const_base; + nvs->param_high = rec->mesa_const_last; + for (i=0; iNumParameters; i++) { + int hw = rec->mesa_const_base + i; + + switch (plist->Parameters[i].Type) { + case PROGRAM_NAMED_PARAM: + case PROGRAM_STATE_VAR: + nvs->params[hw].in_use = GL_TRUE; + nvs->params[hw].source_val = plist->ParameterValues[i]; + COPY_4V(nvs->params[hw].val, plist->ParameterValues[i]); + break; + case PROGRAM_CONSTANT: + nvs->params[hw].in_use = GL_TRUE; + nvs->params[hw].source_val = NULL; + COPY_4V(nvs->params[hw].val, plist->ParameterValues[i]); + break; + default: + assert(0); + break; + } + } +} + GLboolean nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) { @@ -835,12 +887,28 @@ nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) struct pass0_rec *rec; int ret = GL_FALSE; + rec = CALLOC_STRUCT(pass0_rec); + if (!rec) + return GL_FALSE; + + rec->next_temp = prog->NumTemporaries; + nvs->pass_rec = rec; + + nvs->program_tree = (nvsFragmentHeader*) + pass0_create_subroutine(nvs, "program body"); + if (!nvs->program_tree) { + FREE(rec); + return GL_FALSE; + } + switch (prog->Target) { case GL_VERTEX_PROGRAM_ARB: nvs->func = &nmesa->VPfunc; if (vp->IsPositionInvariant) _mesa_insert_mvp_code(ctx, vp); + pass0_prealloc_mesa_consts(nvs); + #if 0 if (IS_FIXEDFUNCTION_PROG && CLIP_PLANES_USED) pass0_insert_ff_clip_planes(); @@ -853,29 +921,20 @@ nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) if (fp->FogOption != GL_NONE) _mesa_append_fog_code(ctx, fp); + pass0_prealloc_mesa_consts(nvs); break; default: fprintf(stderr, "Unknown program type %d", prog->Target); + FREE(rec); + /* DESTROY TREE!! */ return GL_FALSE; } nvs->func->card_priv = &nvs->card_priv; - rec = CALLOC_STRUCT(pass0_rec); - if (rec) { - rec->next_temp = prog->NumTemporaries; - nvs->pass_rec = rec; - - nvs->program_tree = (nvsFragmentHeader*) - pass0_create_subroutine(nvs, "program body"); - if (nvs->program_tree) { - ret = pass0_translate_instructions(nvs, - 0, 0, - nvs->program_tree); - /*XXX: if (!ret) DESTROY TREE!!! */ - } - FREE(rec); - } + ret = pass0_translate_instructions(nvs, 0, 0, nvs->program_tree); + /*XXX: if (!ret) DESTROY TREE!!! */ + FREE(rec); return ret; } -- cgit v1.2.3 From d2c4d9ff9beb36895bb8ee7aabb65e70c3068816 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 30 Jan 2007 16:00:20 +1100 Subject: nouveau: NV40 glClipPlane support. --- src/mesa/drivers/dri/nouveau/nouveau_shader.h | 1 + src/mesa/drivers/dri/nouveau/nouveau_shader_0.c | 88 +++++++++++++++++++++---- src/mesa/drivers/dri/nouveau/nv30_state.c | 15 ++++- src/mesa/drivers/dri/nouveau/nv30_vertprog.c | 3 + src/mesa/drivers/dri/nouveau/nv40_vertprog.c | 7 ++ 5 files changed, 101 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h index 68007dd1ea..b2df3546f6 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -32,6 +32,7 @@ typedef union { struct { uint32_t vp_in_reg; uint32_t vp_out_reg; + uint32_t clip_enables; } NV30VP; } nvsCardPriv; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c index fb6e0b05c3..73c1f7c2a5 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -811,12 +811,65 @@ pass0_build_attrib_map(nouveauShader *nvs, struct gl_vertex_program *vp) } static void -pass0_prealloc_mesa_consts(nouveauShader *nvs) +pass0_vp_insert_ff_clip_planes(GLcontext *ctx, nouveauShader *nvs) +{ + struct gl_program *prog = &nvs->mesa.vp.Base; + nvsFragmentHeader *parent = nvs->program_tree; + nvsInstruction *nvsinst; + GLuint fpos = 0; + nvsRegister opos, epos, eqn, mv[4]; + GLint tokens[6] = { STATE_MATRIX, STATE_MODELVIEW, 0, 0, 0, 0 }; + GLint id; + int i; + + /* modelview transform */ + pass0_make_reg(nvs, &opos, NVS_FILE_ATTRIB, NVS_FR_POSITION); + pass0_make_reg(nvs, &epos, NVS_FILE_TEMP , -1); + for (i=0; i<4; i++) { + tokens[3] = tokens[4] = i; + id = _mesa_add_state_reference(prog->Parameters, tokens); + pass0_make_reg(nvs, &mv[i], NVS_FILE_CONST, id); + } + ARITHu(NVS_OP_DP4, epos, SMASK_X, 0, opos, mv[0], nvr_unused); + ARITHu(NVS_OP_DP4, epos, SMASK_Y, 0, opos, mv[1], nvr_unused); + ARITHu(NVS_OP_DP4, epos, SMASK_Z, 0, opos, mv[2], nvr_unused); + ARITHu(NVS_OP_DP4, epos, SMASK_W, 0, opos, mv[3], nvr_unused); + + /* Emit code to emulate fixed-function glClipPlane */ + for (i=0; i<6; i++) { + GLuint clipmask = SMASK_X; + nvsRegister clip; + + if (!(ctx->Transform.ClipPlanesEnabled & (1<Parameters, tokens); + pass0_make_reg(nvs, &eqn , NVS_FILE_CONST , id); + pass0_make_reg(nvs, &clip, NVS_FILE_RESULT, NVS_FR_CLIP0 + i); + + /*XXX: something else needs to take care of modifying the + * instructions to write to the correct hw clip register. + */ + switch (i) { + case 0: case 3: clipmask = SMASK_Y; break; + case 1: case 4: clipmask = SMASK_Z; break; + case 2: case 5: clipmask = SMASK_W; break; + } + + /* Emit transform */ + ARITHu(NVS_OP_DP4, clip, clipmask, 0, epos, eqn, nvr_unused); + } +} + +static void +pass0_rebase_mesa_consts(nouveauShader *nvs) { struct pass0_rec *rec = nvs->pass_rec; struct gl_program *prog = &nvs->mesa.vp.Base; struct prog_instruction *inst = prog->Instructions; - struct gl_program_parameter_list *plist = prog->Parameters; int i; /*XXX: not a good idea, params->hw_index is malloc'd */ @@ -848,10 +901,23 @@ pass0_prealloc_mesa_consts(nouveauShader *nvs) inst++; } - +} + +static void +pass0_resolve_mesa_consts(nouveauShader *nvs) +{ + struct pass0_rec *rec = nvs->pass_rec; + struct gl_program *prog = &nvs->mesa.vp.Base; + struct gl_program_parameter_list *plist = prog->Parameters; + int i; + /* Init all const tracking/alloc info from the parameter list, rather - * than doing it as we translate the program. Otherwise we can't get - * at the correct constant info when relative addressing is being used. + * than doing it as we translate the program. Otherwise: + * 1) we can't get at the correct constant info when relative + * addressing is being used due to src->Index not pointing + * at the exact const; + * 2) as we add extra consts to the program, mesa will call realloc() + * and we get invalid pointers to the const data. */ rec->mesa_const_last = plist->NumParameters + rec->mesa_const_base; nvs->param_high = rec->mesa_const_last; @@ -907,12 +973,10 @@ nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) if (vp->IsPositionInvariant) _mesa_insert_mvp_code(ctx, vp); - pass0_prealloc_mesa_consts(nvs); + pass0_rebase_mesa_consts(nvs); -#if 0 - if (IS_FIXEDFUNCTION_PROG && CLIP_PLANES_USED) - pass0_insert_ff_clip_planes(); -#endif + if (!prog->String && ctx->Transform.ClipPlanesEnabled) + pass0_vp_insert_ff_clip_planes(ctx, nvs); pass0_build_attrib_map(nvs, vp); break; @@ -921,7 +985,7 @@ nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) if (fp->FogOption != GL_NONE) _mesa_append_fog_code(ctx, fp); - pass0_prealloc_mesa_consts(nvs); + pass0_rebase_mesa_consts(nvs); break; default: fprintf(stderr, "Unknown program type %d", prog->Target); @@ -932,6 +996,8 @@ nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) nvs->func->card_priv = &nvs->card_priv; ret = pass0_translate_instructions(nvs, 0, 0, nvs->program_tree); + if (ret) + pass0_resolve_mesa_consts(nvs); /*XXX: if (!ret) DESTROY TREE!!! */ FREE(rec); diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 55b6463781..db13ec70b4 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -127,6 +127,11 @@ static void nv30ClearStencil(GLcontext *ctx, GLint s) static void nv30ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (NOUVEAU_CARD_USING_SHADERS) + return; + + plane -= GL_CLIP_PLANE0; BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4); OUT_RING_CACHEf(equation[0]); OUT_RING_CACHEf(equation[1]); @@ -208,8 +213,14 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) case GL_CLIP_PLANE3: case GL_CLIP_PLANE4: case GL_CLIP_PLANE5: - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1); - OUT_RING_CACHE(state); + if (NOUVEAU_CARD_USING_SHADERS) { + nouveauShader *nvs = (nouveauShader *)ctx->VertexProgram._Current; + if (nvs) + nvs->translated = GL_FALSE; + } else { + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1); + OUT_RING_CACHE(state); + } break; case GL_COLOR_LOGIC_OP: BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1); diff --git a/src/mesa/drivers/dri/nouveau/nv30_vertprog.c b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c index afcacf36c2..d023e8439e 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_vertprog.c +++ b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c @@ -33,6 +33,9 @@ NV30VPUploadToHW(GLcontext *ctx, nouveauShader *nvs) BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_IN_REG, 2); OUT_RING(nvs->card_priv.NV30VP.vp_in_reg); OUT_RING(nvs->card_priv.NV30VP.vp_out_reg); + + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_CLIPPING_PLANES, 1); + OUT_RING_CACHE (nvs->card_priv.NV30VP.clip_enables); } static void diff --git a/src/mesa/drivers/dri/nouveau/nv40_vertprog.c b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c index 6cb7e1cfd6..d054140bcd 100644 --- a/src/mesa/drivers/dri/nouveau/nv40_vertprog.c +++ b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c @@ -86,6 +86,7 @@ NV40VPTranslateResultReg(nvsFunc *shader, nvsFixedReg result, unsigned int *mask_ret) { unsigned int *out_reg = &shader->card_priv->NV30VP.vp_out_reg; + unsigned int *clip_en = &shader->card_priv->NV30VP.clip_enables; *mask_ret = 0xf; @@ -111,14 +112,17 @@ NV40VPTranslateResultReg(nvsFunc *shader, nvsFixedReg result, return NV40_VP_INST_DEST_FOGC; case NVS_FR_CLIP0: (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP0; + (*clip_en) |= 0x00000002; *mask_ret = 0x4; return NV40_VP_INST_DEST_FOGC; case NVS_FR_CLIP1: (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP1; + (*clip_en) |= 0x00000020; *mask_ret = 0x2; return NV40_VP_INST_DEST_FOGC; case NVS_FR_CLIP2: (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP2; + (*clip_en) |= 0x00000200; *mask_ret = 0x1; return NV40_VP_INST_DEST_FOGC; case NVS_FR_POINTSZ: @@ -127,13 +131,16 @@ NV40VPTranslateResultReg(nvsFunc *shader, nvsFixedReg result, return NV40_VP_INST_DEST_PSZ; case NVS_FR_CLIP3: (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP3; + (*clip_en) |= 0x00002000; *mask_ret = 0x4; return NV40_VP_INST_DEST_PSZ; case NVS_FR_CLIP4: + (*clip_en) |= 0x00020000; (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP4; *mask_ret = 0x2; return NV40_VP_INST_DEST_PSZ; case NVS_FR_CLIP5: + (*clip_en) |= 0x00200000; (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP5; *mask_ret = 0x1; return NV40_VP_INST_DEST_PSZ; -- cgit v1.2.3 From f9345c7c4e22cd40d2efda73f1b044ab808f2c78 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 30 Jan 2007 16:49:27 +1100 Subject: nouveau: misc NV40 fixes --- src/mesa/drivers/dri/nouveau/nv30_state.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index db13ec70b4..e1e0da98d4 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -244,6 +244,8 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) OUT_RING_CACHE(state); break; case GL_FOG: + if (!NOUVEAU_CARD_USING_SHADERS) + break; BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_ENABLE, 1); OUT_RING_CACHE(state); break; @@ -736,9 +738,13 @@ void (*TexParameter)(GLcontext *ctx, GLenum target, static void nv30TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16); - /*XXX: This SHOULD work.*/ - OUT_RING_CACHEp(mat->m, 16); + + if (!NOUVEAU_CARD_USING_SHADERS) { + BEGIN_RING_CACHE(NvSub3D, + NV30_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16); + /*XXX: This SHOULD work.*/ + OUT_RING_CACHEp(mat->m, 16); + } } static void nv30WindowMoved(nouveauContextPtr nmesa) -- cgit v1.2.3 From a4ddd64f3659b9db7719d3746c1469ece6bb44c5 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 30 Jan 2007 16:51:50 +1100 Subject: nouveau: argh --- src/mesa/drivers/dri/nouveau/nv30_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index e1e0da98d4..96a07fd536 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -244,7 +244,7 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) OUT_RING_CACHE(state); break; case GL_FOG: - if (!NOUVEAU_CARD_USING_SHADERS) + if (NOUVEAU_CARD_USING_SHADERS) break; BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_ENABLE, 1); OUT_RING_CACHE(state); -- cgit v1.2.3 From 832417f31e81b415894414621500b7aef328652b Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 30 Jan 2007 08:02:20 -0700 Subject: s/params/pointer/ for glGetVertexAttribPointer --- src/mesa/glapi/gl_API.xml | 2 +- src/mesa/glapi/glapitemp.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/glapi/gl_API.xml b/src/mesa/glapi/gl_API.xml index 905c4a03a6..b45da17ea9 100644 --- a/src/mesa/glapi/gl_API.xml +++ b/src/mesa/glapi/gl_API.xml @@ -7209,7 +7209,7 @@ - + diff --git a/src/mesa/glapi/glapitemp.h b/src/mesa/glapi/glapitemp.h index 340a4f6a04..a7c4f4950a 100644 --- a/src/mesa/glapi/glapitemp.h +++ b/src/mesa/glapi/glapitemp.h @@ -4865,7 +4865,7 @@ KEYWORD1 void KEYWORD2 NAME(GetTrackMatrixivNV)(GLenum target, GLuint address, G DISPATCH(GetTrackMatrixivNV, (target, address, pname, params), (F, "glGetTrackMatrixivNV(0x%x, %d, 0x%x, %p);\n", target, address, pname, (const void *) params)); } -KEYWORD1 void KEYWORD2 NAME(GetVertexAttribPointervARB)(GLuint index, GLenum pname, GLvoid ** params) +KEYWORD1 void KEYWORD2 NAME(GetVertexAttribPointervARB)(GLuint index, GLenum pname, GLvoid ** pointer) { DISPATCH(GetVertexAttribPointervNV, (index, pname, params), (F, "glGetVertexAttribPointervARB(%d, 0x%x, %p);\n", index, pname, (const void *) params)); } -- cgit v1.2.3 From fea6a8e1f1d569163b4b2ea218d548707a21d4dc Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 30 Jan 2007 08:10:03 -0700 Subject: s/params/pointer/ for glGetVertexAttribPointer --- src/mesa/glapi/gl_API.xml | 2 +- src/mesa/glapi/glapitable.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/glapi/gl_API.xml b/src/mesa/glapi/gl_API.xml index 5f15e5fb04..bd31e8871b 100644 --- a/src/mesa/glapi/gl_API.xml +++ b/src/mesa/glapi/gl_API.xml @@ -11234,7 +11234,7 @@ - + diff --git a/src/mesa/glapi/glapitable.h b/src/mesa/glapi/glapitable.h index 026af32af8..55548adcd3 100644 --- a/src/mesa/glapi/glapitable.h +++ b/src/mesa/glapi/glapitable.h @@ -704,7 +704,7 @@ struct _glapi_table void (GLAPIENTRYP GetProgramStringNV)(GLuint id, GLenum pname, GLubyte * program); /* 664 */ void (GLAPIENTRYP GetProgramivNV)(GLuint id, GLenum pname, GLint * params); /* 665 */ void (GLAPIENTRYP GetTrackMatrixivNV)(GLenum target, GLuint address, GLenum pname, GLint * params); /* 666 */ - void (GLAPIENTRYP GetVertexAttribPointervNV)(GLuint index, GLenum pname, GLvoid ** params); /* 667 */ + void (GLAPIENTRYP GetVertexAttribPointervNV)(GLuint index, GLenum pname, GLvoid ** pointer); /* 667 */ void (GLAPIENTRYP GetVertexAttribdvNV)(GLuint index, GLenum pname, GLdouble * params); /* 668 */ void (GLAPIENTRYP GetVertexAttribfvNV)(GLuint index, GLenum pname, GLfloat * params); /* 669 */ void (GLAPIENTRYP GetVertexAttribivNV)(GLuint index, GLenum pname, GLint * params); /* 670 */ -- cgit v1.2.3 From 8811a9e38a9b71c5bb4f0c652ef0d77d5dd075fd Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 30 Jan 2007 08:11:50 -0700 Subject: bump version to 6.5.3 --- src/mesa/main/version.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/mesa/main/version.h b/src/mesa/main/version.h index e6196050b9..e4a74cb0d4 100644 --- a/src/mesa/main/version.h +++ b/src/mesa/main/version.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5.2 + * Version: 6.5.3 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 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"), @@ -30,8 +30,8 @@ /* Mesa version */ #define MESA_MAJOR 6 #define MESA_MINOR 5 -#define MESA_PATCH 2 -#define MESA_VERSION_STRING "6.5.2" +#define MESA_PATCH 3 +#define MESA_VERSION_STRING "6.5.3" /* To make version comparison easy */ #define MESA_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) @@ -39,10 +39,10 @@ /* OpenGL API version */ -#define OPENGL_MAJOR 1 -#define OPENGL_MINOR 5 +#define OPENGL_MAJOR 2 +#define OPENGL_MINOR 0 #define OPENGL_PATCH 0 -#define OPENGL_VERSION_STRING "1.5" +#define OPENGL_VERSION_STRING "2.0" /* To make version comparison easy */ #define OPENGL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) -- cgit v1.2.3 From d2c62e6065acf5ab6003f568e543c59a6e4d5cd1 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 30 Jan 2007 08:13:02 -0700 Subject: s/params/pointer/ for glGetVertexAttribPointer --- src/glx/x11/indirect.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/glx/x11/indirect.h b/src/glx/x11/indirect.h index e5b1fadf2b..630062e233 100644 --- a/src/glx/x11/indirect.h +++ b/src/glx/x11/indirect.h @@ -633,7 +633,7 @@ extern HIDDEN void __indirect_glGetProgramParameterfvNV(GLenum target, GLuint in extern HIDDEN void __indirect_glGetProgramStringNV(GLuint id, GLenum pname, GLubyte * program); extern HIDDEN void __indirect_glGetProgramivNV(GLuint id, GLenum pname, GLint * params); extern HIDDEN void __indirect_glGetTrackMatrixivNV(GLenum target, GLuint address, GLenum pname, GLint * params); -extern HIDDEN void __indirect_glGetVertexAttribPointervNV(GLuint index, GLenum pname, GLvoid ** params); +extern HIDDEN void __indirect_glGetVertexAttribPointervNV(GLuint index, GLenum pname, GLvoid ** pointer); extern HIDDEN void __indirect_glGetVertexAttribdvNV(GLuint index, GLenum pname, GLdouble * params); extern HIDDEN void __indirect_glGetVertexAttribfvNV(GLuint index, GLenum pname, GLfloat * params); extern HIDDEN void __indirect_glGetVertexAttribivNV(GLuint index, GLenum pname, GLint * params); -- cgit v1.2.3 From 876e372567ad44c03b9d9db6e57d3a06b684f6e1 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 30 Jan 2007 08:13:49 -0700 Subject: regenerated --- src/glx/x11/indirect.c | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/glx/x11/indirect.c b/src/glx/x11/indirect.c index b5c306c562..87c523383b 100644 --- a/src/glx/x11/indirect.c +++ b/src/glx/x11/indirect.c @@ -474,7 +474,7 @@ __indirect_glBegin(GLenum mode) void __indirect_glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, - const GLubyte * bitmap) + const GLubyte *bitmap) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint compsize = @@ -541,7 +541,7 @@ __indirect_glColor3b(GLbyte red, GLbyte green, GLbyte blue) #define X_GLrop_Color3bv 6 void -__indirect_glColor3bv(const GLbyte * v) +__indirect_glColor3bv(const GLbyte *v) { generic_3_byte(X_GLrop_Color3bv, v); } @@ -656,7 +656,7 @@ __indirect_glColor3ub(GLubyte red, GLubyte green, GLubyte blue) #define X_GLrop_Color3ubv 11 void -__indirect_glColor3ubv(const GLubyte * v) +__indirect_glColor3ubv(const GLubyte *v) { generic_3_byte(X_GLrop_Color3ubv, v); } @@ -726,7 +726,7 @@ __indirect_glColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha) #define X_GLrop_Color4bv 14 void -__indirect_glColor4bv(const GLbyte * v) +__indirect_glColor4bv(const GLbyte *v) { generic_4_byte(X_GLrop_Color4bv, v); } @@ -847,7 +847,7 @@ __indirect_glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) #define X_GLrop_Color4ubv 19 void -__indirect_glColor4ubv(const GLubyte * v) +__indirect_glColor4ubv(const GLubyte *v) { generic_4_byte(X_GLrop_Color4ubv, v); } @@ -1051,7 +1051,7 @@ __indirect_glNormal3b(GLbyte nx, GLbyte ny, GLbyte nz) #define X_GLrop_Normal3bv 28 void -__indirect_glNormal3bv(const GLbyte * v) +__indirect_glNormal3bv(const GLbyte *v) { generic_3_byte(X_GLrop_Normal3bv, v); } @@ -2584,7 +2584,7 @@ __indirect_glPolygonMode(GLenum face, GLenum mode) #define X_GLrop_PolygonStipple 102 void -__indirect_glPolygonStipple(const GLubyte * mask) +__indirect_glPolygonStipple(const GLubyte *mask) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint compsize = @@ -4207,7 +4207,7 @@ __indirect_glGetPixelMapusv(GLenum map, GLushort * values) #define X_GLsop_GetPolygonStipple 128 void -__indirect_glGetPolygonStipple(GLubyte * mask) +__indirect_glGetPolygonStipple(GLubyte *mask) { __GLXcontext *const gc = __glXGetCurrentContext(); const __GLXattribute *const state = gc->client_state_private; @@ -4977,7 +4977,7 @@ __indirect_glIndexub(GLubyte c) #define X_GLrop_Indexubv 194 void -__indirect_glIndexubv(const GLubyte * c) +__indirect_glIndexubv(const GLubyte *c) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; @@ -7935,7 +7935,7 @@ __indirect_glVertexAttrib3svARB(GLuint index, const GLshort * v) #define X_GLrop_VertexAttrib4NbvARB 4235 void -__indirect_glVertexAttrib4NbvARB(GLuint index, const GLbyte * v) +__indirect_glVertexAttrib4NbvARB(GLuint index, const GLbyte *v) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; @@ -7999,7 +7999,7 @@ __indirect_glVertexAttrib4NubARB(GLuint index, GLubyte x, GLubyte y, #define X_GLrop_VertexAttrib4NubvARB 4201 void -__indirect_glVertexAttrib4NubvARB(GLuint index, const GLubyte * v) +__indirect_glVertexAttrib4NubvARB(GLuint index, const GLubyte *v) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; @@ -8044,7 +8044,7 @@ __indirect_glVertexAttrib4NusvARB(GLuint index, const GLushort * v) #define X_GLrop_VertexAttrib4bvARB 4230 void -__indirect_glVertexAttrib4bvARB(GLuint index, const GLbyte * v) +__indirect_glVertexAttrib4bvARB(GLuint index, const GLbyte *v) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; @@ -8176,7 +8176,7 @@ __indirect_glVertexAttrib4svARB(GLuint index, const GLshort * v) #define X_GLrop_VertexAttrib4ubvARB 4232 void -__indirect_glVertexAttrib4ubvARB(GLuint index, const GLubyte * v) +__indirect_glVertexAttrib4ubvARB(GLuint index, const GLubyte *v) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; @@ -8556,7 +8556,7 @@ __indirect_glSecondaryColor3bEXT(GLbyte red, GLbyte green, GLbyte blue) #define X_GLrop_SecondaryColor3bvEXT 4126 void -__indirect_glSecondaryColor3bvEXT(const GLbyte * v) +__indirect_glSecondaryColor3bvEXT(const GLbyte *v) { generic_3_byte(X_GLrop_SecondaryColor3bvEXT, v); } @@ -8671,7 +8671,7 @@ __indirect_glSecondaryColor3ubEXT(GLubyte red, GLubyte green, GLubyte blue) #define X_GLrop_SecondaryColor3ubvEXT 4131 void -__indirect_glSecondaryColor3ubvEXT(const GLubyte * v) +__indirect_glSecondaryColor3ubvEXT(const GLubyte *v) { generic_3_byte(X_GLrop_SecondaryColor3ubvEXT, v); } @@ -8943,7 +8943,7 @@ __indirect_glGetProgramParameterfvNV(GLenum target, GLuint index, #define X_GLvop_GetProgramStringNV 1299 void -__indirect_glGetProgramStringNV(GLuint id, GLenum pname, GLubyte * program) +__indirect_glGetProgramStringNV(GLuint id, GLenum pname, GLubyte *program) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; @@ -9087,7 +9087,7 @@ __indirect_glIsProgramNV(GLuint program) #define X_GLrop_LoadProgramNV 4183 void __indirect_glLoadProgramNV(GLenum target, GLuint id, GLsizei len, - const GLubyte * program) + const GLubyte *program) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16 + __GLX_PAD(len); @@ -9656,7 +9656,7 @@ __indirect_glVertexAttrib4ubNV(GLuint index, GLubyte x, GLubyte y, GLubyte z, #define X_GLrop_VertexAttrib4ubvNV 4277 void -__indirect_glVertexAttrib4ubvNV(GLuint index, const GLubyte * v) +__indirect_glVertexAttrib4ubvNV(GLuint index, const GLubyte *v) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; @@ -9887,7 +9887,7 @@ __indirect_glVertexAttribs4svNV(GLuint index, GLsizei n, const GLshort * v) #define X_GLrop_VertexAttribs4ubvNV 4214 void -__indirect_glVertexAttribs4ubvNV(GLuint index, GLsizei n, const GLubyte * v) +__indirect_glVertexAttribs4ubvNV(GLuint index, GLsizei n, const GLubyte *v) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((n * 4)); @@ -9951,7 +9951,7 @@ __indirect_glActiveStencilFaceEXT(GLenum face) #define X_GLvop_GetProgramNamedParameterdvNV 1311 void __indirect_glGetProgramNamedParameterdvNV(GLuint id, GLsizei len, - const GLubyte * name, + const GLubyte *name, GLdouble * params) { __GLXcontext *const gc = __glXGetCurrentContext(); @@ -9975,7 +9975,7 @@ __indirect_glGetProgramNamedParameterdvNV(GLuint id, GLsizei len, #define X_GLvop_GetProgramNamedParameterfvNV 1310 void __indirect_glGetProgramNamedParameterfvNV(GLuint id, GLsizei len, - const GLubyte * name, + const GLubyte *name, GLfloat * params) { __GLXcontext *const gc = __glXGetCurrentContext(); @@ -9999,7 +9999,7 @@ __indirect_glGetProgramNamedParameterfvNV(GLuint id, GLsizei len, #define X_GLrop_ProgramNamedParameter4dvNV 4219 void __indirect_glProgramNamedParameter4dNV(GLuint id, GLsizei len, - const GLubyte * name, GLdouble x, + const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w) { __GLXcontext *const gc = __glXGetCurrentContext(); @@ -10023,7 +10023,7 @@ __indirect_glProgramNamedParameter4dNV(GLuint id, GLsizei len, #define X_GLrop_ProgramNamedParameter4dvNV 4219 void __indirect_glProgramNamedParameter4dvNV(GLuint id, GLsizei len, - const GLubyte * name, + const GLubyte *name, const GLdouble * v) { __GLXcontext *const gc = __glXGetCurrentContext(); @@ -10044,7 +10044,7 @@ __indirect_glProgramNamedParameter4dvNV(GLuint id, GLsizei len, #define X_GLrop_ProgramNamedParameter4fvNV 4218 void __indirect_glProgramNamedParameter4fNV(GLuint id, GLsizei len, - const GLubyte * name, GLfloat x, + const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { __GLXcontext *const gc = __glXGetCurrentContext(); @@ -10068,7 +10068,7 @@ __indirect_glProgramNamedParameter4fNV(GLuint id, GLsizei len, #define X_GLrop_ProgramNamedParameter4fvNV 4218 void __indirect_glProgramNamedParameter4fvNV(GLuint id, GLsizei len, - const GLubyte * name, + const GLubyte *name, const GLfloat * v) { __GLXcontext *const gc = __glXGetCurrentContext(); -- cgit v1.2.3 From 240641de0c8532009fd21be7d4b0b84e471e91e8 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 30 Jan 2007 19:27:53 +0000 Subject: Helper for rebasing draw requests where min_index != 0. --- src/mesa/sources | 1 + src/mesa/vbo/vbo.h | 14 +++ src/mesa/vbo/vbo_rebase.c | 221 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 236 insertions(+) create mode 100644 src/mesa/vbo/vbo_rebase.c (limited to 'src') diff --git a/src/mesa/sources b/src/mesa/sources index fd6e8b40e5..6d6d22861c 100644 --- a/src/mesa/sources +++ b/src/mesa/sources @@ -143,6 +143,7 @@ VBO_SOURCES = \ vbo/vbo_exec_array.c \ vbo/vbo_exec_draw.c \ vbo/vbo_exec_eval.c \ + vbo/vbo_rebase.c \ vbo/vbo_split.c \ vbo/vbo_split_copy.c \ vbo/vbo_split_inplace.c \ diff --git a/src/mesa/vbo/vbo.h b/src/mesa/vbo/vbo.h index c81d83f9b6..6a6fb28173 100644 --- a/src/mesa/vbo/vbo.h +++ b/src/mesa/vbo/vbo.h @@ -101,4 +101,18 @@ void vbo_split_prims( GLcontext *ctx, const struct split_limits *limits ); +/* Helpers for dealing translating away non-zero min_index. + */ +GLboolean vbo_all_varyings_in_vbos( const struct gl_client_array *arrays[] ); + +void vbo_rebase_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, + vbo_draw_func draw ); + + #endif diff --git a/src/mesa/vbo/vbo_rebase.c b/src/mesa/vbo/vbo_rebase.c new file mode 100644 index 0000000000..2a6f03797a --- /dev/null +++ b/src/mesa/vbo/vbo_rebase.c @@ -0,0 +1,221 @@ + +/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * 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 + */ + +/* Helper for drivers which find themselves rendering a range of + * indices starting somewhere above zero. Typically the application + * is issuing multiple DrawArrays() or DrawElements() to draw + * successive primitives layed out linearly in the vertex arrays. + * Unless the vertex arrays are all in a VBO, the OpenGL semantics + * imply that we need to re-upload the vertex data on each draw call. + * In that case, we want to avoid starting the upload at zero, as it + * will mean every draw call uploads an increasing amount of not-used + * vertex data. Worse - in the software tnl module, all those + * vertices will be transformed and lit. + * + * If we just upload the new data, however, the indices will be + * incorrect as we tend to upload each set of vertex data to a new + * region. + * + * This file provides a helper to adjust the arrays, primitives and + * indices of a draw call so that it can be re-issued with a min_index + * of zero. + */ + +#include "glheader.h" +#include "imports.h" +#include "mtypes.h" + +#include "vbo.h" + + +#define REBASE(TYPE) \ +static void *rebase_##TYPE( const void *ptr, \ + GLuint count, \ + TYPE min_index ) \ +{ \ + const TYPE *in = (TYPE *)ptr; \ + TYPE *tmp_indices = malloc(count * sizeof(TYPE)); \ + GLuint i; \ + \ + for (i = 0; i < count; i++) \ + tmp_indices[i] = in[i] - min_index; \ + \ + return (void *)tmp_indices; \ +} + + +REBASE(GLuint) +REBASE(GLushort) +REBASE(GLubyte) + +GLboolean vbo_all_varyings_in_vbos( const struct gl_client_array *arrays[] ) +{ + GLuint i; + + for (i = 0; i < VERT_ATTRIB_MAX; i++) + if (arrays[i]->StrideB && + arrays[i]->BufferObj->Name == 0) + return GL_FALSE; + + return GL_TRUE; +} + +/* Adjust primitives, indices and vertex definitions so that min_index + * becomes zero. There are lots of reasons for wanting to do this, eg: + * + * Software tnl: + * - any time min_index != 0, otherwise unused vertices lower than + * min_index will be transformed. + * + * Hardware tnl: + * - if ib != NULL and min_index != 0, otherwise vertices lower than + * min_index will be uploaded. Requires adjusting index values. + * + * - if ib == NULL and min_index != 0, just for convenience so this doesn't + * have to be handled within the driver. + * + * Hardware tnl with VBO support: + * - as above, but only when vertices are not (all?) in VBO's. + * - can't save time by trying to upload half a vbo - typically it is + * all or nothing. + */ +void vbo_rebase_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, + vbo_draw_func draw ) +{ + struct gl_client_array tmp_arrays[VERT_ATTRIB_MAX]; + const struct gl_client_array *tmp_array_pointers[VERT_ATTRIB_MAX]; + + struct _mesa_index_buffer tmp_ib; + struct _mesa_prim *tmp_prims = NULL; + void *tmp_indices = NULL; + GLuint i; + + assert(min_index != 0); + + _mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index); + + if (ib) { + /* Unfortunately need to adjust each index individually. + */ + GLboolean map_ib = ib->obj->Name && !ib->obj->Pointer; + void *ptr; + + if (map_ib) + ctx->Driver.MapBuffer(ctx, + GL_ELEMENT_ARRAY_BUFFER, + GL_READ_ONLY_ARB, + ib->obj); + + + ptr = ADD_POINTERS(ib->obj->Pointer, ib->ptr); + + /* Some users might prefer it if we translated elements to + * GLuints here. Others wouldn't... + */ + switch (ib->type) { + case GL_UNSIGNED_INT: + tmp_indices = rebase_GLuint( ptr, ib->count, min_index ); + break; + case GL_UNSIGNED_SHORT: + tmp_indices = rebase_GLushort( ptr, ib->count, min_index ); + break; + case GL_UNSIGNED_BYTE: + tmp_indices = rebase_GLubyte( ptr, ib->count, min_index ); + break; + } + + if (map_ib) + ctx->Driver.UnmapBuffer(ctx, + GL_ELEMENT_ARRAY_BUFFER, + ib->obj); + + tmp_ib.obj = ctx->Array.NullBufferObj; + tmp_ib.ptr = tmp_indices; + tmp_ib.count = ib->count; + tmp_ib.type = ib->type; + + ib = &tmp_ib; + } + else { + /* Otherwise the primitives need adjustment. + */ + tmp_prims = (struct _mesa_prim *)_mesa_malloc(sizeof(*prim) * nr_prims); + + for (i = 0; i < nr_prims; i++) { + /* If this fails, it could indicate an application error: + */ + assert(prim[i].start >= min_index); + + tmp_prims[i] = prim[i]; + tmp_prims[i].start -= min_index; + } + + prim = tmp_prims; + } + + /* Just need to adjust the pointer values on each incoming array. + * This works for VBO and non-vbo rendering and shouldn't pesimize + * VBO-based upload schemes. However this may still not be a fast + * path for hardware tnl for VBO based rendering as most machines + * will be happier if you just specify a starting vertex value in + * each primitive. + * + * For drivers with hardware tnl, you only want to do this if you + * are forced to, eg non-VBO indexed rendering with start != 0. + */ + for (i = 0; i < VERT_ATTRIB_MAX; i++) { + tmp_arrays[i] = *arrays[i]; + tmp_arrays[i].Ptr += min_index * tmp_arrays[i].StrideB; + tmp_array_pointers[i] = &tmp_arrays[i]; + } + + /* Re-issue the draw call. + */ + draw( ctx, + tmp_array_pointers, + prim, + nr_prims, + ib, + 0, + max_index - min_index ); + + if (tmp_indices) + _mesa_free(tmp_indices); + + if (tmp_prims) + _mesa_free(tmp_prims); +} + + + -- cgit v1.2.3 From 893526b8a823fe1b88f2b46376155afb91c84016 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 30 Jan 2007 20:22:55 +0000 Subject: Use new rebase helper. Remove other rebase code. --- src/mesa/drivers/dri/i965/brw_draw.c | 53 +++++++++- src/mesa/drivers/dri/i965/brw_draw_upload.c | 105 ++++---------------- src/mesa/tnl/t_draw.c | 108 ++++++++------------ src/mesa/vbo/vbo.h | 1 - src/mesa/vbo/vbo_exec_array.c | 146 +++++++++++++++------------- src/mesa/vbo/vbo_rebase.c | 3 +- src/mesa/vbo/vbo_split_copy.c | 1 - src/mesa/vbo/vbo_split_inplace.c | 1 - 8 files changed, 185 insertions(+), 233 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index 63cb079ec9..7d8f837093 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -198,7 +198,9 @@ static void brw_merge_inputs( struct brw_context *brw, brw->state.dirty.brw |= BRW_NEW_INPUT_VARYING; } - +/* XXX: could split the primitive list to fallback only on the + * non-conformant primitives. + */ static GLboolean check_fallbacks( struct brw_context *brw, const struct _mesa_prim *prim, GLuint nr_prims ) @@ -251,7 +253,9 @@ static GLboolean check_fallbacks( struct brw_context *brw, return GL_FALSE; } - +/* May fail if out of video memory for texture or vbo upload, or on + * fallback conditions. + */ static GLboolean brw_try_draw_prims( GLcontext *ctx, const struct gl_client_array *arrays[], const struct _mesa_prim *prim, @@ -376,6 +380,33 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, return retval; } +static GLboolean brw_need_rebase( GLcontext *ctx, + const struct gl_client_array *arrays[], + const struct _mesa_index_buffer *ib, + GLuint min_index ) +{ + if (min_index == 0) + return GL_FALSE; + + if (ib) { + if (!vbo_all_varyings_in_vbos(arrays)) + return GL_TRUE; + else + return GL_FALSE; + } + else { + /* Hmm. This isn't quite what I wanted. BRW can actually + * handle the mixed case well enough that we shouldn't need to + * rebase. However, it's probably not very common, nor hugely + * expensive to do it this way: + */ + if (!vbo_all_varyings_in_vbos(arrays)) + return GL_TRUE; + else + return GL_FALSE; + } +} + void brw_draw_prims( GLcontext *ctx, const struct gl_client_array *arrays[], @@ -388,6 +419,21 @@ void brw_draw_prims( GLcontext *ctx, struct intel_context *intel = intel_context(ctx); GLboolean retval; + /* Decide if we want to rebase. If so we end up recursing once + * only into this function. + */ + if (brw_need_rebase( ctx, arrays, ib, min_index )) { + vbo_rebase_prims( ctx, arrays, + prim, nr_prims, + ib, min_index, max_index, + brw_draw_prims ); + + return; + } + + + /* Make a first attempt at drawing: + */ retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index); @@ -440,14 +486,13 @@ void brw_draw_init( struct brw_context *brw ) for (i = 0; i < BRW_NR_UPLOAD_BUFS; i++) { brw->vb.upload.vbo[i] = ctx->Driver.NewBufferObject(ctx, 1, GL_ARRAY_BUFFER_ARB); - /* XXX: Set these to no-backing-store + /* NOTE: These are set to no-backing-store. */ bmBufferSetInvalidateCB(&brw->intel, intel_bufferobj_buffer(intel_buffer_object(brw->vb.upload.vbo[i])), brw_invalidate_vbo_cb, &brw->intel, GL_TRUE); - } ctx->Driver.BufferData( ctx, diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 90637d16ea..6968d745c1 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -309,7 +309,6 @@ copy_array_to_vbo_array( struct brw_context *brw, GLuint i, const struct gl_client_array *array, GLuint element_size, - GLuint min_index, GLuint count) { GLcontext *ctx = &brw->intel.ctx; @@ -347,7 +346,7 @@ copy_array_to_vbo_array( struct brw_context *brw, map += offset; copy_strided_array( map, - array->Ptr + min_index * array->StrideB, + array->Ptr, element_size, array->StrideB, count); @@ -438,10 +437,8 @@ GLboolean brw_upload_vertices( struct brw_context *brw, } upload[nr_uploads++] = input; - input->vbo_rebase_offset = 0; + assert(min_index == 0); } - else - input->vbo_rebase_offset = min_index * input->glarray->StrideB; } /* Upload interleaved arrays if all uploads are interleaved @@ -454,7 +451,6 @@ GLboolean brw_upload_vertices( struct brw_context *brw, input0->glarray = copy_array_to_vbo_array(brw, 0, input0->glarray, interleave, - min_index, input0->count); for (i = 1; i < nr_uploads; i++) { @@ -472,7 +468,6 @@ GLboolean brw_upload_vertices( struct brw_context *brw, input->glarray = copy_array_to_vbo_array(brw, i, input->glarray, input->element_size, - min_index, input->count); } @@ -520,9 +515,9 @@ GLboolean brw_upload_vertices( struct brw_context *brw, vbp.vb[i].vb0.bits.pad = 0; vbp.vb[i].vb0.bits.access_type = BRW_VERTEXBUFFER_ACCESS_VERTEXDATA; vbp.vb[i].vb0.bits.vb_index = i; - vbp.vb[i].offset = (GLuint)input->glarray->Ptr + input->vbo_rebase_offset; + vbp.vb[i].offset = (GLuint)input->glarray->Ptr; vbp.vb[i].buffer = array_buffer(input->glarray); - vbp.vb[i].max_index = max_index - min_index; + vbp.vb[i].max_index = max_index; } @@ -563,94 +558,32 @@ static GLuint element_size( GLenum type ) - -static void rebase_indices_to_vbo_indices( struct brw_context *brw, - const struct _mesa_index_buffer *index_buffer, - struct gl_buffer_object **vbo_return, - GLuint *offset_return ) +void brw_upload_indices( struct brw_context *brw, + const struct _mesa_index_buffer *index_buffer ) { GLcontext *ctx = &brw->intel.ctx; - GLuint min_index = index_buffer->rebase; - const void *indices = index_buffer->ptr; - GLsizei count = index_buffer->count; - GLenum type = index_buffer->type; - GLuint size = element_size(type) * count; - struct gl_buffer_object *bufferobj; - GLuint offset; - GLuint i; - - get_space(brw, size, &bufferobj, &offset); + struct intel_context *intel = &brw->intel; + GLuint ib_size = get_size(index_buffer->type) * index_buffer->count; + struct gl_buffer_object *bufferobj = index_buffer->obj; + GLuint offset = (GLuint)index_buffer->ptr; - *vbo_return = bufferobj; - *offset_return = offset; + /* Turn into a proper VBO: + */ + if (!bufferobj->Name) { + + /* Get new bufferobj, offset: + */ + get_space(brw, ib_size, &bufferobj, &offset); - if (min_index == 0) { /* Straight upload */ ctx->Driver.BufferSubData( ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, offset, - size, - indices, + ib_size, + index_buffer->ptr, bufferobj); } - else { - void *map = ctx->Driver.MapBuffer(ctx, - GL_ELEMENT_ARRAY_BUFFER_ARB, - GL_DYNAMIC_DRAW_ARB, - bufferobj); - - map += offset; - - switch (type) { - case GL_UNSIGNED_INT: { - GLuint *ui_map = (GLuint *)map; - const GLuint *ui_indices = (const GLuint *)indices; - - for (i = 0; i < count; i++) - ui_map[i] = ui_indices[i] - min_index; - break; - } - case GL_UNSIGNED_SHORT: { - GLushort *us_map = (GLushort *)map; - const GLushort *us_indices = (const GLushort *)indices; - - for (i = 0; i < count; i++) - us_map[i] = us_indices[i] - min_index; - break; - } - case GL_UNSIGNED_BYTE: { - GLubyte *ub_map = (GLubyte *)map; - const GLubyte *ub_indices = (const GLubyte *)indices; - - for (i = 0; i < count; i++) - ub_map[i] = ub_indices[i] - min_index; - break; - } - } - - ctx->Driver.UnmapBuffer(ctx, - GL_ELEMENT_ARRAY_BUFFER_ARB, - bufferobj); - - } -} - - - -void brw_upload_indices( struct brw_context *brw, - const struct _mesa_index_buffer *index_buffer) -{ - struct intel_context *intel = &brw->intel; - GLuint ib_size = get_size(index_buffer->type) * index_buffer->count; - struct gl_buffer_object *bufferobj = index_buffer->obj; - GLuint offset = (GLuint)index_buffer->ptr; - - /* Already turned into a proper VBO: - */ - if (!index_buffer->obj->Name) { - rebase_indices_to_vbo_indices(brw, index_buffer, &bufferobj, &offset ); - } /* Emit the indexbuffer packet: */ diff --git a/src/mesa/tnl/t_draw.c b/src/mesa/tnl/t_draw.c index 0e7c2b6a68..c97cf5f7b2 100644 --- a/src/mesa/tnl/t_draw.c +++ b/src/mesa/tnl/t_draw.c @@ -95,18 +95,14 @@ static void free_space(GLcontext *ctx) */ static void _tnl_import_array( GLcontext *ctx, GLuint attrib, - GLuint start, - GLuint end, + GLuint count, const struct gl_client_array *input, const GLubyte *ptr ) { TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; - const GLuint count = end - start; GLuint stride = input->StrideB; - ptr += start * stride; - if (input->Type != GL_FLOAT) { const GLuint sz = input->Size; GLubyte *buf = get_space(ctx, count * sz * sizeof(GLfloat)); @@ -183,7 +179,7 @@ static GLboolean *_tnl_import_edgeflag( GLcontext *ctx, static void bind_inputs( GLcontext *ctx, const struct gl_client_array *inputs[], - GLint min_index, GLint max_index, + GLint count, struct gl_buffer_object **bo, GLuint *nr_bo ) { @@ -215,18 +211,17 @@ static void bind_inputs( GLcontext *ctx, ptr = inputs[i]->Ptr; /* Just make sure the array is floating point, otherwise convert to - * temporary storage. Rebase arrays so that 'min_index' becomes - * element zero. + * temporary storage. * * XXX: remove the GLvector4f type at some stage and just use * client arrays. */ - _tnl_import_array(ctx, i, min_index, max_index, inputs[i], ptr); + _tnl_import_array(ctx, i, count, inputs[i], ptr); } /* We process only the vertices between min & max index: */ - VB->Count = max_index - min_index; + VB->Count = count; /* Legacy pointers -- remove one day. @@ -264,7 +259,6 @@ static void bind_inputs( GLcontext *ctx, */ static void bind_indices( GLcontext *ctx, const struct _mesa_index_buffer *ib, - GLuint min_index, struct gl_buffer_object **bo, GLuint *nr_bo) { @@ -273,8 +267,10 @@ static void bind_indices( GLcontext *ctx, GLuint i; void *ptr; - if (!ib) + if (!ib) { + VB->Elts = NULL; return; + } if (ib->obj->Name && !ib->obj->Pointer) { bo[*nr_bo] = ib->obj; @@ -289,60 +285,34 @@ static void bind_indices( GLcontext *ctx, ptr = ADD_POINTERS(ib->obj->Pointer, ib->ptr); - if (ib->type == GL_UNSIGNED_INT && min_index == 0) { + if (ib->type == GL_UNSIGNED_INT) { VB->Elts = (GLuint *) ptr; - VB->Elts += ib->rebase; } else { GLuint *elts = (GLuint *)get_space(ctx, ib->count * sizeof(GLuint)); VB->Elts = elts; - switch (ib->type) { - case GL_UNSIGNED_INT: { - const GLuint *in = ((GLuint *)ptr) + ib->rebase; - for (i = 0; i < ib->count; i++) - *elts++ = *in++ - min_index; - break; - } - case GL_UNSIGNED_SHORT: { - const GLushort *in = ((GLushort *)ptr) + ib->rebase; + if (ib->type == GL_UNSIGNED_SHORT) { + const GLushort *in = (GLushort *)ptr; for (i = 0; i < ib->count; i++) - *elts++ = (GLuint)(*in++) - min_index; - break; + *elts++ = (GLuint)(*in++); } - case GL_UNSIGNED_BYTE: { - const GLubyte *in = ((GLubyte *)ptr) + ib->rebase; + else { + const GLubyte *in = (GLubyte *)ptr; for (i = 0; i < ib->count; i++) - *elts++ = (GLuint)(*in++) - min_index; - break; + *elts++ = (GLuint)(*in++); } - } } } static void bind_prims( GLcontext *ctx, const struct _mesa_prim *prim, - GLuint nr_prims, - GLuint min_index ) + GLuint nr_prims ) { TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; - GLuint i; - - if (min_index != 0) { - struct _mesa_prim *tmp = (struct _mesa_prim *)get_space(ctx, nr_prims * sizeof(*prim)); - - for (i = 0; i < nr_prims; i++) { - tmp[i] = prim[i]; - tmp[i].start -= min_index; - } - - VB->Primitive = tmp; - } - else { - VB->Primitive = prim; - } + VB->Primitive = prim; VB->PrimitiveCount = nr_prims; } @@ -373,19 +343,10 @@ void _tnl_draw_prims( GLcontext *ctx, GLuint max_index) { TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - GLint max = VB->Size; - -#ifdef TEST_SPLIT - max = 8 + MAX_CLIPPED_VERTICES; -#endif - - assert(max_index > min_index); - assert(!(max_index & 0x80000000)); + const GLuint TEST_SPLIT = 0; + const GLint max = TEST_SPLIT ? 8 : tnl->vb.Size - MAX_CLIPPED_VERTICES; - VB->Elts = NULL; - -#if 0 + if (0) { GLuint i; _mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index); @@ -395,15 +356,22 @@ void _tnl_draw_prims( GLcontext *ctx, prim[i].start, prim[i].count); } -#endif - /* The software TNL pipeline has a fixed amount of storage for - * vertices and it is necessary to split incoming drawing commands - * if they exceed that limit. - */ - if (max_index - min_index >= max - MAX_CLIPPED_VERTICES) { + if (min_index) { + /* We always translate away calls with min_index != 0. + */ + vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib, + min_index, max_index, + _tnl_draw_prims ); + return; + } + else if (max_index >= max) { + /* The software TNL pipeline has a fixed amount of storage for + * vertices and it is necessary to split incoming drawing commands + * if they exceed that limit. + */ struct split_limits limits; - limits.max_verts = max - MAX_CLIPPED_VERTICES; + limits.max_verts = max; limits.max_vb_size = ~0; limits.max_indices = ~0; @@ -411,7 +379,7 @@ void _tnl_draw_prims( GLcontext *ctx, * recursively call back into this function. */ vbo_split_prims( ctx, arrays, prim, nr_prims, ib, - min_index, max_index, + 0, max_index, _tnl_draw_prims, &limits ); } @@ -425,9 +393,9 @@ void _tnl_draw_prims( GLcontext *ctx, /* Binding inputs may imply mapping some vertex buffer objects. * They will need to be unmapped below. */ - bind_inputs(ctx, arrays, min_index, max_index+1, bo, &nr_bo); - bind_indices(ctx, ib, min_index, bo, &nr_bo); - bind_prims(ctx, prim, nr_prims, VB->Elts ? 0 : min_index ); + bind_inputs(ctx, arrays, max_index+1, bo, &nr_bo); + bind_indices(ctx, ib, bo, &nr_bo); + bind_prims(ctx, prim, nr_prims ); TNL_CONTEXT(ctx)->Driver.RunPipeline(ctx); diff --git a/src/mesa/vbo/vbo.h b/src/mesa/vbo/vbo.h index 6a6fb28173..874a5f9e0e 100644 --- a/src/mesa/vbo/vbo.h +++ b/src/mesa/vbo/vbo.h @@ -55,7 +55,6 @@ struct _mesa_index_buffer { GLenum type; struct gl_buffer_object *obj; const void *ptr; - GLuint rebase; }; diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index 5a3a7488ed..f96df5f164 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -34,45 +34,55 @@ #include "vbo_context.h" -static GLuint get_max_index( GLuint count, GLuint type, - const GLvoid *indices ) +/* Compute min and max elements for drawelements calls. + */ +static void get_minmax_index( GLuint count, GLuint type, + const GLvoid *indices, + GLuint *min_index, + GLuint *max_index) { GLint i; - /* Compute max element. This is only needed for upload of non-VBO, - * non-constant data elements. - * - * XXX: Postpone this calculation until it is known that it is - * needed. Otherwise could scan this pointlessly in the all-vbo - * case. - */ switch(type) { case GL_UNSIGNED_INT: { const GLuint *ui_indices = (const GLuint *)indices; - GLuint max_ui = 0; - for (i = 0; i < count; i++) - if (ui_indices[i] > max_ui) - max_ui = ui_indices[i]; - return max_ui; + GLuint max_ui = ui_indices[0]; + GLuint min_ui = ui_indices[0]; + for (i = 1; i < count; i++) { + if (ui_indices[i] > max_ui) max_ui = ui_indices[i]; + if (ui_indices[i] < min_ui) min_ui = ui_indices[i]; + } + *min_index = min_ui; + *max_index = max_ui; + break; } case GL_UNSIGNED_SHORT: { const GLushort *us_indices = (const GLushort *)indices; - GLuint max_us = 0; - for (i = 0; i < count; i++) - if (us_indices[i] > max_us) - max_us = us_indices[i]; - return max_us; + GLuint max_us = us_indices[0]; + GLuint min_us = us_indices[0]; + for (i = 1; i < count; i++) { + if (us_indices[i] > max_us) max_us = us_indices[i]; + if (us_indices[i] < min_us) min_us = us_indices[i]; + } + *min_index = min_us; + *max_index = max_us; + break; } case GL_UNSIGNED_BYTE: { const GLubyte *ub_indices = (const GLubyte *)indices; - GLuint max_ub = 0; - for (i = 0; i < count; i++) - if (ub_indices[i] > max_ub) - max_ub = ub_indices[i]; - return max_ub; + GLuint max_ub = ub_indices[0]; + GLuint min_ub = ub_indices[0]; + for (i = 1; i < count; i++) { + if (ub_indices[i] > max_ub) max_ub = ub_indices[i]; + if (ub_indices[i] < min_ub) min_ub = ub_indices[i]; + } + *min_index = min_ub; + *max_index = max_ub; + break; } default: - return 0; + assert(0); + break; } } @@ -241,31 +251,12 @@ vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count) prim[0].end = 1; prim[0].weak = 0; prim[0].pad = 0; + prim[0].mode = mode; + prim[0].start = start; + prim[0].count = count; + prim[0].indexed = 0; - if (exec->array.inputs[0]->BufferObj->Name) { - /* Use vertex attribute as a hint to tell us if we expect all - * arrays to be in VBO's and if so, don't worry about avoiding - * the upload of elements < start. - */ - prim[0].mode = mode; - prim[0].start = start; - prim[0].count = count; - prim[0].indexed = 0; - - vbo->draw_prims( ctx, exec->array.inputs, prim, 1, NULL, 0, start + count ); - } - else { - /* If not using VBO's, we don't want to upload any more elements - * than necessary from the arrays as they will not be valid next - * time the application tries to draw with them. - */ - prim[0].mode = mode; - prim[0].start = 0; - prim[0].count = count; - prim[0].indexed = 0; - - vbo->draw_prims( ctx, exec->array.inputs, prim, 1, NULL, start, start + count ); - } + vbo->draw_prims( ctx, exec->array.inputs, prim, 1, NULL, start, start + count - 1 ); } @@ -296,20 +287,6 @@ vbo_exec_DrawRangeElements(GLenum mode, ib.obj = ctx->Array.ElementArrayBufferObj; ib.ptr = indices; - if (ctx->Array.ElementArrayBufferObj->Name) { - /* Use the fact that indices are in a VBO as a hint that the - * program has put all the arrays in VBO's and we don't have to - * worry about performance implications of start > 0. - * - * XXX: consider passing start as min_index to draw_prims instead. - * XXX: don't rebase because it didn't work. - */ - ib.rebase = 0; - } - else { - ib.rebase = /*start*/ 0; - } - prim[0].begin = 1; prim[0].end = 1; prim[0].weak = 0; @@ -319,15 +296,46 @@ vbo_exec_DrawRangeElements(GLenum mode, prim[0].count = count; prim[0].indexed = 1; - vbo->draw_prims( ctx, exec->array.inputs, prim, 1, &ib, /*ib.rebase*/ start, end+1 ); -} + /* Need to give special consideration to rendering a range of + * indices starting somewhere above zero. Typically the + * application is issuing multiple DrawRangeElements() to draw + * successive primitives layed out linearly in the vertex arrays. + * Unless the vertex arrays are all in a VBO (or locked as with + * CVA), the OpenGL semantics imply that we need to re-read or + * re-upload the vertex data on each draw call. + * + * In the case of hardware tnl, we want to avoid starting the + * upload at zero, as it will mean every draw call uploads an + * increasing amount of not-used vertex data. Worse - in the + * software tnl module, all those vertices might be transformed and + * lit but never rendered. + * + * If we just upload or transform the vertices in start..end, + * however, the indices will be incorrect. + * + * At this level, we don't know exactly what the requirements of + * the backend are going to be, though it will likely boil down to + * either: + * + * 1) Do nothing, everything is in a VBO and is processed once + * only. + * + * 2) Adjust the indices and vertex arrays so that start becomes + * zero. + * + * Rather than doing anything here, I'll provide a helper function + * for the latter case elsewhere. + */ + vbo->draw_prims( ctx, exec->array.inputs, prim, 1, &ib, start, end ); +} static void GLAPIENTRY vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) { GET_CURRENT_CONTEXT(ctx); - GLuint max_index; + GLuint min_index = 0; + GLuint max_index = 0; if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) return; @@ -338,17 +346,17 @@ vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *ind GL_READ_ONLY, ctx->Array.ElementArrayBufferObj); - max_index = get_max_index(count, type, ADD_POINTERS(map, indices)); + get_minmax_index(count, type, ADD_POINTERS(map, indices), &min_index, &max_index); ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, ctx->Array.ElementArrayBufferObj); } else { - max_index = get_max_index(count, type, indices); + get_minmax_index(count, type, indices, &min_index, &max_index); } - vbo_exec_DrawRangeElements(mode, 0, max_index, count, type, indices); + vbo_exec_DrawRangeElements(mode, min_index, max_index, count, type, indices); } diff --git a/src/mesa/vbo/vbo_rebase.c b/src/mesa/vbo/vbo_rebase.c index 2a6f03797a..bc4211d852 100644 --- a/src/mesa/vbo/vbo_rebase.c +++ b/src/mesa/vbo/vbo_rebase.c @@ -123,7 +123,8 @@ void vbo_rebase_prims( GLcontext *ctx, assert(min_index != 0); - _mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index); + if (0) + _mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index); if (ib) { /* Unfortunately need to adjust each index individually. diff --git a/src/mesa/vbo/vbo_split_copy.c b/src/mesa/vbo/vbo_split_copy.c index d9c5853782..ef97acbce7 100644 --- a/src/mesa/vbo/vbo_split_copy.c +++ b/src/mesa/vbo/vbo_split_copy.c @@ -479,7 +479,6 @@ static void replay_init( struct copy_context *copy ) copy->dstib.type = GL_UNSIGNED_INT; copy->dstib.obj = ctx->Array.NullBufferObj; copy->dstib.ptr = copy->dstelt; - copy->dstib.rebase = 0; } diff --git a/src/mesa/vbo/vbo_split_inplace.c b/src/mesa/vbo/vbo_split_inplace.c index d3649c59db..ea62866e7c 100644 --- a/src/mesa/vbo/vbo_split_inplace.c +++ b/src/mesa/vbo/vbo_split_inplace.c @@ -223,7 +223,6 @@ static void split_prims( struct split_context *split) ib.type = GL_UNSIGNED_INT; ib.obj = split->ctx->Array.NullBufferObj; ib.ptr = elts; - ib.rebase = 0; /* ? */ tmpprim = *prim; tmpprim.indexed = 1; -- cgit v1.2.3 From 5893474c741274cde7a312c920dacfb00790c302 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Wed, 31 Jan 2007 09:47:02 +0800 Subject: _mesa_pack_rgba_span_float: fix for packing data into group --- src/mesa/main/image.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c index 6ff4089f0e..fc8e1f0f57 100644 --- a/src/mesa/main/image.c +++ b/src/mesa/main/image.c @@ -1331,6 +1331,7 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4], dst[i*4+2] = FLOAT_TO_BYTE(rgba[i][RCOMP]); dst[i*4+3] = FLOAT_TO_BYTE(rgba[i][ACOMP]); } + break; case GL_ABGR_EXT: for (i=0;i Date: Thu, 1 Feb 2007 01:09:26 +0100 Subject: fix unitialized values in radeonClear --- src/mesa/drivers/dri/radeon/radeon_ioctl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c index 737490fcde..4c64bc201a 100644 --- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c +++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c @@ -1087,10 +1087,6 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask ) } } - /* Flip top to bottom */ - cx += dPriv->x; - cy = dPriv->y + dPriv->h - cy - ch; - LOCK_HARDWARE( rmesa ); /* compute region after locking: */ @@ -1099,6 +1095,10 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask ) cw = ctx->DrawBuffer->_Xmax - cx; ch = ctx->DrawBuffer->_Ymax - cy; + /* Flip top to bottom */ + cx += dPriv->x; + cy = dPriv->y + dPriv->h - cy - ch; + /* Throttle the number of clear ioctls we do. */ while ( 1 ) { -- cgit v1.2.3 From bed026e7dda14ac1c555f1fb16d70eadcd1a01fc Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Thu, 1 Feb 2007 10:43:10 +0100 Subject: driDestroyDisplay: Remove Drivers list entry when dlclosing its handle. This fixes a regression from commit f81b1dbe374fe446f6ef676e70a72952ffb47d4e: Since then, driDestroyDisplay gets called from __glXFreeDisplayPrivate. It dlcloses the handles associated with the display but fails to remove their references from the Drivers list, so subsequent calls to OpenDriver return a stale handle and an invalid createNewScreenFunc pointer. The attempt to call the latter results in a segfault when running amoeba, e.g. --- src/glx/x11/dri_glx.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/glx/x11/dri_glx.c b/src/glx/x11/dri_glx.c index 0875361d0b..5ff1a94c71 100644 --- a/src/glx/x11/dri_glx.c +++ b/src/glx/x11/dri_glx.c @@ -386,8 +386,24 @@ static void driDestroyDisplay(Display *dpy, void *private) const int numScreens = ScreenCount(dpy); int i; for (i = 0; i < numScreens; i++) { - if (pdpyp->libraryHandles[i]) - dlclose(pdpyp->libraryHandles[i]); + if (pdpyp->libraryHandles[i]) { + __DRIdriver *driver, *prev; + + /* Remove driver from Drivers list */ + for (prev = NULL, driver = Drivers; driver; + prev = driver, driver = driver->next) { + if (driver->handle == pdpyp->libraryHandles[i]) { + if (prev) + prev->next = driver->next; + else + Drivers = driver->next; + + Xfree(driver); + } + } + + dlclose(pdpyp->libraryHandles[i]); + } } Xfree(pdpyp->libraryHandles); Xfree(pdpyp); -- cgit v1.2.3 From 8628b382e4ac492d829fe720219187b758add003 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Thu, 1 Feb 2007 10:45:51 +0100 Subject: driDestroyDisplay: Fix comment, it is called now. --- src/glx/x11/dri_glx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/glx/x11/dri_glx.c b/src/glx/x11/dri_glx.c index 5ff1a94c71..6f944d7d60 100644 --- a/src/glx/x11/dri_glx.c +++ b/src/glx/x11/dri_glx.c @@ -376,7 +376,7 @@ const char *glXGetDriverConfig (const char *driverName) { } -/* This function isn't currently used. +/* Called from __glXFreeDisplayPrivate. */ static void driDestroyDisplay(Display *dpy, void *private) { -- cgit v1.2.3 From 605d428d20819ac3f46aaeb4a66707febec7ded2 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 Feb 2007 14:20:31 +0000 Subject: Cope with internally-generated null inputs. --- src/mesa/drivers/dri/i965/brw_draw.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index 7d8f837093..092c6bafc2 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -183,10 +183,13 @@ static void brw_merge_inputs( struct brw_context *brw, for (i = 0; i < VERT_ATTRIB_MAX; i++) { brw->vb.inputs[i].glarray = arrays[i]; - if (arrays[i]->StrideB != 0) - brw->vb.info.varying |= 1 << i; + /* XXX: metaops passes null arrays */ + if (arrays[i]) { + if (arrays[i]->StrideB != 0) + brw->vb.info.varying |= 1 << i; - brw->vb.info.sizes[i/16] |= (inputs[i].glarray->Size - 1) << ((i%16) * 2); + brw->vb.info.sizes[i/16] |= (inputs[i].glarray->Size - 1) << ((i%16) * 2); + } } /* Raise statechanges if input sizes and varying have changed: -- cgit v1.2.3 From 5368ae5ec329ddad5963d55b17cd4eccbc83d32f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 Feb 2007 14:21:14 +0000 Subject: Correct usage/meaning of max_index parameter. --- src/mesa/drivers/dri/i965/brw_draw_upload.c | 4 +++- src/mesa/drivers/dri/i965/brw_metaops.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 6968d745c1..803a524324 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -408,6 +408,8 @@ GLboolean brw_upload_vertices( struct brw_context *brw, /* First build an array of pointers to ve's in vb.inputs_read */ + if (0) + _mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index); while (tmp) { GLuint i = ffsll(tmp)-1; @@ -418,7 +420,7 @@ GLboolean brw_upload_vertices( struct brw_context *brw, input->index = i; input->element_size = get_size(input->glarray->Type) * input->glarray->Size; - input->count = input->glarray->StrideB ? max_index - min_index : 1; + input->count = input->glarray->StrideB ? max_index + 1 - min_index : 1; if (!input->glarray->BufferObj->Name) { if (i == 0) { diff --git a/src/mesa/drivers/dri/i965/brw_metaops.c b/src/mesa/drivers/dri/i965/brw_metaops.c index 1728fc8f56..1579762b6d 100644 --- a/src/mesa/drivers/dri/i965/brw_metaops.c +++ b/src/mesa/drivers/dri/i965/brw_metaops.c @@ -480,7 +480,7 @@ static void meta_draw_quad(struct intel_context *intel, prim, 1, NULL, 0, - 4 ); + 3 ); } -- cgit v1.2.3 From 0930248bb1336064337e636aab0f17ee0f8f7043 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 1 Feb 2007 07:22:25 -0700 Subject: fix mem leak in __glXReportDamage (Panagiotis Papadakos) --- src/glx/x11/glxext.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/glx/x11/glxext.c b/src/glx/x11/glxext.c index 7f3857360d..d24f853d54 100644 --- a/src/glx/x11/glxext.c +++ b/src/glx/x11/glxext.c @@ -758,6 +758,7 @@ static void __glXReportDamage(__DRInativeDisplay *dpy, int screen, xrects[i].height = rects[i].y2 - rects[i].y1; } region = XFixesCreateRegion(dpy, xrects, num_rects); + free(xrects); XDamageAdd(dpy, drawable, region); XFixesDestroyRegion(dpy, region); #endif -- cgit v1.2.3 From 8ebda479d90b0c95df50f790316f451a32f4bd4e Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Thu, 1 Feb 2007 20:59:45 +0100 Subject: fix missing ADD_POINTERS, fixes crashes if the index elements are in a vbo. --- src/mesa/vbo/vbo_split_copy.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/mesa/vbo/vbo_split_copy.c b/src/mesa/vbo/vbo_split_copy.c index ef97acbce7..e142dde680 100644 --- a/src/mesa/vbo/vbo_split_copy.c +++ b/src/mesa/vbo/vbo_split_copy.c @@ -360,6 +360,7 @@ static void replay_init( struct copy_context *copy ) GLcontext *ctx = copy->ctx; GLuint i; GLuint offset; + const GLvoid *srcptr; /* Make a list of varying attributes and their vbo's. Also * calculate vertex size. @@ -402,13 +403,15 @@ static void replay_init( struct copy_context *copy ) GL_WRITE_ONLY, /* XXX */ copy->ib->obj); + srcptr = (const GLubyte *)ADD_POINTERS(copy->ib->obj->Pointer, copy->ib->ptr); + switch (copy->ib->type) { case GL_UNSIGNED_BYTE: copy->translated_elt_buf = _mesa_malloc(sizeof(GLuint) * copy->ib->count); copy->srcelt = copy->translated_elt_buf; - + for (i = 0; i < copy->ib->count; i++) - copy->translated_elt_buf[i] = ((const GLubyte *)copy->ib->ptr)[i]; + copy->translated_elt_buf[i] = ((const GLubyte *)srcptr)[i]; break; case GL_UNSIGNED_SHORT: @@ -416,13 +419,12 @@ static void replay_init( struct copy_context *copy ) copy->srcelt = copy->translated_elt_buf; for (i = 0; i < copy->ib->count; i++) - copy->translated_elt_buf[i] = ((const GLushort *)copy->ib->ptr)[i]; + copy->translated_elt_buf[i] = ((const GLushort *)srcptr)[i]; break; case GL_UNSIGNED_INT: copy->translated_elt_buf = NULL; - copy->srcelt = (const GLuint *)ADD_POINTERS(copy->ib->obj->Pointer, - copy->ib->ptr); + copy->srcelt = (const GLuint *)srcptr; break; } -- cgit v1.2.3 From 2dfb3a217f730d6783fb2ac8b73248dc682f923c Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Fri, 2 Feb 2007 09:35:17 +0800 Subject: Fix fd.o #9686, when fall into vertex fog, fog factors are precomputed in t_vb_fog.c compute_fog_blend_factors, which is incompatible with appended fragment fog code. That will make GoogleEarth display abnormally. always use pixel fog. --- src/mesa/drivers/dri/i915/i915_state.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c index 3cec6a2ddf..fd11e10652 100644 --- a/src/mesa/drivers/dri/i915/i915_state.c +++ b/src/mesa/drivers/dri/i915/i915_state.c @@ -611,10 +611,12 @@ void i915_update_fog( GLcontext *ctx ) i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_FOG_ENABLE; } - if (enabled) { - _tnl_allow_vertex_fog( ctx, (i915->vertex_fog == I915_FOG_VERTEX) ); - _tnl_allow_pixel_fog( ctx, (i915->vertex_fog != I915_FOG_VERTEX) ); - } + /* always enbale pixel fog + * vertex fog use precaculted fog coord will conflict with appended + * fog program + */ + _tnl_allow_vertex_fog( ctx, 0 ); + _tnl_allow_pixel_fog( ctx, 1 ); } static void i915Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) -- cgit v1.2.3 From 325196f548f8e46aa8fcc7b030e81ba939e7f6b7 Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Fri, 2 Feb 2007 14:37:24 +0800 Subject: push commit 2dfb3a217f730d6783fb2ac8b73248dc682f923c to i915tex --- src/mesa/drivers/dri/i915tex/i915_state.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/i915_state.c b/src/mesa/drivers/dri/i915tex/i915_state.c index 7c742a7bd9..78ae4bdb5f 100644 --- a/src/mesa/drivers/dri/i915tex/i915_state.c +++ b/src/mesa/drivers/dri/i915tex/i915_state.c @@ -645,10 +645,12 @@ i915_update_fog(GLcontext * ctx) i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_FOG_ENABLE; } - if (enabled) { - _tnl_allow_vertex_fog(ctx, (i915->vertex_fog == I915_FOG_VERTEX)); - _tnl_allow_pixel_fog(ctx, (i915->vertex_fog != I915_FOG_VERTEX)); - } + /* always enbale pixel fog + * vertex fog use precaculted fog coord will conflict with appended + * fog program + */ + _tnl_allow_vertex_fog( ctx, 0 ); + _tnl_allow_pixel_fog( ctx, 1 ); } static void -- cgit v1.2.3 From 47d463e954efcd15d20ab2c96a455aa16ddffdcc Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 2 Feb 2007 10:59:58 +0000 Subject: Modify assert to reflect rebase criteria --- src/mesa/drivers/dri/i965/brw_draw_upload.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 803a524324..feb0901d12 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -439,7 +439,15 @@ GLboolean brw_upload_vertices( struct brw_context *brw, } upload[nr_uploads++] = input; - assert(min_index == 0); + + /* We rebase drawing to start at element zero only when + * varyings are not in vbos, which means we can end up + * uploading non-varying arrays (stride != 0) when min_index + * is zero. This doesn't matter as the amount to upload is + * the same for these arrays whether the draw call is rebased + * or not - we just have to upload the one element. + */ + assert(min_index == 0 || input->glarray->StrideB == 0); } } -- cgit v1.2.3 From 09e4df2c65c1bca0d04c6ffd076ea7808e61c4ae Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Sat, 3 Feb 2007 03:15:14 +0100 Subject: fix errorneously adding fog state params to all vertex programs... --- src/mesa/drivers/dri/r200/r200_vertprog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/r200/r200_vertprog.c b/src/mesa/drivers/dri/r200/r200_vertprog.c index 491701b796..713e2f9eca 100644 --- a/src/mesa/drivers/dri/r200/r200_vertprog.c +++ b/src/mesa/drivers/dri/r200/r200_vertprog.c @@ -461,7 +461,7 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte /* for fogc, can't change mesa_vp, as it would hose swtnl, and exp with base e isn't directly available neither. */ - if (mesa_vp->Base.OutputsWritten & VERT_RESULT_FOGC && !vp->fogpidx) { + if ((mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_FOGC)) && !vp->fogpidx) { struct gl_program_parameter_list *paramList; GLint tokens[6] = { STATE_FOG_PARAMS, 0, 0, 0, 0, 0 }; paramList = mesa_vp->Base.Parameters; -- cgit v1.2.3 From f697308ae583dbcdf0268e98232c32be7f25fac6 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Sat, 3 Feb 2007 03:15:45 +0100 Subject: remove now unused vtxfmt stuff from radeon/r200 header files --- src/mesa/drivers/dri/r200/r200_context.h | 124 --------------------------- src/mesa/drivers/dri/r200/r200_maos_arrays.c | 7 +- src/mesa/drivers/dri/radeon/radeon_context.h | 111 ------------------------ 3 files changed, 3 insertions(+), 239 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h index 44c67b68cb..26a43d20dd 100644 --- a/src/mesa/drivers/dri/r200/r200_context.h +++ b/src/mesa/drivers/dri/r200/r200_context.h @@ -724,8 +724,6 @@ struct r200_store { /* r200_tcl.c */ struct r200_tcl_info { - GLuint vertex_format; - GLint last_offset; GLuint hw_primitive; /* hw can handle 12 components max */ @@ -812,87 +810,6 @@ struct r200_ioctl { #define R200_MAX_PRIMS 64 -/* Want to keep a cache of these around. Each is parameterized by - * only a single value which has only a small range. Only expect a - * few, so just rescan the list each time? - */ -struct dynfn { - struct dynfn *next, *prev; - int key[2]; - char *code; -}; - -struct dfn_lists { - struct dynfn Vertex2f; - struct dynfn Vertex2fv; - struct dynfn Vertex3f; - struct dynfn Vertex3fv; - struct dynfn Color4ub; - struct dynfn Color4ubv; - struct dynfn Color3ub; - struct dynfn Color3ubv; - struct dynfn Color4f; - struct dynfn Color4fv; - struct dynfn Color3f; - struct dynfn Color3fv; - struct dynfn SecondaryColor3ubEXT; - struct dynfn SecondaryColor3ubvEXT; - struct dynfn SecondaryColor3fEXT; - struct dynfn SecondaryColor3fvEXT; - struct dynfn Normal3f; - struct dynfn Normal3fv; - struct dynfn TexCoord3f; - struct dynfn TexCoord3fv; - struct dynfn TexCoord2f; - struct dynfn TexCoord2fv; - struct dynfn TexCoord1f; - struct dynfn TexCoord1fv; - struct dynfn MultiTexCoord3fARB; - struct dynfn MultiTexCoord3fvARB; - struct dynfn MultiTexCoord2fARB; - struct dynfn MultiTexCoord2fvARB; - struct dynfn MultiTexCoord1fARB; - struct dynfn MultiTexCoord1fvARB; - struct dynfn FogCoordfEXT; - struct dynfn FogCoordfvEXT; -}; - -struct dfn_generators { - struct dynfn *(*Vertex2f)( GLcontext *, const int * ); - struct dynfn *(*Vertex2fv)( GLcontext *, const int * ); - struct dynfn *(*Vertex3f)( GLcontext *, const int * ); - struct dynfn *(*Vertex3fv)( GLcontext *, const int * ); - struct dynfn *(*Color4ub)( GLcontext *, const int * ); - struct dynfn *(*Color4ubv)( GLcontext *, const int * ); - struct dynfn *(*Color3ub)( GLcontext *, const int * ); - struct dynfn *(*Color3ubv)( GLcontext *, const int * ); - struct dynfn *(*Color4f)( GLcontext *, const int * ); - struct dynfn *(*Color4fv)( GLcontext *, const int * ); - struct dynfn *(*Color3f)( GLcontext *, const int * ); - struct dynfn *(*Color3fv)( GLcontext *, const int * ); - struct dynfn *(*SecondaryColor3ubEXT)( GLcontext *, const int * ); - struct dynfn *(*SecondaryColor3ubvEXT)( GLcontext *, const int * ); - struct dynfn *(*SecondaryColor3fEXT)( GLcontext *, const int * ); - struct dynfn *(*SecondaryColor3fvEXT)( GLcontext *, const int * ); - struct dynfn *(*Normal3f)( GLcontext *, const int * ); - struct dynfn *(*Normal3fv)( GLcontext *, const int * ); - struct dynfn *(*TexCoord3f)( GLcontext *, const int * ); - struct dynfn *(*TexCoord3fv)( GLcontext *, const int * ); - struct dynfn *(*TexCoord2f)( GLcontext *, const int * ); - struct dynfn *(*TexCoord2fv)( GLcontext *, const int * ); - struct dynfn *(*TexCoord1f)( GLcontext *, const int * ); - struct dynfn *(*TexCoord1fv)( GLcontext *, const int * ); - struct dynfn *(*MultiTexCoord3fARB)( GLcontext *, const int * ); - struct dynfn *(*MultiTexCoord3fvARB)( GLcontext *, const int * ); - struct dynfn *(*MultiTexCoord2fARB)( GLcontext *, const int * ); - struct dynfn *(*MultiTexCoord2fvARB)( GLcontext *, const int * ); - struct dynfn *(*MultiTexCoord1fARB)( GLcontext *, const int * ); - struct dynfn *(*MultiTexCoord1fvARB)( GLcontext *, const int * ); - struct dynfn *(*FogCoordfEXT)( GLcontext *, const int * ); - struct dynfn *(*FogCoordfvEXT)( GLcontext *, const int * ); -}; - - struct r200_prim { GLuint start; @@ -913,43 +830,6 @@ struct r200_prim { #define R200_MAX_VERTEX_SIZE ((3*6)+11) -struct r200_vbinfo { - GLint counter, initial_counter; - GLint *dmaptr; - void (*notify)( void ); - GLint vertex_size; - - union { float f; int i; r200_color_t color; } vertex[R200_MAX_VERTEX_SIZE]; - - GLfloat *normalptr; - GLfloat *floatcolorptr; - GLfloat *fogptr; - r200_color_t *colorptr; - GLfloat *floatspecptr; - r200_color_t *specptr; - GLfloat *texcoordptr[8]; /* 6 (TMU) + 2 for r200_vtxfmt_c.c when GL_TEXTURE6/7 */ - - - GLenum *prim; /* &ctx->Driver.CurrentExecPrimitive */ - GLuint primflags; - GLboolean enabled; /* *_NO_VTXFMT / *_NO_TCL env vars */ - GLboolean installed; - GLboolean fell_back; - GLboolean recheck; - GLint nrverts; - GLuint vtxfmt_0, vtxfmt_1; - - GLuint installed_vertex_format; - GLuint installed_color_3f_sz; - - struct r200_prim primlist[R200_MAX_PRIMS]; - int nrprims; - - struct dfn_lists dfn_cache; - struct dfn_generators codegen; - GLvertexformat vtxfmt; -}; - struct r200_context { GLcontext *glCtx; /* Mesa context */ @@ -1041,10 +921,6 @@ struct r200_context { */ struct r200_swtcl_info swtcl; - /* r200_vtxfmt.c - */ - struct r200_vbinfo vb; - /* Mirrors of some DRI state */ struct r200_dri_mirror dri; diff --git a/src/mesa/drivers/dri/r200/r200_maos_arrays.c b/src/mesa/drivers/dri/r200/r200_maos_arrays.c index 270dc35a46..db5ac6fc8a 100644 --- a/src/mesa/drivers/dri/r200/r200_maos_arrays.c +++ b/src/mesa/drivers/dri/r200/r200_maos_arrays.c @@ -664,14 +664,13 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs ) */ if (vfmt0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] || - vfmt1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) { - R200_STATECHANGE( rmesa, vtx ); + vfmt1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) { + R200_STATECHANGE( rmesa, vtx ); rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = vfmt0; rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = vfmt1; - } + } rmesa->tcl.nr_aos_components = nr; - rmesa->tcl.vertex_format = vfmt0; } diff --git a/src/mesa/drivers/dri/radeon/radeon_context.h b/src/mesa/drivers/dri/radeon/radeon_context.h index 0a7c3b2f54..02cea2f4e3 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_context.h @@ -529,7 +529,6 @@ struct radeon_store { */ struct radeon_tcl_info { GLuint vertex_format; - GLint last_offset; GLuint hw_primitive; /* Temporary for cases where incoming vertex data is incompatible @@ -600,75 +599,6 @@ struct radeon_ioctl { #define RADEON_MAX_PRIMS 64 -/* Want to keep a cache of these around. Each is parameterized by - * only a single value which has only a small range. Only expect a - * few, so just rescan the list each time? - */ -struct dynfn { - struct dynfn *next, *prev; - int key; - char *code; -}; - -struct dfn_lists { - struct dynfn Vertex2f; - struct dynfn Vertex2fv; - struct dynfn Vertex3f; - struct dynfn Vertex3fv; - struct dynfn Color4ub; - struct dynfn Color4ubv; - struct dynfn Color3ub; - struct dynfn Color3ubv; - struct dynfn Color4f; - struct dynfn Color4fv; - struct dynfn Color3f; - struct dynfn Color3fv; - struct dynfn SecondaryColor3ubEXT; - struct dynfn SecondaryColor3ubvEXT; - struct dynfn SecondaryColor3fEXT; - struct dynfn SecondaryColor3fvEXT; - struct dynfn Normal3f; - struct dynfn Normal3fv; - struct dynfn TexCoord2f; - struct dynfn TexCoord2fv; - struct dynfn TexCoord1f; - struct dynfn TexCoord1fv; - struct dynfn MultiTexCoord2fARB; - struct dynfn MultiTexCoord2fvARB; - struct dynfn MultiTexCoord1fARB; - struct dynfn MultiTexCoord1fvARB; -}; - -struct dfn_generators { - struct dynfn *(*Vertex2f)( GLcontext *, int ); - struct dynfn *(*Vertex2fv)( GLcontext *, int ); - struct dynfn *(*Vertex3f)( GLcontext *, int ); - struct dynfn *(*Vertex3fv)( GLcontext *, int ); - struct dynfn *(*Color4ub)( GLcontext *, int ); - struct dynfn *(*Color4ubv)( GLcontext *, int ); - struct dynfn *(*Color3ub)( GLcontext *, int ); - struct dynfn *(*Color3ubv)( GLcontext *, int ); - struct dynfn *(*Color4f)( GLcontext *, int ); - struct dynfn *(*Color4fv)( GLcontext *, int ); - struct dynfn *(*Color3f)( GLcontext *, int ); - struct dynfn *(*Color3fv)( GLcontext *, int ); - struct dynfn *(*SecondaryColor3ubEXT)( GLcontext *, int ); - struct dynfn *(*SecondaryColor3ubvEXT)( GLcontext *, int ); - struct dynfn *(*SecondaryColor3fEXT)( GLcontext *, int ); - struct dynfn *(*SecondaryColor3fvEXT)( GLcontext *, int ); - struct dynfn *(*Normal3f)( GLcontext *, int ); - struct dynfn *(*Normal3fv)( GLcontext *, int ); - struct dynfn *(*TexCoord2f)( GLcontext *, int ); - struct dynfn *(*TexCoord2fv)( GLcontext *, int ); - struct dynfn *(*TexCoord1f)( GLcontext *, int ); - struct dynfn *(*TexCoord1fv)( GLcontext *, int ); - struct dynfn *(*MultiTexCoord2fARB)( GLcontext *, int ); - struct dynfn *(*MultiTexCoord2fvARB)( GLcontext *, int ); - struct dynfn *(*MultiTexCoord1fARB)( GLcontext *, int ); - struct dynfn *(*MultiTexCoord1fvARB)( GLcontext *, int ); -}; - - struct radeon_prim { GLuint start; @@ -685,43 +615,6 @@ struct radeon_prim { */ #define RADEON_MAX_VERTEX_SIZE 20 -struct radeon_vbinfo { - GLint counter, initial_counter; - GLint *dmaptr; - void (*notify)( void ); - GLint vertex_size; - - union { float f; int i; radeon_color_t color; } vertex[RADEON_MAX_VERTEX_SIZE]; - - GLfloat *normalptr; - GLfloat *floatcolorptr; - radeon_color_t *colorptr; - GLfloat *floatspecptr; - radeon_color_t *specptr; - GLfloat *texcoordptr[4]; /* 3 (TMU) + 1 for radeon_vtxfmt_c.c when GL_TEXTURE3 */ - - GLenum *prim; /* &ctx->Driver.CurrentExecPrimitive */ - GLuint primflags; - GLboolean enabled; /* *_NO_VTXFMT / *_NO_TCL env vars */ - GLboolean installed; - GLboolean fell_back; - GLboolean recheck; - GLint nrverts; - GLuint vertex_format; - - GLuint installed_vertex_format; - GLuint installed_color_3f_sz; - - struct radeon_prim primlist[RADEON_MAX_PRIMS]; - int nrprims; - - struct dfn_lists dfn_cache; - struct dfn_generators codegen; - GLvertexformat vtxfmt; -}; - - - struct radeon_context { GLcontext *glCtx; /* Mesa context */ @@ -808,10 +701,6 @@ struct radeon_context { */ struct radeon_swtcl_info swtcl; - /* radeon_vtxfmt.c - */ - struct radeon_vbinfo vb; - /* Mirrors of some DRI state */ struct radeon_dri_mirror dri; -- cgit v1.2.3 From 2a441c488f4bcf11fe032ea7ba448bbfb7449c66 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Sat, 3 Feb 2007 03:31:31 +0100 Subject: disable r200 materials-between-begin-end check if vertex progs are enabled --- src/mesa/drivers/dri/r200/r200_state.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c index bab767838d..bdb487f2b9 100644 --- a/src/mesa/drivers/dri/r200/r200_state.c +++ b/src/mesa/drivers/dri/r200/r200_state.c @@ -2542,15 +2542,17 @@ static void r200InvalidateState( GLcontext *ctx, GLuint new_state ) } /* A hack. The r200 can actually cope just fine with materials - * between begin/ends, so fix this. But how ? + * between begin/ends, so fix this. + * Should map to inputs just like the generic vertex arrays for vertex progs. + * In theory there could still be too many and we'd still need a fallback. */ static GLboolean check_material( GLcontext *ctx ) { TNLcontext *tnl = TNL_CONTEXT(ctx); GLint i; - for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT; - i < _TNL_ATTRIB_MAT_BACK_INDEXES; + for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT; + i < _TNL_ATTRIB_MAT_BACK_INDEXES; i++) if (tnl->vb.AttribPtr[i] && tnl->vb.AttribPtr[i]->stride) @@ -2558,7 +2560,7 @@ static GLboolean check_material( GLcontext *ctx ) return GL_FALSE; } - + static void r200WrapRunPipeline( GLcontext *ctx ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); @@ -2572,7 +2574,7 @@ static void r200WrapRunPipeline( GLcontext *ctx ) if (rmesa->NewGLState) r200ValidateState( ctx ); - has_material = (ctx->Light.Enabled && check_material( ctx )); + has_material = !ctx->VertexProgram._Enabled && ctx->Light.Enabled && check_material( ctx ); if (has_material) { TCL_FALLBACK( ctx, R200_TCL_FALLBACK_MATERIAL, GL_TRUE ); -- cgit v1.2.3 From 1c25561e30ada8036d00aa84344377aa2a4f791a Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 3 Feb 2007 13:20:16 +0100 Subject: nouveau: use color pitch as depth pitch if depth disabled --- src/mesa/drivers/dri/nouveau/nv10_state.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index f6e47b7f48..055f538a3a 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -667,7 +667,7 @@ static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color, nouveau_renderbuffer *depth) { GLuint x, y, w, h; - GLuint pitch, format; + GLuint pitch, format, depth_pitch; w = color[0]->mesa.Width; h = color[0]->mesa.Height; @@ -680,10 +680,8 @@ static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color, BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 6); OUT_RING_CACHE((w << 16) | x); OUT_RING_CACHE((h << 16) | y); - pitch = color[0]->pitch; - if (depth) { - pitch |= (depth->pitch << 16); - } + depth_pitch = (depth ? depth->pitch : color[0]->pitch); + pitch = (depth_pitch<<16) | color[0]->pitch; format = 0x108; if (color[0]->mesa._ActualFormat != GL_RGBA8) { format = 0x103; /* R5G6B5 color buffer */ -- cgit v1.2.3 From de24b01b05d4c7402c06851dd7dbbb5854b1ff41 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 3 Feb 2007 13:22:42 +0100 Subject: nouveau: fix viewport clipping initialization --- src/mesa/drivers/dri/nouveau/nv10_state.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 055f538a3a..88c1d7d9e1 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -612,10 +612,13 @@ static void nv10WindowMoved(nouveauContextPtr nmesa) OUT_RING_CACHE((h << 16) | y); /* something to do with clears, possibly doesn't belong here */ + BEGIN_RING_SIZE(NvSub3D, 0x02b4, 1); + OUT_RING(0); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 2); - OUT_RING_CACHE(((w+x) << 16) | x | 0x800); - OUT_RING_CACHE(((h+y) << 16) | y | 0x800); + OUT_RING_CACHE(((w+x-1) << 16) | x | 0x08000800); + OUT_RING_CACHE(((h+y-1) << 16) | y | 0x08000800); for (i=1; i<7; i++) { BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 1); @@ -651,14 +654,12 @@ static GLboolean nv10InitCard(nouveauContextPtr nmesa) OUT_RING(NvDmaFB); /* 194 dma_in_memory2 */ OUT_RING(NvDmaFB); /* 198 dma_in_memory3 */ - BEGIN_RING_SIZE(NvSub3D, 0x02b4, 1); - OUT_RING(0); BEGIN_RING_SIZE(NvSub3D, 0x0290, 1); OUT_RING(0x00100001); BEGIN_RING_SIZE(NvSub3D, 0x03f4, 1); OUT_RING(0); - return GL_FALSE; + return GL_TRUE; } /* Update buffer offset/pitch/format */ -- cgit v1.2.3 From 0afc2d37c32540b90bcb7861186b80a781dc0a4a Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Sat, 3 Feb 2007 17:23:19 +0100 Subject: r300CreateContext: Really initialize r300->initialMaxAnisotropy. --- src/mesa/drivers/dri/r300/r300_context.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index 00489ba14e..d10a9d87d3 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -200,6 +200,8 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, */ driParseConfigFiles(&r300->radeon.optionCache, &screen->optionCache, screen->driScreen->myNum, "r300"); + r300->initialMaxAnisotropy = driQueryOptionf(&r300->radeon.optionCache, + "def_max_anisotropy"); //r300->texmicrotile = GL_TRUE; -- cgit v1.2.3 From beffa17bb984b29696a99a0c54922ff6a7d0b386 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Sat, 3 Feb 2007 17:24:22 +0100 Subject: Remove unused r200 files from r300 driver directory. --- src/mesa/drivers/dri/r300/r200_context.h | 822 ----------------- src/mesa/drivers/dri/r300/r200_ioctl.h | 204 ----- src/mesa/drivers/dri/r300/r200_reg.h | 1423 ------------------------------ src/mesa/drivers/dri/r300/r200_state.h | 58 -- 4 files changed, 2507 deletions(-) delete mode 100644 src/mesa/drivers/dri/r300/r200_context.h delete mode 100644 src/mesa/drivers/dri/r300/r200_ioctl.h delete mode 100644 src/mesa/drivers/dri/r300/r200_reg.h delete mode 100644 src/mesa/drivers/dri/r300/r200_state.h (limited to 'src') diff --git a/src/mesa/drivers/dri/r300/r200_context.h b/src/mesa/drivers/dri/r300/r200_context.h deleted file mode 100644 index a06d7152d7..0000000000 --- a/src/mesa/drivers/dri/r300/r200_context.h +++ /dev/null @@ -1,822 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_context.h,v 1.2 2002/12/16 16:18:54 dawes Exp $ */ -/* -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -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 (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 NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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 - */ - -#ifndef __R200_CONTEXT_H__ -#define __R200_CONTEXT_H__ - -#ifdef GLX_DIRECT_RENDERING - -#include "tnl/t_vertex.h" -#include "drm.h" -#include "radeon_drm.h" -#include "dri_util.h" -#include "texmem.h" - -#include "macros.h" -#include "mtypes.h" -#include "colormac.h" -#include "r200_reg.h" -#include "radeon_context.h" - -#define ENABLE_HW_3D_TEXTURE 1 /* XXX this is temporary! */ - -struct r200_context; -typedef struct r200_context r200ContextRec; -typedef struct r200_context *r200ContextPtr; - -#include "mm.h" - -/* The blit width for texture uploads - */ -#define BLIT_WIDTH_BYTES 1024 - -/* Use the templated vertex format: - */ -#define COLOR_IS_RGBA -#define TAG(x) r200##x -#include "tnl_dd/t_dd_vertex.h" -#undef TAG - -typedef void (*r200_tri_func) (r200ContextPtr, - r200Vertex *, r200Vertex *, r200Vertex *); - -typedef void (*r200_line_func) (r200ContextPtr, r200Vertex *, r200Vertex *); - -typedef void (*r200_point_func) (r200ContextPtr, r200Vertex *); - -struct r200_depthbuffer_state { - GLfloat scale; -}; - -struct r200_stencilbuffer_state { - GLboolean hwBuffer; - GLuint clear; /* rb3d_stencilrefmask value */ -}; - -struct r200_stipple_state { - GLuint mask[32]; -}; - -typedef struct r200_tex_obj r200TexObj, *r200TexObjPtr; - -/* Texture object in locally shared texture space. - */ -struct r200_tex_obj { - driTextureObject base; - - GLuint bufAddr; /* Offset to start of locally - shared texture block */ - - GLuint dirty_state; /* Flags (1 per texunit) for - whether or not this texobj - has dirty hardware state - (pp_*) that needs to be - brought into the - texunit. */ - - drm_radeon_tex_image_t image[6][RADEON_MAX_TEXTURE_LEVELS]; - /* Six, for the cube faces */ - - GLuint pp_txfilter; /* hardware register values */ - GLuint pp_txformat; - GLuint pp_txformat_x; - GLuint pp_txoffset; /* Image location in texmem. - All cube faces follow. */ - GLuint pp_txsize; /* npot only */ - GLuint pp_txpitch; /* npot only */ - GLuint pp_border_color; - GLuint pp_cubic_faces; /* cube face 1,2,3,4 log2 sizes */ - - GLboolean border_fallback; -}; - -struct r200_texture_env_state { - r200TexObjPtr texobj; - GLenum format; - GLenum envMode; -}; - -#define R200_MAX_TEXTURE_UNITS 6 - -struct r200_texture_state { - struct r200_texture_env_state unit[R200_MAX_TEXTURE_UNITS]; -}; - -struct r200_state_atom { - struct r200_state_atom *next, *prev; - const char *name; /* for debug */ - int cmd_size; /* size in bytes */ - GLuint idx; - int *cmd; /* one or more cmd's */ - int *lastcmd; /* one or more cmd's */ - int *savedcmd; /* one or more cmd's */ - GLboolean dirty; - GLboolean(*check) (GLcontext *, int); /* is this state active? */ -}; - -/* Trying to keep these relatively short as the variables are becoming - * extravagently long. Drop the driver name prefix off the front of - * everything - I think we know which driver we're in by now, and keep the - * prefix to 3 letters unless absolutely impossible. - */ - -#define CTX_CMD_0 0 -#define CTX_PP_MISC 1 -#define CTX_PP_FOG_COLOR 2 -#define CTX_RE_SOLID_COLOR 3 -#define CTX_RB3D_BLENDCNTL 4 -#define CTX_RB3D_DEPTHOFFSET 5 -#define CTX_RB3D_DEPTHPITCH 6 -#define CTX_RB3D_ZSTENCILCNTL 7 -#define CTX_CMD_1 8 -#define CTX_PP_CNTL 9 -#define CTX_RB3D_CNTL 10 -#define CTX_RB3D_COLOROFFSET 11 -#define CTX_CMD_2 12 /* why */ -#define CTX_RB3D_COLORPITCH 13 /* why */ -#define CTX_STATE_SIZE_OLDDRM 14 -#define CTX_CMD_3 14 -#define CTX_RB3D_BLENDCOLOR 15 -#define CTX_RB3D_ABLENDCNTL 16 -#define CTX_RB3D_CBLENDCNTL 17 -#define CTX_STATE_SIZE_NEWDRM 18 - -#define SET_CMD_0 0 -#define SET_SE_CNTL 1 -#define SET_RE_CNTL 2 /* replace se_coord_fmt */ -#define SET_STATE_SIZE 3 - -#define VTE_CMD_0 0 -#define VTE_SE_VTE_CNTL 1 -#define VTE_STATE_SIZE 2 - -#define LIN_CMD_0 0 -#define LIN_RE_LINE_PATTERN 1 -#define LIN_RE_LINE_STATE 2 -#define LIN_CMD_1 3 -#define LIN_SE_LINE_WIDTH 4 -#define LIN_STATE_SIZE 5 - -#define MSK_CMD_0 0 -#define MSK_RB3D_STENCILREFMASK 1 -#define MSK_RB3D_ROPCNTL 2 -#define MSK_RB3D_PLANEMASK 3 -#define MSK_STATE_SIZE 4 - -#define VPT_CMD_0 0 -#define VPT_SE_VPORT_XSCALE 1 -#define VPT_SE_VPORT_XOFFSET 2 -#define VPT_SE_VPORT_YSCALE 3 -#define VPT_SE_VPORT_YOFFSET 4 -#define VPT_SE_VPORT_ZSCALE 5 -#define VPT_SE_VPORT_ZOFFSET 6 -#define VPT_STATE_SIZE 7 - -#define ZBS_CMD_0 0 -#define ZBS_SE_ZBIAS_FACTOR 1 -#define ZBS_SE_ZBIAS_CONSTANT 2 -#define ZBS_STATE_SIZE 3 - -#define MSC_CMD_0 0 -#define MSC_RE_MISC 1 -#define MSC_STATE_SIZE 2 - -#define TAM_CMD_0 0 -#define TAM_DEBUG3 1 -#define TAM_STATE_SIZE 2 - -#define TEX_CMD_0 0 -#define TEX_PP_TXFILTER 1 /*2c00 */ -#define TEX_PP_TXFORMAT 2 /*2c04 */ -#define TEX_PP_TXFORMAT_X 3 /*2c08 */ -#define TEX_PP_TXSIZE 4 /*2c0c */ -#define TEX_PP_TXPITCH 5 /*2c10 */ -#define TEX_PP_BORDER_COLOR 6 /*2c14 */ -#define TEX_CMD_1 7 -#define TEX_PP_TXOFFSET 8 /*2d00 */ -#define TEX_STATE_SIZE 9 - -#define CUBE_CMD_0 0 /* 1 register follows */ -#define CUBE_PP_CUBIC_FACES 1 /* 0x2c18 */ -#define CUBE_CMD_1 2 /* 5 registers follow */ -#define CUBE_PP_CUBIC_OFFSET_F1 3 /* 0x2d04 */ -#define CUBE_PP_CUBIC_OFFSET_F2 4 /* 0x2d08 */ -#define CUBE_PP_CUBIC_OFFSET_F3 5 /* 0x2d0c */ -#define CUBE_PP_CUBIC_OFFSET_F4 6 /* 0x2d10 */ -#define CUBE_PP_CUBIC_OFFSET_F5 7 /* 0x2d14 */ -#define CUBE_STATE_SIZE 8 - -#define PIX_CMD_0 0 -#define PIX_PP_TXCBLEND 1 -#define PIX_PP_TXCBLEND2 2 -#define PIX_PP_TXABLEND 3 -#define PIX_PP_TXABLEND2 4 -#define PIX_STATE_SIZE 5 - -#define TF_CMD_0 0 -#define TF_TFACTOR_0 1 -#define TF_TFACTOR_1 2 -#define TF_TFACTOR_2 3 -#define TF_TFACTOR_3 4 -#define TF_TFACTOR_4 5 -#define TF_TFACTOR_5 6 -#define TF_STATE_SIZE 7 - -#define TCL_CMD_0 0 -#define TCL_LIGHT_MODEL_CTL_0 1 -#define TCL_LIGHT_MODEL_CTL_1 2 -#define TCL_PER_LIGHT_CTL_0 3 -#define TCL_PER_LIGHT_CTL_1 4 -#define TCL_PER_LIGHT_CTL_2 5 -#define TCL_PER_LIGHT_CTL_3 6 -#define TCL_CMD_1 7 -#define TCL_UCP_VERT_BLEND_CTL 8 -#define TCL_STATE_SIZE 9 - -#define MSL_CMD_0 0 -#define MSL_MATRIX_SELECT_0 1 -#define MSL_MATRIX_SELECT_1 2 -#define MSL_MATRIX_SELECT_2 3 -#define MSL_MATRIX_SELECT_3 4 -#define MSL_MATRIX_SELECT_4 5 -#define MSL_STATE_SIZE 6 - -#define TCG_CMD_0 0 -#define TCG_TEX_PROC_CTL_2 1 -#define TCG_TEX_PROC_CTL_3 2 -#define TCG_TEX_PROC_CTL_0 3 -#define TCG_TEX_PROC_CTL_1 4 -#define TCG_TEX_CYL_WRAP_CTL 5 -#define TCG_STATE_SIZE 6 - -#define MTL_CMD_0 0 -#define MTL_EMMISSIVE_RED 1 -#define MTL_EMMISSIVE_GREEN 2 -#define MTL_EMMISSIVE_BLUE 3 -#define MTL_EMMISSIVE_ALPHA 4 -#define MTL_AMBIENT_RED 5 -#define MTL_AMBIENT_GREEN 6 -#define MTL_AMBIENT_BLUE 7 -#define MTL_AMBIENT_ALPHA 8 -#define MTL_DIFFUSE_RED 9 -#define MTL_DIFFUSE_GREEN 10 -#define MTL_DIFFUSE_BLUE 11 -#define MTL_DIFFUSE_ALPHA 12 -#define MTL_SPECULAR_RED 13 -#define MTL_SPECULAR_GREEN 14 -#define MTL_SPECULAR_BLUE 15 -#define MTL_SPECULAR_ALPHA 16 -#define MTL_CMD_1 17 -#define MTL_SHININESS 18 -#define MTL_STATE_SIZE 19 - -#define VAP_CMD_0 0 -#define VAP_SE_VAP_CNTL 1 -#define VAP_STATE_SIZE 2 - -/* Replaces a lot of packet info from radeon - */ -#define VTX_CMD_0 0 -#define VTX_VTXFMT_0 1 -#define VTX_VTXFMT_1 2 -#define VTX_TCL_OUTPUT_VTXFMT_0 3 -#define VTX_TCL_OUTPUT_VTXFMT_1 4 -#define VTX_CMD_1 5 -#define VTX_TCL_OUTPUT_COMPSEL 6 -#define VTX_CMD_2 7 -#define VTX_STATE_CNTL 8 -#define VTX_STATE_SIZE 9 - -#define VTX_COLOR(v,n) (((v)>>(R200_VTX_COLOR_0_SHIFT+(n)*2))&\ - R200_VTX_COLOR_MASK) - -/** - * Given the \c R200_SE_VTX_FMT_1 for the current vertex state, determine - * how many components are in texture coordinate \c n. - */ -#define VTX_TEXn_COUNT(v,n) (((v) >> (3 * n)) & 0x07) - -#define MAT_CMD_0 0 -#define MAT_ELT_0 1 -#define MAT_STATE_SIZE 17 - -#define GRD_CMD_0 0 -#define GRD_VERT_GUARD_CLIP_ADJ 1 -#define GRD_VERT_GUARD_DISCARD_ADJ 2 -#define GRD_HORZ_GUARD_CLIP_ADJ 3 -#define GRD_HORZ_GUARD_DISCARD_ADJ 4 -#define GRD_STATE_SIZE 5 - -/* position changes frequently when lighting in modelpos - separate - * out to new state item? - */ -#define LIT_CMD_0 0 -#define LIT_AMBIENT_RED 1 -#define LIT_AMBIENT_GREEN 2 -#define LIT_AMBIENT_BLUE 3 -#define LIT_AMBIENT_ALPHA 4 -#define LIT_DIFFUSE_RED 5 -#define LIT_DIFFUSE_GREEN 6 -#define LIT_DIFFUSE_BLUE 7 -#define LIT_DIFFUSE_ALPHA 8 -#define LIT_SPECULAR_RED 9 -#define LIT_SPECULAR_GREEN 10 -#define LIT_SPECULAR_BLUE 11 -#define LIT_SPECULAR_ALPHA 12 -#define LIT_POSITION_X 13 -#define LIT_POSITION_Y 14 -#define LIT_POSITION_Z 15 -#define LIT_POSITION_W 16 -#define LIT_DIRECTION_X 17 -#define LIT_DIRECTION_Y 18 -#define LIT_DIRECTION_Z 19 -#define LIT_DIRECTION_W 20 -#define LIT_ATTEN_QUADRATIC 21 -#define LIT_ATTEN_LINEAR 22 -#define LIT_ATTEN_CONST 23 -#define LIT_ATTEN_XXX 24 -#define LIT_CMD_1 25 -#define LIT_SPOT_DCD 26 -#define LIT_SPOT_DCM 27 -#define LIT_SPOT_EXPONENT 28 -#define LIT_SPOT_CUTOFF 29 -#define LIT_SPECULAR_THRESH 30 -#define LIT_RANGE_CUTOFF 31 /* ? */ -#define LIT_ATTEN_CONST_INV 32 -#define LIT_STATE_SIZE 33 - -/* Fog - */ -#define FOG_CMD_0 0 -#define FOG_R 1 -#define FOG_C 2 -#define FOG_D 3 -#define FOG_PAD 4 -#define FOG_STATE_SIZE 5 - -/* UCP - */ -#define UCP_CMD_0 0 -#define UCP_X 1 -#define UCP_Y 2 -#define UCP_Z 3 -#define UCP_W 4 -#define UCP_STATE_SIZE 5 - -/* GLT - Global ambient - */ -#define GLT_CMD_0 0 -#define GLT_RED 1 -#define GLT_GREEN 2 -#define GLT_BLUE 3 -#define GLT_ALPHA 4 -#define GLT_STATE_SIZE 5 - -/* EYE - */ -#define EYE_CMD_0 0 -#define EYE_X 1 -#define EYE_Y 2 -#define EYE_Z 3 -#define EYE_RESCALE_FACTOR 4 -#define EYE_STATE_SIZE 5 - -/* CST - constant state - */ -#define CST_CMD_0 0 -#define CST_PP_CNTL_X 1 -#define CST_CMD_1 2 -#define CST_RB3D_DEPTHXY_OFFSET 3 -#define CST_CMD_2 4 -#define CST_RE_AUX_SCISSOR_CNTL 5 -#define CST_CMD_3 6 -#define CST_RE_SCISSOR_TL_0 7 -#define CST_RE_SCISSOR_BR_0 8 -#define CST_CMD_4 9 -#define CST_SE_VAP_CNTL_STATUS 10 -#define CST_CMD_5 11 -#define CST_RE_POINTSIZE 12 -#define CST_CMD_6 13 -#define CST_SE_TCL_INPUT_VTX_0 14 -#define CST_SE_TCL_INPUT_VTX_1 15 -#define CST_SE_TCL_INPUT_VTX_2 16 -#define CST_SE_TCL_INPUT_VTX_3 17 -#define CST_STATE_SIZE 18 - -struct r200_hw_state { - /* Head of the linked list of state atoms. */ - struct r200_state_atom atomlist; - - /* Hardware state, stored as cmdbuf commands: - * -- Need to doublebuffer for - * - reviving state after loss of context - * - eliding noop statechange loops? (except line stipple count) - */ - struct r200_state_atom ctx; - struct r200_state_atom set; - struct r200_state_atom vte; - struct r200_state_atom lin; - struct r200_state_atom msk; - struct r200_state_atom vpt; - struct r200_state_atom vap; - struct r200_state_atom vtx; - struct r200_state_atom tcl; - struct r200_state_atom msl; - struct r200_state_atom tcg; - struct r200_state_atom msc; - struct r200_state_atom cst; - struct r200_state_atom tam; - struct r200_state_atom tf; - struct r200_state_atom tex[6]; - struct r200_state_atom cube[6]; - struct r200_state_atom zbs; - struct r200_state_atom mtl[2]; - struct r200_state_atom mat[9]; - struct r200_state_atom lit[8]; /* includes vec, scl commands */ - struct r200_state_atom ucp[6]; - struct r200_state_atom pix[6]; /* pixshader stages */ - struct r200_state_atom eye; /* eye pos */ - struct r200_state_atom grd; /* guard band clipping */ - struct r200_state_atom fog; - struct r200_state_atom glt; - - int max_state_size; /* Number of bytes necessary for a full state emit. */ - GLboolean is_dirty, all_dirty; -}; - -struct r200_colorbuffer_state { - int roundEnable; -}; - -struct r200_state { - /* Derived state for internal purposes: - */ - struct r200_colorbuffer_state color; - struct r200_depthbuffer_state depth; - struct r200_stencilbuffer_state stencil; - struct r200_stipple_state stipple; - struct r200_texture_state texture; -}; - -/* Need refcounting on dma buffers: - */ -struct r200_dma_buffer { - int refcount; /* the number of retained regions in buf */ - drmBufPtr buf; -}; - -#define GET_START(rvb) (rmesa->radeon.radeonScreen->gart_buffer_offset + \ - (rvb)->address - rmesa->dma.buf0_address + \ - (rvb)->start) - -/* A retained region, eg vertices for indexed vertices. - */ -struct r200_dma_region { - struct r200_dma_buffer *buf; - char *address; /* == buf->address */ - int start, end, ptr; /* offsets from start of buf */ - int aos_start; - int aos_stride; - int aos_size; -}; - -struct r200_dma { - /* Active dma region. Allocations for vertices and retained - * regions come from here. Also used for emitting random vertices, - * these may be flushed by calling flush_current(); - */ - struct r200_dma_region current; - - void (*flush) (r200ContextPtr); - - char *buf0_address; /* start of buf[0], for index calcs */ - GLuint nr_released_bufs; /* flush after so many buffers released */ -}; - -#define R200_CMD_BUF_SZ (8*1024) - -struct r200_store { - GLuint statenr; - GLuint primnr; - char cmd_buf[R200_CMD_BUF_SZ]; - int cmd_used; - int elts_start; -}; - -/* r200_tcl.c - */ -struct r200_tcl_info { - GLuint vertex_format; - GLint last_offset; - GLuint hw_primitive; - - struct r200_dma_region *aos_components[8]; - GLuint nr_aos_components; - - GLuint *Elts; - - struct r200_dma_region indexed_verts; - struct r200_dma_region obj; - struct r200_dma_region rgba; - struct r200_dma_region spec; - struct r200_dma_region fog; - struct r200_dma_region tex[R200_MAX_TEXTURE_UNITS]; - struct r200_dma_region norm; -}; - -/* r200_swtcl.c - */ -struct r200_swtcl_info { - GLuint RenderIndex; - - /** - * Size of a hardware vertex. This is calculated when \c ::vertex_attrs is - * installed in the Mesa state vector. - */ - GLuint vertex_size; - - /** - * Attributes instructing the Mesa TCL pipeline where / how to put vertex - * data in the hardware buffer. - */ - struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; - - /** - * Number of elements of \c ::vertex_attrs that are actually used. - */ - GLuint vertex_attr_count; - - /** - * Cached pointer to the buffer where Mesa will store vertex data. - */ - GLubyte *verts; - - /* Fallback rasterization functions - */ - r200_point_func draw_point; - r200_line_func draw_line; - r200_tri_func draw_tri; - - GLuint hw_primitive; - GLenum render_primitive; - GLuint numverts; - - /** - * Offset of the 4UB color data within a hardware (swtcl) vertex. - */ - GLuint coloroffset; - - /** - * Offset of the 3UB specular color data within a hardware (swtcl) vertex. - */ - GLuint specoffset; - - /** - * Should Mesa project vertex data or will the hardware do it? - */ - GLboolean needproj; - - struct r200_dma_region indexed_verts; -}; - -struct r200_ioctl { - GLuint vertex_offset; - GLuint vertex_size; -}; - -#define R200_MAX_PRIMS 64 - -/* Want to keep a cache of these around. Each is parameterized by - * only a single value which has only a small range. Only expect a - * few, so just rescan the list each time? - */ -struct dynfn { - struct dynfn *next, *prev; - int key[2]; - char *code; -}; - -struct dfn_lists { - struct dynfn Vertex2f; - struct dynfn Vertex2fv; - struct dynfn Vertex3f; - struct dynfn Vertex3fv; - struct dynfn Color4ub; - struct dynfn Color4ubv; - struct dynfn Color3ub; - struct dynfn Color3ubv; - struct dynfn Color4f; - struct dynfn Color4fv; - struct dynfn Color3f; - struct dynfn Color3fv; - struct dynfn SecondaryColor3ubEXT; - struct dynfn SecondaryColor3ubvEXT; - struct dynfn SecondaryColor3fEXT; - struct dynfn SecondaryColor3fvEXT; - struct dynfn Normal3f; - struct dynfn Normal3fv; - struct dynfn TexCoord3f; - struct dynfn TexCoord3fv; - struct dynfn TexCoord2f; - struct dynfn TexCoord2fv; - struct dynfn TexCoord1f; - struct dynfn TexCoord1fv; - struct dynfn MultiTexCoord3fARB; - struct dynfn MultiTexCoord3fvARB; - struct dynfn MultiTexCoord2fARB; - struct dynfn MultiTexCoord2fvARB; - struct dynfn MultiTexCoord1fARB; - struct dynfn MultiTexCoord1fvARB; -}; - -struct dfn_generators { - struct dynfn *(*Vertex2f) (GLcontext *, const int *); - struct dynfn *(*Vertex2fv) (GLcontext *, const int *); - struct dynfn *(*Vertex3f) (GLcontext *, const int *); - struct dynfn *(*Vertex3fv) (GLcontext *, const int *); - struct dynfn *(*Color4ub) (GLcontext *, const int *); - struct dynfn *(*Color4ubv) (GLcontext *, const int *); - struct dynfn *(*Color3ub) (GLcontext *, const int *); - struct dynfn *(*Color3ubv) (GLcontext *, const int *); - struct dynfn *(*Color4f) (GLcontext *, const int *); - struct dynfn *(*Color4fv) (GLcontext *, const int *); - struct dynfn *(*Color3f) (GLcontext *, const int *); - struct dynfn *(*Color3fv) (GLcontext *, const int *); - struct dynfn *(*SecondaryColor3ubEXT) (GLcontext *, const int *); - struct dynfn *(*SecondaryColor3ubvEXT) (GLcontext *, const int *); - struct dynfn *(*SecondaryColor3fEXT) (GLcontext *, const int *); - struct dynfn *(*SecondaryColor3fvEXT) (GLcontext *, const int *); - struct dynfn *(*Normal3f) (GLcontext *, const int *); - struct dynfn *(*Normal3fv) (GLcontext *, const int *); - struct dynfn *(*TexCoord3f) (GLcontext *, const int *); - struct dynfn *(*TexCoord3fv) (GLcontext *, const int *); - struct dynfn *(*TexCoord2f) (GLcontext *, const int *); - struct dynfn *(*TexCoord2fv) (GLcontext *, const int *); - struct dynfn *(*TexCoord1f) (GLcontext *, const int *); - struct dynfn *(*TexCoord1fv) (GLcontext *, const int *); - struct dynfn *(*MultiTexCoord3fARB) (GLcontext *, const int *); - struct dynfn *(*MultiTexCoord3fvARB) (GLcontext *, const int *); - struct dynfn *(*MultiTexCoord2fARB) (GLcontext *, const int *); - struct dynfn *(*MultiTexCoord2fvARB) (GLcontext *, const int *); - struct dynfn *(*MultiTexCoord1fARB) (GLcontext *, const int *); - struct dynfn *(*MultiTexCoord1fvARB) (GLcontext *, const int *); -}; - -struct r200_prim { - GLuint start; - GLuint end; - GLuint prim; -}; - - /* A maximum total of 29 elements per vertex: 3 floats for position, 3 - * floats for normal, 4 floats for color, 4 bytes for secondary color, - * 3 floats for each texture unit (18 floats total). - * - * we maybe need add. 4 to prevent segfault if someone specifies - * GL_TEXTURE6/GL_TEXTURE7 (esp. for the codegen-path) (FIXME: ) - * - * The position data is never actually stored here, so 3 elements could be - * trimmed out of the buffer. - */ - -#define R200_MAX_VERTEX_SIZE ((3*6)+11) - -struct r200_vbinfo { - GLint counter, initial_counter; - GLint *dmaptr; - void (*notify) (void); - GLint vertex_size; - - union { - float f; - int i; - r200_color_t color; - } vertex[R200_MAX_VERTEX_SIZE]; - - GLfloat *normalptr; - GLfloat *floatcolorptr; - r200_color_t *colorptr; - GLfloat *floatspecptr; - r200_color_t *specptr; - GLfloat *texcoordptr[8]; /* 6 (TMU) + 2 for r200_vtxfmt_c.c when GL_TEXTURE6/7 */ - - GLenum *prim; /* &ctx->Driver.CurrentExecPrimitive */ - GLuint primflags; - GLboolean enabled; /* *_NO_VTXFMT / *_NO_TCL env vars */ - GLboolean installed; - GLboolean fell_back; - GLboolean recheck; - GLint nrverts; - GLuint vtxfmt_0, vtxfmt_1; - - GLuint installed_vertex_format; - GLuint installed_color_3f_sz; - - struct r200_prim primlist[R200_MAX_PRIMS]; - int nrprims; - - struct dfn_lists dfn_cache; - struct dfn_generators codegen; - GLvertexformat vtxfmt; -}; - -/** - * R200 context structure. - */ -struct r200_context { - struct radeon_context radeon; /* parent class, must be first */ - - /* Driver and hardware state management - */ - struct r200_hw_state hw; - struct r200_state state; - - /* Texture object bookkeeping - */ - unsigned nr_heaps; - driTexHeap *texture_heaps[RADEON_NR_TEX_HEAPS]; - driTextureObject swapped; - int texture_depth; - float initialMaxAnisotropy; - - /* Rasterization and vertex state: - */ - GLuint NewGLState; - - /* Vertex buffers - */ - struct r200_ioctl ioctl; - struct r200_dma dma; - struct r200_store store; - GLboolean save_on_next_unlock; - - /* Clientdata textures; - */ - GLuint prefer_gart_client_texturing; - - /* TCL stuff - */ - GLmatrix TexGenMatrix[R200_MAX_TEXTURE_UNITS]; - GLboolean recheck_texgen[R200_MAX_TEXTURE_UNITS]; - GLboolean TexGenNeedNormals[R200_MAX_TEXTURE_UNITS]; - GLuint TexMatEnabled; - GLuint TexMatCompSel; - GLuint TexGenEnabled; - GLuint TexGenInputs; - GLuint TexGenCompSel; - GLmatrix tmpmat; - - /* r200_tcl.c - */ - struct r200_tcl_info tcl; - - /* r200_swtcl.c - */ - struct r200_swtcl_info swtcl; - - /* r200_vtxfmt.c - */ - struct r200_vbinfo vb; -}; - -#define R200_CONTEXT(ctx) ((r200ContextPtr)(ctx->DriverCtx)) - -extern void r200DestroyContext(__DRIcontextPrivate * driContextPriv); -extern GLboolean r200CreateContext(const __GLcontextModes * glVisual, - __DRIcontextPrivate * driContextPriv, - void *sharedContextPrivate); - -#endif -#endif /* __R200_CONTEXT_H__ */ diff --git a/src/mesa/drivers/dri/r300/r200_ioctl.h b/src/mesa/drivers/dri/r300/r200_ioctl.h deleted file mode 100644 index db7bd7697f..0000000000 --- a/src/mesa/drivers/dri/r300/r200_ioctl.h +++ /dev/null @@ -1,204 +0,0 @@ -/* -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -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 (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 NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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 - */ - -#ifndef __R200_IOCTL_H__ -#define __R200_IOCTL_H__ - -#include "simple_list.h" -#include "radeon_dri.h" -#include "radeon_lock.h" - -#include "xf86drm.h" -#include "drm.h" -#include "r200_context.h" -#include "radeon_drm.h" - -extern void r200EmitState(r200ContextPtr rmesa); -extern void r200EmitVertexAOS(r200ContextPtr rmesa, - GLuint vertex_size, GLuint offset); - -extern void r200EmitVbufPrim(r200ContextPtr rmesa, - GLuint primitive, GLuint vertex_nr); - -extern void r200FlushElts(r200ContextPtr rmesa); - -extern GLushort *r200AllocEltsOpenEnded(r200ContextPtr rmesa, - GLuint primitive, GLuint min_nr); - -extern void r200EmitAOS(r200ContextPtr rmesa, - struct r200_dma_region **regions, - GLuint n, GLuint offset); - -extern void r200EmitBlit(r200ContextPtr rmesa, - GLuint color_fmt, - GLuint src_pitch, - GLuint src_offset, - GLuint dst_pitch, - GLuint dst_offset, - GLint srcx, GLint srcy, - GLint dstx, GLint dsty, GLuint w, GLuint h); - -extern void r200EmitWait(r200ContextPtr rmesa, GLuint flags); - -extern void r200FlushCmdBuf(r200ContextPtr rmesa, const char *); -extern int r200FlushCmdBufLocked(r200ContextPtr rmesa, const char *caller); -extern void r200Flush(GLcontext * ctx); - -extern void r200RefillCurrentDmaRegion(r200ContextPtr rmesa); - -extern void r200AllocDmaRegion(r200ContextPtr rmesa, - struct r200_dma_region *region, - int bytes, int alignment); - -extern void r200AllocDmaRegionVerts(r200ContextPtr rmesa, - struct r200_dma_region *region, - int numverts, int vertsize, int alignment); - -extern void r200ReleaseDmaRegion(r200ContextPtr rmesa, - struct r200_dma_region *region, - const char *caller); - -extern void r200WaitForVBlank(r200ContextPtr rmesa); -extern void r200InitIoctlFuncs(struct dd_function_table *functions); - -extern void *r200AllocateMemoryMESA(__DRInativeDisplay * dpy, int scrn, - GLsizei size, GLfloat readfreq, - GLfloat writefreq, GLfloat priority); -extern void r200FreeMemoryMESA(__DRInativeDisplay * dpy, int scrn, - GLvoid * pointer); -extern GLuint r200GetMemoryOffsetMESA(__DRInativeDisplay * dpy, int scrn, - const GLvoid * pointer); - -extern GLboolean r200IsGartMemory(r200ContextPtr rmesa, const GLvoid * pointer, - GLint size); - -extern GLuint r200GartOffsetFromVirtual(r200ContextPtr rmesa, - const GLvoid * pointer); - -void r200SaveHwState(r200ContextPtr radeon); -void r200SetUpAtomList(r200ContextPtr rmesa); - -/* ================================================================ - * Helper macros: - */ - -/* Close off the last primitive, if it exists. - */ -#define R200_NEWPRIM( rmesa ) \ -do { \ - if ( rmesa->dma.flush ) \ - rmesa->dma.flush( rmesa ); \ -} while (0) - -/* Can accomodate several state changes and primitive changes without - * actually firing the buffer. - */ -#define R200_STATECHANGE( rmesa, ATOM ) \ -do { \ - R200_NEWPRIM( rmesa ); \ - rmesa->hw.ATOM.dirty = GL_TRUE; \ - rmesa->hw.is_dirty = GL_TRUE; \ -} while (0) - -#define R200_DB_STATE( ATOM ) \ - memcpy( rmesa->hw.ATOM.lastcmd, rmesa->hw.ATOM.cmd, \ - rmesa->hw.ATOM.cmd_size * 4) - -static __inline int R200_DB_STATECHANGE(r200ContextPtr rmesa, - struct r200_state_atom *atom) -{ - if (memcmp(atom->cmd, atom->lastcmd, atom->cmd_size * 4)) { - int *tmp; - R200_NEWPRIM(rmesa); - atom->dirty = GL_TRUE; - rmesa->hw.is_dirty = GL_TRUE; - tmp = atom->cmd; - atom->cmd = atom->lastcmd; - atom->lastcmd = tmp; - return 1; - } else - return 0; -} - -/* Fire the buffered vertices no matter what. - */ -#define R200_FIREVERTICES( r200 ) \ -do { \ - if ( (r200)->store.cmd_used || (r200)->dma.flush ) { \ - radeonFlush( (r200)->radeon.glCtx ); \ - } \ -} while (0) - -/* Command lengths. Note that any time you ensure ELTS_BUFSZ or VBUF_BUFSZ - * are available, you will also be adding an rmesa->state.max_state_size because - * r200EmitState is called from within r200EmitVbufPrim and r200FlushElts. - */ -#define AOS_BUFSZ(nr) ((3 + ((nr / 2) * 3) + ((nr & 1) * 2)) * sizeof(int)) -#define VERT_AOS_BUFSZ (5 * sizeof(int)) -#define ELTS_BUFSZ(nr) (12 + nr * 2) -#define VBUF_BUFSZ (3 * sizeof(int)) - -/* Ensure that a minimum amount of space is available in the command buffer. - * This is used to ensure atomicity of state updates with the rendering requests - * that rely on them. - * - * An alternative would be to implement a "soft lock" such that when the buffer - * wraps at an inopportune time, we grab the lock, flush the current buffer, - * and hang on to the lock until the critical section is finished and we flush - * the buffer again and unlock. - */ -static __inline void r200EnsureCmdBufSpace(r200ContextPtr rmesa, int bytes) -{ - if (rmesa->store.cmd_used + bytes > R200_CMD_BUF_SZ) - r200FlushCmdBuf(rmesa, __FUNCTION__); - assert(bytes <= R200_CMD_BUF_SZ); -} - -/* Alloc space in the command buffer - */ -static __inline char *r200AllocCmdBuf(r200ContextPtr rmesa, - int bytes, const char *where) -{ - char *head; - - if (rmesa->store.cmd_used + bytes > R200_CMD_BUF_SZ) - r200FlushCmdBuf(rmesa, where); - - head = rmesa->store.cmd_buf + rmesa->store.cmd_used; - rmesa->store.cmd_used += bytes; - assert(rmesa->store.cmd_used <= R200_CMD_BUF_SZ); - return head; -} - -#endif /* __R200_IOCTL_H__ */ diff --git a/src/mesa/drivers/dri/r300/r200_reg.h b/src/mesa/drivers/dri/r300/r200_reg.h deleted file mode 100644 index 1336e961ac..0000000000 --- a/src/mesa/drivers/dri/r300/r200_reg.h +++ /dev/null @@ -1,1423 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_reg.h,v 1.2 2002/12/16 16:18:54 dawes Exp $ */ -/* -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -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 (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 NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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. -*/ - -#ifndef _R200_REG_H_ -#define _R200_REG_H_ - -#define R200_PP_MISC 0x1c14 -#define R200_REF_ALPHA_MASK 0x000000ff -#define R200_ALPHA_TEST_FAIL (0 << 8) -#define R200_ALPHA_TEST_LESS (1 << 8) -#define R200_ALPHA_TEST_LEQUAL (2 << 8) -#define R200_ALPHA_TEST_EQUAL (3 << 8) -#define R200_ALPHA_TEST_GEQUAL (4 << 8) -#define R200_ALPHA_TEST_GREATER (5 << 8) -#define R200_ALPHA_TEST_NEQUAL (6 << 8) -#define R200_ALPHA_TEST_PASS (7 << 8) -#define R200_ALPHA_TEST_OP_MASK (7 << 8) -#define R200_CHROMA_FUNC_FAIL (0 << 16) -#define R200_CHROMA_FUNC_PASS (1 << 16) -#define R200_CHROMA_FUNC_NEQUAL (2 << 16) -#define R200_CHROMA_FUNC_EQUAL (3 << 16) -#define R200_CHROMA_KEY_NEAREST (0 << 18) -#define R200_CHROMA_KEY_ZERO (1 << 18) -#define R200_RIGHT_HAND_CUBE_D3D (0 << 24) -#define R200_RIGHT_HAND_CUBE_OGL (1 << 24) -#define R200_PP_FOG_COLOR 0x1c18 -#define R200_FOG_COLOR_MASK 0x00ffffff -#define R200_FOG_VERTEX (0 << 24) -#define R200_FOG_TABLE (1 << 24) -#define R200_FOG_USE_DEPTH (0 << 25) -#define R200_FOG_USE_W (1 << 25) -#define R200_FOG_USE_DIFFUSE_ALPHA (2 << 25) -#define R200_FOG_USE_SPEC_ALPHA (3 << 25) -#define R200_FOG_USE_VTX_FOG (4 << 25) -#define R200_FOG_USE_MASK (7 << 25) -#define R200_RE_SOLID_COLOR 0x1c1c -#define R200_RB3D_BLENDCNTL 0x1c20 -#define R200_COMB_FCN_MASK (7 << 12) -#define R200_COMB_FCN_ADD_CLAMP (0 << 12) -#define R200_COMB_FCN_ADD_NOCLAMP (1 << 12) -#define R200_COMB_FCN_SUB_CLAMP (2 << 12) -#define R200_COMB_FCN_SUB_NOCLAMP (3 << 12) -#define R200_COMB_FCN_MIN (4 << 12) -#define R200_COMB_FCN_MAX (5 << 12) -#define R200_COMB_FCN_RSUB_CLAMP (6 << 12) -#define R200_COMB_FCN_RSUB_NOCLAMP (7 << 12) -#define R200_BLEND_GL_ZERO (32) -#define R200_BLEND_GL_ONE (33) -#define R200_BLEND_GL_SRC_COLOR (34) -#define R200_BLEND_GL_ONE_MINUS_SRC_COLOR (35) -#define R200_BLEND_GL_DST_COLOR (36) -#define R200_BLEND_GL_ONE_MINUS_DST_COLOR (37) -#define R200_BLEND_GL_SRC_ALPHA (38) -#define R200_BLEND_GL_ONE_MINUS_SRC_ALPHA (39) -#define R200_BLEND_GL_DST_ALPHA (40) -#define R200_BLEND_GL_ONE_MINUS_DST_ALPHA (41) -#define R200_BLEND_GL_SRC_ALPHA_SATURATE (42) /* src factor only */ -#define R200_BLEND_GL_CONST_COLOR (43) -#define R200_BLEND_GL_ONE_MINUS_CONST_COLOR (44) -#define R200_BLEND_GL_CONST_ALPHA (45) -#define R200_BLEND_GL_ONE_MINUS_CONST_ALPHA (46) -#define R200_BLEND_MASK (63) -#define R200_SRC_BLEND_SHIFT (16) -#define R200_DST_BLEND_SHIFT (24) -#define R200_RB3D_DEPTHOFFSET 0x1c24 -#define R200_RB3D_DEPTHPITCH 0x1c28 -#define R200_DEPTHPITCH_MASK 0x00001ff8 -#define R200_DEPTH_ENDIAN_NO_SWAP (0 << 18) -#define R200_DEPTH_ENDIAN_WORD_SWAP (1 << 18) -#define R200_DEPTH_ENDIAN_DWORD_SWAP (2 << 18) -#define R200_RB3D_ZSTENCILCNTL 0x1c2c -#define R200_DEPTH_FORMAT_MASK (0xf << 0) -#define R200_DEPTH_FORMAT_16BIT_INT_Z (0 << 0) -#define R200_DEPTH_FORMAT_24BIT_INT_Z (2 << 0) -#define R200_DEPTH_FORMAT_24BIT_FLOAT_Z (3 << 0) -#define R200_DEPTH_FORMAT_32BIT_INT_Z (4 << 0) -#define R200_DEPTH_FORMAT_32BIT_FLOAT_Z (5 << 0) -#define R200_DEPTH_FORMAT_24BIT_FLOAT_W (9 << 0) -#define R200_DEPTH_FORMAT_32BIT_FLOAT_W (11 << 0) -#define R200_Z_TEST_NEVER (0 << 4) -#define R200_Z_TEST_LESS (1 << 4) -#define R200_Z_TEST_LEQUAL (2 << 4) -#define R200_Z_TEST_EQUAL (3 << 4) -#define R200_Z_TEST_GEQUAL (4 << 4) -#define R200_Z_TEST_GREATER (5 << 4) -#define R200_Z_TEST_NEQUAL (6 << 4) -#define R200_Z_TEST_ALWAYS (7 << 4) -#define R200_Z_TEST_MASK (7 << 4) -#define R200_STENCIL_TEST_NEVER (0 << 12) -#define R200_STENCIL_TEST_LESS (1 << 12) -#define R200_STENCIL_TEST_LEQUAL (2 << 12) -#define R200_STENCIL_TEST_EQUAL (3 << 12) -#define R200_STENCIL_TEST_GEQUAL (4 << 12) -#define R200_STENCIL_TEST_GREATER (5 << 12) -#define R200_STENCIL_TEST_NEQUAL (6 << 12) -#define R200_STENCIL_TEST_ALWAYS (7 << 12) -#define R200_STENCIL_TEST_MASK (0x7 << 12) -#define R200_STENCIL_FAIL_KEEP (0 << 16) -#define R200_STENCIL_FAIL_ZERO (1 << 16) -#define R200_STENCIL_FAIL_REPLACE (2 << 16) -#define R200_STENCIL_FAIL_INC (3 << 16) -#define R200_STENCIL_FAIL_DEC (4 << 16) -#define R200_STENCIL_FAIL_INVERT (5 << 16) -#define R200_STENCIL_FAIL_INC_WRAP (6 << 16) -#define R200_STENCIL_FAIL_DEC_WRAP (7 << 16) -#define R200_STENCIL_FAIL_MASK (0x7 << 16) -#define R200_STENCIL_ZPASS_KEEP (0 << 20) -#define R200_STENCIL_ZPASS_ZERO (1 << 20) -#define R200_STENCIL_ZPASS_REPLACE (2 << 20) -#define R200_STENCIL_ZPASS_INC (3 << 20) -#define R200_STENCIL_ZPASS_DEC (4 << 20) -#define R200_STENCIL_ZPASS_INVERT (5 << 20) -#define R200_STENCIL_ZPASS_INC_WRAP (6 << 20) -#define R200_STENCIL_ZPASS_DEC_WRAP (7 << 20) -#define R200_STENCIL_ZPASS_MASK (0x7 << 20) -#define R200_STENCIL_ZFAIL_KEEP (0 << 24) -#define R200_STENCIL_ZFAIL_ZERO (1 << 24) -#define R200_STENCIL_ZFAIL_REPLACE (2 << 24) -#define R200_STENCIL_ZFAIL_INC (3 << 24) -#define R200_STENCIL_ZFAIL_DEC (4 << 24) -#define R200_STENCIL_ZFAIL_INVERT (5 << 24) -#define R200_STENCIL_ZFAIL_INC_WRAP (6 << 24) -#define R200_STENCIL_ZFAIL_DEC_WRAP (7 << 24) -#define R200_STENCIL_ZFAIL_MASK (0x7 << 24) -#define R200_Z_WRITE_ENABLE (1 << 30) -/*gap*/ -#define R200_PP_CNTL 0x1c38 -#define R200_TEX_0_ENABLE 0x00000010 -#define R200_TEX_1_ENABLE 0x00000020 -#define R200_TEX_2_ENABLE 0x00000040 -#define R200_TEX_3_ENABLE 0x00000080 -#define R200_TEX_4_ENABLE 0x00000100 -#define R200_TEX_5_ENABLE 0x00000200 -#define R200_TEX_ENABLE_MASK 0x000003f0 -#define R200_FILTER_ROUND_MODE_MASK 0x00000400 -#define R200_TEX_BLEND_7_ENABLE 0x00000800 -#define R200_TEX_BLEND_0_ENABLE 0x00001000 -#define R200_TEX_BLEND_1_ENABLE 0x00002000 -#define R200_TEX_BLEND_2_ENABLE 0x00004000 -#define R200_TEX_BLEND_3_ENABLE 0x00008000 -#define R200_TEX_BLEND_4_ENABLE 0x00010000 -#define R200_TEX_BLEND_5_ENABLE 0x00020000 -#define R200_TEX_BLEND_6_ENABLE 0x00040000 -#define R200_MULTI_PASS_ENABLE 0x00080000 -#define R200_SPECULAR_ENABLE 0x00200000 -#define R200_FOG_ENABLE 0x00400000 -#define R200_ALPHA_TEST_ENABLE 0x00800000 -#define R200_ANTI_ALIAS_NONE 0x00000000 -#define R200_ANTI_ALIAS_LINE 0x01000000 -#define R200_ANTI_ALIAS_POLY 0x02000000 -#define R200_ANTI_ALIAS_MASK 0x03000000 -#define R200_RB3D_CNTL 0x1c3c -#define R200_ALPHA_BLEND_ENABLE (1 << 0) -#define R200_PLANE_MASK_ENABLE (1 << 1) -#define R200_DITHER_ENABLE (1 << 2) -#define R200_ROUND_ENABLE (1 << 3) -#define R200_SCALE_DITHER_ENABLE (1 << 4) -#define R200_DITHER_INIT (1 << 5) -#define R200_ROP_ENABLE (1 << 6) -#define R200_STENCIL_ENABLE (1 << 7) -#define R200_Z_ENABLE (1 << 8) -#define R200_DEPTH_XZ_OFFEST_ENABLE (1 << 9) -#define R200_COLOR_FORMAT_ARGB1555 (3 << 10) -#define R200_COLOR_FORMAT_RGB565 (4 << 10) -#define R200_COLOR_FORMAT_ARGB8888 (6 << 10) -#define R200_COLOR_FORMAT_RGB332 (7 << 10) -#define R200_COLOR_FORMAT_Y8 (8 << 10) -#define R200_COLOR_FORMAT_RGB8 (9 << 10) -#define R200_COLOR_FORMAT_YUV422_VYUY (11 << 10) -#define R200_COLOR_FORMAT_YUV422_YVYU (12 << 10) -#define R200_COLOR_FORMAT_aYUV444 (14 << 10) -#define R200_COLOR_FORMAT_ARGB4444 (15 << 10) -#define R200_CLRCMP_FLIP_ENABLE (1 << 14) -#define R200_SEPARATE_ALPHA_ENABLE (1 << 16) -#define R200_RB3D_COLOROFFSET 0x1c40 -#define R200_COLOROFFSET_MASK 0xfffffff0 -#define R200_RE_WIDTH_HEIGHT 0x1c44 -#define R200_RE_WIDTH_SHIFT 0 -#define R200_RE_HEIGHT_SHIFT 16 -#define R200_RB3D_COLORPITCH 0x1c48 -#define R200_COLORPITCH_MASK 0x000001ff8 -#define R200_COLOR_ENDIAN_NO_SWAP (0 << 18) -#define R200_COLOR_ENDIAN_WORD_SWAP (1 << 18) -#define R200_COLOR_ENDIAN_DWORD_SWAP (2 << 18) -#define R200_SE_CNTL 0x1c4c -#define R200_FFACE_CULL_CW (0 << 0) -#define R200_FFACE_CULL_CCW (1 << 0) -#define R200_FFACE_CULL_DIR_MASK (1 << 0) -#define R200_BFACE_CULL (0 << 1) -#define R200_BFACE_SOLID (3 << 1) -#define R200_FFACE_CULL (0 << 3) -#define R200_FFACE_SOLID (3 << 3) -#define R200_FFACE_CULL_MASK (3 << 3) -#define R200_FLAT_SHADE_VTX_0 (0 << 6) -#define R200_FLAT_SHADE_VTX_1 (1 << 6) -#define R200_FLAT_SHADE_VTX_2 (2 << 6) -#define R200_FLAT_SHADE_VTX_LAST (3 << 6) -#define R200_DIFFUSE_SHADE_SOLID (0 << 8) -#define R200_DIFFUSE_SHADE_FLAT (1 << 8) -#define R200_DIFFUSE_SHADE_GOURAUD (2 << 8) -#define R200_DIFFUSE_SHADE_MASK (3 << 8) -#define R200_ALPHA_SHADE_SOLID (0 << 10) -#define R200_ALPHA_SHADE_FLAT (1 << 10) -#define R200_ALPHA_SHADE_GOURAUD (2 << 10) -#define R200_ALPHA_SHADE_MASK (3 << 10) -#define R200_SPECULAR_SHADE_SOLID (0 << 12) -#define R200_SPECULAR_SHADE_FLAT (1 << 12) -#define R200_SPECULAR_SHADE_GOURAUD (2 << 12) -#define R200_SPECULAR_SHADE_MASK (3 << 12) -#define R200_FOG_SHADE_SOLID (0 << 14) -#define R200_FOG_SHADE_FLAT (1 << 14) -#define R200_FOG_SHADE_GOURAUD (2 << 14) -#define R200_FOG_SHADE_MASK (3 << 14) -#define R200_ZBIAS_ENABLE_POINT (1 << 16) -#define R200_ZBIAS_ENABLE_LINE (1 << 17) -#define R200_ZBIAS_ENABLE_TRI (1 << 18) -#define R200_WIDELINE_ENABLE (1 << 20) -#define R200_VTX_PIX_CENTER_D3D (0 << 27) -#define R200_VTX_PIX_CENTER_OGL (1 << 27) -#define R200_ROUND_MODE_TRUNC (0 << 28) -#define R200_ROUND_MODE_ROUND (1 << 28) -#define R200_ROUND_MODE_ROUND_EVEN (2 << 28) -#define R200_ROUND_MODE_ROUND_ODD (3 << 28) -#define R200_ROUND_PREC_16TH_PIX (0 << 30) -#define R200_ROUND_PREC_8TH_PIX (1 << 30) -#define R200_ROUND_PREC_4TH_PIX (2 << 30) -#define R200_ROUND_PREC_HALF_PIX (3 << 30) -#define R200_RE_CNTL 0x1c50 -#define R200_STIPPLE_ENABLE 0x1 -#define R200_SCISSOR_ENABLE 0x2 -#define R200_PATTERN_ENABLE 0x4 -#define R200_PERSPECTIVE_ENABLE 0x8 -#define R200_POINT_SMOOTH 0x20 -#define R200_VTX_STQ0_D3D 0x00010000 -#define R200_VTX_STQ1_D3D 0x00040000 -#define R200_VTX_STQ2_D3D 0x00100000 -#define R200_VTX_STQ3_D3D 0x00400000 -#define R200_VTX_STQ4_D3D 0x01000000 -#define R200_VTX_STQ5_D3D 0x04000000 -/* gap */ -#define R200_RE_STIPPLE_ADDR 0x1cc8 -#define R200_RE_STIPPLE_DATA 0x1ccc -#define R200_RE_LINE_PATTERN 0x1cd0 -#define R200_LINE_PATTERN_MASK 0x0000ffff -#define R200_LINE_REPEAT_COUNT_SHIFT 16 -#define R200_LINE_PATTERN_START_SHIFT 24 -#define R200_LINE_PATTERN_LITTLE_BIT_ORDER (0 << 28) -#define R200_LINE_PATTERN_BIG_BIT_ORDER (1 << 28) -#define R200_LINE_PATTERN_AUTO_RESET (1 << 29) -#define R200_RE_LINE_STATE 0x1cd4 -#define R200_LINE_CURRENT_PTR_SHIFT 0 -#define R200_LINE_CURRENT_COUNT_SHIFT 8 -#define R200_RE_SCISSOR_TL_0 0x1cd8 -#define R200_RE_SCISSOR_BR_0 0x1cdc -#define R200_RE_SCISSOR_TL_1 0x1ce0 -#define R200_RE_SCISSOR_BR_1 0x1ce4 -#define R200_RE_SCISSOR_TL_2 0x1ce8 -#define R200_RE_SCISSOR_BR_2 0x1cec -/* gap */ -#define R200_RB3D_DEPTHXY_OFFSET 0x1d60 -#define R200_DEPTHX_SHIFT 0 -#define R200_DEPTHY_SHIFT 16 -/* gap */ -#define R200_RB3D_STENCILREFMASK 0x1d7c -#define R200_STENCIL_REF_SHIFT 0 -#define R200_STENCIL_REF_MASK (0xff << 0) -#define R200_STENCIL_MASK_SHIFT 16 -#define R200_STENCIL_VALUE_MASK (0xff << 16) -#define R200_STENCIL_WRITEMASK_SHIFT 24 -#define R200_STENCIL_WRITE_MASK (0xff << 24) -#define R200_RB3D_ROPCNTL 0x1d80 -#define R200_ROP_MASK (15 << 8) -#define R200_ROP_CLEAR (0 << 8) -#define R200_ROP_NOR (1 << 8) -#define R200_ROP_AND_INVERTED (2 << 8) -#define R200_ROP_COPY_INVERTED (3 << 8) -#define R200_ROP_AND_REVERSE (4 << 8) -#define R200_ROP_INVERT (5 << 8) -#define R200_ROP_XOR (6 << 8) -#define R200_ROP_NAND (7 << 8) -#define R200_ROP_AND (8 << 8) -#define R200_ROP_EQUIV (9 << 8) -#define R200_ROP_NOOP (10 << 8) -#define R200_ROP_OR_INVERTED (11 << 8) -#define R200_ROP_COPY (12 << 8) -#define R200_ROP_OR_REVERSE (13 << 8) -#define R200_ROP_OR (14 << 8) -#define R200_ROP_SET (15 << 8) -#define R200_RB3D_PLANEMASK 0x1d84 -/* gap */ -#define R200_SE_VPORT_XSCALE 0x1d98 -#define R200_SE_VPORT_XOFFSET 0x1d9c -#define R200_SE_VPORT_YSCALE 0x1da0 -#define R200_SE_VPORT_YOFFSET 0x1da4 -#define R200_SE_VPORT_ZSCALE 0x1da8 -#define R200_SE_VPORT_ZOFFSET 0x1dac -#define R200_SE_ZBIAS_FACTOR 0x1db0 -#define R200_SE_ZBIAS_CONSTANT 0x1db4 -#define R200_SE_LINE_WIDTH 0x1db8 -#define R200_LINE_WIDTH_SHIFT 0x00000000 -#define R200_MINPOINTSIZE_SHIFT 0x00000010 -/* gap */ -#define R200_SE_VAP_CNTL 0x2080 -#define R200_VAP_TCL_ENABLE 0x00000001 -#define R200_VAP_SINGLE_BUF_STATE_ENABLE 0x00000010 -#define R200_VAP_FORCE_W_TO_ONE 0x00010000 -#define R200_VAP_D3D_TEX_DEFAULT 0x00020000 -#define R200_VAP_VF_MAX_VTX_NUM__SHIFT 18 -#define R200_VAP_DX_CLIP_SPACE_DEF 0x00400000 -#define R200_SE_VF_CNTL 0x2084 -#define R200_VF_PRIM_NONE 0x00000000 -#define R200_VF_PRIM_POINTS 0x00000001 -#define R200_VF_PRIM_LINES 0x00000002 -#define R200_VF_PRIM_LINE_STRIP 0x00000003 -#define R200_VF_PRIM_TRIANGLES 0x00000004 -#define R200_VF_PRIM_TRIANGLE_FAN 0x00000005 -#define R200_VF_PRIM_TRIANGLE_STRIP 0x00000006 -#define R200_VF_PRIM_RECT_LIST 0x00000008 -#define R200_VF_PRIM_3VRT_POINTS 0x00000009 -#define R200_VF_PRIM_3VRT_LINES 0x0000000a -#define R200_VF_PRIM_POINT_SPRITES 0x0000000b -#define R200_VF_PRIM_LINE_LOOP 0x0000000c -#define R200_VF_PRIM_QUADS 0x0000000d -#define R200_VF_PRIM_QUAD_STRIP 0x0000000e -#define R200_VF_PRIM_POLYGON 0x0000000f -#define R200_VF_PRIM_MASK 0x0000000f -#define R200_VF_PRIM_WALK_IND 0x00000010 -#define R200_VF_PRIM_WALK_LIST 0x00000020 -#define R200_VF_PRIM_WALK_RING 0x00000030 -#define R200_VF_PRIM_WALK_MASK 0x00000030 -#define R200_VF_COLOR_ORDER_RGBA 0x00000040 -#define R200_VF_TCL_OUTPUT_VTX_ENABLE 0x00000200 -#define R200_VF_INDEX_SZ_4 0x00000800 -#define R200_VF_VERTEX_NUMBER_MASK 0xffff0000 -#define R200_VF_VERTEX_NUMBER_SHIFT 16 -#define R200_SE_VTX_FMT_0 0x2088 -#define R200_VTX_XY 0 /* always have xy */ -#define R200_VTX_Z0 (1<<0) -#define R200_VTX_W0 (1<<1) -#define R200_VTX_WEIGHT_COUNT_SHIFT (2) -#define R200_VTX_PV_MATRIX_SEL (1<<5) -#define R200_VTX_N0 (1<<6) -#define R200_VTX_POINT_SIZE (1<<7) -#define R200_VTX_DISCRETE_FOG (1<<8) -#define R200_VTX_SHININESS_0 (1<<9) -#define R200_VTX_SHININESS_1 (1<<10) -#define R200_VTX_COLOR_NOT_PRESENT 0 -#define R200_VTX_PK_RGBA 1 -#define R200_VTX_FP_RGB 2 -#define R200_VTX_FP_RGBA 3 -#define R200_VTX_COLOR_MASK 3 -#define R200_VTX_COLOR_0_SHIFT 11 -#define R200_VTX_COLOR_1_SHIFT 13 -#define R200_VTX_COLOR_2_SHIFT 15 -#define R200_VTX_COLOR_3_SHIFT 17 -#define R200_VTX_COLOR_4_SHIFT 19 -#define R200_VTX_COLOR_5_SHIFT 21 -#define R200_VTX_COLOR_6_SHIFT 23 -#define R200_VTX_COLOR_7_SHIFT 25 -#define R200_VTX_XY1 (1<<28) -#define R200_VTX_Z1 (1<<29) -#define R200_VTX_W1 (1<<30) -#define R200_VTX_N1 (1<<31) -#define R200_SE_VTX_FMT_1 0x208c -#define R200_VTX_TEX0_COMP_CNT_SHIFT 0 -#define R200_VTX_TEX1_COMP_CNT_SHIFT 3 -#define R200_VTX_TEX2_COMP_CNT_SHIFT 6 -#define R200_VTX_TEX3_COMP_CNT_SHIFT 9 -#define R200_VTX_TEX4_COMP_CNT_SHIFT 12 -#define R200_VTX_TEX5_COMP_CNT_SHIFT 15 -#define R200_SE_TCL_OUTPUT_VTX_FMT_0 0x2090 -#define R200_SE_TCL_OUTPUT_VTX_FMT_1 0x2094 -/* gap */ -#define R200_SE_VTE_CNTL 0x20b0 -#define R200_VPORT_X_SCALE_ENA 0x00000001 -#define R200_VPORT_X_OFFSET_ENA 0x00000002 -#define R200_VPORT_Y_SCALE_ENA 0x00000004 -#define R200_VPORT_Y_OFFSET_ENA 0x00000008 -#define R200_VPORT_Z_SCALE_ENA 0x00000010 -#define R200_VPORT_Z_OFFSET_ENA 0x00000020 -#define R200_VTX_XY_FMT 0x00000100 -#define R200_VTX_Z_FMT 0x00000200 -#define R200_VTX_W0_FMT 0x00000400 -#define R200_VTX_W0_NORMALIZE 0x00000800 -#define R200_VTX_ST_DENORMALIZED 0x00001000 -/* gap */ -#define R200_SE_VTX_NUM_ARRAYS 0x20c0 -#define R200_SE_VTX_AOS_ATTR01 0x20c4 -#define R200_SE_VTX_AOS_ADDR0 0x20c8 -#define R200_SE_VTX_AOS_ADDR1 0x20cc -#define R200_SE_VTX_AOS_ATTR23 0x20d0 -#define R200_SE_VTX_AOS_ADDR2 0x20d4 -#define R200_SE_VTX_AOS_ADDR3 0x20d8 -#define R200_SE_VTX_AOS_ATTR45 0x20dc -#define R200_SE_VTX_AOS_ADDR4 0x20e0 -#define R200_SE_VTX_AOS_ADDR5 0x20e4 -#define R200_SE_VTX_AOS_ATTR67 0x20e8 -#define R200_SE_VTX_AOS_ADDR6 0x20ec -#define R200_SE_VTX_AOS_ADDR7 0x20f0 -#define R200_SE_VTX_AOS_ATTR89 0x20f4 -#define R200_SE_VTX_AOS_ADDR8 0x20f8 -#define R200_SE_VTX_AOS_ADDR9 0x20fc -#define R200_SE_VTX_AOS_ATTR1011 0x2100 -#define R200_SE_VTX_AOS_ADDR10 0x2104 -#define R200_SE_VTX_AOS_ADDR11 0x2108 -#define R200_SE_VF_MAX_VTX_INDX 0x210c -#define R200_SE_VF_MIN_VTX_INDX 0x2110 -/* gap */ -#define R200_SE_VAP_CNTL_STATUS 0x2140 -#define R200_VC_NO_SWAP (0 << 0) -#define R200_VC_16BIT_SWAP (1 << 0) -#define R200_VC_32BIT_SWAP (2 << 0) -/* gap */ -#define R200_SE_VTX_STATE_CNTL 0x2180 -#define R200_VSC_COLOR_0_ASSEMBLY_CNTL_SHIFT 0x00000000 -#define R200_VSC_COLOR_1_ASSEMBLY_CNTL_SHIFT 0x00000002 -#define R200_VSC_COLOR_2_ASSEMBLY_CNTL_SHIFT 0x00000004 -#define R200_VSC_COLOR_3_ASSEMBLY_CNTL_SHIFT 0x00000006 -#define R200_VSC_COLOR_4_ASSEMBLY_CNTL_SHIFT 0x00000008 -#define R200_VSC_COLOR_5_ASSEMBLY_CNTL_SHIFT 0x0000000a -#define R200_VSC_COLOR_6_ASSEMBLY_CNTL_SHIFT 0x0000000c -#define R200_VSC_COLOR_7_ASSEMBLY_CNTL_SHIFT 0x0000000e -#define R200_VSC_UPDATE_USER_COLOR_0_ENABLE 0x00010000 -#define R200_VSC_UPDATE_USER_COLOR_1_ENABLE 0x00020000 -/* gap */ -#define R200_SE_TCL_VECTOR_INDX_REG 0x2200 -#define R200_SE_TCL_VECTOR_DATA_REG 0x2204 -#define R200_SE_TCL_SCALAR_INDX_REG 0x2208 -#define R200_SE_TCL_SCALAR_DATA_REG 0x220c -/* gap */ -#define R200_SE_TCL_MATRIX_SEL_0 0x2230 -#define R200_MODELVIEW_0_SHIFT (0) -#define R200_MODELVIEW_1_SHIFT (8) -#define R200_MODELVIEW_2_SHIFT (16) -#define R200_MODELVIEW_3_SHIFT (24) -#define R200_SE_TCL_MATRIX_SEL_1 0x2234 -#define R200_IT_MODELVIEW_0_SHIFT (0) -#define R200_IT_MODELVIEW_1_SHIFT (8) -#define R200_IT_MODELVIEW_2_SHIFT (16) -#define R200_IT_MODELVIEW_3_SHIFT (24) -#define R200_SE_TCL_MATRIX_SEL_2 0x2238 -#define R200_MODELPROJECT_0_SHIFT (0) -#define R200_MODELPROJECT_1_SHIFT (8) -#define R200_MODELPROJECT_2_SHIFT (16) -#define R200_MODELPROJECT_3_SHIFT (24) -#define R200_SE_TCL_MATRIX_SEL_3 0x223c -#define R200_TEXMAT_0_SHIFT 0 -#define R200_TEXMAT_1_SHIFT 8 -#define R200_TEXMAT_2_SHIFT 16 -#define R200_TEXMAT_3_SHIFT 24 -#define R200_SE_TCL_MATRIX_SEL_4 0x2240 -#define R200_TEXMAT_4_SHIFT 0 -#define R200_TEXMAT_5_SHIFT 8 -/* gap */ -#define R200_SE_TCL_OUTPUT_VTX_COMP_SEL 0x2250 -#define R200_OUTPUT_XYZW (1<<0) -#define R200_OUTPUT_COLOR_0 (1<<8) -#define R200_OUTPUT_COLOR_1 (1<<9) -#define R200_OUTPUT_TEX_0 (1<<16) -#define R200_OUTPUT_TEX_1 (1<<17) -#define R200_OUTPUT_TEX_2 (1<<18) -#define R200_OUTPUT_TEX_3 (1<<19) -#define R200_OUTPUT_TEX_4 (1<<20) -#define R200_OUTPUT_TEX_5 (1<<21) -#define R200_OUTPUT_TEX_MASK (0x3f<<16) -#define R200_OUTPUT_DISCRETE_FOG (1<<24) -#define R200_OUTPUT_PT_SIZE (1<<25) -#define R200_FORCE_INORDER_PROC (1<<31) -#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0 0x2254 -#define R200_VERTEX_POSITION_ADDR__SHIFT 0x00000000 -#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_1 0x2258 -#define R200_VTX_COLOR_0_ADDR__SHIFT 0x00000000 -#define R200_VTX_COLOR_1_ADDR__SHIFT 0x00000008 -#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_2 0x225c -#define R200_VTX_TEX_0_ADDR__SHIFT 0x00000000 -#define R200_VTX_TEX_1_ADDR__SHIFT 0x00000008 -#define R200_VTX_TEX_2_ADDR__SHIFT 0x00000010 -#define R200_VTX_TEX_3_ADDR__SHIFT 0x00000018 -#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_3 0x2260 -#define R200_VTX_TEX_4_ADDR__SHIFT 0x00000000 -#define R200_VTX_TEX_5_ADDR__SHIFT 0x00000008 - -/* gap */ -#define R200_SE_TCL_LIGHT_MODEL_CTL_0 0x2268 -#define R200_LIGHTING_ENABLE (1<<0) -#define R200_LIGHT_IN_MODELSPACE (1<<1) -#define R200_LOCAL_VIEWER (1<<2) -#define R200_NORMALIZE_NORMALS (1<<3) -#define R200_RESCALE_NORMALS (1<<4) -#define R200_SPECULAR_LIGHTS (1<<5) -#define R200_DIFFUSE_SPECULAR_COMBINE (1<<6) -#define R200_LIGHT_ALPHA (1<<7) -#define R200_LOCAL_LIGHT_VEC_GL (1<<8) -#define R200_LIGHT_NO_NORMAL_AMBIENT_ONLY (1<<9) -#define R200_LIGHT_TWOSIDE (1<<10) -#define R200_FRONT_SHININESS_SOURCE_SHIFT (0xb) -#define R200_BACK_SHININESS_SOURCE_SHIFT (0xd) -#define R200_LM0_SOURCE_MATERIAL_0 (0) -#define R200_LM0_SOURCE_MATERIAL_1 (1) -#define R200_LM0_SOURCE_VERTEX_SHININESS_0 (2) -#define R200_LM0_SOURCE_VERTEX_SHININESS_1 (3) -#define R200_SE_TCL_LIGHT_MODEL_CTL_1 0x226c -#define R200_LM1_SOURCE_LIGHT_PREMULT (0) -#define R200_LM1_SOURCE_MATERIAL_0 (1) -#define R200_LM1_SOURCE_VERTEX_COLOR_0 (2) -#define R200_LM1_SOURCE_VERTEX_COLOR_1 (3) -#define R200_LM1_SOURCE_VERTEX_COLOR_2 (4) -#define R200_LM1_SOURCE_VERTEX_COLOR_3 (5) -#define R200_LM1_SOURCE_VERTEX_COLOR_4 (6) -#define R200_LM1_SOURCE_VERTEX_COLOR_5 (7) -#define R200_LM1_SOURCE_VERTEX_COLOR_6 (8) -#define R200_LM1_SOURCE_VERTEX_COLOR_7 (9) -#define R200_LM1_SOURCE_MATERIAL_1 (0xf) -#define R200_FRONT_EMISSIVE_SOURCE_SHIFT (0) -#define R200_FRONT_AMBIENT_SOURCE_SHIFT (4) -#define R200_FRONT_DIFFUSE_SOURCE_SHIFT (8) -#define R200_FRONT_SPECULAR_SOURCE_SHIFT (12) -#define R200_BACK_EMISSIVE_SOURCE_SHIFT (16) -#define R200_BACK_AMBIENT_SOURCE_SHIFT (20) -#define R200_BACK_DIFFUSE_SOURCE_SHIFT (24) -#define R200_BACK_SPECULAR_SOURCE_SHIFT (28) -#define R200_SE_TCL_PER_LIGHT_CTL_0 0x2270 -#define R200_LIGHT_0_ENABLE (1<<0) -#define R200_LIGHT_0_ENABLE_AMBIENT (1<<1) -#define R200_LIGHT_0_ENABLE_SPECULAR (1<<2) -#define R200_LIGHT_0_IS_LOCAL (1<<3) -#define R200_LIGHT_0_IS_SPOT (1<<4) -#define R200_LIGHT_0_DUAL_CONE (1<<5) -#define R200_LIGHT_0_ENABLE_RANGE_ATTEN (1<<6) -#define R200_LIGHT_0_CONSTANT_RANGE_ATTEN (1<<7) -#define R200_LIGHT_1_ENABLE (1<<16) -#define R200_LIGHT_1_ENABLE_AMBIENT (1<<17) -#define R200_LIGHT_1_ENABLE_SPECULAR (1<<18) -#define R200_LIGHT_1_IS_LOCAL (1<<19) -#define R200_LIGHT_1_IS_SPOT (1<<20) -#define R200_LIGHT_1_DUAL_CONE (1<<21) -#define R200_LIGHT_1_ENABLE_RANGE_ATTEN (1<<22) -#define R200_LIGHT_1_CONSTANT_RANGE_ATTEN (1<<23) -#define R200_LIGHT_0_SHIFT (0) -#define R200_LIGHT_1_SHIFT (16) -#define R200_SE_TCL_PER_LIGHT_CTL_1 0x2274 -#define R200_LIGHT_2_SHIFT (0) -#define R200_LIGHT_3_SHIFT (16) -#define R200_SE_TCL_PER_LIGHT_CTL_2 0x2278 -#define R200_LIGHT_4_SHIFT (0) -#define R200_LIGHT_5_SHIFT (16) -#define R200_SE_TCL_PER_LIGHT_CTL_3 0x227c -#define R200_LIGHT_6_SHIFT (0) -#define R200_LIGHT_7_SHIFT (16) -/* gap */ -#define R200_SE_TCL_TEX_PROC_CTL_2 0x22a8 -#define R200_TEXGEN_0_COMP_MASK_SHIFT (0) -#define R200_TEXGEN_1_COMP_MASK_SHIFT (4) -#define R200_TEXGEN_2_COMP_MASK_SHIFT (8) -#define R200_TEXGEN_3_COMP_MASK_SHIFT (12) -#define R200_TEXGEN_4_COMP_MASK_SHIFT (16) -#define R200_TEXGEN_5_COMP_MASK_SHIFT (20) -#define R200_SE_TCL_TEX_PROC_CTL_3 0x22ac -#define R200_TEXGEN_0_INPUT_TEX_SHIFT (0) -#define R200_TEXGEN_1_INPUT_TEX_SHIFT (4) -#define R200_TEXGEN_2_INPUT_TEX_SHIFT (8) -#define R200_TEXGEN_3_INPUT_TEX_SHIFT (12) -#define R200_TEXGEN_4_INPUT_TEX_SHIFT (16) -#define R200_TEXGEN_5_INPUT_TEX_SHIFT (20) -#define R200_SE_TCL_TEX_PROC_CTL_0 0x22b0 -#define R200_TEXGEN_TEXMAT_0_ENABLE (1<<0) -#define R200_TEXGEN_TEXMAT_1_ENABLE (1<<1) -#define R200_TEXGEN_TEXMAT_2_ENABLE (1<<2) -#define R200_TEXGEN_TEXMAT_3_ENABLE (1<<3) -#define R200_TEXGEN_TEXMAT_4_ENABLE (1<<4) -#define R200_TEXGEN_TEXMAT_5_ENABLE (1<<5) -#define R200_TEXMAT_0_ENABLE (1<<8) -#define R200_TEXMAT_1_ENABLE (1<<9) -#define R200_TEXMAT_2_ENABLE (1<<10) -#define R200_TEXMAT_3_ENABLE (1<<11) -#define R200_TEXMAT_4_ENABLE (1<<12) -#define R200_TEXMAT_5_ENABLE (1<<13) -#define R200_TEXGEN_FORCE_W_TO_ONE (1<<16) -#define R200_SE_TCL_TEX_PROC_CTL_1 0x22b4 -#define R200_TEXGEN_INPUT_MASK (0xf) -#define R200_TEXGEN_INPUT_TEXCOORD_0 (0) -#define R200_TEXGEN_INPUT_TEXCOORD_1 (1) -#define R200_TEXGEN_INPUT_TEXCOORD_2 (2) -#define R200_TEXGEN_INPUT_TEXCOORD_3 (3) -#define R200_TEXGEN_INPUT_TEXCOORD_4 (4) -#define R200_TEXGEN_INPUT_TEXCOORD_5 (5) -#define R200_TEXGEN_INPUT_OBJ (8) -#define R200_TEXGEN_INPUT_EYE (9) -#define R200_TEXGEN_INPUT_EYE_NORMAL (0xa) -#define R200_TEXGEN_INPUT_EYE_REFLECT (0xb) -#define R200_TEXGEN_INPUT_SPHERE (0xd) -#define R200_TEXGEN_0_INPUT_SHIFT (0) -#define R200_TEXGEN_1_INPUT_SHIFT (4) -#define R200_TEXGEN_2_INPUT_SHIFT (8) -#define R200_TEXGEN_3_INPUT_SHIFT (12) -#define R200_TEXGEN_4_INPUT_SHIFT (16) -#define R200_TEXGEN_5_INPUT_SHIFT (20) -#define R200_SE_TC_TEX_CYL_WRAP_CTL 0x22b8 -/* gap */ -#define R200_SE_TCL_UCP_VERT_BLEND_CTL 0x22c0 -#define R200_UCP_IN_CLIP_SPACE (1<<0) -#define R200_UCP_IN_MODEL_SPACE (1<<1) -#define R200_UCP_ENABLE_0 (1<<2) -#define R200_UCP_ENABLE_1 (1<<3) -#define R200_UCP_ENABLE_2 (1<<4) -#define R200_UCP_ENABLE_3 (1<<5) -#define R200_UCP_ENABLE_4 (1<<6) -#define R200_UCP_ENABLE_5 (1<<7) -#define R200_TCL_FOG_MASK (3<<8) -#define R200_TCL_FOG_DISABLE (0<<8) -#define R200_TCL_FOG_EXP (1<<8) -#define R200_TCL_FOG_EXP2 (2<<8) -#define R200_TCL_FOG_LINEAR (3<<8) -#define R200_RNG_BASED_FOG (1<<10) -#define R200_CLIP_DISABLE (1<<11) -#define R200_CULL_FRONT_IS_CW (0<<28) -#define R200_CULL_FRONT_IS_CCW (1<<28) -#define R200_CULL_FRONT (1<<29) -#define R200_CULL_BACK (1<<30) -#define R200_SE_TCL_POINT_SPRITE_CNTL 0x22c4 -/* gap */ -#define R200_SE_VTX_ST_POS_0_X_4 0x2300 -#define R200_SE_VTX_ST_POS_0_Y_4 0x2304 -#define R200_SE_VTX_ST_POS_0_Z_4 0x2308 -#define R200_SE_VTX_ST_POS_0_W_4 0x230c -#define R200_SE_VTX_ST_NORM_0_X 0x2310 -#define R200_SE_VTX_ST_NORM_0_Y 0x2314 -#define R200_SE_VTX_ST_NORM_0_Z 0x2318 -#define R200_SE_VTX_ST_PVMS 0x231c -#define R200_SE_VTX_ST_CLR_0_R 0x2320 -#define R200_SE_VTX_ST_CLR_0_G 0x2324 -#define R200_SE_VTX_ST_CLR_0_B 0x2328 -#define R200_SE_VTX_ST_CLR_0_A 0x232c -#define R200_SE_VTX_ST_CLR_1_R 0x2330 -#define R200_SE_VTX_ST_CLR_1_G 0x2334 -#define R200_SE_VTX_ST_CLR_1_B 0x2338 -#define R200_SE_VTX_ST_CLR_1_A 0x233c -#define R200_SE_VTX_ST_CLR_2_R 0x2340 -#define R200_SE_VTX_ST_CLR_2_G 0x2344 -#define R200_SE_VTX_ST_CLR_2_B 0x2348 -#define R200_SE_VTX_ST_CLR_2_A 0x234c -#define R200_SE_VTX_ST_CLR_3_R 0x2350 -#define R200_SE_VTX_ST_CLR_3_G 0x2354 -#define R200_SE_VTX_ST_CLR_3_B 0x2358 -#define R200_SE_VTX_ST_CLR_3_A 0x235c -#define R200_SE_VTX_ST_CLR_4_R 0x2360 -#define R200_SE_VTX_ST_CLR_4_G 0x2364 -#define R200_SE_VTX_ST_CLR_4_B 0x2368 -#define R200_SE_VTX_ST_CLR_4_A 0x236c -#define R200_SE_VTX_ST_CLR_5_R 0x2370 -#define R200_SE_VTX_ST_CLR_5_G 0x2374 -#define R200_SE_VTX_ST_CLR_5_B 0x2378 -#define R200_SE_VTX_ST_CLR_5_A 0x237c -#define R200_SE_VTX_ST_CLR_6_R 0x2380 -#define R200_SE_VTX_ST_CLR_6_G 0x2384 -#define R200_SE_VTX_ST_CLR_6_B 0x2388 -#define R200_SE_VTX_ST_CLR_6_A 0x238c -#define R200_SE_VTX_ST_CLR_7_R 0x2390 -#define R200_SE_VTX_ST_CLR_7_G 0x2394 -#define R200_SE_VTX_ST_CLR_7_B 0x2398 -#define R200_SE_VTX_ST_CLR_7_A 0x239c -#define R200_SE_VTX_ST_TEX_0_S 0x23a0 -#define R200_SE_VTX_ST_TEX_0_T 0x23a4 -#define R200_SE_VTX_ST_TEX_0_R 0x23a8 -#define R200_SE_VTX_ST_TEX_0_Q 0x23ac -#define R200_SE_VTX_ST_TEX_1_S 0x23b0 -#define R200_SE_VTX_ST_TEX_1_T 0x23b4 -#define R200_SE_VTX_ST_TEX_1_R 0x23b8 -#define R200_SE_VTX_ST_TEX_1_Q 0x23bc -#define R200_SE_VTX_ST_TEX_2_S 0x23c0 -#define R200_SE_VTX_ST_TEX_2_T 0x23c4 -#define R200_SE_VTX_ST_TEX_2_R 0x23c8 -#define R200_SE_VTX_ST_TEX_2_Q 0x23cc -#define R200_SE_VTX_ST_TEX_3_S 0x23d0 -#define R200_SE_VTX_ST_TEX_3_T 0x23d4 -#define R200_SE_VTX_ST_TEX_3_R 0x23d8 -#define R200_SE_VTX_ST_TEX_3_Q 0x23dc -#define R200_SE_VTX_ST_TEX_4_S 0x23e0 -#define R200_SE_VTX_ST_TEX_4_T 0x23e4 -#define R200_SE_VTX_ST_TEX_4_R 0x23e8 -#define R200_SE_VTX_ST_TEX_4_Q 0x23ec -#define R200_SE_VTX_ST_TEX_5_S 0x23f0 -#define R200_SE_VTX_ST_TEX_5_T 0x23f4 -#define R200_SE_VTX_ST_TEX_5_R 0x23f8 -#define R200_SE_VTX_ST_TEX_5_Q 0x23fc -#define R200_SE_VTX_ST_PNT_SPRT_SZ 0x2400 -#define R200_SE_VTX_ST_DISC_FOG 0x2404 -#define R200_SE_VTX_ST_SHININESS_0 0x2408 -#define R200_SE_VTX_ST_SHININESS_1 0x240c -#define R200_SE_VTX_ST_BLND_WT_0 0x2410 -#define R200_SE_VTX_ST_BLND_WT_1 0x2414 -#define R200_SE_VTX_ST_BLND_WT_2 0x2418 -#define R200_SE_VTX_ST_BLND_WT_3 0x241c -#define R200_SE_VTX_ST_POS_1_X 0x2420 -#define R200_SE_VTX_ST_POS_1_Y 0x2424 -#define R200_SE_VTX_ST_POS_1_Z 0x2428 -#define R200_SE_VTX_ST_POS_1_W 0x242c -#define R200_SE_VTX_ST_NORM_1_X 0x2430 -#define R200_SE_VTX_ST_NORM_1_Y 0x2434 -#define R200_SE_VTX_ST_NORM_1_Z 0x2438 -#define R200_SE_VTX_ST_USR_CLR_0_R 0x2440 -#define R200_SE_VTX_ST_USR_CLR_0_G 0x2444 -#define R200_SE_VTX_ST_USR_CLR_0_B 0x2448 -#define R200_SE_VTX_ST_USR_CLR_0_A 0x244c -#define R200_SE_VTX_ST_USR_CLR_1_R 0x2450 -#define R200_SE_VTX_ST_USR_CLR_1_G 0x2454 -#define R200_SE_VTX_ST_USR_CLR_1_B 0x2458 -#define R200_SE_VTX_ST_USR_CLR_1_A 0x245c -#define R200_SE_VTX_ST_CLR_0_PKD 0x2460 -#define R200_SE_VTX_ST_CLR_1_PKD 0x2464 -#define R200_SE_VTX_ST_CLR_2_PKD 0x2468 -#define R200_SE_VTX_ST_CLR_3_PKD 0x246c -#define R200_SE_VTX_ST_CLR_4_PKD 0x2470 -#define R200_SE_VTX_ST_CLR_5_PKD 0x2474 -#define R200_SE_VTX_ST_CLR_6_PKD 0x2478 -#define R200_SE_VTX_ST_CLR_7_PKD 0x247c -#define R200_SE_VTX_ST_POS_0_X_2 0x2480 -#define R200_SE_VTX_ST_POS_0_Y_2 0x2484 -#define R200_SE_VTX_ST_PAR_CLR_LD 0x2488 -#define R200_SE_VTX_ST_USR_CLR_PKD 0x248c -#define R200_SE_VTX_ST_POS_0_X_3 0x2490 -#define R200_SE_VTX_ST_POS_0_Y_3 0x2494 -#define R200_SE_VTX_ST_POS_0_Z_3 0x2498 -#define R200_SE_VTX_ST_END_OF_PKT 0x249c -/* gap */ -#define R200_RE_POINTSIZE 0x2648 -#define R200_POINTSIZE_SHIFT 0 -#define R200_MAXPOINTSIZE_SHIFT 16 -/* gap */ -#define R200_RE_TOP_LEFT 0x26c0 -#define R200_RE_LEFT_SHIFT 0 -#define R200_RE_TOP_SHIFT 16 -#define R200_RE_MISC 0x26c4 -#define R200_STIPPLE_COORD_MASK 0x1f -#define R200_STIPPLE_X_OFFSET_SHIFT 0 -#define R200_STIPPLE_X_OFFSET_MASK (0x1f << 0) -#define R200_STIPPLE_Y_OFFSET_SHIFT 8 -#define R200_STIPPLE_Y_OFFSET_MASK (0x1f << 8) -#define R200_STIPPLE_LITTLE_BIT_ORDER (0 << 16) -#define R200_STIPPLE_BIG_BIT_ORDER (1 << 16) -/* gap */ -#define R200_RE_AUX_SCISSOR_CNTL 0x26f0 -#define R200_EXCLUSIVE_SCISSOR_0 0x01000000 -#define R200_EXCLUSIVE_SCISSOR_1 0x02000000 -#define R200_EXCLUSIVE_SCISSOR_2 0x04000000 -#define R200_SCISSOR_ENABLE_0 0x10000000 -#define R200_SCISSOR_ENABLE_1 0x20000000 -#define R200_SCISSOR_ENABLE_2 0x40000000 -/* gap */ -#define R200_PP_TXFILTER_0 0x2c00 -#define R200_MAG_FILTER_NEAREST (0 << 0) -#define R200_MAG_FILTER_LINEAR (1 << 0) -#define R200_MAG_FILTER_MASK (1 << 0) -#define R200_MIN_FILTER_NEAREST (0 << 1) -#define R200_MIN_FILTER_LINEAR (1 << 1) -#define R200_MIN_FILTER_NEAREST_MIP_NEAREST (2 << 1) -#define R200_MIN_FILTER_NEAREST_MIP_LINEAR (3 << 1) -#define R200_MIN_FILTER_LINEAR_MIP_NEAREST (6 << 1) -#define R200_MIN_FILTER_LINEAR_MIP_LINEAR (7 << 1) -#define R200_MIN_FILTER_ANISO_NEAREST (8 << 1) -#define R200_MIN_FILTER_ANISO_LINEAR (9 << 1) -#define R200_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST (10 << 1) -#define R200_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR (11 << 1) -#define R200_MIN_FILTER_MASK (15 << 1) -#define R200_MAX_ANISO_1_TO_1 (0 << 5) -#define R200_MAX_ANISO_2_TO_1 (1 << 5) -#define R200_MAX_ANISO_4_TO_1 (2 << 5) -#define R200_MAX_ANISO_8_TO_1 (3 << 5) -#define R200_MAX_ANISO_16_TO_1 (4 << 5) -#define R200_MAX_ANISO_MASK (7 << 5) -#define R200_MAX_MIP_LEVEL_MASK (0x0f << 16) -#define R200_MAX_MIP_LEVEL_SHIFT 16 -#define R200_YUV_TO_RGB (1 << 20) -#define R200_YUV_TEMPERATURE_COOL (0 << 21) -#define R200_YUV_TEMPERATURE_HOT (1 << 21) -#define R200_YUV_TEMPERATURE_MASK (1 << 21) -#define R200_WRAPEN_S (1 << 22) -#define R200_CLAMP_S_WRAP (0 << 23) -#define R200_CLAMP_S_MIRROR (1 << 23) -#define R200_CLAMP_S_CLAMP_LAST (2 << 23) -#define R200_CLAMP_S_MIRROR_CLAMP_LAST (3 << 23) -#define R200_CLAMP_S_CLAMP_BORDER (4 << 23) -#define R200_CLAMP_S_MIRROR_CLAMP_BORDER (5 << 23) -#define R200_CLAMP_S_CLAMP_GL (6 << 23) -#define R200_CLAMP_S_MIRROR_CLAMP_GL (7 << 23) -#define R200_CLAMP_S_MASK (7 << 23) -#define R200_WRAPEN_T (1 << 26) -#define R200_CLAMP_T_WRAP (0 << 27) -#define R200_CLAMP_T_MIRROR (1 << 27) -#define R200_CLAMP_T_CLAMP_LAST (2 << 27) -#define R200_CLAMP_T_MIRROR_CLAMP_LAST (3 << 27) -#define R200_CLAMP_T_CLAMP_BORDER (4 << 27) -#define R200_CLAMP_T_MIRROR_CLAMP_BORDER (5 << 27) -#define R200_CLAMP_T_CLAMP_GL (6 << 27) -#define R200_CLAMP_T_MIRROR_CLAMP_GL (7 << 27) -#define R200_CLAMP_T_MASK (7 << 27) -#define R200_KILL_LT_ZERO (1 << 30) -#define R200_BORDER_MODE_OGL (0 << 31) -#define R200_BORDER_MODE_D3D (1 << 31) -#define R200_PP_TXFORMAT_0 0x2c04 -#define R200_TXFORMAT_I8 (0 << 0) -#define R200_TXFORMAT_AI88 (1 << 0) -#define R200_TXFORMAT_RGB332 (2 << 0) -#define R200_TXFORMAT_ARGB1555 (3 << 0) -#define R200_TXFORMAT_RGB565 (4 << 0) -#define R200_TXFORMAT_ARGB4444 (5 << 0) -#define R200_TXFORMAT_ARGB8888 (6 << 0) -#define R200_TXFORMAT_RGBA8888 (7 << 0) -#define R200_TXFORMAT_Y8 (8 << 0) -#define R200_TXFORMAT_AVYU4444 (9 << 0) -#define R200_TXFORMAT_VYUY422 (10 << 0) -#define R200_TXFORMAT_YVYU422 (11 << 0) -#define R200_TXFORMAT_DXT1 (12 << 0) -#define R200_TXFORMAT_DXT23 (14 << 0) -#define R200_TXFORMAT_DXT45 (15 << 0) -#define R200_TXFORMAT_FORMAT_MASK (31 << 0) -#define R200_TXFORMAT_FORMAT_SHIFT 0 -#define R200_TXFORMAT_ALPHA_IN_MAP (1 << 6) -#define R200_TXFORMAT_NON_POWER2 (1 << 7) -#define R200_TXFORMAT_WIDTH_MASK (15 << 8) -#define R200_TXFORMAT_WIDTH_SHIFT 8 -#define R200_TXFORMAT_HEIGHT_MASK (15 << 12) -#define R200_TXFORMAT_HEIGHT_SHIFT 12 -#define R200_TXFORMAT_F5_WIDTH_MASK (15 << 16) /* cube face 5 */ -#define R200_TXFORMAT_F5_WIDTH_SHIFT 16 -#define R200_TXFORMAT_F5_HEIGHT_MASK (15 << 20) -#define R200_TXFORMAT_F5_HEIGHT_SHIFT 20 -#define R200_TXFORMAT_ST_ROUTE_STQ0 (0 << 24) -#define R200_TXFORMAT_ST_ROUTE_STQ1 (1 << 24) -#define R200_TXFORMAT_ST_ROUTE_STQ2 (2 << 24) -#define R200_TXFORMAT_ST_ROUTE_STQ3 (3 << 24) -#define R200_TXFORMAT_ST_ROUTE_STQ4 (4 << 24) -#define R200_TXFORMAT_ST_ROUTE_STQ5 (5 << 24) -#define R200_TXFORMAT_ST_ROUTE_MASK (7 << 24) -#define R200_TXFORMAT_ST_ROUTE_SHIFT 24 -#define R200_TXFORMAT_ALPHA_MASK_ENABLE (1 << 28) -#define R200_TXFORMAT_CHROMA_KEY_ENABLE (1 << 29) -#define R200_TXFORMAT_CUBIC_MAP_ENABLE (1 << 30) -#define R200_PP_TXFORMAT_X_0 0x2c08 -#define R200_DEPTH_LOG2_MASK (0xf << 0) -#define R200_DEPTH_LOG2_SHIFT 0 -#define R200_VOLUME_FILTER_SHIFT 4 -#define R200_VOLUME_FILTER_MASK (1 << 4) -#define R200_VOLUME_FILTER_NEAREST (0 << 4) -#define R200_VOLUME_FILTER_LINEAR (1 << 4) -#define R200_WRAPEN_Q (1 << 8) -#define R200_CLAMP_Q_WRAP (0 << 9) -#define R200_CLAMP_Q_MIRROR (1 << 9) -#define R200_CLAMP_Q_CLAMP_LAST (2 << 9) -#define R200_CLAMP_Q_MIRROR_CLAMP_LAST (3 << 9) -#define R200_CLAMP_Q_CLAMP_BORDER (4 << 9) -#define R200_CLAMP_Q_MIRROR_CLAMP_BORDER (5 << 9) -#define R200_CLAMP_Q_CLAMP_GL (6 << 9) -#define R200_CLAMP_Q_MIRROR_CLAMP_GL (7 << 9) -#define R200_CLAMP_Q_MASK (7 << 9) -#define R200_MIN_MIP_LEVEL_MASK (0xff << 12) -#define R200_MIN_MIP_LEVEL_SHIFT 12 -#define R200_TEXCOORD_NONPROJ (0 << 16) -#define R200_TEXCOORD_CUBIC_ENV (1 << 16) -#define R200_TEXCOORD_VOLUME (2 << 16) -#define R200_TEXCOORD_PROJ (3 << 16) -#define R200_TEXCOORD_DEPTH (4 << 16) -#define R200_TEXCOORD_1D_PROJ (5 << 16) -#define R200_TEXCOORD_1D (6 << 16) -#define R200_TEXCOORD_ZERO (7 << 16) -#define R200_TEXCOORD_MASK (7 << 16) -#define R200_LOD_BIAS_MASK (0xfff80000) -#define R200_LOD_BIAS_SHIFT 19 -#define R200_PP_TXSIZE_0 0x2c0c /* NPOT only */ -#define R200_PP_TXPITCH_0 0x2c10 /* NPOT only */ -#define R200_PP_BORDER_COLOR_0 0x2c14 -#define R200_PP_CUBIC_FACES_0 0x2c18 -#define R200_FACE_WIDTH_1_SHIFT 0 -#define R200_FACE_HEIGHT_1_SHIFT 4 -#define R200_FACE_WIDTH_1_MASK (0xf << 0) -#define R200_FACE_HEIGHT_1_MASK (0xf << 4) -#define R200_FACE_WIDTH_2_SHIFT 8 -#define R200_FACE_HEIGHT_2_SHIFT 12 -#define R200_FACE_WIDTH_2_MASK (0xf << 8) -#define R200_FACE_HEIGHT_2_MASK (0xf << 12) -#define R200_FACE_WIDTH_3_SHIFT 16 -#define R200_FACE_HEIGHT_3_SHIFT 20 -#define R200_FACE_WIDTH_3_MASK (0xf << 16) -#define R200_FACE_HEIGHT_3_MASK (0xf << 20) -#define R200_FACE_WIDTH_4_SHIFT 24 -#define R200_FACE_HEIGHT_4_SHIFT 28 -#define R200_FACE_WIDTH_4_MASK (0xf << 24) -#define R200_FACE_HEIGHT_4_MASK (0xf << 28) -#define R200_PP_TXFILTER_1 0x2c20 -#define R200_PP_TXFORMAT_1 0x2c24 -#define R200_PP_TXFORMAT_X_1 0x2c28 -#define R200_PP_TXSIZE_1 0x2c2c -#define R200_PP_TXPITCH_1 0x2c30 -#define R200_PP_BORDER_COLOR_1 0x2c34 -#define R200_PP_CUBIC_FACES_1 0x2c38 -#define R200_PP_TXFILTER_2 0x2c40 -#define R200_PP_TXFORMAT_2 0x2c44 -#define R200_PP_TXSIZE_2 0x2c4c -#define R200_PP_TXFORMAT_X_2 0x2c48 -#define R200_PP_TXPITCH_2 0x2c50 -#define R200_PP_BORDER_COLOR_2 0x2c54 -#define R200_PP_CUBIC_FACES_2 0x2c58 -#define R200_PP_TXFILTER_3 0x2c60 -#define R200_PP_TXFORMAT_3 0x2c64 -#define R200_PP_TXSIZE_3 0x2c6c -#define R200_PP_TXFORMAT_X_3 0x2c68 -#define R200_PP_TXPITCH_3 0x2c70 -#define R200_PP_BORDER_COLOR_3 0x2c74 -#define R200_PP_CUBIC_FACES_3 0x2c78 -#define R200_PP_TXFILTER_4 0x2c80 -#define R200_PP_TXFORMAT_4 0x2c84 -#define R200_PP_TXSIZE_4 0x2c8c -#define R200_PP_TXFORMAT_X_4 0x2c88 -#define R200_PP_TXPITCH_4 0x2c90 -#define R200_PP_BORDER_COLOR_4 0x2c94 -#define R200_PP_CUBIC_FACES_4 0x2c98 -#define R200_PP_TXFILTER_5 0x2ca0 -#define R200_PP_TXFORMAT_5 0x2ca4 -#define R200_PP_TXSIZE_5 0x2cac -#define R200_PP_TXFORMAT_X_5 0x2ca8 -#define R200_PP_TXPITCH_5 0x2cb0 -#define R200_PP_BORDER_COLOR_5 0x2cb4 -#define R200_PP_CUBIC_FACES_5 0x2cb8 -/* gap */ -#define R200_PP_CNTL_X 0x2cc4 -/* gap */ -#define R200_PP_TXOFFSET_0 0x2d00 -#define R200_TXO_ENDIAN_NO_SWAP (0 << 0) -#define R200_TXO_ENDIAN_BYTE_SWAP (1 << 0) -#define R200_TXO_ENDIAN_WORD_SWAP (2 << 0) -#define R200_TXO_ENDIAN_HALFDW_SWAP (3 << 0) -#define R200_TXO_OFFSET_MASK 0xffffffe0 -#define R200_TXO_OFFSET_SHIFT 5 -#define R200_PP_CUBIC_OFFSET_F1_0 0x2d04 -#define R200_PP_CUBIC_OFFSET_F2_0 0x2d08 -#define R200_PP_CUBIC_OFFSET_F3_0 0x2d0c -#define R200_PP_CUBIC_OFFSET_F4_0 0x2d10 -#define R200_PP_CUBIC_OFFSET_F5_0 0x2d14 -#define R200_PP_TXOFFSET_1 0x2d18 -#define R200_PP_CUBIC_OFFSET_F1_1 0x2d1c -#define R200_PP_CUBIC_OFFSET_F2_1 0x2d20 -#define R200_PP_CUBIC_OFFSET_F3_1 0x2d24 -#define R200_PP_CUBIC_OFFSET_F4_1 0x2d28 -#define R200_PP_CUBIC_OFFSET_F5_1 0x2d2c -#define R200_PP_TXOFFSET_2 0x2d30 -#define R200_PP_CUBIC_OFFSET_F1_2 0x2d34 -#define R200_PP_CUBIC_OFFSET_F2_2 0x2d38 -#define R200_PP_CUBIC_OFFSET_F3_2 0x2d3c -#define R200_PP_CUBIC_OFFSET_F4_2 0x2d40 -#define R200_PP_CUBIC_OFFSET_F5_2 0x2d44 -#define R200_PP_TXOFFSET_3 0x2d48 -#define R200_PP_CUBIC_OFFSET_F1_3 0x2d4c -#define R200_PP_CUBIC_OFFSET_F2_3 0x2d50 -#define R200_PP_CUBIC_OFFSET_F3_3 0x2d54 -#define R200_PP_CUBIC_OFFSET_F4_3 0x2d58 -#define R200_PP_CUBIC_OFFSET_F5_3 0x2d5c -#define R200_PP_TXOFFSET_4 0x2d60 -#define R200_PP_CUBIC_OFFSET_F1_4 0x2d64 -#define R200_PP_CUBIC_OFFSET_F2_4 0x2d68 -#define R200_PP_CUBIC_OFFSET_F3_4 0x2d6c -#define R200_PP_CUBIC_OFFSET_F4_4 0x2d70 -#define R200_PP_CUBIC_OFFSET_F5_4 0x2d74 -#define R200_PP_TXOFFSET_5 0x2d78 -#define R200_PP_CUBIC_OFFSET_F1_5 0x2d7c -#define R200_PP_CUBIC_OFFSET_F2_5 0x2d80 -#define R200_PP_CUBIC_OFFSET_F3_5 0x2d84 -#define R200_PP_CUBIC_OFFSET_F4_5 0x2d88 -#define R200_PP_CUBIC_OFFSET_F5_5 0x2d8c -/* gap */ -#define R200_PP_TAM_DEBUG3 0x2d9c -/* gap */ -#define R200_PP_TFACTOR_0 0x2ee0 -#define R200_PP_TFACTOR_1 0x2ee4 -#define R200_PP_TFACTOR_2 0x2ee8 -#define R200_PP_TFACTOR_3 0x2eec -#define R200_PP_TFACTOR_4 0x2ef0 -#define R200_PP_TFACTOR_5 0x2ef4 -/* gap */ -#define R200_PP_TXCBLEND_0 0x2f00 -#define R200_TXC_ARG_A_ZERO (0) -#define R200_TXC_ARG_A_CURRENT_COLOR (2) -#define R200_TXC_ARG_A_CURRENT_ALPHA (3) -#define R200_TXC_ARG_A_DIFFUSE_COLOR (4) -#define R200_TXC_ARG_A_DIFFUSE_ALPHA (5) -#define R200_TXC_ARG_A_SPECULAR_COLOR (6) -#define R200_TXC_ARG_A_SPECULAR_ALPHA (7) -#define R200_TXC_ARG_A_TFACTOR_COLOR (8) -#define R200_TXC_ARG_A_TFACTOR_ALPHA (9) -#define R200_TXC_ARG_A_R0_COLOR (10) -#define R200_TXC_ARG_A_R0_ALPHA (11) -#define R200_TXC_ARG_A_R1_COLOR (12) -#define R200_TXC_ARG_A_R1_ALPHA (13) -#define R200_TXC_ARG_A_R2_COLOR (14) -#define R200_TXC_ARG_A_R2_ALPHA (15) -#define R200_TXC_ARG_A_R3_COLOR (16) -#define R200_TXC_ARG_A_R3_ALPHA (17) -#define R200_TXC_ARG_A_R4_COLOR (18) -#define R200_TXC_ARG_A_R4_ALPHA (19) -#define R200_TXC_ARG_A_R5_COLOR (20) -#define R200_TXC_ARG_A_R5_ALPHA (21) -#define R200_TXC_ARG_A_TFACTOR1_COLOR (26) -#define R200_TXC_ARG_A_TFACTOR1_ALPHA (27) -#define R200_TXC_ARG_A_MASK (31 << 0) -#define R200_TXC_ARG_A_SHIFT 0 -#define R200_TXC_ARG_B_ZERO (0<<5) -#define R200_TXC_ARG_B_CURRENT_COLOR (2<<5) -#define R200_TXC_ARG_B_CURRENT_ALPHA (3<<5) -#define R200_TXC_ARG_B_DIFFUSE_COLOR (4<<5) -#define R200_TXC_ARG_B_DIFFUSE_ALPHA (5<<5) -#define R200_TXC_ARG_B_SPECULAR_COLOR (6<<5) -#define R200_TXC_ARG_B_SPECULAR_ALPHA (7<<5) -#define R200_TXC_ARG_B_TFACTOR_COLOR (8<<5) -#define R200_TXC_ARG_B_TFACTOR_ALPHA (9<<5) -#define R200_TXC_ARG_B_R0_COLOR (10<<5) -#define R200_TXC_ARG_B_R0_ALPHA (11<<5) -#define R200_TXC_ARG_B_R1_COLOR (12<<5) -#define R200_TXC_ARG_B_R1_ALPHA (13<<5) -#define R200_TXC_ARG_B_R2_COLOR (14<<5) -#define R200_TXC_ARG_B_R2_ALPHA (15<<5) -#define R200_TXC_ARG_B_R3_COLOR (16<<5) -#define R200_TXC_ARG_B_R3_ALPHA (17<<5) -#define R200_TXC_ARG_B_R4_COLOR (18<<5) -#define R200_TXC_ARG_B_R4_ALPHA (19<<5) -#define R200_TXC_ARG_B_R5_COLOR (20<<5) -#define R200_TXC_ARG_B_R5_ALPHA (21<<5) -#define R200_TXC_ARG_B_TFACTOR1_COLOR (26<<5) -#define R200_TXC_ARG_B_TFACTOR1_ALPHA (27<<5) -#define R200_TXC_ARG_B_MASK (31 << 5) -#define R200_TXC_ARG_B_SHIFT 5 -#define R200_TXC_ARG_C_ZERO (0<<10) -#define R200_TXC_ARG_C_CURRENT_COLOR (2<<10) -#define R200_TXC_ARG_C_CURRENT_ALPHA (3<<10) -#define R200_TXC_ARG_C_DIFFUSE_COLOR (4<<10) -#define R200_TXC_ARG_C_DIFFUSE_ALPHA (5<<10) -#define R200_TXC_ARG_C_SPECULAR_COLOR (6<<10) -#define R200_TXC_ARG_C_SPECULAR_ALPHA (7<<10) -#define R200_TXC_ARG_C_TFACTOR_COLOR (8<<10) -#define R200_TXC_ARG_C_TFACTOR_ALPHA (9<<10) -#define R200_TXC_ARG_C_R0_COLOR (10<<10) -#define R200_TXC_ARG_C_R0_ALPHA (11<<10) -#define R200_TXC_ARG_C_R1_COLOR (12<<10) -#define R200_TXC_ARG_C_R1_ALPHA (13<<10) -#define R200_TXC_ARG_C_R2_COLOR (14<<10) -#define R200_TXC_ARG_C_R2_ALPHA (15<<10) -#define R200_TXC_ARG_C_R3_COLOR (16<<10) -#define R200_TXC_ARG_C_R3_ALPHA (17<<10) -#define R200_TXC_ARG_C_R4_COLOR (18<<10) -#define R200_TXC_ARG_C_R4_ALPHA (19<<10) -#define R200_TXC_ARG_C_R5_COLOR (20<<10) -#define R200_TXC_ARG_C_R5_ALPHA (21<<10) -#define R200_TXC_ARG_C_TFACTOR1_COLOR (26<<10) -#define R200_TXC_ARG_C_TFACTOR1_ALPHA (27<<10) -#define R200_TXC_ARG_C_MASK (31 << 10) -#define R200_TXC_ARG_C_SHIFT 10 -#define R200_TXC_COMP_ARG_A (1 << 16) -#define R200_TXC_COMP_ARG_A_SHIFT (16) -#define R200_TXC_BIAS_ARG_A (1 << 17) -#define R200_TXC_SCALE_ARG_A (1 << 18) -#define R200_TXC_NEG_ARG_A (1 << 19) -#define R200_TXC_COMP_ARG_B (1 << 20) -#define R200_TXC_COMP_ARG_B_SHIFT (20) -#define R200_TXC_BIAS_ARG_B (1 << 21) -#define R200_TXC_SCALE_ARG_B (1 << 22) -#define R200_TXC_NEG_ARG_B (1 << 23) -#define R200_TXC_COMP_ARG_C (1 << 24) -#define R200_TXC_COMP_ARG_C_SHIFT (24) -#define R200_TXC_BIAS_ARG_C (1 << 25) -#define R200_TXC_SCALE_ARG_C (1 << 26) -#define R200_TXC_NEG_ARG_C (1 << 27) -#define R200_TXC_OP_MADD (0 << 28) -#define R200_TXC_OP_CND0 (2 << 28) -#define R200_TXC_OP_LERP (3 << 28) -#define R200_TXC_OP_DOT3 (4 << 28) -#define R200_TXC_OP_DOT4 (5 << 28) -#define R200_TXC_OP_CONDITIONAL (6 << 28) -#define R200_TXC_OP_DOT2_ADD (7 << 28) -#define R200_TXC_OP_MASK (7 << 28) -#define R200_PP_TXCBLEND2_0 0x2f04 -#define R200_TXC_TFACTOR_SEL_SHIFT 0 -#define R200_TXC_TFACTOR_SEL_MASK 0x7 -#define R200_TXC_TFACTOR1_SEL_SHIFT 4 -#define R200_TXC_TFACTOR1_SEL_MASK (0x7 << 4) -#define R200_TXC_SCALE_SHIFT 8 -#define R200_TXC_SCALE_MASK (7 << 8) -#define R200_TXC_SCALE_1X (0 << 8) -#define R200_TXC_SCALE_2X (1 << 8) -#define R200_TXC_SCALE_4X (2 << 8) -#define R200_TXC_SCALE_8X (3 << 8) -#define R200_TXC_SCALE_INV2 (5 << 8) -#define R200_TXC_SCALE_INV4 (6 << 8) -#define R200_TXC_SCALE_INV8 (7 << 8) -#define R200_TXC_CLAMP_SHIFT 12 -#define R200_TXC_CLAMP_MASK (3 << 12) -#define R200_TXC_CLAMP_WRAP (0 << 12) -#define R200_TXC_CLAMP_0_1 (1 << 12) -#define R200_TXC_CLAMP_8_8 (2 << 12) -#define R200_TXC_OUTPUT_REG_MASK (7 << 16) -#define R200_TXC_OUTPUT_REG_NONE (0 << 16) -#define R200_TXC_OUTPUT_REG_R0 (1 << 16) -#define R200_TXC_OUTPUT_REG_R1 (2 << 16) -#define R200_TXC_OUTPUT_REG_R2 (3 << 16) -#define R200_TXC_OUTPUT_REG_R3 (4 << 16) -#define R200_TXC_OUTPUT_REG_R4 (5 << 16) -#define R200_TXC_OUTPUT_REG_R5 (6 << 16) -#define R200_TXC_OUTPUT_MASK_MASK (7 << 20) -#define R200_TXC_OUTPUT_MASK_RGB (0 << 20) -#define R200_TXC_OUTPUT_MASK_RG (1 << 20) -#define R200_TXC_OUTPUT_MASK_RB (2 << 20) -#define R200_TXC_OUTPUT_MASK_R (3 << 20) -#define R200_TXC_OUTPUT_MASK_GB (4 << 20) -#define R200_TXC_OUTPUT_MASK_G (5 << 20) -#define R200_TXC_OUTPUT_MASK_B (6 << 20) -#define R200_TXC_OUTPUT_MASK_NONE (7 << 20) -#define R200_TXC_REPL_NORMAL 0 -#define R200_TXC_REPL_RED 1 -#define R200_TXC_REPL_GREEN 2 -#define R200_TXC_REPL_BLUE 3 -#define R200_TXC_REPL_ARG_A_SHIFT 26 -#define R200_TXC_REPL_ARG_A_MASK (3 << 26) -#define R200_TXC_REPL_ARG_B_SHIFT 28 -#define R200_TXC_REPL_ARG_B_MASK (3 << 28) -#define R200_TXC_REPL_ARG_C_SHIFT 30 -#define R200_TXC_REPL_ARG_C_MASK (3 << 30) -#define R200_PP_TXABLEND_0 0x2f08 -#define R200_TXA_ARG_A_ZERO (0) -#define R200_TXA_ARG_A_CURRENT_ALPHA (2) /* guess */ -#define R200_TXA_ARG_A_CURRENT_BLUE (3) /* guess */ -#define R200_TXA_ARG_A_DIFFUSE_ALPHA (4) -#define R200_TXA_ARG_A_DIFFUSE_BLUE (5) -#define R200_TXA_ARG_A_SPECULAR_ALPHA (6) -#define R200_TXA_ARG_A_SPECULAR_BLUE (7) -#define R200_TXA_ARG_A_TFACTOR_ALPHA (8) -#define R200_TXA_ARG_A_TFACTOR_BLUE (9) -#define R200_TXA_ARG_A_R0_ALPHA (10) -#define R200_TXA_ARG_A_R0_BLUE (11) -#define R200_TXA_ARG_A_R1_ALPHA (12) -#define R200_TXA_ARG_A_R1_BLUE (13) -#define R200_TXA_ARG_A_R2_ALPHA (14) -#define R200_TXA_ARG_A_R2_BLUE (15) -#define R200_TXA_ARG_A_R3_ALPHA (16) -#define R200_TXA_ARG_A_R3_BLUE (17) -#define R200_TXA_ARG_A_R4_ALPHA (18) -#define R200_TXA_ARG_A_R4_BLUE (19) -#define R200_TXA_ARG_A_R5_ALPHA (20) -#define R200_TXA_ARG_A_R5_BLUE (21) -#define R200_TXA_ARG_A_TFACTOR1_ALPHA (26) -#define R200_TXA_ARG_A_TFACTOR1_BLUE (27) -#define R200_TXA_ARG_A_MASK (31 << 0) -#define R200_TXA_ARG_A_SHIFT 0 -#define R200_TXA_ARG_B_ZERO (0<<5) -#define R200_TXA_ARG_B_CURRENT_ALPHA (2<<5) /* guess */ -#define R200_TXA_ARG_B_CURRENT_BLUE (3<<5) /* guess */ -#define R200_TXA_ARG_B_DIFFUSE_ALPHA (4<<5) -#define R200_TXA_ARG_B_DIFFUSE_BLUE (5<<5) -#define R200_TXA_ARG_B_SPECULAR_ALPHA (6<<5) -#define R200_TXA_ARG_B_SPECULAR_BLUE (7<<5) -#define R200_TXA_ARG_B_TFACTOR_ALPHA (8<<5) -#define R200_TXA_ARG_B_TFACTOR_BLUE (9<<5) -#define R200_TXA_ARG_B_R0_ALPHA (10<<5) -#define R200_TXA_ARG_B_R0_BLUE (11<<5) -#define R200_TXA_ARG_B_R1_ALPHA (12<<5) -#define R200_TXA_ARG_B_R1_BLUE (13<<5) -#define R200_TXA_ARG_B_R2_ALPHA (14<<5) -#define R200_TXA_ARG_B_R2_BLUE (15<<5) -#define R200_TXA_ARG_B_R3_ALPHA (16<<5) -#define R200_TXA_ARG_B_R3_BLUE (17<<5) -#define R200_TXA_ARG_B_R4_ALPHA (18<<5) -#define R200_TXA_ARG_B_R4_BLUE (19<<5) -#define R200_TXA_ARG_B_R5_ALPHA (20<<5) -#define R200_TXA_ARG_B_R5_BLUE (21<<5) -#define R200_TXA_ARG_B_TFACTOR1_ALPHA (26<<5) -#define R200_TXA_ARG_B_TFACTOR1_BLUE (27<<5) -#define R200_TXA_ARG_B_MASK (31 << 5) -#define R200_TXA_ARG_B_SHIFT 5 -#define R200_TXA_ARG_C_ZERO (0<<10) -#define R200_TXA_ARG_C_CURRENT_ALPHA (2<<10) /* guess */ -#define R200_TXA_ARG_C_CURRENT_BLUE (3<<10) /* guess */ -#define R200_TXA_ARG_C_DIFFUSE_ALPHA (4<<10) -#define R200_TXA_ARG_C_DIFFUSE_BLUE (5<<10) -#define R200_TXA_ARG_C_SPECULAR_ALPHA (6<<10) -#define R200_TXA_ARG_C_SPECULAR_BLUE (7<<10) -#define R200_TXA_ARG_C_TFACTOR_ALPHA (8<<10) -#define R200_TXA_ARG_C_TFACTOR_BLUE (9<<10) -#define R200_TXA_ARG_C_R0_ALPHA (10<<10) -#define R200_TXA_ARG_C_R0_BLUE (11<<10) -#define R200_TXA_ARG_C_R1_ALPHA (12<<10) -#define R200_TXA_ARG_C_R1_BLUE (13<<10) -#define R200_TXA_ARG_C_R2_ALPHA (14<<10) -#define R200_TXA_ARG_C_R2_BLUE (15<<10) -#define R200_TXA_ARG_C_R3_ALPHA (16<<10) -#define R200_TXA_ARG_C_R3_BLUE (17<<10) -#define R200_TXA_ARG_C_R4_ALPHA (18<<10) -#define R200_TXA_ARG_C_R4_BLUE (19<<10) -#define R200_TXA_ARG_C_R5_ALPHA (20<<10) -#define R200_TXA_ARG_C_R5_BLUE (21<<10) -#define R200_TXA_ARG_C_TFACTOR1_ALPHA (26<<10) -#define R200_TXA_ARG_C_TFACTOR1_BLUE (27<<10) -#define R200_TXA_ARG_C_MASK (31 << 10) -#define R200_TXA_ARG_C_SHIFT 10 -#define R200_TXA_COMP_ARG_A (1 << 16) -#define R200_TXA_COMP_ARG_A_SHIFT (16) -#define R200_TXA_BIAS_ARG_A (1 << 17) -#define R200_TXA_SCALE_ARG_A (1 << 18) -#define R200_TXA_NEG_ARG_A (1 << 19) -#define R200_TXA_COMP_ARG_B (1 << 20) -#define R200_TXA_COMP_ARG_B_SHIFT (20) -#define R200_TXA_BIAS_ARG_B (1 << 21) -#define R200_TXA_SCALE_ARG_B (1 << 22) -#define R200_TXA_NEG_ARG_B (1 << 23) -#define R200_TXA_COMP_ARG_C (1 << 24) -#define R200_TXA_COMP_ARG_C_SHIFT (24) -#define R200_TXA_BIAS_ARG_C (1 << 25) -#define R200_TXA_SCALE_ARG_C (1 << 26) -#define R200_TXA_NEG_ARG_C (1 << 27) -#define R200_TXA_OP_MADD (0 << 28) -#define R200_TXA_OP_CND0 (2 << 28) -#define R200_TXA_OP_LERP (3 << 28) -#define R200_TXA_OP_CONDITIONAL (6 << 28) -#define R200_TXA_OP_MASK (7 << 28) -#define R200_PP_TXABLEND2_0 0x2f0c -#define R200_TXA_TFACTOR_SEL_SHIFT 0 -#define R200_TXA_TFACTOR_SEL_MASK 0x7 -#define R200_TXA_TFACTOR1_SEL_SHIFT 4 -#define R200_TXA_TFACTOR1_SEL_MASK (0x7 << 4) -#define R200_TXA_SCALE_SHIFT 8 -#define R200_TXA_SCALE_MASK (7 << 8) -#define R200_TXA_SCALE_1X (0 << 8) -#define R200_TXA_SCALE_2X (1 << 8) -#define R200_TXA_SCALE_4X (2 << 8) -#define R200_TXA_SCALE_8X (3 << 8) -#define R200_TXA_SCALE_INV2 (5 << 8) -#define R200_TXA_SCALE_INV4 (6 << 8) -#define R200_TXA_SCALE_INV8 (7 << 8) -#define R200_TXA_CLAMP_SHIFT 12 -#define R200_TXA_CLAMP_MASK (3 << 12) -#define R200_TXA_CLAMP_WRAP (0 << 12) -#define R200_TXA_CLAMP_0_1 (1 << 12) -#define R200_TXA_CLAMP_8_8 (2 << 12) -#define R200_TXA_OUTPUT_REG_MASK (7 << 16) -#define R200_TXA_OUTPUT_REG_NONE (0 << 16) -#define R200_TXA_OUTPUT_REG_R0 (1 << 16) -#define R200_TXA_OUTPUT_REG_R1 (2 << 16) -#define R200_TXA_OUTPUT_REG_R2 (3 << 16) -#define R200_TXA_OUTPUT_REG_R3 (4 << 16) -#define R200_TXA_OUTPUT_REG_R4 (5 << 16) -#define R200_TXA_OUTPUT_REG_R5 (6 << 16) -#define R200_TXA_DOT_ALPHA (1 << 20) -#define R200_TXA_REPL_NORMAL 0 -#define R200_TXA_REPL_RED 1 -#define R200_TXA_REPL_GREEN 2 -#define R200_TXA_REPL_ARG_A_SHIFT 26 -#define R200_TXA_REPL_ARG_A_MASK (3 << 26) -#define R200_TXA_REPL_ARG_B_SHIFT 28 -#define R200_TXA_REPL_ARG_B_MASK (3 << 28) -#define R200_TXA_REPL_ARG_C_SHIFT 30 -#define R200_TXA_REPL_ARG_C_MASK (3 << 30) -#define R200_PP_TXCBLEND_1 0x2f10 -#define R200_PP_TXCBLEND2_1 0x2f14 -#define R200_PP_TXABLEND_1 0x2f18 -#define R200_PP_TXABLEND2_1 0x2f1c -#define R200_PP_TXCBLEND_2 0x2f20 -#define R200_PP_TXCBLEND2_2 0x2f24 -#define R200_PP_TXABLEND_2 0x2f28 -#define R200_PP_TXABLEND2_2 0x2f2c -#define R200_PP_TXCBLEND_3 0x2f30 -#define R200_PP_TXCBLEND2_3 0x2f34 -#define R200_PP_TXABLEND_3 0x2f38 -#define R200_PP_TXABLEND2_3 0x2f3c -#define R200_PP_TXCBLEND_4 0x2f40 -#define R200_PP_TXCBLEND2_4 0x2f44 -#define R200_PP_TXABLEND_4 0x2f48 -#define R200_PP_TXABLEND2_4 0x2f4c -#define R200_PP_TXCBLEND_5 0x2f50 -#define R200_PP_TXCBLEND2_5 0x2f54 -#define R200_PP_TXABLEND_5 0x2f58 -#define R200_PP_TXABLEND2_5 0x2f5c -#define R200_PP_TXCBLEND_6 0x2f60 -#define R200_PP_TXCBLEND2_6 0x2f64 -#define R200_PP_TXABLEND_6 0x2f68 -#define R200_PP_TXABLEND2_6 0x2f6c -#define R200_PP_TXCBLEND_7 0x2f70 -#define R200_PP_TXCBLEND2_7 0x2f74 -#define R200_PP_TXABLEND_7 0x2f78 -#define R200_PP_TXABLEND2_7 0x2f7c -/* gap */ -#define R200_RB3D_BLENDCOLOR 0x3218 /* ARGB 8888 */ -#define R200_RB3D_ABLENDCNTL 0x321C /* see BLENDCTL */ -#define R200_RB3D_CBLENDCNTL 0x3220 /* see BLENDCTL */ - -/* - * Offsets in TCL vector state. NOTE: Hardwiring matrix positions. - * Multiple contexts could collaberate to eliminate state bouncing. - */ -#define R200_VS_LIGHT_AMBIENT_ADDR 0x00000028 -#define R200_VS_LIGHT_DIFFUSE_ADDR 0x00000030 -#define R200_VS_LIGHT_SPECULAR_ADDR 0x00000038 -#define R200_VS_LIGHT_DIRPOS_ADDR 0x00000040 -#define R200_VS_LIGHT_HWVSPOT_ADDR 0x00000048 -#define R200_VS_LIGHT_ATTENUATION_ADDR 0x00000050 -#define R200_VS_SPOT_DUAL_CONE 0x00000058 -#define R200_VS_GLOBAL_AMBIENT_ADDR 0x0000005C -#define R200_VS_FOG_PARAM_ADDR 0x0000005D -#define R200_VS_EYE_VECTOR_ADDR 0x0000005E -#define R200_VS_UCP_ADDR 0x00000060 -#define R200_VS_PNT_SPRITE_VPORT_SCALE 0x00000068 -#define R200_VS_MATRIX_0_MV 0x00000080 -#define R200_VS_MATRIX_1_INV_MV 0x00000084 -#define R200_VS_MATRIX_2_MVP 0x00000088 -#define R200_VS_MATRIX_3_TEX0 0x0000008C -#define R200_VS_MATRIX_4_TEX1 0x00000090 -#define R200_VS_MATRIX_5_TEX2 0x00000094 -#define R200_VS_MATRIX_6_TEX3 0x00000098 -#define R200_VS_MATRIX_7_TEX4 0x0000009C -#define R200_VS_MATRIX_8_TEX5 0x000000A0 -#define R200_VS_MAT_0_EMISS 0x000000B0 -#define R200_VS_MAT_0_AMB 0x000000B1 -#define R200_VS_MAT_0_DIF 0x000000B2 -#define R200_VS_MAT_0_SPEC 0x000000B3 -#define R200_VS_MAT_1_EMISS 0x000000B4 -#define R200_VS_MAT_1_AMB 0x000000B5 -#define R200_VS_MAT_1_DIF 0x000000B6 -#define R200_VS_MAT_1_SPEC 0x000000B7 -#define R200_VS_EYE2CLIP_MTX 0x000000B8 -#define R200_VS_PNT_SPRITE_ATT_CONST 0x000000BC -#define R200_VS_PNT_SPRITE_EYE_IN_MODEL 0x000000BD -#define R200_VS_PNT_SPRITE_CLAMP 0x000000BE -#define R200_VS_MAX 0x000001C0 - -/* - * Offsets in TCL scalar state - */ -#define R200_SS_LIGHT_DCD_ADDR 0x00000000 -#define R200_SS_LIGHT_DCM_ADDR 0x00000008 -#define R200_SS_LIGHT_SPOT_EXPONENT_ADDR 0x00000010 -#define R200_SS_LIGHT_SPOT_CUTOFF_ADDR 0x00000018 -#define R200_SS_LIGHT_SPECULAR_THRESH_ADDR 0x00000020 -#define R200_SS_LIGHT_RANGE_CUTOFF_SQRD 0x00000028 -#define R200_SS_LIGHT_RANGE_ATT_CONST 0x00000030 -#define R200_SS_VERT_GUARD_CLIP_ADJ_ADDR 0x00000080 -#define R200_SS_VERT_GUARD_DISCARD_ADJ_ADDR 0x00000081 -#define R200_SS_HORZ_GUARD_CLIP_ADJ_ADDR 0x00000082 -#define R200_SS_HORZ_GUARD_DISCARD_ADJ_ADDR 0x00000083 -#define R200_SS_MAT_0_SHININESS 0x00000100 -#define R200_SS_MAT_1_SHININESS 0x00000101 - -/* - * Matrix indices - */ -#define R200_MTX_MV 0 -#define R200_MTX_IMV 1 -#define R200_MTX_MVP 2 -#define R200_MTX_TEX0 3 -#define R200_MTX_TEX1 4 -#define R200_MTX_TEX2 5 -#define R200_MTX_TEX3 6 -#define R200_MTX_TEX4 7 -#define R200_MTX_TEX5 8 - -/* Color formats for 2d packets - */ -#define R200_CP_COLOR_FORMAT_CI8 2 -#define R200_CP_COLOR_FORMAT_ARGB1555 3 -#define R200_CP_COLOR_FORMAT_RGB565 4 -#define R200_CP_COLOR_FORMAT_ARGB8888 6 -#define R200_CP_COLOR_FORMAT_RGB332 7 -#define R200_CP_COLOR_FORMAT_RGB8 9 -#define R200_CP_COLOR_FORMAT_ARGB4444 15 - -/* - * CP type-3 packets - */ -#define R200_CP_CMD_NOP 0xC0001000 -#define R200_CP_CMD_NEXT_CHAR 0xC0001900 -#define R200_CP_CMD_PLY_NEXTSCAN 0xC0001D00 -#define R200_CP_CMD_SET_SCISSORS 0xC0001E00 -#define R200_CP_CMD_LOAD_MICROCODE 0xC0002400 -#define R200_CP_CMD_WAIT_FOR_IDLE 0xC0002600 -#define R200_CP_CMD_3D_DRAW_VBUF 0xC0002800 -#define R200_CP_CMD_3D_DRAW_IMMD 0xC0002900 -#define R200_CP_CMD_3D_DRAW_INDX 0xC0002A00 -#define R200_CP_CMD_LOAD_PALETTE 0xC0002C00 -#define R200_CP_CMD_3D_LOAD_VBPNTR 0xC0002F00 -#define R200_CP_CMD_INDX_BUFFER 0xC0003300 -#define R200_CP_CMD_3D_DRAW_VBUF_2 0xC0003400 -#define R200_CP_CMD_3D_DRAW_IMMD_2 0xC0003500 -#define R200_CP_CMD_3D_DRAW_INDX_2 0xC0003600 -#define R200_CP_CMD_PAINT 0xC0009100 -#define R200_CP_CMD_BITBLT 0xC0009200 -#define R200_CP_CMD_SMALLTEXT 0xC0009300 -#define R200_CP_CMD_HOSTDATA_BLT 0xC0009400 -#define R200_CP_CMD_POLYLINE 0xC0009500 -#define R200_CP_CMD_POLYSCANLINES 0xC0009800 -#define R200_CP_CMD_PAINT_MULTI 0xC0009A00 -#define R200_CP_CMD_BITBLT_MULTI 0xC0009B00 -#define R200_CP_CMD_TRANS_BITBLT 0xC0009C00 - -#endif diff --git a/src/mesa/drivers/dri/r300/r200_state.h b/src/mesa/drivers/dri/r300/r200_state.h deleted file mode 100644 index 3e1a9c8ba1..0000000000 --- a/src/mesa/drivers/dri/r300/r200_state.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -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 (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 NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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 - */ - -#ifndef __R200_STATE_H__ -#define __R200_STATE_H__ - -#ifdef GLX_DIRECT_RENDERING - -#include "r200_context.h" - -extern void r200InitState(r200ContextPtr rmesa); -extern void r200InitStateFuncs(struct dd_function_table *functions); -extern void r200InitTnlFuncs(GLcontext * ctx); - -extern void r200UpdateMaterial(GLcontext * ctx); - -extern void r200UpdateViewportOffset(GLcontext * ctx); -extern void r200UpdateWindow(GLcontext * ctx); - -extern void r200ValidateState(GLcontext * ctx); - -extern void r200PrintDirty(r200ContextPtr rmesa, const char *msg); - -extern void r200LightingSpaceChange(GLcontext * ctx); - -#endif -#endif -- cgit v1.2.3 From cf4ccd5020743591b8d2b29df279c729004ca393 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Sat, 3 Feb 2007 17:32:02 +0100 Subject: Fall back to software rasterization if r300_translate_fragment_shader() fails. Aborting immediately is a bad idea with AIGLX. --- src/mesa/drivers/dri/r300/r300_render.c | 10 ++++++++++ src/mesa/drivers/dri/r300/r300_state.c | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index 3d094b9db5..e29df87696 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -385,8 +385,18 @@ GLboolean r300_run_vb_render(GLcontext *ctx, int r300Fallback(GLcontext *ctx) { r300ContextPtr r300 = R300_CONTEXT(ctx); + struct r300_fragment_program *rp = + (struct r300_fragment_program *) + (char *)ctx->FragmentProgram._Current; int i; + if (rp) { + if (!rp->translated) + r300_translate_fragment_shader(rp); + + FALLBACK_IF(!rp->translated); + } + /* We do not do SELECT or FEEDBACK (yet ?) * Is it worth doing them ? */ diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index e06999aa26..a12f3bb531 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -1823,7 +1823,7 @@ void r300SetupPixelShader(r300ContextPtr rmesa) r300_translate_fragment_shader(rp); if (!rp->translated) { fprintf(stderr, "%s: No valid fragment shader, exiting\n", __func__); - exit(-1); + return; } #define OUTPUT_FIELD(st, reg, field) \ -- cgit v1.2.3 From 49a17a45fb893f0b2e93f27b16d54fe86f51c08c Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 3 Feb 2007 10:30:50 -0700 Subject: Add _NEW_PROGRAM flag to _MESA_NEW_NEED_EYE_COORDS. This fixes a segfault in the texgen code that can occur after we've disabled a vertex program. --- src/mesa/main/mtypes.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 2ad37d3a8d..e8f0f45d39 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2674,6 +2674,7 @@ struct matrix_stack #define _MESA_NEW_NEED_EYE_COORDS (_NEW_LIGHT | \ _NEW_TEXTURE | \ _NEW_POINT | \ + _NEW_PROGRAM | \ _NEW_MODELVIEW) #define _MESA_NEW_NEED_NORMALS (_NEW_LIGHT | \ -- cgit v1.2.3 From be85770f148a0b3cac1720f843b2fa34dd74295f Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 3 Feb 2007 23:32:12 +0100 Subject: nouveau: nv50: use nv50 state --- src/mesa/drivers/dri/nouveau/nouveau_state.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c index aef1f63494..e9fd188d73 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -170,9 +170,11 @@ void nouveauDDInitState(nouveauContextPtr nmesa) case NV_30: case NV_40: case NV_44: - case NV_50: nv30InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver); break; + case NV_50: + nv50InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver); + break; default: break; } -- cgit v1.2.3 From f8ec7f1398e600f4ed2ff3d0fb8d77d706f0fc18 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 3 Feb 2007 23:46:58 +0100 Subject: nouveau: forgot function declaration --- src/mesa/drivers/dri/nouveau/nouveau_state.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.h b/src/mesa/drivers/dri/nouveau/nouveau_state.h index 5b85287445..dbac71760b 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.h @@ -36,6 +36,7 @@ extern void nv04InitStateFuncs(GLcontext *ctx, struct dd_function_table *func); extern void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func); extern void nv20InitStateFuncs(GLcontext *ctx, struct dd_function_table *func); extern void nv30InitStateFuncs(GLcontext *ctx, struct dd_function_table *func); +extern void nv50InitStateFuncs(GLcontext *ctx, struct dd_function_table *func); extern void nouveauInitState(GLcontext *ctx); -- cgit v1.2.3 From 63568745863a54308fecc32dbb96397c35b22496 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sun, 4 Feb 2007 03:17:06 +0100 Subject: nouveau: fix nv04 and nv10 swtcl, more work on nv04 state. --- src/mesa/drivers/dri/nouveau/nouveau_swtcl.c | 4 +- src/mesa/drivers/dri/nouveau/nv04_state.c | 20 +++++----- src/mesa/drivers/dri/nouveau/nv04_swtcl.c | 52 +++++++++++++++++++++++++- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 56 ++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c b/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c index f5c92a1b4e..8a013bd999 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c @@ -84,7 +84,7 @@ void nouveauFallback(struct nouveau_context *nmesa, GLuint bit, GLboolean mode) if (nmesa->screen->card->typescreen->card->typeColor.AlphaFunc ) { + switch ( f ) { case GL_NEVER: return 1; case GL_LESS: return 2; case GL_EQUAL: return 3; @@ -51,9 +51,9 @@ static uint32_t nv04_compare_func(GLcontext *ctx,GLuint f) return 0; } -static uint32_t nv04_blend_func(GLcontext *ctx,GLuint f) +static uint32_t nv04_blend_func(GLuint f) { - switch ( ctx->Color.AlphaFunc ) { + switch ( f ) { case GL_ZERO: return 0x1; case GL_ONE: return 0x2; case GL_SRC_COLOR: return 0x3; @@ -66,7 +66,7 @@ static uint32_t nv04_blend_func(GLcontext *ctx,GLuint f) case GL_ONE_MINUS_DST_COLOR: return 0xA; case GL_SRC_ALPHA_SATURATE: return 0xB; } - WARN_ONCE("Unable to find the function\n"); + WARN_ONCE("Unable to find the function 0x%x\n",f); return 0; } @@ -78,11 +78,11 @@ static void nv04_emit_control(GLcontext *ctx) CLAMPED_FLOAT_TO_UBYTE(alpha_ref, ctx->Color.AlphaRef); control=alpha_ref; - control|=(nv04_compare_func(ctx,ctx->Color.AlphaFunc)<<8); + control|=(nv04_compare_func(ctx->Color.AlphaFunc)<<8); control|=(ctx->Color.AlphaEnabled<<12); control|=(1<<13); control|=(ctx->Depth.Test<<14); - control|=(nv04_compare_func(ctx,ctx->Depth.Func)<<16); + control|=(nv04_compare_func(ctx->Depth.Func)<<16); if ((ctx->Polygon.CullFlag)&&(ctx->Polygon.CullFaceMode!=GL_FRONT_AND_BACK)) { if ((ctx->Polygon.FrontFace==GL_CW)&&(ctx->Polygon.CullFaceMode==GL_FRONT)) @@ -126,8 +126,8 @@ static void nv04_emit_blend(GLcontext *ctx) blend|=(1<<8); blend|=(ctx->Fog.Enabled<<16); blend|=(ctx->Color.BlendEnabled<<20); - blend|=(nv04_blend_func(ctx,ctx->Color.BlendSrcRGB)<<24); - blend|=(nv04_blend_func(ctx,ctx->Color.BlendDstRGB)<<28); + blend|=(nv04_blend_func(ctx->Color.BlendSrcRGB)<<24); + blend|=(nv04_blend_func(ctx->Color.BlendDstRGB)<<28); BEGIN_RING_CACHE(NvSub3D, NV04_DX5_TEXTURED_TRIANGLE_BLEND, 1); OUT_RING_CACHE(blend); @@ -463,7 +463,7 @@ static GLboolean nv04BindBuffers(nouveauContextPtr nmesa, int num_color, /* FIXME pitches have to be aligned ! */ BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_PITCH, 2); - OUT_RING(color[0]->pitch|(depth->pitch<<16)); + OUT_RING(color[0]->pitch|(depth?(depth->pitch<<16):0)); OUT_RING(color[0]->offset); if (depth) { diff --git a/src/mesa/drivers/dri/nouveau/nv04_swtcl.c b/src/mesa/drivers/dri/nouveau/nv04_swtcl.c index f31c0d692d..9b5332b77a 100644 --- a/src/mesa/drivers/dri/nouveau/nv04_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv04_swtcl.c @@ -84,6 +84,43 @@ static inline void nv04_1quad(struct nouveau_context *nmesa,nouveauVertex* v0,no OUT_RING(0xFECEDC); } +static inline void nv04_render_points(GLcontext *ctx,GLuint first,GLuint last) +{ + WARN_ONCE("Unimplemented\n"); +} + +static inline void nv04_render_line(GLcontext *ctx,GLuint v1,GLuint v2) +{ + WARN_ONCE("Unimplemented\n"); +} + +static inline void nv04_render_triangle(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + + nv04_1triangle(nmesa, + (nouveauVertex*)(vertptr+v1*vertsize), + (nouveauVertex*)(vertptr+v2*vertsize), + (nouveauVertex*)(vertptr+v3*vertsize) + ); +} + +static inline void nv04_render_quad(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3,GLuint v4) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + + nv04_1quad(nmesa, + (nouveauVertex*)(vertptr+v1*vertsize), + (nouveauVertex*)(vertptr+v2*vertsize), + (nouveauVertex*)(vertptr+v3*vertsize), + (nouveauVertex*)(vertptr+v4*vertsize) + ); +} + /**********************************************************************/ /* Render unclipped begin/end objects */ /**********************************************************************/ @@ -404,6 +441,13 @@ do { \ nmesa->vertex_attr_count++; \ } while (0) +static void nv04_render_clipped_line(GLcontext *ctx,GLuint ii,GLuint jj) +{ +} + +static void nv04_render_clipped_poly(GLcontext *ctx,const GLuint *elts,GLuint n) +{ +} static void nv04ChooseRenderState(GLcontext *ctx) { @@ -411,8 +455,12 @@ static void nv04ChooseRenderState(GLcontext *ctx) tnl->Driver.Render.PrimTabVerts = nv04_render_tab_verts; tnl->Driver.Render.PrimTabElts = nv04_render_tab_elts; - tnl->Driver.Render.ClippedLine = NULL; - tnl->Driver.Render.ClippedPolygon = NULL; + tnl->Driver.Render.ClippedLine = nv04_render_clipped_line; + tnl->Driver.Render.ClippedPolygon = nv04_render_clipped_poly; + tnl->Driver.Render.Points = nv04_render_points; + tnl->Driver.Render.Line = nv04_render_line; + tnl->Driver.Render.Triangle = nv04_render_triangle; + tnl->Driver.Render.Quad = nv04_render_quad; } diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index c9bfac8c4a..9891b363cb 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -303,6 +303,58 @@ static void nv10_render_clipped_poly(GLcontext *ctx,const GLuint *elts,GLuint n) VB->Elts = tmp; } +static inline void nv10_render_points(GLcontext *ctx,GLuint first,GLuint last) +{ + WARN_ONCE("Unimplemented\n"); +} + +static inline void nv10_render_line(GLcontext *ctx,GLuint v1,GLuint v2) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + GLuint size_dword = vertsize*(2)/4; + + nv10ExtendPrimitive(nmesa, size_dword); + nv10StartPrimitive(nmesa,GL_LINES+1,size_dword); + OUT_RINGp((nouveauVertex*)(vertptr+(v1*vertsize)),vertsize); + OUT_RINGp((nouveauVertex*)(vertptr+(v2*vertsize)),vertsize); + nv10FinishPrimitive(nmesa); +} + +static inline void nv10_render_triangle(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + GLuint size_dword = vertsize*(3)/4; + + nv10ExtendPrimitive(nmesa, size_dword); + nv10StartPrimitive(nmesa,GL_TRIANGLES+1,size_dword); + OUT_RINGp((nouveauVertex*)(vertptr+(v1*vertsize)),vertsize); + OUT_RINGp((nouveauVertex*)(vertptr+(v2*vertsize)),vertsize); + OUT_RINGp((nouveauVertex*)(vertptr+(v3*vertsize)),vertsize); + nv10FinishPrimitive(nmesa); +} + +static inline void nv10_render_quad(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3,GLuint v4) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + GLuint size_dword = vertsize*(4)/4; + + nv10ExtendPrimitive(nmesa, size_dword); + nv10StartPrimitive(nmesa,GL_QUADS+1,size_dword); + OUT_RINGp((nouveauVertex*)(vertptr+(v1*vertsize)),vertsize); + OUT_RINGp((nouveauVertex*)(vertptr+(v2*vertsize)),vertsize); + OUT_RINGp((nouveauVertex*)(vertptr+(v3*vertsize)),vertsize); + OUT_RINGp((nouveauVertex*)(vertptr+(v4*vertsize)),vertsize); + nv10FinishPrimitive(nmesa); +} + + + static void nv10ChooseRenderState(GLcontext *ctx) { TNLcontext *tnl = TNL_CONTEXT(ctx); @@ -312,6 +364,10 @@ static void nv10ChooseRenderState(GLcontext *ctx) tnl->Driver.Render.PrimTabElts = nv10_render_tab_elts; tnl->Driver.Render.ClippedLine = nv10_render_clipped_line; tnl->Driver.Render.ClippedPolygon = nv10_render_clipped_poly; + tnl->Driver.Render.Points = nv10_render_points; + tnl->Driver.Render.Line = nv10_render_line; + tnl->Driver.Render.Triangle = nv10_render_triangle; + tnl->Driver.Render.Quad = nv10_render_quad; } -- cgit v1.2.3 From 296eeb882fa9fd7528f33ed307f87171dff7ee1c Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sun, 4 Feb 2007 13:10:23 +0100 Subject: nouveau: nv10: add init for unknown 0x120 --- src/mesa/drivers/dri/nouveau/nv10_state.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 88c1d7d9e1..8fbc76c308 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -659,6 +659,14 @@ static GLboolean nv10InitCard(nouveauContextPtr nmesa) BEGIN_RING_SIZE(NvSub3D, 0x03f4, 1); OUT_RING(0); + /* not for nv10, only for >= nv11 */ + if ((nmesa->screen->card->id>>4) >= 0x11) { + BEGIN_RING_SIZE(NvSub3D, 0x120, 3); + OUT_RING(0); + OUT_RING(1); + OUT_RING(2); + } + return GL_TRUE; } -- cgit v1.2.3 From 3805ccf02015e8127748e6f53ae9d7419ae3f633 Mon Sep 17 00:00:00 2001 From: Panagiotis Papadakos Date: Mon, 5 Feb 2007 10:34:55 +0200 Subject: break if we removed driver from Drivers list in driDestroyDisplay Else we read memory we just released, in for statement. --- src/glx/x11/dri_glx.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/glx/x11/dri_glx.c b/src/glx/x11/dri_glx.c index 6f944d7d60..0649358ecc 100644 --- a/src/glx/x11/dri_glx.c +++ b/src/glx/x11/dri_glx.c @@ -399,6 +399,7 @@ static void driDestroyDisplay(Display *dpy, void *private) Drivers = driver->next; Xfree(driver); + break; } } -- cgit v1.2.3 From e7654b22aa02636d17a88a9a5ee1eeb213d81f30 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 6 Feb 2007 00:39:50 +1100 Subject: nouveau: new bufferobj code. The old code suffered from a number of issues, the most severe being that with the Mesa VBO merge even swtcl used the driver's bufferobj interface. On most VBO types (or non-AGP cards) the buffer ended up in vram, and killed swtcl performance greatly. All bufferobj's start in system memory now, until they get referenced as a "real" VBO. The other big change is that only potentially "damaged" areas are uploaded/downloaded to/from the hardware. --- src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c | 662 +++++++++++++++++------ src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h | 64 ++- src/mesa/drivers/dri/nouveau/nv30_fragprog.c | 5 +- 3 files changed, 562 insertions(+), 169 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c index d36196aeef..684ed7b017 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c @@ -8,29 +8,458 @@ #include "nouveau_object.h" #include "nouveau_msg.h" +#define NOUVEAU_MEM_FREE(mem) do { \ + nouveau_mem_free(ctx, (mem)); \ + (mem) = NULL; \ +} while(0) + #define DEBUG(fmt,args...) do { \ if (NOUVEAU_DEBUG & DEBUG_BUFFEROBJ) { \ fprintf(stderr, "%s: "fmt, __func__, ##args); \ } \ } while(0) -/* Wrapper for nouveau_mem_gpu_offset_get() that marks the bufferobj dirty - * if the GPU modifies the data. - */ +static GLboolean +nouveau_bo_download_from_screen(GLcontext *ctx, GLuint offset, GLuint size, + struct gl_buffer_object *bo) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + nouveau_mem *in_mem; + + DEBUG("bo=%p, offset=%d, size=%d\n", bo, offset, size); + + /* If there's a permanent backing store, blit directly into it */ + if (nbo->cpu_mem) { + if (nbo->cpu_mem != nbo->gpu_mem) { + DEBUG("..cpu_mem\n"); + nouveau_memformat_flat_emit(ctx, nbo->cpu_mem, + nbo->gpu_mem, + offset, offset, size); + } + } else { + DEBUG("..sys_mem\n"); + in_mem = nouveau_mem_alloc(ctx, NOUVEAU_MEM_AGP, size, 0); + if (in_mem) { + DEBUG("....via AGP\n"); + /* otherwise, try blitting to faster memory and + * copying from there + */ + nouveau_memformat_flat_emit(ctx, in_mem, nbo->gpu_mem, + 0, offset, size); + nouveau_notifier_wait_nop(ctx, nmesa->syncNotifier, + NvSubMemFormat); + _mesa_memcpy(nbo->cpu_mem_sys + offset, + in_mem->map, size); + NOUVEAU_MEM_FREE(in_mem); + } else { + DEBUG("....direct VRAM copy\n"); + /* worst case, copy directly from vram */ + _mesa_memcpy(nbo->cpu_mem_sys + offset, + nbo->gpu_mem + offset, + size); + } + } + + return GL_TRUE; +} + +static GLboolean +nouveau_bo_upload_to_screen(GLcontext *ctx, GLuint offset, GLuint size, + struct gl_buffer_object *bo) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + nouveau_mem *out_mem; + + DEBUG("bo=%p, offset=%d, size=%d\n", bo, offset, size); + + if (nbo->cpu_mem) { + if (nbo->cpu_mem != nbo->gpu_mem) { + DEBUG("..cpu_mem\n"); + nouveau_memformat_flat_emit(ctx, nbo->gpu_mem, + nbo->cpu_mem, + offset, offset, size); + } + } else { + out_mem = nouveau_mem_alloc(ctx, NOUVEAU_MEM_AGP | + NOUVEAU_MEM_MAPPED, + size, 0); + if (out_mem) { + DEBUG("....via AGP\n"); + _mesa_memcpy(out_mem->map, + nbo->cpu_mem_sys + offset, size); + nouveau_memformat_flat_emit(ctx, nbo->gpu_mem, out_mem, + offset, 0, size); + nouveau_notifier_wait_nop(ctx, nmesa->syncNotifier, + NvSubMemFormat); + NOUVEAU_MEM_FREE(out_mem); + } else { + DEBUG("....direct VRAM copy\n"); + _mesa_memcpy(nbo->gpu_mem->map + offset, + nbo->cpu_mem_sys + offset, + size); + } + } + + return GL_TRUE; +} + +GLboolean +nouveau_bo_move_in(GLcontext *ctx, struct gl_buffer_object *bo) +{ + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + + DEBUG("bo=%p\n", bo); + + if (bo->OnCard) + return GL_TRUE; + assert(nbo->gpu_mem_flags); + + nbo->gpu_mem = nouveau_mem_alloc(ctx, nbo->gpu_mem_flags | + NOUVEAU_MEM_MAPPED, + bo->Size, 0); + assert(nbo->gpu_mem); + + if (nbo->cpu_mem_flags) { + if ((nbo->cpu_mem_flags|NOUVEAU_MEM_MAPPED) != nbo->gpu_mem->type) { + DEBUG("..need cpu_mem buffer\n"); + + nbo->cpu_mem = nouveau_mem_alloc(ctx, + nbo->cpu_mem_flags | + NOUVEAU_MEM_MAPPED, + bo->Size, 0); + + if (nbo->cpu_mem) { + DEBUG("....alloc ok, kill sys_mem buffer\n"); + _mesa_memcpy(nbo->cpu_mem->map, + nbo->cpu_mem_sys, bo->Size); + FREE(nbo->cpu_mem_sys); + } + } else { + DEBUG("..cpu direct access to GPU buffer\n"); + nbo->cpu_mem = nbo->gpu_mem; + } + } + nouveau_bo_upload_to_screen(ctx, 0, bo->Size, bo); + + bo->OnCard = GL_TRUE; + return GL_TRUE; +} + +GLboolean +nouveau_bo_move_out(GLcontext *ctx, struct gl_buffer_object *bo) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + GLuint nr_dirty; + + DEBUG("bo=%p\n", bo); + if (!bo->OnCard) + return GL_TRUE; + + nr_dirty = nouveau_bo_download_dirty(ctx, bo); + if (nbo->cpu_mem) { + if (nr_dirty && nbo->cpu_mem != nbo->gpu_mem) + nouveau_notifier_wait_nop(ctx, nmesa->syncNotifier, + NvSubMemFormat); + DEBUG("..destroy cpu_mem buffer\n"); + nbo->cpu_mem_sys = malloc(bo->Size); + assert(nbo->cpu_mem_sys); + _mesa_memcpy(nbo->cpu_mem_sys, nbo->cpu_mem->map, bo->Size); + if (nbo->cpu_mem == nbo->gpu_mem) + nbo->cpu_mem = NULL; + else + NOUVEAU_MEM_FREE(nbo->cpu_mem); + } + NOUVEAU_MEM_FREE(nbo->gpu_mem); + + bo->OnCard = GL_FALSE; + return GL_TRUE; +} + +static void +nouveau_bo_choose_storage_method(GLcontext *ctx, GLenum usage, + struct gl_buffer_object *bo) +{ + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + GLuint gpu_type = 0; + GLuint cpu_type = 0; + + switch (usage) { + /* Client source, changes often, used by GL many times */ + case GL_DYNAMIC_DRAW_ARB: + gpu_type = NOUVEAU_MEM_AGP | NOUVEAU_MEM_FB_ACCEPTABLE; + cpu_type = NOUVEAU_MEM_AGP; + break; + /* GL source, changes often, client reads many times */ + case GL_DYNAMIC_READ_ARB: + /* Client source, specified once, used by GL many times */ + case GL_STATIC_DRAW_ARB: + /* GL source, specified once, client reads many times */ + case GL_STATIC_READ_ARB: + /* Client source, specified once, used by GL a few times */ + case GL_STREAM_DRAW_ARB: + /* GL source, specified once, client reads a few times */ + case GL_STREAM_READ_ARB: + /* GL source, changes often, used by GL many times*/ + case GL_DYNAMIC_COPY_ARB: + /* GL source, specified once, used by GL many times */ + case GL_STATIC_COPY_ARB: + /* GL source, specified once, used by GL a few times */ + case GL_STREAM_COPY_ARB: + gpu_type = NOUVEAU_MEM_FB; + break; + default: + assert(0); + } + + nbo->gpu_mem_flags = gpu_type; + nbo->cpu_mem_flags = cpu_type; + nbo->usage = usage; +} + +void +nouveau_bo_init_storage(GLcontext *ctx, GLuint valid_gpu_access, + GLsizeiptrARB size, + const GLvoid *data, + GLenum usage, + struct gl_buffer_object *bo) +{ + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + + DEBUG("bo=%p\n", bo); + + /* Free up previous buffers if we can't reuse them */ + if (nbo->usage != usage || + (nbo->gpu_mem && (nbo->gpu_mem->size != size))) { + if (nbo->cpu_mem_sys) + FREE(nbo->cpu_mem_sys); + if (nbo->cpu_mem) { + if (nbo->cpu_mem != nbo->gpu_mem) + NOUVEAU_MEM_FREE(nbo->cpu_mem); + else + nbo->cpu_mem = NULL; + } + if (nbo->gpu_mem) + NOUVEAU_MEM_FREE(nbo->gpu_mem); + + bo->OnCard = GL_FALSE; + nbo->cpu_mem_sys = calloc(1, size); + } + + nouveau_bo_choose_storage_method(ctx, usage, bo); + /* Force off flags that may not be ok for a given buffer */ + nbo->gpu_mem_flags &= valid_gpu_access; + + bo->Usage = usage; + bo->Size = size; + + if (data) { + GLvoid *map = nouveau_bo_map(ctx, GL_WRITE_ONLY_ARB, bo); + _mesa_memcpy(map, data, size); + nouveau_bo_dirty_all(ctx, GL_FALSE, bo); + nouveau_bo_unmap(ctx, bo); + } +} + +void * +nouveau_bo_map(GLcontext *ctx, GLenum access, struct gl_buffer_object *bo) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + + DEBUG("bo=%p, access=%s\n", bo, _mesa_lookup_enum_by_nr(access)); + + if (bo->OnCard && + (access == GL_READ_ONLY_ARB || access == GL_READ_WRITE_ARB)) { + GLuint nr_dirty; + + DEBUG("..on card\n"); + nr_dirty = nouveau_bo_download_dirty(ctx, bo); + + /* nouveau_bo_download_dirty won't wait unless it needs to + * free a temp buffer, which isn't the case if cpu_mem is + * present. + */ + if (nr_dirty && nbo->cpu_mem && nbo->cpu_mem != nbo->gpu_mem) + nouveau_notifier_wait_nop(ctx, nmesa->syncNotifier, + NvSubMemFormat); + } + + if (nbo->cpu_mem) { + DEBUG("..access via cpu_mem\n"); + return nbo->cpu_mem->map; + } else { + DEBUG("..access via cpu_mem_sys\n"); + return nbo->cpu_mem_sys; + } +} + +void +nouveau_bo_unmap(GLcontext *ctx, struct gl_buffer_object *bo) +{ + DEBUG("unmap bo=%p\n", bo); +} + uint32_t -nouveau_bufferobj_gpu_ref(GLcontext *ctx, GLenum access, - struct gl_buffer_object *obj) +nouveau_bo_gpu_ref(GLcontext *ctx, struct gl_buffer_object *bo) { - nouveau_buffer_object *nbo = (nouveau_buffer_object *)obj; + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; - DEBUG("obj=%p, access=%s\n", obj, _mesa_lookup_enum_by_nr(access)); + assert(nbo->mapped == GL_FALSE); - if (access == GL_WRITE_ONLY_ARB || access == GL_READ_WRITE_ARB) - nbo->gpu_dirty = GL_TRUE; + DEBUG("gpu_ref\n"); + + if (!bo->OnCard) { + nouveau_bo_move_in(ctx, bo); + bo->OnCard = GL_TRUE; + } + nouveau_bo_upload_dirty(ctx, bo); return nouveau_mem_gpu_offset_get(ctx, nbo->gpu_mem); } +void +nouveau_bo_dirty_linear(GLcontext *ctx, GLboolean on_card, + uint32_t offset, uint32_t size, + struct gl_buffer_object *bo) +{ + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + nouveau_bufferobj_dirty *dirty; + uint32_t start = offset; + uint32_t end = offset + size; + int i; + + if (nbo->cpu_mem == nbo->gpu_mem) + return; + + dirty = on_card ? &nbo->gpu_dirty : &nbo->cpu_dirty; + + DEBUG("on_card=%d, offset=%d, size=%d, bo=%p\n", + on_card, offset, size, bo); + + for (i=0; inr_dirty; i++) { + nouveau_bufferobj_region *r = &dirty->dirty[i]; + + /* already dirty */ + if (start >= r->start && end <= r->end) { + DEBUG("..already dirty\n"); + return; + } + + /* add to the end of a region */ + if (start >= r->start && start <= r->end) { + if (end > r->end) { + DEBUG("..extend end of region\n"); + r->end = end; + return; + } + } + + /* add to the start of a region */ + if (start < r->start && end >= r->end) { + DEBUG("..extend start of region\n"); + r->start = start; + /* .. and to the end */ + if (end > r->end) { + DEBUG("....and end\n"); + r->end = end; + } + return; + } + } + + /* new region */ + DEBUG("..new dirty\n"); + dirty->nr_dirty++; + dirty->dirty = realloc(dirty->dirty, + sizeof(nouveau_bufferobj_region) * + dirty->nr_dirty); + dirty->dirty[dirty->nr_dirty - 1].start = start; + dirty->dirty[dirty->nr_dirty - 1].end = end; +} + +void +nouveau_bo_dirty_all(GLcontext *ctx, GLboolean on_card, + struct gl_buffer_object *bo) +{ + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + nouveau_bufferobj_dirty *dirty; + + dirty = on_card ? &nbo->gpu_dirty : &nbo->cpu_dirty; + + DEBUG("dirty all\n"); + if (dirty->nr_dirty) { + FREE(dirty->dirty); + dirty->dirty = NULL; + dirty->nr_dirty = 0; + } + + nouveau_bo_dirty_linear(ctx, on_card, 0, bo->Size, bo); +} + +GLuint +nouveau_bo_upload_dirty(GLcontext *ctx, struct gl_buffer_object *bo) +{ + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + nouveau_bufferobj_dirty *dirty = &nbo->cpu_dirty; + GLuint nr_dirty; + int i; + + nr_dirty = dirty->nr_dirty; + if (!nr_dirty) { + DEBUG("clean\n"); + return nr_dirty; + } + + for (i=0; idirty[i]; + + DEBUG("dirty %d: o=0x%08x, s=0x%08x\n", + i, r->start, r->end - r->start); + nouveau_bo_upload_to_screen(ctx, + r->start, r->end - r->start, bo); + } + + FREE(dirty->dirty); + dirty->dirty = NULL; + dirty->nr_dirty = 0; + + return nr_dirty; +} + +GLuint +nouveau_bo_download_dirty(GLcontext *ctx, struct gl_buffer_object *bo) +{ + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + nouveau_bufferobj_dirty *dirty = &nbo->gpu_dirty; + GLuint nr_dirty; + int i; + + nr_dirty = dirty->nr_dirty; + if (nr_dirty) { + DEBUG("clean\n"); + return nr_dirty; + } + + for (i=0; idirty[i]; + + DEBUG("dirty %d: o=0x%08x, s=0x%08x\n", + i, r->start, r->end - r->start); + nouveau_bo_download_from_screen(ctx, + r->start, + r->end - r->start, bo); + } + + FREE(dirty->dirty); + dirty->dirty = NULL; + dirty->nr_dirty = 0; + + return nr_dirty; +} + static void nouveauBindBuffer(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj) { @@ -42,10 +471,11 @@ nouveauNewBufferObject(GLcontext *ctx, GLuint buffer, GLenum target) nouveau_buffer_object *nbo; nbo = CALLOC_STRUCT(nouveau_buffer_object_t); - DEBUG("name=0x%08x, target=%s, obj=%p\n", - buffer, _mesa_lookup_enum_by_nr(target), nbo); - _mesa_initialize_buffer_object(&nbo->mesa, buffer, target); - return &nbo->mesa; + if (nbo) + _mesa_initialize_buffer_object(&nbo->mesa, buffer, target); + DEBUG("bo=%p\n", nbo); + + return nbo ? &nbo->mesa : NULL; } static void @@ -53,11 +483,13 @@ nouveauDeleteBuffer(GLcontext *ctx, struct gl_buffer_object *obj) { nouveau_buffer_object *nbo = (nouveau_buffer_object *)obj; - DEBUG("obj=%p\n", obj); + if (nbo->gpu_dirty.nr_dirty) + FREE(nbo->gpu_dirty.dirty); + if (nbo->cpu_dirty.nr_dirty) + FREE(nbo->cpu_dirty.dirty); + if (nbo->cpu_mem) nouveau_mem_free(ctx, nbo->cpu_mem); + if (nbo->gpu_mem) nouveau_mem_free(ctx, nbo->gpu_mem); - if (nbo->gpu_mem) { - nouveau_mem_free(ctx, nbo->gpu_mem); - } _mesa_delete_buffer_object(ctx, obj); } @@ -66,193 +498,105 @@ nouveauBufferData(GLcontext *ctx, GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage, struct gl_buffer_object *obj) { - nouveau_buffer_object *nbo = (nouveau_buffer_object *)obj; + GLuint gpu_flags; - DEBUG("obj=%p, target=%s, usage=%s, size=%d, data=%p\n", - obj, + DEBUG("target=%s, size=%d, data=%p, usage=%s, obj=%p\n", _mesa_lookup_enum_by_nr(target), + (GLuint)size, data, _mesa_lookup_enum_by_nr(usage), - (unsigned int)size, - data); - - if (nbo->gpu_mem && nbo->gpu_mem->size != size) - nouveau_mem_free(ctx, nbo->gpu_mem); - - /* Always have the GPU access the data from VRAM if possible. For - * some "usage" values it may be better from AGP be default? - * - * TODO: At some point we should drop the NOUVEAU_MEM_MAPPED flag. - * TODO: Use the NOUVEAU_MEM_AGP_ACCEPTABLE flag. - * TODO: What about PCI-E and shared system memory? - */ - if (!nbo->gpu_mem) - nbo->gpu_mem = nouveau_mem_alloc(ctx, - NOUVEAU_MEM_FB | - NOUVEAU_MEM_MAPPED, - size, - 0); - - if (!nbo->gpu_mem) { - MESSAGE("AIII bufferobj malloc failed\n"); - return; + obj); + + switch (target) { + case GL_ELEMENT_ARRAY_BUFFER_ARB: + gpu_flags = 0; + break; + default: + gpu_flags = NOUVEAU_BO_VRAM_OK | NOUVEAU_BO_AGP_OK; + break; } - - obj->Usage = usage; - obj->Size = size; - if (!data) - return; - - ctx->Driver.MapBuffer(ctx, target, GL_WRITE_ONLY_ARB, obj); - _mesa_memcpy(nbo->cpu_mem->map, data, size); - ctx->Driver.UnmapBuffer(ctx, target, obj); + nouveau_bo_init_storage(ctx, gpu_flags, size, data, usage, obj); } -/*TODO: we don't need to DMA the entire buffer like MapBuffer does.. */ static void nouveauBufferSubData(GLcontext *ctx, GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data, struct gl_buffer_object *obj) { - DEBUG("obj=%p, target=%s, offset=0x%x, size=%d, data=%p\n", - obj, + GLvoid *out; + + DEBUG("target=%s, offset=0x%x, size=%d, data=%p, obj=%p\n", _mesa_lookup_enum_by_nr(target), - (unsigned int)offset, - (unsigned int)size, - data); + (GLuint)offset, (GLuint)size, data, obj); - ctx->Driver.MapBuffer(ctx, target, GL_WRITE_ONLY_ARB, obj); - _mesa_memcpy((GLubyte *)obj->Pointer + offset, data, size); - ctx->Driver.UnmapBuffer(ctx, target, obj); + out = nouveau_bo_map(ctx, GL_WRITE_ONLY_ARB, obj); + _mesa_memcpy(out + offset, data, size); + nouveau_bo_dirty_linear(ctx, GL_FALSE, offset, size, obj); + nouveau_bo_unmap(ctx, obj); } -/*TODO: we don't need to DMA the entire buffer like MapBuffer does.. */ static void nouveauGetBufferSubData(GLcontext *ctx, GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data, struct gl_buffer_object *obj) { - DEBUG("obj=%p, target=%s, offset=0x%x, size=%d, data=%p\n", - obj, + const GLvoid *in; + + DEBUG("target=%s, offset=0x%x, size=%d, data=%p, obj=%p\n", _mesa_lookup_enum_by_nr(target), - (unsigned int)offset, - (unsigned int)size, - data); + (GLuint)offset, (GLuint)size, data, obj); - ctx->Driver.MapBuffer(ctx, target, GL_READ_ONLY_ARB, obj); - _mesa_memcpy(data, (GLubyte *)obj->Pointer + offset, size); - ctx->Driver.UnmapBuffer(ctx, target, obj); + in = nouveau_bo_map(ctx, GL_READ_ONLY_ARB, obj); + _mesa_memcpy(data, in + offset, size); + nouveau_bo_unmap(ctx, obj); } static void * nouveauMapBuffer(GLcontext *ctx, GLenum target, GLenum access, struct gl_buffer_object *obj) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - nouveau_buffer_object *nbo = (nouveau_buffer_object *)obj; - - DEBUG("obj=%p, target=%s, access=%s\n", - obj, + DEBUG("target=%s, access=%s, obj=%p\n", _mesa_lookup_enum_by_nr(target), - _mesa_lookup_enum_by_nr(access)); + _mesa_lookup_enum_by_nr(access), + obj + ); - if (obj->Pointer) { - DEBUG("already mapped, return NULL\n"); + /* Already mapped.. */ + if (obj->Pointer) return NULL; - } -#ifdef ALLOW_MULTI_SUBCHANNEL - /* If GPU is accessing the data from VRAM, copy to faster AGP memory - * before CPU access to the buffer. + /* Have to pass READ_WRITE here, nouveau_bo_map will only ensure that + * the cpu_mem buffer is up-to-date if we ask for read access. + * + * However, even if the client only asks for write access, we're still + * forced to reupload the entire buffer. So, we need the cpu_mem buffer + * to have the correct data all the time. */ - if (nbo->gpu_mem->type & NOUVEAU_MEM_FB) { - DEBUG("Data in VRAM, copying to AGP for CPU access\n"); - - /* This can happen if BufferData grows the GPU-access buffer */ - if (nbo->cpu_mem && nbo->cpu_mem->size != nbo->gpu_mem->size) { - nouveau_mem_free(ctx, nbo->cpu_mem); - nbo->cpu_mem = NULL; - } - - if (!nbo->cpu_mem) { - nbo->cpu_mem = nouveau_mem_alloc(ctx, - NOUVEAU_MEM_AGP | - NOUVEAU_MEM_MAPPED, - nbo->gpu_mem->size, - 0); + obj->Pointer = nouveau_bo_map(ctx, GL_READ_WRITE_ARB, obj); - /* Mark GPU data as modified, so it gets copied to - * the new buffer */ - nbo->gpu_dirty = GL_TRUE; - } - - if (nbo->cpu_mem && nbo->gpu_dirty) { - nouveau_memformat_flat_emit(ctx, nbo->cpu_mem, - nbo->gpu_mem, - 0, 0, - nbo->gpu_mem->size); - - nouveau_notifier_wait_nop(ctx, - nmesa->syncNotifier, - NvSubMemFormat); - nbo->gpu_dirty = GL_FALSE; - } - - /* buffer isn't guaranteed to be up-to-date on the card now */ - nbo->cpu_dirty = GL_TRUE; - } -#endif - - /* If the copy to AGP failed for some reason, just return a pointer - * directly to vram.. + /* The GL spec says that a client attempting to write to a bufferobj + * mapped READ_ONLY object may have unpredictable results, possibly + * even program termination. + * + * We're going to use this, and only mark the buffer as dirtied if + * the client asks for write access. */ - if (!nbo->cpu_mem) { - DEBUG("Returning direct pointer to VRAM\n"); - nbo->cpu_mem = nbo->gpu_mem; - nbo->cpu_dirty = GL_FALSE; + if (target != GL_READ_ONLY_ARB) { + /* We have no way of knowing what was modified by the client, + * so the entire buffer gets dirtied. */ + nouveau_bo_dirty_all(ctx, GL_FALSE, obj); } - obj->Pointer = nbo->cpu_mem->map; return obj->Pointer; } static GLboolean nouveauUnmapBuffer(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - nouveau_buffer_object *nbo = (nouveau_buffer_object *)obj; - - DEBUG("obj=%p, target=%s\n", obj, _mesa_lookup_enum_by_nr(target)); + DEBUG("target=%s, obj=%p\n", _mesa_lookup_enum_by_nr(target), obj); -#ifdef ALLOW_MULTI_SUBCHANNEL - if (nbo->cpu_dirty && nbo->cpu_mem != nbo->gpu_mem) { - DEBUG("Copying potentially modified data back to GPU\n"); - - /* blit from GPU buffer -> CPU buffer */ - nouveau_memformat_flat_emit(ctx, nbo->gpu_mem, nbo->cpu_mem, - 0, 0, nbo->cpu_mem->size); - - /* buffer is now up-to-date on the hardware (or rather, will - * be by the time any other commands in this channel reference - * the data.) - */ - nbo->cpu_dirty = GL_FALSE; - - /* we can avoid this wait in some cases.. */ - nouveau_notifier_wait_nop(ctx, - nmesa->syncNotifier, - NvSubMemFormat); - - /* If it's likely CPU access to the buffer will occur often, - * keep the cpu_mem around to avoid repeated allocs. - */ - if (obj->Usage != GL_DYNAMIC_DRAW_ARB) { - - nouveau_mem_free(ctx, nbo->cpu_mem); - nbo->cpu_mem = NULL; - } - } -#endif + assert(obj->Pointer); + nouveau_bo_unmap(ctx, obj); obj->Pointer = NULL; return GL_TRUE; } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h index fccc349b83..932450fd87 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h @@ -4,24 +4,74 @@ #include "mtypes.h" #include "nouveau_buffers.h" +#define NOUVEAU_BO_VRAM_OK (NOUVEAU_MEM_FB | NOUVEAU_MEM_FB_ACCEPTABLE) +#define NOUVEAU_BO_AGP_OK (NOUVEAU_MEM_AGP | NOUVEAU_MEM_AGP_ACCEPTABLE) + +typedef struct nouveau_bufferobj_region_t { + uint32_t start; + uint32_t end; +} nouveau_bufferobj_region; + +typedef struct nouveau_bufferobj_dirty_t { + nouveau_bufferobj_region *dirty; + int nr_dirty; +} nouveau_bufferobj_dirty; + typedef struct nouveau_buffer_object_t { /* Base class, must be first */ struct gl_buffer_object mesa; + GLboolean mapped; + GLenum usage; + /* Memory used for GPU access to the buffer*/ + GLuint gpu_mem_flags; nouveau_mem * gpu_mem; - /* Buffer has been dirtied by the GPU */ - GLboolean gpu_dirty; + nouveau_bufferobj_dirty gpu_dirty; /* Memory used for CPU access to the buffer */ + GLuint cpu_mem_flags; nouveau_mem * cpu_mem; - /* Buffer has possibly been dirtied by the CPU */ - GLboolean cpu_dirty; + GLvoid * cpu_mem_sys; + nouveau_bufferobj_dirty cpu_dirty; } nouveau_buffer_object; -extern uint32_t nouveau_bufferobj_gpu_ref(GLcontext *ctx, GLenum access, - struct gl_buffer_object *obj); +extern void +nouveau_bo_init_storage(GLcontext *ctx, GLuint valid_gpu_access, + GLsizeiptrARB size, const GLvoid *data, GLenum usage, + struct gl_buffer_object *bo); + +extern GLboolean +nouveau_bo_move_in(GLcontext *ctx, struct gl_buffer_object *bo); + +extern GLboolean +nouveau_bo_move_out(GLcontext *ctx, struct gl_buffer_object *bo); + +extern void * +nouveau_bo_map(GLcontext *ctx, GLenum usage, struct gl_buffer_object *bo); + +extern void +nouveau_bo_unmap(GLcontext *ctx, struct gl_buffer_object *bo); + +extern uint32_t +nouveau_bo_gpu_ref(GLcontext *ctx, struct gl_buffer_object *bo); + +extern void +nouveau_bo_dirty_linear(GLcontext *ctx, GLboolean on_card, + uint32_t offset, uint32_t size, + struct gl_buffer_object *bo); + +extern void +nouveau_bo_dirty_all(GLcontext *ctx, GLboolean on_card, + struct gl_buffer_object *bo); + +extern GLuint +nouveau_bo_upload_dirty(GLcontext *ctx, struct gl_buffer_object *bo); + +extern GLuint +nouveau_bo_download_dirty(GLcontext *ctx, struct gl_buffer_object *bo); -extern void nouveauInitBufferObjects(GLcontext *ctx); +extern void +nouveauInitBufferObjects(GLcontext *ctx); #endif diff --git a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c index 02bd8014cc..f868ec9293 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c +++ b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c @@ -32,14 +32,13 @@ NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs) GL_ARRAY_BUFFER_ARB); /* Should use STATIC_DRAW_ARB if shader doesn't use changable params */ - ctx->Driver.BufferData(ctx, GL_ARRAY_BUFFER_ARB, + nouveau_bo_init_storage(ctx, NOUVEAU_BO_VRAM_OK, nvs->program_size * sizeof(uint32_t), (const GLvoid *)nvs->program, GL_DYNAMIC_DRAW_ARB, nvs->program_buffer); - offset = nouveau_bufferobj_gpu_ref(ctx, GL_READ_ONLY_ARB, - nvs->program_buffer); + offset = nouveau_bo_gpu_ref(ctx, nvs->program_buffer); /* Not using state cache here, updated programs at the same address don't * seem to take effect unless the ACTIVE_PROGRAM method is called again. -- cgit v1.2.3 From 47bd759fc9a8f886b90af9a5d53cbb896f37358e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 6 Feb 2007 01:57:04 +1100 Subject: nouveau: fix a small bug in nv10 swtcl --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 9891b363cb..6f57b775df 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -196,7 +196,7 @@ static inline void nv10_render_generic_primitive_elts(GLcontext *ctx,GLuint star GLuint j; nv10ExtendPrimitive(nmesa, size_dword); - nv10StartPrimitive(nmesa,prim+1,size_dword); + nv10StartPrimitive(nmesa,prim+1,size_dword*count); for (j=start; j Date: Mon, 5 Feb 2007 08:17:50 -0700 Subject: fix mem leaks --- src/glx/x11/dri_glx.c | 1 + src/glx/x11/glxext.c | 4 ++++ 2 files changed, 5 insertions(+) (limited to 'src') diff --git a/src/glx/x11/dri_glx.c b/src/glx/x11/dri_glx.c index 0649358ecc..d88ce91364 100644 --- a/src/glx/x11/dri_glx.c +++ b/src/glx/x11/dri_glx.c @@ -398,6 +398,7 @@ static void driDestroyDisplay(Display *dpy, void *private) else Drivers = driver->next; + Xfree(driver->name); Xfree(driver); break; } diff --git a/src/glx/x11/glxext.c b/src/glx/x11/glxext.c index d24f853d54..a039bca234 100644 --- a/src/glx/x11/glxext.c +++ b/src/glx/x11/glxext.c @@ -396,6 +396,10 @@ static int __glXFreeDisplayPrivate(XExtData *extension) (*priv->driDisplay.destroyDisplay)(priv->dpy, priv->driDisplay.private); priv->driDisplay.private = NULL; + if (priv->driDisplay.createNewScreen) { + Xfree(priv->driDisplay.createNewScreen); /* free array of ptrs */ + priv->driDisplay.createNewScreen = NULL; + } #endif Xfree((char*) priv); -- cgit v1.2.3 From 4b3679c6c5b8b47e8071a253bcea570b91e30b17 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 6 Feb 2007 02:28:55 +1100 Subject: nouveau: OUT_RINGp expects the size in dwords, not bytes. This fixes the *actual* bug that the previous commit was supposed to fix.. --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 6f57b775df..eec67bd805 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -196,9 +196,9 @@ static inline void nv10_render_generic_primitive_elts(GLcontext *ctx,GLuint star GLuint j; nv10ExtendPrimitive(nmesa, size_dword); - nv10StartPrimitive(nmesa,prim+1,size_dword*count); + nv10StartPrimitive(nmesa,prim+1,size_dword); for (j=start; j Date: Mon, 5 Feb 2007 10:29:10 -0700 Subject: fix mem leak --- src/mesa/main/mipmap.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c index f154bd4651..cc1fb97eed 100644 --- a/src/mesa/main/mipmap.c +++ b/src/mesa/main/mipmap.c @@ -928,6 +928,9 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, return; } + if (dstImage->ImageOffsets) + _mesa_free(dstImage->ImageOffsets); + /* Free old image data */ if (dstImage->Data) ctx->Driver.FreeTexImageData(ctx, dstImage); -- cgit v1.2.3 From 17c13b406f4f8a3e7cf755749aa65448f79f6a84 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Mon, 5 Feb 2007 21:29:25 +0100 Subject: fix issues when using mixed-mode pos-invariant vp and ff tnl (bug #9856) ARB_vp requires vertex transformation to be invariant to fixed function tnl if the position_invariant option is used. So the same function needs to be used, otherwise z-fighting artifacts may happen with applications which rely on the results being really the same due to precision issues when dealing with floating point values (may not be a problem when using a non-optimizing compiler strictly following IEEE rules). --- src/mesa/tnl/t_vb_arbprogram.c | 51 ++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/mesa/tnl/t_vb_arbprogram.c b/src/mesa/tnl/t_vb_arbprogram.c index 524472a777..4c8f967fdf 100644 --- a/src/mesa/tnl/t_vb_arbprogram.c +++ b/src/mesa/tnl/t_vb_arbprogram.c @@ -1249,8 +1249,7 @@ run_arb_vertex_program(GLcontext *ctx, struct tnl_pipeline_stage *stage) m->nr_inputs = m->nr_outputs = 0; for (i = 0; i < VERT_ATTRIB_MAX; i++) { - if (program->Base.InputsRead & (1<IsPositionInvariant)) { + if (program->Base.InputsRead & (1<nr_inputs++; m->input[j].idx = i; m->input[j].data = (GLfloat *)m->VB->AttribPtr[i]->data; @@ -1258,16 +1257,15 @@ run_arb_vertex_program(GLcontext *ctx, struct tnl_pipeline_stage *stage) m->input[j].size = m->VB->AttribPtr[i]->size; ASSIGN_4V(m->File[0][REG_IN0 + i], 0, 0, 0, 1); } - } + } for (i = 0; i < VERT_RESULT_MAX; i++) { - if (program->Base.OutputsWritten & (1 << i) || - (i == VERT_RESULT_HPOS && program->IsPositionInvariant)) { + if (program->Base.OutputsWritten & (1 << i)) { GLuint j = m->nr_outputs++; m->output[j].idx = i; m->output[j].data = (GLfloat *)m->attribs[i].data; } - } + } /* Run the actual program: @@ -1297,15 +1295,6 @@ run_arb_vertex_program(GLcontext *ctx, struct tnl_pipeline_stage *stage) } } - /* If the program is position invariant, multiply the input position - * by the MVP matrix and store in the vertex position result register. - */ - if (program->IsPositionInvariant) { - TRANSFORM_POINT( m->File[0][REG_OUT0+0], - ctx->_ModelProjectMatrix.m, - m->File[0][REG_IN0+0]); - } - for (j = 0; j < m->nr_outputs; j++) { GLuint idx = REG_OUT0 + m->output[j].idx; m->output[j].data[0] = m->File[0][idx][0]; @@ -1327,15 +1316,39 @@ run_arb_vertex_program(GLcontext *ctx, struct tnl_pipeline_stage *stage) * TODO: 2) Integrate t_vertex.c so that we just go straight ahead * and build machine vertices here. */ - VB->ClipPtr = &m->attribs[VERT_RESULT_HPOS]; - VB->ClipPtr->count = VB->Count; /* XXX There seems to be confusion between using the VERT_ATTRIB_* * values vs _TNL_ATTRIB_* tokens here: */ outputs = program->Base.OutputsWritten; - if (program->IsPositionInvariant) - outputs |= (1<IsPositionInvariant) { + /* We need the exact same transform as in the fixed function path here + to guarantee invariance, depending on compiler optimization flags results + could be different otherwise */ + VB->ClipPtr = TransformRaw( &m->attribs[0], + &ctx->_ModelProjectMatrix, + m->VB->AttribPtr[0] ); + + /* Drivers expect this to be clean to element 4... + */ + switch (VB->ClipPtr->size) { + case 1: + /* impossible */ + case 2: + _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 2 ); + /* fall-through */ + case 3: + _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 3 ); + /* fall-through */ + case 4: + break; + } + } + else { + VB->ClipPtr = &m->attribs[VERT_RESULT_HPOS]; + VB->ClipPtr->count = VB->Count; + } if (outputs & (1<ColorPtr[0] = -- cgit v1.2.3 From 8518ddda7b5f8e43de4859042fe59f55aa0c2760 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 6 Feb 2007 10:22:47 +1100 Subject: Add support for CN700 chipset in miniglx --- src/mesa/drivers/dri/unichrome/server/via_dri.c | 1 + src/mesa/drivers/dri/unichrome/server/via_regs.h | 1 + 2 files changed, 2 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/unichrome/server/via_dri.c b/src/mesa/drivers/dri/unichrome/server/via_dri.c index 2fe61e4039..6944bd66f9 100644 --- a/src/mesa/drivers/dri/unichrome/server/via_dri.c +++ b/src/mesa/drivers/dri/unichrome/server/via_dri.c @@ -1179,6 +1179,7 @@ static int viaInitFBDev(DRIDriverContext *ctx) pVia->Chipset = VIA_KM400; break; case PCI_CHIP_VT3204: + case PCI_CHIP_VT3344: pVia->Chipset = VIA_K8M800; break; case PCI_CHIP_VT3259: diff --git a/src/mesa/drivers/dri/unichrome/server/via_regs.h b/src/mesa/drivers/dri/unichrome/server/via_regs.h index 5c5eecbe83..87e1e9daa9 100644 --- a/src/mesa/drivers/dri/unichrome/server/via_regs.h +++ b/src/mesa/drivers/dri/unichrome/server/via_regs.h @@ -44,6 +44,7 @@ #define PCI_CHIP_VT7205 0x7205 #define PCI_CHIP_VT3204 0x3108 #define PCI_CHIP_VT3259 0x3118 +#define PCI_CHIP_VT3344 0x3344 #define BIOS_BSIZE 1024 -- cgit v1.2.3 From f46c19d965fb05a49d361aa251e37b5ef32dd839 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 6 Feb 2007 13:49:39 +1100 Subject: nouveau: a couple of NV3x fixes --- src/mesa/drivers/dri/nouveau/nouveau_context.h | 1 + src/mesa/drivers/dri/nouveau/nouveau_shader.c | 19 +++++++++++++++++++ src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 10 ++++++++++ src/mesa/drivers/dri/nouveau/nv30_fragprog.c | 15 ++++++++++++--- src/mesa/drivers/dri/nouveau/nv30_state.c | 5 +++-- 5 files changed, 45 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index c1d06654ee..f61fcbb48c 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -159,6 +159,7 @@ typedef struct nouveau_context { nouveauShader *current_fragprog; nouveauShader *current_vertprog; nouveauShader *passthrough_vp; + nouveauShader *passthrough_fp; nouveauScreenRec *screen; drm_nouveau_sarea_t *sarea; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.c b/src/mesa/drivers/dri/nouveau/nouveau_shader.c index c78b72bd11..ba471325aa 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.c @@ -220,6 +220,21 @@ nvsBuildPassthroughVP(GLcontext *ctx) vp_text); } +static void +nvsBuildPassthroughFP(GLcontext *ctx) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + const char *fp_text = + "!!ARBfp1.0\n" + "MOV result.color, fragment.color;\n" + "END"; + + nmesa->passthrough_fp = nvsBuildTextShader(ctx, + GL_FRAGMENT_PROGRAM_ARB, + fp_text); +} + void nouveauShaderInitFuncs(GLcontext * ctx) { @@ -249,6 +264,10 @@ nouveauShaderInitFuncs(GLcontext * ctx) if (nmesa->screen->card->type >= NV_40) nvsBuildPassthroughVP(ctx); + /* Needed on NV30, even when using swtcl, if you want to get colours */ + if (nmesa->screen->card->type >= NV_30) + nvsBuildPassthroughFP(ctx); + ctx->Const.VertexProgram.MaxNativeInstructions = nmesa->VPfunc.MaxInst; ctx->Const.VertexProgram.MaxNativeAluInstructions = nmesa->VPfunc.MaxInst; ctx->Const.VertexProgram.MaxNativeTexInstructions = nmesa->VPfunc.MaxInst; diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index eec67bd805..32da40661b 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -527,6 +527,16 @@ static void nv10ChooseVertexState( GLcontext *ctx ) nv10OutputVertexFormat(nmesa); } + if (nmesa->screen->card->type == NV_30) { + nouveauShader *fp; + + if (ctx->FragmentProgram.Enabled) { + fp = (nouveauShader *) ctx->FragmentProgram.Current; + nvsUpdateShader(ctx, fp); + } else + nvsUpdateShader(ctx, nmesa->passthrough_fp); + } + if (nmesa->screen->card->type >= NV_40) { /* Ensure passthrough shader is being used, and mvp matrix * is up to date diff --git a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c index f868ec9293..e32452361e 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c +++ b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c @@ -46,9 +46,18 @@ NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs) */ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM, 1); OUT_RING (offset | 1); - BEGIN_RING_SIZE(NvSub3D, 0x1d60 /*NV30_TCL_PRIMITIVE_3D_FP_CONTROL*/, 1); - OUT_RING ((priv->NV30FP.uses_kil << 7) | - (priv->NV30FP.num_regs << 24)); + if (nmesa->screen->card->type == NV_30) { + BEGIN_RING_SIZE(NvSub3D, + 0x1d60 /*NV30_TCL_PRIMITIVE_3D_FP_CONTROL*/, 1); + OUT_RING ((priv->NV30FP.uses_kil << 7)); + BEGIN_RING_SIZE(NvSub3D, 0x1450, 1); + OUT_RING (priv->NV30FP.num_regs << 16); + } else { + BEGIN_RING_SIZE(NvSub3D, + 0x1d60 /*NV30_TCL_PRIMITIVE_3D_FP_CONTROL*/, 1); + OUT_RING ((priv->NV30FP.uses_kil << 7) | + (priv->NV30FP.num_regs << 24)); + } } static void diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 96a07fd536..ad21fa2730 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -811,8 +811,6 @@ static GLboolean nv30InitCard(nouveauContextPtr nmesa) OUT_RING(0); BEGIN_RING_SIZE(NvSub3D, 0x1d80, 1); OUT_RING(3); - BEGIN_RING_SIZE(NvSub3D, 0x1450, 1); - OUT_RING(0x00030004); /* NEW */ BEGIN_RING_SIZE(NvSub3D, 0x1e98, 1); @@ -840,6 +838,9 @@ static GLboolean nv30InitCard(nouveauContextPtr nmesa) BEGIN_RING_SIZE(NvSub3D, 0x1d88, 1); OUT_RING(0x00001200); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_RC_ENABLE, 1); + OUT_RING (0); + return GL_TRUE; } -- cgit v1.2.3 From 6cf892eeb6edd69d4ba77d4ececa21a09ba317c4 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Thu, 8 Feb 2007 23:54:28 +0100 Subject: fix issues in vp when using FRAG_BIT_WPOS in a fragment program (bug #9910) Redirect all VERT_RESULT_HPOS writes to a temp and use that for fixup. The viewport transformation still seems to take some shortcuts, and it still does not seem to work at all... --- src/mesa/drivers/dri/r300/r300_vertexprog.c | 35 +++++++++++++---------------- 1 file changed, 15 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/r300/r300_vertexprog.c b/src/mesa/drivers/dri/r300/r300_vertexprog.c index c08c98767e..2ff92e1328 100644 --- a/src/mesa/drivers/dri/r300/r300_vertexprog.c +++ b/src/mesa/drivers/dri/r300/r300_vertexprog.c @@ -960,26 +960,23 @@ static void position_invariant(struct gl_program *prog) static void insert_wpos(struct r300_vertex_program *vp, struct gl_program *prog, - GLint pos) + GLuint temp_index) { GLint tokens[6] = { STATE_INTERNAL, STATE_R300_WINDOW_DIMENSION, 0, 0, 0, 0 }; struct prog_instruction *vpi; struct prog_instruction *vpi_insert; - GLuint temp_index; GLuint window_index; int i = 0; vpi = malloc((prog->NumInstructions + 5) * sizeof(struct prog_instruction)); - memcpy(vpi, prog->Instructions, (pos+1) * sizeof(struct prog_instruction)); + /* all but END */ + memcpy(vpi, prog->Instructions, (prog->NumInstructions - 1) * sizeof(struct prog_instruction)); + /* END */ + memcpy(&vpi[prog->NumInstructions + 4], &prog->Instructions[prog->NumInstructions - 1], + sizeof(struct prog_instruction)); - vpi_insert = &vpi[pos]; - - /* make a copy before outputting VERT_RESULT_HPOS */ - vpi_insert->DstReg.File = vpi_insert->SrcReg[2].File; - vpi_insert->DstReg.Index = temp_index = vpi_insert->SrcReg[2].Index; - - vpi_insert++; + vpi_insert = &vpi[prog->NumInstructions - 1]; memset(vpi_insert, 0, 5 * sizeof(struct prog_instruction)); vpi_insert[i].Opcode = OPCODE_MOV; @@ -1062,8 +1059,6 @@ static void insert_wpos(struct r300_vertex_program *vp, vpi_insert[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ONE, SWIZZLE_ONE); i++; - memcpy(&vpi_insert[i], &prog->Instructions[pos+1], (prog->NumInstructions-(pos+1)) * sizeof(struct prog_instruction)); - free(prog->Instructions); prog->Instructions = vpi; @@ -1072,24 +1067,24 @@ static void insert_wpos(struct r300_vertex_program *vp, vpi = &prog->Instructions[prog->NumInstructions-1]; assert(vpi->Opcode == OPCODE_END); - /* we need position, don't we ? :) */ - prog->InputsRead |= (1 << VERT_ATTRIB_POS); } static void pos_as_texcoord(struct r300_vertex_program *vp, struct gl_program *prog) { struct prog_instruction *vpi; - int pos = 0; - - for(vpi = prog->Instructions; vpi->Opcode != OPCODE_END; vpi++, pos++){ + GLuint tempregi = prog->NumTemporaries; + /* should do something else if no temps left... */ + prog->NumTemporaries++; + + for(vpi = prog->Instructions; vpi->Opcode != OPCODE_END; vpi++){ if( vpi->DstReg.File == PROGRAM_OUTPUT && vpi->DstReg.Index == VERT_RESULT_HPOS ){ - insert_wpos(vp, prog, pos); - break; + vpi->DstReg.File = PROGRAM_TEMPORARY; + vpi->DstReg.Index = tempregi; } } - + insert_wpos(vp, prog, tempregi); } static struct r300_vertex_program *build_program(struct r300_vertex_program_key *wanted_key, -- cgit v1.2.3 From 54dac2c84310536cce962101de29546d3eb80175 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Fri, 9 Feb 2007 00:36:40 +0100 Subject: optimize generated vertex programs a bit Use new internal state to avoid per-vertex normalization of static spot direction vector. Use internal state for simpler per-vertex fog computations (MAD instead of SUB/MUL for linear fog, EX2 instead of POW for EXP/EXP2 fog). Simplify point size calc (2 MADs instead of MOV, MUL, MUL, DP3), and while there fix it up (RSQ instead of RCP). All untested... --- src/mesa/main/imports.h | 8 ++++++ src/mesa/shader/arbprogparse.c | 2 +- src/mesa/shader/program.c | 30 +++++++++++++++++++++ src/mesa/shader/program.h | 2 ++ src/mesa/tnl/t_vp_build.c | 61 +++++++++++++++++++++--------------------- 5 files changed, 71 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h index d9885dbeec..0633b3b8bf 100644 --- a/src/mesa/main/imports.h +++ b/src/mesa/main/imports.h @@ -138,6 +138,14 @@ typedef union { GLfloat f; GLint i; } fi_type; #define M_E (2.7182818284590452354) #endif +#ifndef ONE_DIV_LN2 +#define ONE_DIV_LN2 (1.442695040888963456) +#endif + +#ifndef ONE_DIV_SQRT_LN2 +#define ONE_DIV_SQRT_LN2 (1.201122408786449815) +#endif + #ifndef FLT_MAX_EXP #define FLT_MAX_EXP 128 #endif diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c index 72d4909372..b9ff08de5f 100644 --- a/src/mesa/shader/arbprogparse.c +++ b/src/mesa/shader/arbprogparse.c @@ -4101,7 +4101,7 @@ _mesa_parse_arb_vertex_program(GLcontext *ctx, GLenum target, program->Base.Parameters = ap.Base.Parameters; #if DEBUG_VP - _mesa_printf("____________Vertex program %u __________\n", program->Base.ID); + _mesa_printf("____________Vertex program %u __________\n", program->Base.Id); _mesa_print_program(&program->Base); #endif } diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index d301f19090..7e6cd26c55 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -996,6 +996,30 @@ _mesa_fetch_state(GLcontext *ctx, const enum state_index state[], } break; } + case STATE_FOG_PARAMS_OPTIMIZED: + /* this makes it possible to use simpler per-vertex fog calcs. POW + (for EXP/EXP2 fog) might be more expensive than EX2 on some hw, + plus it needs another constant (e) anyway. Linear fog can now be + done with a single MAD. + linear: fogcoord * -1/(end-start) + end/(end-start) + exp: 2^-(density/ln(2) * fogcoord) + exp2: 2^-((density/(ln(2)^2) * fogcoord)^2) */ + value[0] = -1.0F / (ctx->Fog.End - ctx->Fog.Start); + value[1] = ctx->Fog.End / (ctx->Fog.End - ctx->Fog.Start); + value[2] = ctx->Fog.Density * ONE_DIV_LN2; + value[3] = ctx->Fog.Density * ONE_DIV_SQRT_LN2; + break; + case STATE_SPOT_DIR_NORMALIZED: { + /* here, state[2] is the light number */ + /* pre-normalize spot dir */ + const GLuint ln = (GLuint) state[2]; + value[0] = ctx->Light.Light[ln].EyeDirection[0]; + value[1] = ctx->Light.Light[ln].EyeDirection[1]; + value[2] = ctx->Light.Light[ln].EyeDirection[2]; + NORMALIZE_3FV(value); + value[3] = ctx->Light.Light[ln]._CosCutoff; + break; + } default: /* unknown state indexes are silently ignored * should be handled by the driver. @@ -1075,6 +1099,10 @@ make_state_flags(const GLint state[]) return _NEW_MODELVIEW; case STATE_TEXRECT_SCALE: return _NEW_TEXTURE; + case STATE_FOG_PARAMS_OPTIMIZED: + return _NEW_FOG; + case STATE_SPOT_DIR_NORMALIZED: + return _NEW_LIGHT; default: /* unknown state indexes are silently ignored and * no flag set, since it is handled by the driver. @@ -1232,6 +1260,8 @@ append_token(char *dst, enum state_index k) case STATE_INTERNAL: case STATE_NORMAL_SCALE: case STATE_POSITION_NORMALIZED: + case STATE_FOG_PARAMS_OPTIMIZED: + case STATE_SPOT_DIR_NORMALIZED: append(dst, "(internal)"); break; default: diff --git a/src/mesa/shader/program.h b/src/mesa/shader/program.h index af06c03598..a0bde07762 100644 --- a/src/mesa/shader/program.h +++ b/src/mesa/shader/program.h @@ -190,6 +190,8 @@ enum state_index { STATE_NORMAL_SCALE, STATE_TEXRECT_SCALE, STATE_POSITION_NORMALIZED, /* normalized light position */ + STATE_FOG_PARAMS_OPTIMIZED, /* for faster fog calc */ + STATE_SPOT_DIR_NORMALIZED, /* pre-normalized spot dir */ STATE_INTERNAL_DRIVER /* first available state index for drivers (must be last) */ }; diff --git a/src/mesa/tnl/t_vp_build.c b/src/mesa/tnl/t_vp_build.c index 805d05ae72..0b6f506f4e 100644 --- a/src/mesa/tnl/t_vp_build.c +++ b/src/mesa/tnl/t_vp_build.c @@ -806,14 +806,13 @@ static struct ureg calculate_light_attenuation( struct tnl_program *p, /* Calculate spot attenuation: */ if (!p->state->unit[i].light_spotcutoff_is_180) { - struct ureg spot_dir = register_param3(p, STATE_LIGHT, i, - STATE_SPOT_DIRECTION); + struct ureg spot_dir_norm = register_param3(p, STATE_INTERNAL, + STATE_SPOT_DIR_NORMALIZED, i); struct ureg spot = get_temp(p); struct ureg slt = get_temp(p); - - emit_normalize_vec3( p, spot, spot_dir ); /* XXX: precompute! */ - emit_op2(p, OPCODE_DP3, spot, 0, negate(VPpli), spot); - emit_op2(p, OPCODE_SLT, slt, 0, swizzle1(spot_dir,W), spot); + + emit_op2(p, OPCODE_DP3, spot, 0, negate(VPpli), spot_dir_norm); + emit_op2(p, OPCODE_SLT, slt, 0, swizzle1(spot_dir_norm,W), spot); emit_op2(p, OPCODE_POW, spot, 0, spot, swizzle1(attenuation, W)); emit_op2(p, OPCODE_MUL, att, 0, slt, spot); @@ -1103,29 +1102,26 @@ static void build_fog( struct tnl_program *p ) } if (p->state->tnl_do_vertex_fog) { - struct ureg params = register_param1(p, STATE_FOG_PARAMS); + struct ureg params = register_param1(p, STATE_FOG_PARAMS_OPTIMIZED); struct ureg tmp = get_temp(p); switch (p->state->fog_mode) { case FOG_LINEAR: { struct ureg id = get_identity_param(p); - emit_op2(p, OPCODE_SUB, tmp, 0, swizzle1(params,Z), input); - emit_op2(p, OPCODE_MUL, tmp, 0, tmp, swizzle1(params,W)); + emit_op3(p, OPCODE_MAD, tmp, 0, input, swizzle1(params,X), swizzle1(params,Y)); emit_op2(p, OPCODE_MAX, tmp, 0, tmp, swizzle1(id,X)); /* saturate */ emit_op2(p, OPCODE_MIN, fog, WRITEMASK_X, tmp, swizzle1(id,W)); break; } case FOG_EXP: emit_op1(p, OPCODE_ABS, tmp, 0, input); - emit_op2(p, OPCODE_MUL, tmp, 0, tmp, swizzle1(params,X)); - emit_op2(p, OPCODE_POW, fog, WRITEMASK_X, - register_const1f(p, M_E), negate(tmp)); + emit_op2(p, OPCODE_MUL, tmp, 0, tmp, swizzle1(params,Z)); + emit_op1(p, OPCODE_EX2, fog, WRITEMASK_X, negate(tmp)); break; case FOG_EXP2: - emit_op2(p, OPCODE_MUL, tmp, 0, input, swizzle1(params,X)); + emit_op2(p, OPCODE_MUL, tmp, 0, input, swizzle1(params,W)); emit_op2(p, OPCODE_MUL, tmp, 0, tmp, tmp); - emit_op2(p, OPCODE_POW, fog, WRITEMASK_X, - register_const1f(p, M_E), negate(tmp)); + emit_op1(p, OPCODE_EX2, fog, WRITEMASK_X, negate(tmp)); break; } @@ -1317,8 +1313,6 @@ static void build_texture_transform( struct tnl_program *p ) } -/* Seems like it could be tighter: - */ static void build_pointsize( struct tnl_program *p ) { struct ureg eye = get_eye_position(p); @@ -1327,20 +1321,25 @@ static void build_pointsize( struct tnl_program *p ) struct ureg out = register_output(p, VERT_RESULT_PSIZ); struct ureg ut = get_temp(p); - /* 1, -Z, Z * Z, 1 */ - emit_op1(p, OPCODE_MOV, ut, 0, swizzle1(get_identity_param(p), W)); - emit_op2(p, OPCODE_MUL, ut, WRITEMASK_YZ, ut, negate(swizzle1(eye, Z))); - emit_op2(p, OPCODE_MUL, ut, WRITEMASK_Z, ut, negate(swizzle1(eye, Z))); - - - /* p1 + p2 * dist + p3 * dist * dist, 0 */ - emit_op2(p, OPCODE_DP3, ut, 0, ut, state_attenuation); - - /* 1 / factor */ - emit_op1(p, OPCODE_RCP, ut, 0, ut ); - - /* out = pointSize / factor */ - emit_op2(p, OPCODE_MUL, out, WRITEMASK_X, ut, state_size); + /* p1 + dist * (p2 + dist * p3); */ + emit_op3(p, OPCODE_MAD, ut, 0, negate(swizzle1(eye, Z)), + swizzle1(state_attenuation, Z), swizzle1(state_attenuation, Y)); + emit_op3(p, OPCODE_MAD, ut, 0, negate(swizzle1(eye, Z)), + ut, swizzle1(state_attenuation, X)); + + /* 1 / sqrt(factor) */ + emit_op1(p, OPCODE_RSQ, ut, 0, ut ); + +#if 1 + /* out = pointSize / sqrt(factor) */ + emit_op2(p, OPCODE_MUL, out, WRITEMASK_X, ut, state_size); +#else + /* not sure, might make sense to do clamping here, + but it's not done in t_vb_points neither */ + emit_op2(p, OPCODE_MUL, ut, 0, ut, state_size); + emit_op2(p, OPCODE_MAX, ut, 0, ut, swizzle1(state_size, Y)); + emit_op2(p, OPCODE_MIN, out, WRITEMASK_X, ut, swizzle1(state_size, Z)); +#endif release_temp(p, ut); } -- cgit v1.2.3 From 421ce180f52ff55b866066fabd861a51dd6d2b26 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Fri, 9 Feb 2007 00:36:53 +0100 Subject: r200: simplify / unify input map handling for vp and fftnl Use the same input map handling for fftnl and vertex programs. It doesn't enable any new functionality (should make it easy to support per-vertex materials though), but the code is much cleaner. --- src/mesa/drivers/dri/r200/r200_context.h | 12 +- src/mesa/drivers/dri/r200/r200_maos.h | 2 +- src/mesa/drivers/dri/r200/r200_maos_arrays.c | 402 +++++++-------------------- src/mesa/drivers/dri/r200/r200_tcl.c | 42 +-- src/mesa/drivers/dri/r200/r200_vertprog.c | 17 +- 5 files changed, 141 insertions(+), 334 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h index 26a43d20dd..e840a502c0 100644 --- a/src/mesa/drivers/dri/r200/r200_context.h +++ b/src/mesa/drivers/dri/r200/r200_context.h @@ -107,8 +107,7 @@ struct r200_vertex_program { VERTEX_SHADER_INSTRUCTION instr[R200_VSF_MAX_INST + 6]; int pos_end; int inputs[VERT_ATTRIB_MAX]; - int rev_inputs[16]; - int gen_inputs_mapped; + GLubyte inputmap_rev[16]; int native; int fogpidx; int fogmode; @@ -733,14 +732,7 @@ struct r200_tcl_info { GLuint *Elts; struct r200_dma_region indexed_verts; - struct r200_dma_region weight; - struct r200_dma_region obj; - struct r200_dma_region rgba; - struct r200_dma_region spec; - struct r200_dma_region fog; - struct r200_dma_region tex[R200_MAX_TEXTURE_UNITS]; - struct r200_dma_region norm; - struct r200_dma_region generic[16]; + struct r200_dma_region vertex_data[15]; }; diff --git a/src/mesa/drivers/dri/r200/r200_maos.h b/src/mesa/drivers/dri/r200/r200_maos.h index b9e4d3c239..4998f67445 100644 --- a/src/mesa/drivers/dri/r200/r200_maos.h +++ b/src/mesa/drivers/dri/r200/r200_maos.h @@ -38,7 +38,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_context.h" -extern void r200EmitArrays( GLcontext *ctx, GLuint inputs ); +extern void r200EmitArrays( GLcontext *ctx, GLubyte *vimap_rev ); extern void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs ); #endif diff --git a/src/mesa/drivers/dri/r200/r200_maos_arrays.c b/src/mesa/drivers/dri/r200/r200_maos_arrays.c index db5ac6fc8a..6a6c30a2b0 100644 --- a/src/mesa/drivers/dri/r200/r200_maos_arrays.c +++ b/src/mesa/drivers/dri/r200/r200_maos_arrays.c @@ -376,7 +376,7 @@ static void emit_vector( GLcontext *ctx, /* Emit any changed arrays to new GART memory, re-emit a packet to * update the arrays. */ -void r200EmitArrays( GLcontext *ctx, GLuint inputs ) +void r200EmitArrays( GLcontext *ctx, GLubyte *vimap_rev ) { r200ContextPtr rmesa = R200_CONTEXT( ctx ); struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb; @@ -384,284 +384,109 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs ) GLuint nr = 0; GLuint vfmt0 = 0, vfmt1 = 0; GLuint count = VB->Count; - GLuint i; - GLuint generic_in_mapped = 0; - struct r200_vertex_program *vp = NULL; - - /* this looks way more complicated than necessary... */ - if (ctx->VertexProgram._Enabled) { - vp = rmesa->curr_vp_hw; - generic_in_mapped = vp->gen_inputs_mapped; - } - - if (inputs & VERT_BIT_POS) { - if (!rmesa->tcl.obj.buf) - emit_vector( ctx, - &rmesa->tcl.obj, - (char *)VB->ObjPtr->data, - VB->ObjPtr->size, - VB->ObjPtr->stride, - count); - - switch( VB->ObjPtr->size ) { - case 4: vfmt0 |= R200_VTX_W0; - case 3: vfmt0 |= R200_VTX_Z0; - case 2: - default: - break; - } - component[nr++] = &rmesa->tcl.obj; - } - else if (generic_in_mapped & (1 << 0)) { - int geninput = vp->rev_inputs[0] - VERT_ATTRIB_GENERIC0; - if (!rmesa->tcl.generic[geninput].buf) { - emit_vector( ctx, - &(rmesa->tcl.generic[geninput]), - (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data, - 4, - VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride, - count ); - } - component[nr++] = &rmesa->tcl.generic[geninput]; - vfmt0 |= R200_VTX_W0 | R200_VTX_Z0; - } - - if (inputs & VERT_BIT_WEIGHT) { - if (!rmesa->tcl.weight.buf) - emit_vector( ctx, - &rmesa->tcl.weight, - (char *)VB->AttribPtr[VERT_ATTRIB_WEIGHT]->data, - VB->AttribPtr[VERT_ATTRIB_WEIGHT]->size, - VB->AttribPtr[VERT_ATTRIB_WEIGHT]->stride, - count); - - assert(VB->AttribPtr[VERT_ATTRIB_WEIGHT]->size <= 4); - vfmt0 |= VB->AttribPtr[VERT_ATTRIB_WEIGHT]->size << R200_VTX_WEIGHT_COUNT_SHIFT; - component[nr++] = &rmesa->tcl.weight; - } - - if (inputs & VERT_BIT_NORMAL) { - if (!rmesa->tcl.norm.buf) - emit_vector( ctx, - &(rmesa->tcl.norm), - (char *)VB->NormalPtr->data, - 3, - VB->NormalPtr->stride, - count); - - vfmt0 |= R200_VTX_N0; - component[nr++] = &rmesa->tcl.norm; - } - - if (inputs & VERT_BIT_FOG) { - if (!rmesa->tcl.fog.buf) { - if (ctx->VertexProgram._Enabled) - emit_vector( ctx, - &(rmesa->tcl.fog), - (char *)VB->FogCoordPtr->data, + GLuint i, emitsize; + + for ( i = 0; i < 15; i++ ) { + GLubyte attrib = vimap_rev[i]; + if (attrib != 255) { + switch (i) { + case 0: + emitsize = (VB->AttribPtr[attrib]->size); + switch (emitsize) { + case 4: + vfmt0 |= R200_VTX_W0; + /* fallthrough */ + case 3: + vfmt0 |= R200_VTX_Z0; + break; + case 2: + break; + default: assert(0); + } + break; + case 1: + assert(attrib == VERT_ATTRIB_WEIGHT); + emitsize = (VB->AttribPtr[attrib]->size); + vfmt0 |= emitsize << R200_VTX_WEIGHT_COUNT_SHIFT; + break; + case 2: + assert(attrib == VERT_ATTRIB_NORMAL); + emitsize = 3; + vfmt0 |= R200_VTX_N0; + break; + case 3: + /* special handling to fix up fog. Will get us into trouble with vbos...*/ + assert(attrib == VERT_ATTRIB_FOG); + if (!rmesa->tcl.vertex_data[i].buf) { + if (ctx->VertexProgram._Enabled) + emit_vector( ctx, + &(rmesa->tcl.vertex_data[attrib]), + (char *)VB->AttribPtr[attrib]->data, 1, - VB->FogCoordPtr->stride, + VB->AttribPtr[attrib]->stride, count); - else - emit_vecfog( ctx, - &(rmesa->tcl.fog), - (char *)VB->FogCoordPtr->data, - VB->FogCoordPtr->stride, + else + emit_vecfog( ctx, + &(rmesa->tcl.vertex_data[attrib]), + (char *)VB->AttribPtr[attrib]->data, + VB->AttribPtr[attrib]->stride, count); - } - - vfmt0 |= R200_VTX_DISCRETE_FOG; - component[nr++] = &rmesa->tcl.fog; - } - - if (inputs & VERT_BIT_COLOR0) { - int emitsize; - - if (VB->ColorPtr[0]->size == 4 && - (VB->ColorPtr[0]->stride != 0 || - VB->ColorPtr[0]->data[0][3] != 1.0)) { - vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT; - emitsize = 4; - } - else { - vfmt0 |= R200_VTX_FP_RGB << R200_VTX_COLOR_0_SHIFT; - emitsize = 3; - } - - if (!rmesa->tcl.rgba.buf) - emit_vector( ctx, - &(rmesa->tcl.rgba), - (char *)VB->ColorPtr[0]->data, - emitsize, - VB->ColorPtr[0]->stride, - count); - - component[nr++] = &rmesa->tcl.rgba; - } -/* vfmt0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT; - emit_ubyte_rgba( ctx, &rmesa->tcl.rgba, - (char *)VB->ColorPtr[0]->data, 4, - VB->ColorPtr[0]->stride, count);*/ - else if (generic_in_mapped & (1 << 2)) { - int geninput = vp->rev_inputs[2] - VERT_ATTRIB_GENERIC0; - if (!rmesa->tcl.generic[geninput].buf) { - emit_vector( ctx, - &(rmesa->tcl.generic[geninput]), - (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data, - 4, - VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride, - count ); - } - component[nr++] = &rmesa->tcl.generic[geninput]; - vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT; - } - - - if (inputs & VERT_BIT_COLOR1) { - if (!rmesa->tcl.spec.buf) { - emit_vector( ctx, - &rmesa->tcl.spec, - (char *)VB->SecondaryColorPtr[0]->data, - 3, - VB->SecondaryColorPtr[0]->stride, - count); - } - - /* How does this work? - */ - vfmt0 |= R200_VTX_FP_RGB << R200_VTX_COLOR_1_SHIFT; - component[nr++] = &rmesa->tcl.spec; - } - else if (generic_in_mapped & (1 << 3)) { - int geninput = vp->rev_inputs[3] - VERT_ATTRIB_GENERIC0; - if (!rmesa->tcl.generic[geninput].buf) { - emit_vector( ctx, - &(rmesa->tcl.generic[geninput]), - (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data, - 4, - VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride, - count ); - } - component[nr++] = &rmesa->tcl.generic[geninput]; - vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT; - } - - if (generic_in_mapped & (1 << 4)) { - int geninput = vp->rev_inputs[4] - VERT_ATTRIB_GENERIC0; - if (!rmesa->tcl.generic[geninput].buf) { - emit_vector( ctx, - &(rmesa->tcl.generic[geninput]), - (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data, - 4, - VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride, - count ); - } - component[nr++] = &rmesa->tcl.generic[geninput]; - vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_2_SHIFT; - } - - if (generic_in_mapped & (1 << 5)) { - int geninput = vp->rev_inputs[5] - VERT_ATTRIB_GENERIC0; - if (!rmesa->tcl.generic[geninput].buf) { - emit_vector( ctx, - &(rmesa->tcl.generic[geninput]), - (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data, - 4, - VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride, - count ); - } - component[nr++] = &rmesa->tcl.generic[geninput]; - vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_3_SHIFT; - } - - for ( i = 0 ; i < 6 ; i++ ) { - if (inputs & (VERT_BIT_TEX0 << i)) { - if (!rmesa->tcl.tex[i].buf) - emit_vector( ctx, - &(rmesa->tcl.tex[i]), - (char *)VB->TexCoordPtr[i]->data, - VB->TexCoordPtr[i]->size, - VB->TexCoordPtr[i]->stride, - count ); - - vfmt1 |= VB->TexCoordPtr[i]->size << (i * 3); - component[nr++] = &rmesa->tcl.tex[i]; - } - else if (generic_in_mapped & (1 << (i + 6))) { - int geninput = vp->rev_inputs[i + 6] - VERT_ATTRIB_GENERIC0; - if (!rmesa->tcl.generic[geninput].buf) { - emit_vector( ctx, - &(rmesa->tcl.generic[geninput]), - (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data, - 4, - VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride, - count ); - } - component[nr++] = &rmesa->tcl.generic[geninput]; - vfmt1 |= 4 << (R200_VTX_TEX0_COMP_CNT_SHIFT + (i * 3)); - } - } - - if (generic_in_mapped & (1 << 13)) { - int geninput = vp->rev_inputs[13] - VERT_ATTRIB_GENERIC0; - if (!rmesa->tcl.generic[geninput].buf) { - emit_vector( ctx, - &(rmesa->tcl.generic[geninput]), - (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data, - 4, - VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride, - count ); - } - component[nr++] = &rmesa->tcl.generic[geninput]; - vfmt0 |= R200_VTX_XY1 | R200_VTX_Z1 | R200_VTX_W1; - } - -/* doesn't work. Wrong order with mixed generic & conventional! */ -/* - if (ctx->VertexProgram._Enabled) { - int *vp_inputs = rmesa->curr_vp_hw->inputs; - for ( i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++ ) { - if (inputs & (1 << i)) { - int geninput = i - VERT_ATTRIB_GENERIC0; - if (!rmesa->tcl.generic[geninput].buf) { - emit_vector( ctx, - &(rmesa->tcl.generic[geninput]), - (char *)VB->AttribPtr[i]->data, - 4, - VB->AttribPtr[i]->stride, - count ); } - component[nr++] = &rmesa->tcl.generic[geninput]; - switch (vp_inputs[i]) { - case 0: - vfmt0 |= R200_VTX_W0 | R200_VTX_Z0; - break; + vfmt0 |= R200_VTX_DISCRETE_FOG; + goto after_emit; + break; + case 4: + case 5: + case 6: + case 7: + if (VB->AttribPtr[attrib]->size == 4 && + (VB->AttribPtr[attrib]->stride != 0 || + VB->AttribPtr[attrib]->data[0][3] != 1.0)) emitsize = 4; + else emitsize = 3; + if (emitsize == 4) + vfmt0 |= R200_VTX_FP_RGBA << (R200_VTX_COLOR_0_SHIFT + (i - 4) * 2); + else { + vfmt0 |= R200_VTX_FP_RGB << (R200_VTX_COLOR_0_SHIFT + (i - 4) * 2); + } + break; + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + emitsize = VB->AttribPtr[attrib]->size; + vfmt1 |= emitsize << (R200_VTX_TEX0_COMP_CNT_SHIFT + (i - 8) * 3); + break; + case 14: + emitsize = VB->AttribPtr[attrib]->size >= 2 ? VB->AttribPtr[attrib]->size : 2; + switch (emitsize) { case 2: + vfmt0 |= R200_VTX_XY1; + /* fallthrough */ case 3: + vfmt0 |= R200_VTX_Z1; + /* fallthrough */ case 4: - case 5: - vfmt0 |= R200_VTX_FP_RGBA << (R200_VTX_COLOR_0_SHIFT + (vp_inputs[i] - 2) * 2); - break; - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - vfmt1 |= 4 << (R200_VTX_TEX0_COMP_CNT_SHIFT + (vp_inputs[i] - 6) * 3); - break; - case 13: - vfmt0 |= R200_VTX_XY1 | R200_VTX_Z1 | R200_VTX_W1; - break; - case 1: - case 12: - default: - assert(0); + vfmt0 |= R200_VTX_W1; + break; } + default: + assert(0); + } + if (!rmesa->tcl.vertex_data[i].buf) { + emit_vector( ctx, + &(rmesa->tcl.vertex_data[i]), + (char *)VB->AttribPtr[attrib]->data, + emitsize, + VB->AttribPtr[attrib]->stride, + count ); } +after_emit: + assert(nr < 12); + component[nr++] = &rmesa->tcl.vertex_data[i]; } } -*/ if (vfmt0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] || vfmt1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) { @@ -676,42 +501,13 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs ) void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs ) { - GLuint unit; r200ContextPtr rmesa = R200_CONTEXT( ctx ); -/* if (R200_DEBUG & DEBUG_VERTS) */ -/* _tnl_print_vert_flags( __FUNCTION__, newinputs ); */ - - if (newinputs & VERT_BIT_POS) - r200ReleaseDmaRegion( rmesa, &rmesa->tcl.obj, __FUNCTION__ ); - - if (newinputs & VERT_BIT_WEIGHT) - r200ReleaseDmaRegion( rmesa, &rmesa->tcl.weight, __FUNCTION__ ); - - if (newinputs & VERT_BIT_NORMAL) - r200ReleaseDmaRegion( rmesa, &rmesa->tcl.norm, __FUNCTION__ ); - - if (newinputs & VERT_BIT_FOG) - r200ReleaseDmaRegion( rmesa, &rmesa->tcl.fog, __FUNCTION__ ); - - if (newinputs & VERT_BIT_COLOR0) - r200ReleaseDmaRegion( rmesa, &rmesa->tcl.rgba, __FUNCTION__ ); - - if (newinputs & VERT_BIT_COLOR1) - r200ReleaseDmaRegion( rmesa, &rmesa->tcl.spec, __FUNCTION__ ); - - for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) { - if (newinputs & VERT_BIT_TEX(unit)) - r200ReleaseDmaRegion( rmesa, &rmesa->tcl.tex[unit], __FUNCTION__ ); - } - - if (ctx->VertexProgram._Enabled) { - int i; - for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) { - if (newinputs & (1 << i)) - r200ReleaseDmaRegion( rmesa, - &rmesa->tcl.generic[i - VERT_ATTRIB_GENERIC0], __FUNCTION__ ); - } + /* only do it for changed inputs ? */ + int i; + for (i = 0; i < 15; i++) { + if (newinputs & (1 << i)) + r200ReleaseDmaRegion( rmesa, + &rmesa->tcl.vertex_data[i], __FUNCTION__ ); } - } diff --git a/src/mesa/drivers/dri/r200/r200_tcl.c b/src/mesa/drivers/dri/r200/r200_tcl.c index 62c335a707..e0c32b26d9 100644 --- a/src/mesa/drivers/dri/r200/r200_tcl.c +++ b/src/mesa/drivers/dri/r200/r200_tcl.c @@ -384,8 +384,14 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx, r200ContextPtr rmesa = R200_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; - GLuint inputs = 0; GLuint i; + GLubyte *vimap_rev; +/* use hw fixed order for simplicity, pos 0, weight 1, normal 2, fog 3, + color0 - color3 4-7, texcoord0 - texcoord5 8-13, pos 1 14. Must not use + more than 12 of those at the same time. */ + GLubyte map_rev_fixed[15] = {255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255}; + /* TODO: separate this from the swtnl pipeline */ @@ -404,30 +410,40 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx, r200ValidateState( ctx ); if (!ctx->VertexProgram._Enabled) { - inputs = VERT_BIT_POS | VERT_BIT_COLOR0; /* NOTE: inputs != tnl->render_inputs - these are the untransformed * inputs. */ + map_rev_fixed[0] = VERT_ATTRIB_POS; + /* technically there is no reason we always need VA_COLOR0. In theory + could disable it depending on lighting, color materials, texturing... */ + map_rev_fixed[4] = VERT_ATTRIB_COLOR0; + if (ctx->Light.Enabled) { - inputs |= VERT_BIT_NORMAL; + map_rev_fixed[2] = VERT_ATTRIB_NORMAL; } + /* this also enables VA_COLOR1 when using separate specular + lighting model, which is unnecessary. + FIXME: OTOH, we're missing the case where a ATI_fragment_shader accesses + the secondary color (if lighting is disabled). The chip seems + misconfigured for that though elsewhere (tcl output, might lock up) */ if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { - inputs |= VERT_BIT_COLOR1; + map_rev_fixed[5] = VERT_ATTRIB_COLOR1; } if ( (ctx->Fog.FogCoordinateSource == GL_FOG_COORD) && ctx->Fog.Enabled ) { - inputs |= VERT_BIT_FOG; + map_rev_fixed[3] = VERT_ATTRIB_FOG; } for (i = 0 ; i < ctx->Const.MaxTextureUnits; i++) { if (ctx->Texture.Unit[i]._ReallyEnabled) { if (rmesa->TexGenNeedNormals[i]) { - inputs |= VERT_BIT_NORMAL; + map_rev_fixed[2] = VERT_ATTRIB_NORMAL; } - inputs |= VERT_BIT_TEX(i); + map_rev_fixed[8 + i] = VERT_ATTRIB_TEX0 + i; } } + vimap_rev = &map_rev_fixed[0]; } else { /* vtx_tcl_output_vtxfmt_0/1 need to match configuration of "fragment @@ -437,14 +453,8 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx, We only need to change compsel. */ GLuint out_compsel = 0; GLuint vp_out = rmesa->curr_vp_hw->mesa_program.Base.OutputsWritten; -#if 0 - /* can't handle other inputs, generic attribs etc. currently - should never arrive here */ - assert ((rmesa->curr_vp_hw->mesa_program.Base.InputsRead & - ~(VERT_BIT_POS | VERT_BIT_NORMAL | VERT_BIT_COLOR0 | VERT_BIT_COLOR1 | - VERT_BIT_FOG | VERT_BIT_TEX0 | VERT_BIT_TEX1 | VERT_BIT_TEX2 | - VERT_BIT_TEX3 | VERT_BIT_TEX4 | VERT_BIT_TEX5)) == 0); -#endif - inputs |= rmesa->curr_vp_hw->mesa_program.Base.InputsRead; + + vimap_rev = &rmesa->curr_vp_hw->inputmap_rev[0]; assert(vp_out & (1 << VERT_RESULT_HPOS)); out_compsel = R200_OUTPUT_XYZW; if (vp_out & (1 << VERT_RESULT_COL0)) { @@ -473,7 +483,7 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx, /* Do the actual work: */ r200ReleaseArrays( ctx, ~0 /* stage->changed_inputs */ ); - r200EmitArrays( ctx, inputs ); + r200EmitArrays( ctx, vimap_rev ); rmesa->tcl.Elts = VB->Elts; diff --git a/src/mesa/drivers/dri/r200/r200_vertprog.c b/src/mesa/drivers/dri/r200/r200_vertprog.c index 713e2f9eca..4960d481d5 100644 --- a/src/mesa/drivers/dri/r200/r200_vertprog.c +++ b/src/mesa/drivers/dri/r200/r200_vertprog.c @@ -405,7 +405,6 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte int dofogfix = 0; int fog_temp_i = 0; int free_inputs; - int free_inputs_conv; int array_count = 0; vp->native = GL_FALSE; @@ -477,6 +476,8 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte for(i = 0; i < VERT_ATTRIB_MAX; i++) vp->inputs[i] = -1; + for(i = 0; i < 15; i++) + vp->inputmap_rev[i] = 255; free_inputs = 0x2ffd; /* fglrx uses fixed inputs as follows for conventional attribs. @@ -499,38 +500,45 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte /* may look different when using idx buf / input_route instead of se_vtx_fmt? */ if (mesa_vp->Base.InputsRead & VERT_BIT_POS) { vp->inputs[VERT_ATTRIB_POS] = 0; + vp->inputmap_rev[0] = VERT_ATTRIB_POS; free_inputs &= ~(1 << 0); array_count++; } if (mesa_vp->Base.InputsRead & VERT_BIT_WEIGHT) { vp->inputs[VERT_ATTRIB_WEIGHT] = 12; + vp->inputmap_rev[1] = VERT_ATTRIB_WEIGHT; array_count++; } if (mesa_vp->Base.InputsRead & VERT_BIT_NORMAL) { vp->inputs[VERT_ATTRIB_NORMAL] = 1; + vp->inputmap_rev[2] = VERT_ATTRIB_NORMAL; array_count++; } if (mesa_vp->Base.InputsRead & VERT_BIT_COLOR0) { vp->inputs[VERT_ATTRIB_COLOR0] = 2; + vp->inputmap_rev[4] = VERT_ATTRIB_COLOR0; free_inputs &= ~(1 << 2); array_count++; } if (mesa_vp->Base.InputsRead & VERT_BIT_COLOR1) { vp->inputs[VERT_ATTRIB_COLOR1] = 3; + vp->inputmap_rev[5] = VERT_ATTRIB_COLOR1; free_inputs &= ~(1 << 3); array_count++; } if (mesa_vp->Base.InputsRead & VERT_BIT_FOG) { vp->inputs[VERT_ATTRIB_FOG] = 15; array_count++; + vp->inputmap_rev[3] = VERT_ATTRIB_FOG; + array_count++; } for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX5; i++) { if (mesa_vp->Base.InputsRead & (1 << i)) { vp->inputs[i] = i - VERT_ATTRIB_TEX0 + 6; + vp->inputmap_rev[8 + i - VERT_ATTRIB_TEX0] = i; free_inputs &= ~(1 << (i - VERT_ATTRIB_TEX0 + 6)); array_count++; } } - free_inputs_conv = free_inputs; /* using VERT_ATTRIB_TEX6/7 would be illegal */ /* completely ignore aliasing? */ for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) { @@ -549,13 +557,14 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte if (free_inputs & (1 << j)) { free_inputs &= ~(1 << j); vp->inputs[i] = j; - vp->rev_inputs[j] = i; + if (j == 0) vp->inputmap_rev[j] = i; /* mapped to pos */ + else if (j < 12) vp->inputmap_rev[j + 2] = i; /* mapped to col/tex */ + else vp->inputmap_rev[j + 1] = i; /* mapped to pos1 */ break; } } } } - vp->gen_inputs_mapped = free_inputs ^ free_inputs_conv; if (!(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS))) { if (R200_DEBUG & DEBUG_FALLBACKS) { -- cgit v1.2.3 From fcccf8943213a20957f305161e8aae7fef55baab Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Fri, 9 Feb 2007 13:28:56 +0800 Subject: array overflow fix --- src/mesa/vbo/vbo_exec_array.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index f96df5f164..7ea55470ac 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -147,8 +147,8 @@ static void recalculate_input_bindings( GLcontext *ctx ) /* Could use just about anything, just to fill in the empty * slots: */ - for (i = MAT_ATTRIB_MAX; i < VERT_ATTRIB_MAX; i++) - inputs[i] = &vbo->generic_currval[i - VERT_ATTRIB_GENERIC0]; + for (i = MAT_ATTRIB_MAX; i < VERT_ATTRIB_MAX - VERT_ATTRIB_GENERIC0; i++) + inputs[VERT_ATTRIB_GENERIC0 + i] = &vbo->generic_currval[i]; break; case VP_NV: -- cgit v1.2.3 From b2d30ca0cb01a80ff440a4a07b293daa16486e12 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Fri, 9 Feb 2007 19:21:29 +0100 Subject: optimize per-pixel fog program use the same internal state as for vertex fog. From the old implemenentation, this changes a SUB+MUL into a MAD for linear fog, and saves a MUL for EXP/EXP2, plus saves a (constant) parameter. While here, fix the broken (forgotten) swizzling. (untested) --- src/mesa/shader/program.c | 2 +- src/mesa/shader/programopt.c | 79 +++++++++++++++++--------------------------- 2 files changed, 31 insertions(+), 50 deletions(-) (limited to 'src') diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index 7e6cd26c55..490f919445 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -997,7 +997,7 @@ _mesa_fetch_state(GLcontext *ctx, const enum state_index state[], break; } case STATE_FOG_PARAMS_OPTIMIZED: - /* this makes it possible to use simpler per-vertex fog calcs. POW + /* for simpler per-vertex/pixel fog calcs. POW (for EXP/EXP2 fog) might be more expensive than EX2 on some hw, plus it needs another constant (e) anyway. Linear fog can now be done with a single MAD. diff --git a/src/mesa/shader/programopt.c b/src/mesa/shader/programopt.c index 783177739d..dca44c853d 100644 --- a/src/mesa/shader/programopt.c +++ b/src/mesa/shader/programopt.c @@ -126,16 +126,15 @@ _mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog) void _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) { - static const GLint fogParamsState[] = { STATE_FOG_PARAMS, 0, 0, 0, 0 }; + static const GLint fogPStateOpt[] = { STATE_INTERNAL, + STATE_FOG_PARAMS_OPTIMIZED, 0, 0, 0 }; static const GLint fogColorState[] = { STATE_FOG_COLOR, 0, 0, 0, 0 }; struct prog_instruction *newInst, *inst; const GLuint origLen = fprog->Base.NumInstructions; - const GLuint newLen = origLen + 6; + const GLuint newLen = origLen + 5; GLuint i; - GLint fogParamsRef, fogColorRef; /* state references */ + GLint fogPRefOpt, fogColorRef; /* state references */ GLuint colorTemp, fogFactorTemp; /* temporary registerss */ - GLfloat fogVals[4]; - GLuint fogConsts; /* constant values for EXP, EXP2 mode */ if (fprog->FogOption == GL_NONE) { _mesa_problem(ctx, "_mesa_append_fog_code() called for fragment program" @@ -155,9 +154,9 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) _mesa_memcpy(newInst, fprog->Base.Instructions, origLen * sizeof(struct prog_instruction)); - /* PARAM fogParamsRef = state.fog.params; */ - fogParamsRef - = _mesa_add_state_reference(fprog->Base.Parameters, fogParamsState); + /* PARAM fogParamsRefOpt = internal optimized fog params; */ + fogPRefOpt + = _mesa_add_state_reference(fprog->Base.Parameters, fogPStateOpt); /* PARAM fogColorRef = state.fog.color; */ fogColorRef = _mesa_add_state_reference(fprog->Base.Parameters, fogColorState); @@ -167,13 +166,6 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) /* TEMP fogFactorTemp; */ fogFactorTemp = fprog->Base.NumTemporaries++; - /* PARAM fogVals = { 1/ln(2), 1/sqrt(ln(2), 0, 0 }; */ - fogVals[0] = 1.0 / log(2.0); - fogVals[1] = 1.0 / SQRTF(log(2.0)); - fogVals[2] = 0.0; - fogVals[3] = 0.0; - fogConsts = _mesa_add_unnamed_constant(fprog->Base.Parameters, fogVals, 4); - /* Scan program to find where result.color is written */ inst = newInst; for (i = 0; i < fprog->Base.NumInstructions; i++) { @@ -191,43 +183,39 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) } assert(inst->Opcode == OPCODE_END); /* we'll overwrite this inst */ - _mesa_init_instructions(inst, 6); + _mesa_init_instructions(inst, 5); /* emit instructions to compute fog blending factor */ if (fprog->FogOption == GL_LINEAR) { - /* SUB fogFactorTemp.x, fogParamsRef.z, fragment.fogcoord.x; */ - inst->Opcode = OPCODE_SUB; - inst->DstReg.File = PROGRAM_TEMPORARY; - inst->DstReg.Index = fogFactorTemp; - inst->DstReg.WriteMask = WRITEMASK_X; - inst->SrcReg[0].File = PROGRAM_STATE_VAR; - inst->SrcReg[0].Index = fogParamsRef; - inst->SrcReg[0].Swizzle = SWIZZLE_Z; - inst->SrcReg[1].File = PROGRAM_INPUT; - inst->SrcReg[1].Index = FRAG_ATTRIB_FOGC; - inst++; - /* MUL fogFactorTemp.x, fogFactorTemp, fogParamsRef.w; */ - inst->Opcode = OPCODE_MUL; + /* MAD fogFactorTemp.x, fragment.fogcoord.x, fogPRefOpt.x, fogPRefOpt.y; */ + inst->Opcode = OPCODE_MAD; inst->DstReg.File = PROGRAM_TEMPORARY; inst->DstReg.Index = fogFactorTemp; inst->DstReg.WriteMask = WRITEMASK_X; - inst->SrcReg[0].File = PROGRAM_TEMPORARY; - inst->SrcReg[0].Index = fogFactorTemp; + inst->SrcReg[0].File = PROGRAM_INPUT; + inst->SrcReg[0].Index = FRAG_ATTRIB_FOGC; + inst->SrcReg[0].Swizzle = SWIZZLE_X; inst->SrcReg[1].File = PROGRAM_STATE_VAR; - inst->SrcReg[1].Index = fogParamsRef; - inst->SrcReg[1].Swizzle = SWIZZLE_W; + inst->SrcReg[1].Index = fogPRefOpt; + inst->SrcReg[1].Swizzle = SWIZZLE_X; + inst->SrcReg[2].File = PROGRAM_STATE_VAR; + inst->SrcReg[2].Index = fogPRefOpt; + inst->SrcReg[2].Swizzle = SWIZZLE_Y; inst++; } else { ASSERT(fprog->FogOption == GL_EXP || fprog->FogOption == GL_EXP2); - /* MUL fogFactorTemp.x, fogParamsRef.x, fragment.fogcoord; */ + /* fogPRefOpt.z = d/ln(2), fogPRefOpt.w = d/sqrt(ln(2) */ + /* EXP: MUL fogFactorTemp.x, fogPRefOpt.z, fragment.fogcoord.x; */ + /* EXP2: MUL fogFactorTemp.x, fogPRefOpt.w, fragment.fogcoord.x; */ inst->Opcode = OPCODE_MUL; inst->DstReg.File = PROGRAM_TEMPORARY; inst->DstReg.Index = fogFactorTemp; inst->DstReg.WriteMask = WRITEMASK_X; inst->SrcReg[0].File = PROGRAM_STATE_VAR; - inst->SrcReg[0].Index = fogParamsRef; - inst->SrcReg[0].Swizzle = SWIZZLE_X; /* X=density */ + inst->SrcReg[0].Index = fogPRefOpt; + inst->SrcReg[0].Swizzle + = (fprog->FogOption == GL_EXP) ? SWIZZLE_Z : SWIZZLE_W; inst->SrcReg[1].File = PROGRAM_INPUT; inst->SrcReg[1].Index = FRAG_ATTRIB_FOGC; inst->SrcReg[1].Swizzle = SWIZZLE_X; @@ -240,23 +228,12 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) inst->DstReg.WriteMask = WRITEMASK_X; inst->SrcReg[0].File = PROGRAM_TEMPORARY; inst->SrcReg[0].Index = fogFactorTemp; + inst->SrcReg[0].Swizzle = SWIZZLE_X; inst->SrcReg[1].File = PROGRAM_TEMPORARY; inst->SrcReg[1].Index = fogFactorTemp; + inst->SrcReg[1].Swizzle = SWIZZLE_X; inst++; } - /* EXP: MUL fogFactorTemp.x, fogFactorTemp.x, {1/ln(2)}; */ - /* EXP2: MUL fogFactorTemp.x, fogFactorTemp.x, {1/sqrt(ln(2))}; */ - inst->Opcode = OPCODE_MUL; - inst->DstReg.File = PROGRAM_TEMPORARY; - inst->DstReg.Index = fogFactorTemp; - inst->DstReg.WriteMask = WRITEMASK_X; - inst->SrcReg[0].File = PROGRAM_TEMPORARY; - inst->SrcReg[0].Index = fogFactorTemp; - inst->SrcReg[1].File = PROGRAM_CONSTANT; - inst->SrcReg[1].Index = fogConsts; - inst->SrcReg[1].Swizzle - = (fprog->FogOption == GL_EXP) ? SWIZZLE_X : SWIZZLE_Y; - inst++; /* EX2_SAT fogFactorTemp.x, -fogFactorTemp.x; */ inst->Opcode = OPCODE_EX2; inst->DstReg.File = PROGRAM_TEMPORARY; @@ -265,6 +242,7 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) inst->SrcReg[0].File = PROGRAM_TEMPORARY; inst->SrcReg[0].Index = fogFactorTemp; inst->SrcReg[0].NegateBase = GL_TRUE; + inst->SrcReg[0].Swizzle = SWIZZLE_X; inst->SaturateMode = SATURATE_ZERO_ONE; inst++; } @@ -279,8 +257,10 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X); inst->SrcReg[1].File = PROGRAM_TEMPORARY; inst->SrcReg[1].Index = colorTemp; + inst->SrcReg[1].Swizzle = SWIZZLE_NOOP; inst->SrcReg[2].File = PROGRAM_STATE_VAR; inst->SrcReg[2].Index = fogColorRef; + inst->SrcReg[2].Swizzle = SWIZZLE_NOOP; inst++; /* MOV result.color.w, colorTemp.x; # copy alpha */ inst->Opcode = OPCODE_MOV; @@ -289,6 +269,7 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) inst->DstReg.WriteMask = WRITEMASK_W; inst->SrcReg[0].File = PROGRAM_TEMPORARY; inst->SrcReg[0].Index = colorTemp; + inst->SrcReg[0].Swizzle = SWIZZLE_NOOP; inst++; /* END; */ inst->Opcode = OPCODE_END; -- cgit v1.2.3 From 3bacb68c70e4a0813bf944061a97e727cbd89c43 Mon Sep 17 00:00:00 2001 From: Rune Peterson Date: Sat, 10 Feb 2007 18:19:43 -0700 Subject: ctx->Point._Size fix --- src/mesa/main/points.c | 27 +++++++-------------------- src/mesa/main/points.h | 3 --- src/mesa/main/state.c | 3 --- 3 files changed, 7 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/mesa/main/points.c b/src/mesa/main/points.c index c6b032460e..9caa9ab3ab 100644 --- a/src/mesa/main/points.c +++ b/src/mesa/main/points.c @@ -57,6 +57,13 @@ _mesa_PointSize( GLfloat size ) FLUSH_VERTICES(ctx, _NEW_POINT); ctx->Point.Size = size; + ctx->Point._Size = CLAMP(ctx->Point.Size, + ctx->Point.MinSize, + ctx->Point.MaxSize); + + ctx->Point._Attenuated = (ctx->Point.Params[0] != 1.0 || + ctx->Point.Params[1] != 0.0 || + ctx->Point.Params[2] != 0.0); if (ctx->Driver.PointSize) ctx->Driver.PointSize(ctx, size); @@ -231,26 +238,6 @@ _mesa_PointParameterfvEXT( GLenum pname, const GLfloat *params) -/** - * Update derived point-related state. - */ -void -_mesa_update_point(GLcontext *ctx) -{ - /* clamp to user-specified limits now, clamp to ctx->Const.Min/Max - * limits during rasterization. - */ - ctx->Point._Size = CLAMP(ctx->Point.Size, - ctx->Point.MinSize, - ctx->Point.MaxSize); - - ctx->Point._Attenuated = (ctx->Point.Params[0] != 1.0 || - ctx->Point.Params[1] != 0.0 || - ctx->Point.Params[2] != 0.0); -} - - - /** * Initialize the context point state. * diff --git a/src/mesa/main/points.h b/src/mesa/main/points.h index 56acd9ee57..951ff677db 100644 --- a/src/mesa/main/points.h +++ b/src/mesa/main/points.h @@ -50,9 +50,6 @@ _mesa_PointParameterfEXT( GLenum pname, GLfloat param ); extern void GLAPIENTRY _mesa_PointParameterfvEXT( GLenum pname, const GLfloat *params ); -extern void -_mesa_update_point(GLcontext *ctx); - extern void _mesa_init_point( GLcontext * ctx ); diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index 55fb4552d2..f4f73a5089 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -1111,9 +1111,6 @@ _mesa_update_state_locked( GLcontext *ctx ) if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT)) _mesa_update_draw_buffer_bounds( ctx ); - if (new_state & _NEW_POINT) - _mesa_update_point( ctx ); - if (new_state & _NEW_LIGHT) _mesa_update_lighting( ctx ); -- cgit v1.2.3 From ee5417bca883d82d618e1c0b65011940253555dd Mon Sep 17 00:00:00 2001 From: Rune Peterson Date: Mon, 12 Feb 2007 00:24:36 +0100 Subject: r300: Add proper support for sin/cos instruction in fragment program Getting proper SIN and COS wasn't as easy as it appeared. I had to make make some changes to the fragment program code. general FP changes: - support HHH swizzle for vector instructions. - don't copy a source to a temp when it is not XYZW swizzled, but combine the two and have the swizzle resolve any issues. (saves temps/instructions with more elaborate shader code) - fix overflow in cnstv[]. --- src/mesa/drivers/dri/r300/r300_context.h | 5 + src/mesa/drivers/dri/r300/r300_fragprog.c | 271 ++++++++++++++++------------ src/mesa/drivers/dri/r300/r300_fragprog.h | 5 +- src/mesa/drivers/dri/r300/r300_render.c | 2 +- src/mesa/drivers/dri/r300/r300_state.c | 2 +- src/mesa/drivers/dri/radeon/radeon_screen.c | 11 +- 6 files changed, 175 insertions(+), 121 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 02f8e9107d..b140235159 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -729,6 +729,11 @@ struct r300_fragment_program { GLboolean params_uptodate; int max_temp_idx; + + /* the index of the sin constant is stored here */ + GLint const_sin; + + GLuint optimization; }; #define R300_MAX_AOS_ARRAYS 16 diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c index 6e85f0b5dd..b00cf9ed33 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog.c @@ -33,7 +33,7 @@ /*TODO'S * - * - COS/SIN/SCS instructions + * - SCS instructions * - Depth write, WPOS/FOGC inputs * - FogOption * - Verify results of opcodes for accuracy, I've only checked them @@ -187,6 +187,10 @@ static const struct { #define SLOT_VECTOR (1<<0) #define SLOT_SCALAR (1<<3) #define SLOT_BOTH (SLOT_VECTOR | SLOT_SCALAR) + +/* mapping from SWIZZLE_* to r300 native values for scalar insns */ +#define SWIZZLE_HALF 6 + #define MAKE_SWZ3(x, y, z) (MAKE_SWIZZLE4(SWIZZLE_##x, \ SWIZZLE_##y, \ SWIZZLE_##z, \ @@ -208,7 +212,7 @@ static const struct r300_pfs_swizzle { { MAKE_SWZ3(W, Z, Y), R300_FPI0_ARGC_SRC0CA_WZY, 1, SLOT_BOTH }, { MAKE_SWZ3(ONE, ONE, ONE), R300_FPI0_ARGC_ONE, 0, 0}, { MAKE_SWZ3(ZERO, ZERO, ZERO), R300_FPI0_ARGC_ZERO, 0, 0}, - { PFS_INVAL, R300_FPI0_ARGC_HALF, 0, 0}, + { MAKE_SWZ3(HALF, HALF, HALF), R300_FPI0_ARGC_HALF, 0, 0}, { PFS_INVAL, 0, 0, 0}, }; @@ -232,8 +236,6 @@ static const struct { { PFS_INVAL, PFS_INVAL, PFS_INVAL} }; -/* mapping from SWIZZLE_* to r300 native values for scalar insns */ -#define SWIZZLE_HALF 6 static const struct { int base; /* hw value of swizzle */ int stride; /* difference between SRC0/1/2 */ @@ -590,6 +592,7 @@ static GLuint do_swizzle(struct r300_fragment_program *rp, /* If swizzling from something without an XYZW native swizzle, * emit result to a temp, and do new swizzle from the temp. */ +#if 0 if (REG_GET_VSWZ(src) != SWIZZLE_XYZ || REG_GET_SSWZ(src) != SWIZZLE_W) { GLuint temp = get_temp_reg(rp); @@ -603,10 +606,30 @@ static GLuint do_swizzle(struct r300_fragment_program *rp, 0); src = temp; } +#endif - /* set scalar swizzling */ - REG_SET_SSWZ(src, GET_SWZ(arbswz, 3)); + if (REG_GET_VSWZ(src) != SWIZZLE_XYZ || + REG_GET_SSWZ(src) != SWIZZLE_W) { + GLuint vsrcswz = (v_swiz[REG_GET_VSWZ(src)].hash & (SWZ_X_MASK|SWZ_Y_MASK|SWZ_Z_MASK)) | REG_GET_SSWZ(src) << 9; + GLint i; + GLuint newswz = 0; + GLuint offset; + for(i=0; i < 4; ++i){ + offset = GET_SWZ(arbswz, i); + + newswz |= (offset <= 3)?GET_SWZ(vsrcswz, offset) << i*3:offset << i*3; + } + + arbswz = newswz & (SWZ_X_MASK|SWZ_Y_MASK|SWZ_Z_MASK); + REG_SET_SSWZ(src, GET_SWZ(newswz, 3)); + } + else + { + /* set scalar swizzling */ + REG_SET_SSWZ(src, GET_SWZ(arbswz, 3)); + + } do { vswz = REG_GET_VSWZ(src); do { @@ -1234,62 +1257,87 @@ static GLboolean parse_program(struct r300_fragment_program *rp) break; case OPCODE_COS: /* - * cos using taylor serie: - * cos(x) = 1 - x^2/2! + x^4/4! - x^6/6! + * cos using a parabola (see SIN): + * cos(x): + * x += PI/2 + * x = (x < PI)?x : x-2*PI + * result = sin(x) */ temp = get_temp_reg(rp); - cnstv[0] = 0.5; - cnstv[1] = 0.041666667; - cnstv[2] = 0.001388889; - cnstv[4] = 0.0; - cnst = emit_const4fv(rp, cnstv); + if(rp->const_sin == -1){ + cnstv[0] = 1.273239545; + cnstv[1] =-0.405284735; + cnstv[2] = 3.141592654; + cnstv[3] = 0.225; + rp->const_sin = emit_const4fv(rp, cnstv); + } + cnst = rp->const_sin; src[0] = t_scalar_src(rp, fpi->SrcReg[0]); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_XYZ, - src[0], - src[0], - pfs_zero, - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_Y | WRITEMASK_Z, - temp, temp, - pfs_zero, - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_Z, - temp, - swizzle(temp, X, X, X, W), - pfs_zero, - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_XYZ, - temp, cnst, - pfs_zero, - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_X, - pfs_one, - pfs_one, - negate(temp), - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_X, - temp, - pfs_one, - swizzle(temp, Y, Y, Y, W), - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_X, - temp, - pfs_one, - negate(swizzle(temp, Z, Z, Z, W)), - flags); - emit_arith(rp, PFS_OP_MAD, dest, mask, + emit_arith(rp, PFS_OP_LG2, temp, WRITEMASK_W, + pfs_half, + undef, + undef, + 0); + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, + swizzle(cnst, Z, Z, Z, Z), //PI + pfs_half, + swizzle(keep(src[0]), X, X, X, X), + 0); + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_W, + negate(swizzle(temp, W, W, W, W)), //-2 + swizzle(cnst, Z, Z, Z, Z), //PI swizzle(temp, X, X, X, X), - pfs_one, + 0); + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Y, + swizzle(cnst, Z, Z, Z, Z), //PI + negate(pfs_half), + swizzle(src[0], X, X, X, X), + 0); + + emit_arith(rp, PFS_OP_CMP, temp, WRITEMASK_Z, + swizzle(temp, W, W, W, W), + swizzle(temp, X, X, X, X), + swizzle(temp, Y, Y, Y, Y), + 0); + + /* SIN */ + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X | WRITEMASK_Y, + swizzle(temp, Z, Z, Z, Z), + cnst, pfs_zero, - flags); + 0); + + if(rp->optimization == DRI_CONF_FP_OPTIMIZATION_SPEED){ + emit_arith(rp, PFS_OP_MAD, dest, mask, + swizzle(temp, Y, Y, Y, Y), + absolute(swizzle(temp, Z, Z, Z, Z)), + swizzle(temp, X, X, X, X), + flags); + }else{ + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, + swizzle(temp, Y, Y, Y, Y), + absolute(swizzle(temp, Z, Z, Z, Z)), + swizzle(temp, X, X, X, X), + 0); + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Y, + swizzle(temp, X, X, X, X), + absolute(swizzle(temp, X, X, X, X)), + negate(swizzle(temp, X, X, X, X)), + 0); + + + emit_arith(rp, PFS_OP_MAD, dest, mask, + swizzle(temp, Y, Y, Y, Y), + swizzle(cnst, W, W, W, W), + swizzle(temp, X, X, X, X), + flags); + } free_temp(rp, temp); break; case OPCODE_DP3: @@ -1398,7 +1446,7 @@ static GLboolean parse_program(struct r300_fragment_program *rp) * change the compare to (t.x + 0.5) > 0.5 we may * save one instruction by doing CMP -t.x */ - cnstv[0] = cnstv[1] = cnstv[2] = cnstv[4] = 0.50001; + cnstv[0] = cnstv[1] = cnstv[2] = cnstv[3] = 0.50001; src[0] = t_src(rp, fpi->SrcReg[0]); temp = get_temp_reg(rp); cnst = emit_const4fv(rp, cnstv); @@ -1548,68 +1596,55 @@ static GLboolean parse_program(struct r300_fragment_program *rp) break; case OPCODE_SIN: /* - * sin using taylor serie: - * sin(x) = x - x^3/3! + x^5/5! - x^7/7! + * using a parabola: + * sin(x) = 4/pi * x + -4/(pi*pi) * x * abs(x) + * extra precision is obtained by weighting against + * itself squared. */ + temp = get_temp_reg(rp); - cnstv[0] = 0.333333333; - cnstv[1] = 0.008333333; - cnstv[2] = 0.000198413; - cnstv[4] = 0.0; - cnst = emit_const4fv(rp, cnstv); + if(rp->const_sin == -1){ + cnstv[0] = 1.273239545; + cnstv[1] =-0.405284735; + cnstv[2] = 3.141592654; + cnstv[3] = 0.225; + rp->const_sin = emit_const4fv(rp, cnstv); + } + cnst = rp->const_sin; src[0] = t_scalar_src(rp, fpi->SrcReg[0]); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_XYZ, - src[0], - src[0], - pfs_zero, - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_Y | WRITEMASK_Z, - temp, temp, - pfs_zero, - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_Z, - temp, - swizzle(temp, X, X, X, W), + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X | WRITEMASK_Y, + swizzle(keep(src[0]), X, X, X, X), + cnst, pfs_zero, - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_XYZ, - src[0], - temp, - pfs_zero, - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_XYZ, - temp, cnst, - pfs_zero, - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_X, - src[0], - pfs_one, - negate(temp), - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_X, - temp, - pfs_one, - swizzle(temp, Y, Y, Y, W), - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_X, - temp, - pfs_one, - negate(swizzle(temp, Z, Z, Z, W)), - flags); - emit_arith(rp, PFS_OP_MAD, dest, mask, - swizzle(temp, X, X, X, X), - pfs_one, - pfs_zero, - flags); + 0); + + if(rp->optimization == DRI_CONF_FP_OPTIMIZATION_SPEED){ + emit_arith(rp, PFS_OP_MAD, dest, mask, + swizzle(temp, Y, Y, Y, Y), + absolute(swizzle(src[0], X, X, X, X)), + swizzle(temp, X, X, X, X), + flags); + }else{ + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, + swizzle(temp, Y, Y, Y, Y), + absolute(swizzle(src[0], X, X, X, X)), + swizzle(temp, X, X, X, X), + 0); + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Y, + swizzle(temp, X, X, X, X), + absolute(swizzle(temp, X, X, X, X)), + negate(swizzle(temp, X, X, X, X)), + 0); + + + emit_arith(rp, PFS_OP_MAD, dest, mask, + swizzle(temp, Y, Y, Y, Y), + swizzle(cnst, W, W, W, W), + swizzle(temp, X, X, X, X), + flags); + } free_temp(rp, temp); break; case OPCODE_SLT: @@ -1681,7 +1716,7 @@ static GLboolean parse_program(struct r300_fragment_program *rp) /* - Init structures * - Determine what hwregs each input corresponds to */ -static void init_program(struct r300_fragment_program *rp) +static void init_program(r300ContextPtr r300, struct r300_fragment_program *rp) { struct r300_pfs_compile_state *cs = NULL; struct gl_fragment_program *mp = &rp->mesa_program; @@ -1691,6 +1726,7 @@ static void init_program(struct r300_fragment_program *rp) int i,j; /* New compile, reset tracking data */ + rp->optimization = driQueryOptioni(&r300->radeon.optionCache, "fp_optimization"); rp->translated = GL_FALSE; rp->error = GL_FALSE; rp->cs = cs = &(R300_CONTEXT(rp->ctx)->state.pfs_compile); @@ -1703,6 +1739,7 @@ static void init_program(struct r300_fragment_program *rp) rp->max_temp_idx = 0; rp->node[0].alu_end = -1; rp->node[0].tex_end = -1; + rp->const_sin = -1; _mesa_memset(cs, 0, sizeof(*rp->cs)); for (i=0;iparams_uptodate = GL_TRUE; } -void r300_translate_fragment_shader(struct r300_fragment_program *rp) +void r300_translate_fragment_shader(r300ContextPtr r300, struct r300_fragment_program *rp) { struct r300_pfs_compile_state *cs = NULL; if (!rp->translated) { - init_program(rp); + init_program(r300, rp); cs = rp->cs; if (parse_program(rp) == GL_FALSE) { diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.h b/src/mesa/drivers/dri/r300/r300_fragprog.h index b0cebe60bb..73986abc3c 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.h +++ b/src/mesa/drivers/dri/r300/r300_fragprog.h @@ -112,8 +112,11 @@ typedef struct r300_fragment_program_swizzle { ((0 | SRC_CONST) << R300_FPI3_SRC1A_SHIFT) | \ ((0 | SRC_CONST) << R300_FPI3_SRC2A_SHIFT)) +#define DRI_CONF_FP_OPTIMIZATION_SPEED 0 +#define DRI_CONF_FP_OPTIMIZATION_QUALITY 1 + struct r300_fragment_program; -extern void r300_translate_fragment_shader(struct r300_fragment_program *rp); +extern void r300_translate_fragment_shader(r300ContextPtr r300, struct r300_fragment_program *rp); #endif diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index e29df87696..211c451f66 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -392,7 +392,7 @@ int r300Fallback(GLcontext *ctx) if (rp) { if (!rp->translated) - r300_translate_fragment_shader(rp); + r300_translate_fragment_shader(r300, rp); FALLBACK_IF(!rp->translated); } diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index a12f3bb531..906dfceb48 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -1820,7 +1820,7 @@ void r300SetupPixelShader(r300ContextPtr rmesa) if (!rp) /* should only happenen once, just after context is created */ return; - r300_translate_fragment_shader(rp); + r300_translate_fragment_shader(rmesa, rp); if (!rp->translated) { fprintf(stderr, "%s: No valid fragment shader, exiting\n", __func__); return; diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index cee1f7e2f9..fc5aa11462 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -55,6 +55,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_span.h" #elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) #include "r300_context.h" +#include "r300_fragprog.h" #include "radeon_span.h" #endif @@ -168,6 +169,13 @@ DRI_CONF_OPT_BEGIN(disable_stencil_two_side,bool,def) \ DRI_CONF_DESC(en,"Disable GL_EXT_stencil_two_side") \ DRI_CONF_OPT_END +#define DRI_CONF_FP_OPTIMIZATION(def) \ +DRI_CONF_OPT_BEGIN_V(fp_optimization,enum,def,"0:1") \ + DRI_CONF_DESC_BEGIN(en,"Fragment Program optimization") \ + DRI_CONF_ENUM(0,"Optimize for Speed") \ + DRI_CONF_ENUM(1,"Optimize for Quality") \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END const char __driConfigOptions[] = DRI_CONF_BEGIN @@ -190,12 +198,13 @@ DRI_CONF_BEGIN DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER) DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC) DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF) + DRI_CONF_FP_OPTIMIZATION(DRI_CONF_FP_OPTIMIZATION_SPEED) DRI_CONF_SECTION_END DRI_CONF_SECTION_DEBUG DRI_CONF_NO_RAST(false) DRI_CONF_SECTION_END DRI_CONF_END; -static const GLuint __driNConfigOptions = 17; +static const GLuint __driNConfigOptions = 18; #ifndef RADEON_DEBUG int RADEON_DEBUG = 0; -- cgit v1.2.3 From ebcc9b5d12995cc83c032beeff468c5ecb30b33f Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Mon, 12 Feb 2007 12:16:49 +0800 Subject: fd.o #BZ 9684 gcc may cast an overflowed float value to an negative int value on i386, fix it to make sure at least some apps will not crash if it contains wrong normal data. --- src/mesa/main/light.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/main/light.h b/src/mesa/main/light.h index f47fe58a83..b97e17b5be 100644 --- a/src/mesa/main/light.h +++ b/src/mesa/main/light.h @@ -92,7 +92,8 @@ do { \ struct gl_shine_tab *_tab = table; \ float f = (dp * (SHINE_TABLE_SIZE-1)); \ int k = (int) f; \ - if (k > SHINE_TABLE_SIZE-2) \ + if (k < 0 /* gcc may cast an overflow float value to negative int value*/ \ + || k > SHINE_TABLE_SIZE-2) \ result = (GLfloat) _mesa_pow( dp, _tab->shininess ); \ else \ result = _tab->tab[k] + (f-k)*(_tab->tab[k+1]-_tab->tab[k]); \ -- cgit v1.2.3 From 1e6688742e6a6e11d002c1fce5dca3da3d58594f Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Mon, 12 Feb 2007 16:38:50 +0800 Subject: I965: fix a failure on waiting irq. Wait until getting the right fence if drm/i915 resets the counter. --- src/mesa/drivers/dri/i965/intel_ioctl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/intel_ioctl.c b/src/mesa/drivers/dri/i965/intel_ioctl.c index 4da31277ea..0a8e976f70 100644 --- a/src/mesa/drivers/dri/i965/intel_ioctl.c +++ b/src/mesa/drivers/dri/i965/intel_ioctl.c @@ -108,7 +108,8 @@ void intelWaitIrq( struct intel_context *intel, int seq ) /* This seems quite often to return before it should!?! */ - } while (ret == -EAGAIN || ret == -EINTR || (ret == -EBUSY && lastdispatch != intel->sarea->last_dispatch) || (ret == 0 && seq > intel->sarea->last_dispatch)); + } while (ret == -EAGAIN || ret == -EINTR || (ret == -EBUSY && lastdispatch != intel->sarea->last_dispatch) || (ret == 0 && seq > intel->sarea->last_dispatch) + || (ret == 0 && intel->sarea->last_dispatch - seq >= (1 << 24))); if ( ret ) { -- cgit v1.2.3 From bc82b44db9dbb6ea0f02c2a9a430e8d402c85bd3 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 14 Feb 2007 11:11:23 +0100 Subject: i915tex: Take into account various mapping states when dropping the batch buffer after a resolution / rotation switch. --- src/mesa/drivers/dri/i915tex/intel_context.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c b/src/mesa/drivers/dri/i915tex/intel_context.c index aa76875a4a..a5ce08b170 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.c +++ b/src/mesa/drivers/dri/i915tex/intel_context.c @@ -643,7 +643,9 @@ intelContendedLock(struct intel_context *intel, GLuint flags) if (sarea->width != intel->width || sarea->height != intel->height || sarea->rotation != intel->current_rotation) { - + + void *batchMap = intel->batch->map; + /* * FIXME: Really only need to do this when drawing to a * common back- or front buffer. @@ -653,9 +655,18 @@ intelContendedLock(struct intel_context *intel, GLuint flags) * This will drop the outstanding batchbuffer on the floor */ - driBOUnmap(intel->batch->buffer); + if (batchMap != NULL) { + driBOUnmap(intel->batch->buffer); + intel->batch->map = NULL; + } + intel_batchbuffer_reset(intel->batch); + if (batchMap == NULL) { + driBOUnmap(intel->batch->buffer); + intel->batch->map = NULL; + } + /* lose all primitives */ intel->prim.primitive = ~0; intel->prim.start_ptr = 0; -- cgit v1.2.3 From 99dfca1e7fb32157135511bded07376ebb25acb3 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Wed, 14 Feb 2007 16:38:32 +0100 Subject: fix stupid bug in the optimized per-vertex fog generation code --- src/mesa/tnl/t_vp_build.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/tnl/t_vp_build.c b/src/mesa/tnl/t_vp_build.c index 0b6f506f4e..81266f3c8b 100644 --- a/src/mesa/tnl/t_vp_build.c +++ b/src/mesa/tnl/t_vp_build.c @@ -1102,7 +1102,8 @@ static void build_fog( struct tnl_program *p ) } if (p->state->tnl_do_vertex_fog) { - struct ureg params = register_param1(p, STATE_FOG_PARAMS_OPTIMIZED); + struct ureg params = register_param2(p, STATE_INTERNAL, + STATE_FOG_PARAMS_OPTIMIZED); struct ureg tmp = get_temp(p); switch (p->state->fog_mode) { -- cgit v1.2.3 From 83cf4ce6e40ed1841b94f528dc89838e875c720d Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Wed, 14 Feb 2007 20:28:31 +0100 Subject: nouveau: nv10: there are 8 clipping regions --- src/mesa/drivers/dri/nouveau/nv10_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 8fbc76c308..d69c6824ed 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -619,7 +619,7 @@ static void nv10WindowMoved(nouveauContextPtr nmesa) NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 2); OUT_RING_CACHE(((w+x-1) << 16) | x | 0x08000800); OUT_RING_CACHE(((h+y-1) << 16) | y | 0x08000800); - for (i=1; i<7; i++) { + for (i=1; i<8; i++) { BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 1); OUT_RING_CACHE(0); -- cgit v1.2.3 From 7d8ed0f5f5960a492734cb415b8a85ef4ad79846 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Wed, 14 Feb 2007 20:34:52 +0100 Subject: fix typo preventing generic arrays from working with ARB_vp (bug #9952) --- src/mesa/vbo/vbo_exec_array.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index 7ea55470ac..1e4c310203 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -196,7 +196,7 @@ static void recalculate_input_bindings( GLcontext *ctx ) } for (i = 0; i < 16; i++) { - if (exec->array.generic_array[0]->Enabled) + if (exec->array.generic_array[i]->Enabled) inputs[VERT_ATTRIB_GENERIC0 + i] = exec->array.generic_array[i]; else inputs[VERT_ATTRIB_GENERIC0 + i] = &vbo->generic_currval[i]; -- cgit v1.2.3 From 1e2b46963595e02172b4d651cc8a219e9f5c8176 Mon Sep 17 00:00:00 2001 From: Etienne Clement Date: Wed, 14 Feb 2007 13:21:12 -0700 Subject: test for POT before using sample_2d_linear_repeat() --- src/mesa/swrast/s_texfilter.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/swrast/s_texfilter.c b/src/mesa/swrast/s_texfilter.c index f55e23422d..b2c5574d95 100644 --- a/src/mesa/swrast/s_texfilter.c +++ b/src/mesa/swrast/s_texfilter.c @@ -1196,7 +1196,9 @@ sample_linear_2d( GLcontext *ctx, GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; (void) lambda; - if (tObj->WrapS == GL_REPEAT && tObj->WrapT == GL_REPEAT) { + if (tObj->WrapS == GL_REPEAT && + tObj->WrapT == GL_REPEAT && + image->_IsPowerOfTwo) { for (i=0;i Date: Wed, 14 Feb 2007 23:10:52 +0100 Subject: r300: Fix cos & add scs to fragment program. So this do : - Fixes COS. - Does range reductions for SIN & COS. - Adds SCS. - removes the optimized version of SIN & COS. - tweaked weight (should help on precision). - fixed a copy paste typo in emit_arith(). --- src/mesa/drivers/dri/r300/r300_context.h | 2 +- src/mesa/drivers/dri/r300/r300_fragprog.c | 270 ++++++++++++++++++++---------- 2 files changed, 184 insertions(+), 88 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index b140235159..48b50bca65 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -731,7 +731,7 @@ struct r300_fragment_program { int max_temp_idx; /* the index of the sin constant is stored here */ - GLint const_sin; + GLint const_sin[2]; GLuint optimization; }; diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c index b00cf9ed33..8e45bd5403 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog.c @@ -33,7 +33,6 @@ /*TODO'S * - * - SCS instructions * - Depth write, WPOS/FOGC inputs * - FogOption * - Verify results of opcodes for accuracy, I've only checked them @@ -1081,7 +1080,7 @@ static void emit_arith(struct r300_fragment_program *rp, break; } if (emit_sop && - (s_swiz[REG_GET_VSWZ(src[i])].flags & SLOT_VECTOR)) { + (s_swiz[REG_GET_SSWZ(src[i])].flags & SLOT_VECTOR)) { vpos = spos = MAX2(vpos, spos); break; } @@ -1204,6 +1203,25 @@ static GLuint get_attrib(struct r300_fragment_program *rp, GLuint attr) } #endif +static void make_sin_const(struct r300_fragment_program *rp) +{ + if(rp->const_sin[0] == -1){ + GLfloat cnstv[4]; + + cnstv[0] = 1.273239545; // 4/PI + cnstv[1] =-0.405284735; // -4/(PI*PI) + cnstv[2] = 3.141592654; // PI + cnstv[3] = 0.2225; // weight + rp->const_sin[0] = emit_const4fv(rp, cnstv); + + cnstv[0] = 0.5; + cnstv[1] = -1.5; + cnstv[2] = 0.159154943; // 1/(2*PI) + cnstv[3] = 6.283185307; // 2*PI + rp->const_sin[1] = emit_const4fv(rp, cnstv); + } +} + static GLboolean parse_program(struct r300_fragment_program *rp) { struct gl_fragment_program *mp = &rp->mesa_program; @@ -1260,84 +1278,68 @@ static GLboolean parse_program(struct r300_fragment_program *rp) * cos using a parabola (see SIN): * cos(x): * x += PI/2 - * x = (x < PI)?x : x-2*PI + * x = (x/(2*PI))+0.5 + * x = frac(x) + * x = (x*2*PI)-PI * result = sin(x) */ temp = get_temp_reg(rp); - if(rp->const_sin == -1){ - cnstv[0] = 1.273239545; - cnstv[1] =-0.405284735; - cnstv[2] = 3.141592654; - cnstv[3] = 0.225; - rp->const_sin = emit_const4fv(rp, cnstv); - } - cnst = rp->const_sin; + make_sin_const(rp); src[0] = t_scalar_src(rp, fpi->SrcReg[0]); - emit_arith(rp, PFS_OP_LG2, temp, WRITEMASK_W, - pfs_half, - undef, - undef, - 0); + /* add 0.5*PI and do range reduction */ emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, - swizzle(cnst, Z, Z, Z, Z), //PI + swizzle(rp->const_sin[0], Z, Z, Z, Z), //PI pfs_half, swizzle(keep(src[0]), X, X, X, X), 0); - emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_W, - negate(swizzle(temp, W, W, W, W)), //-2 - swizzle(cnst, Z, Z, Z, Z), //PI + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, swizzle(temp, X, X, X, X), + swizzle(rp->const_sin[1], Z, Z, Z, Z), + pfs_half, 0); - emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Y, - swizzle(cnst, Z, Z, Z, Z), //PI - negate(pfs_half), - swizzle(src[0], X, X, X, X), + emit_arith(rp, PFS_OP_FRC, temp, WRITEMASK_X, + swizzle(temp, X, X, X, X), + undef, + undef, 0); - - emit_arith(rp, PFS_OP_CMP, temp, WRITEMASK_Z, - swizzle(temp, W, W, W, W), + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Z, swizzle(temp, X, X, X, X), - swizzle(temp, Y, Y, Y, Y), + swizzle(rp->const_sin[1], W, W, W, W), //2*PI + negate(swizzle(rp->const_sin[0], Z, Z, Z, Z)), //-PI 0); /* SIN */ emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X | WRITEMASK_Y, swizzle(temp, Z, Z, Z, Z), - cnst, + rp->const_sin[0], pfs_zero, 0); - if(rp->optimization == DRI_CONF_FP_OPTIMIZATION_SPEED){ - emit_arith(rp, PFS_OP_MAD, dest, mask, - swizzle(temp, Y, Y, Y, Y), - absolute(swizzle(temp, Z, Z, Z, Z)), - swizzle(temp, X, X, X, X), - flags); - }else{ - emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, - swizzle(temp, Y, Y, Y, Y), - absolute(swizzle(temp, Z, Z, Z, Z)), - swizzle(temp, X, X, X, X), - 0); + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, + swizzle(temp, Y, Y, Y, Y), + absolute(swizzle(temp, Z, Z, Z, Z)), + swizzle(temp, X, X, X, X), + 0); - emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Y, - swizzle(temp, X, X, X, X), - absolute(swizzle(temp, X, X, X, X)), - negate(swizzle(temp, X, X, X, X)), - 0); + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Y, + swizzle(temp, X, X, X, X), + absolute(swizzle(temp, X, X, X, X)), + negate(swizzle(temp, X, X, X, X)), + 0); - emit_arith(rp, PFS_OP_MAD, dest, mask, - swizzle(temp, Y, Y, Y, Y), - swizzle(cnst, W, W, W, W), - swizzle(temp, X, X, X, X), - flags); - } + emit_arith(rp, PFS_OP_MAD, dest, mask, + swizzle(temp, Y, Y, Y, Y), + swizzle(rp->const_sin[0], W, W, W, W), + swizzle(temp, X, X, X, X), + flags); + free_temp(rp, temp); break; case OPCODE_DP3: @@ -1577,7 +1579,93 @@ static GLboolean parse_program(struct r300_fragment_program *rp) flags); break; case OPCODE_SCS: - ERROR("SCS not implemented\n"); + /* + * cos using a parabola (see SIN): + * cos(x): + * x += PI/2 + * x = (x/(2*PI))+0.5 + * x = frac(x) + * x = (x*2*PI)-PI + * result = sin(x) + */ + temp = get_temp_reg(rp); + make_sin_const(rp); + src[0] = t_scalar_src(rp, fpi->SrcReg[0]); + + /* add 0.5*PI and do range reduction */ + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X|WRITEMASK_Y, + swizzle(rp->const_sin[0], Z, Z, Z, Z), + rp->const_sin[1], + swizzle(keep(src[0]), X, X, X, X), + 0); + + emit_arith(rp, PFS_OP_CMP, temp, WRITEMASK_W, + swizzle(rp->const_sin[0], Z, Z, Z, Z), + negate(pfs_half), + swizzle(keep(src[0]), X, X, X, X), + 0); + + emit_arith(rp, PFS_OP_CMP, temp, WRITEMASK_Z, + swizzle(temp, X, X, X, X), + swizzle(temp, Y, Y, Y, Y), + swizzle(temp, W, W, W, W), + 0); + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X | WRITEMASK_Y, + swizzle(temp, Z, Z, Z, Z), + rp->const_sin[0], + pfs_zero, + 0); + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_W, + swizzle(temp, Y, Y, Y, Y), + absolute(swizzle(temp, Z, Z, Z, Z)), + swizzle(temp, X, X, X, X), + 0); + + if(mask & WRITEMASK_Y) + { + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X | WRITEMASK_Y, + swizzle(keep(src[0]), X, X, X, X), + rp->const_sin[0], + pfs_zero, + 0); + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, + swizzle(temp, Y, Y, Y, Y), + absolute(swizzle(keep(src[0]), X, X, X, X)), + swizzle(temp, X, X, X, X), + 0); + } + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Z, + swizzle(temp, W, W, W, W), + absolute(swizzle(temp, W, W, W, W)), + negate(swizzle(temp, W, W, W, W)), + 0); + + emit_arith(rp, PFS_OP_MAD, dest, WRITEMASK_X, + swizzle(temp, Z, Z, Z, Z), + swizzle(rp->const_sin[0], W, W, W, W), + swizzle(temp, W, W, W, W), + flags); + + if(mask & WRITEMASK_Y) + { + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_W, + swizzle(temp, X, X, X, X), + absolute(swizzle(temp, X, X, X, X)), + negate(swizzle(temp, X, X, X, X)), + 0); + + emit_arith(rp, PFS_OP_MAD, dest, WRITEMASK_Y, + swizzle(temp, W, W, W, W), + swizzle(rp->const_sin[0], W, W, W, W), + swizzle(temp, X, X, X, X), + flags); + } + free_temp(rp, temp); break; case OPCODE_SGE: src[0] = t_src(rp, fpi->SrcReg[0]); @@ -1603,48 +1691,56 @@ static GLboolean parse_program(struct r300_fragment_program *rp) */ temp = get_temp_reg(rp); - if(rp->const_sin == -1){ - cnstv[0] = 1.273239545; - cnstv[1] =-0.405284735; - cnstv[2] = 3.141592654; - cnstv[3] = 0.225; - rp->const_sin = emit_const4fv(rp, cnstv); - } - cnst = rp->const_sin; + make_sin_const(rp); src[0] = t_scalar_src(rp, fpi->SrcReg[0]); - emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X | WRITEMASK_Y, + /* do range reduction */ + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, swizzle(keep(src[0]), X, X, X, X), - cnst, + swizzle(rp->const_sin[1], Z, Z, Z, Z), + pfs_half, + 0); + + emit_arith(rp, PFS_OP_FRC, temp, WRITEMASK_X, + swizzle(temp, X, X, X, X), + undef, + undef, + 0); + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Z, + swizzle(temp, X, X, X, X), + swizzle(rp->const_sin[1], W, W, W, W), //2*PI + negate(swizzle(rp->const_sin[0], Z, Z, Z, Z)), //PI + 0); + + /* SIN */ + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X | WRITEMASK_Y, + swizzle(temp, Z, Z, Z, Z), + rp->const_sin[0], pfs_zero, 0); - if(rp->optimization == DRI_CONF_FP_OPTIMIZATION_SPEED){ - emit_arith(rp, PFS_OP_MAD, dest, mask, - swizzle(temp, Y, Y, Y, Y), - absolute(swizzle(src[0], X, X, X, X)), - swizzle(temp, X, X, X, X), - flags); - }else{ - emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, - swizzle(temp, Y, Y, Y, Y), - absolute(swizzle(src[0], X, X, X, X)), - swizzle(temp, X, X, X, X), - 0); + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, + swizzle(temp, Y, Y, Y, Y), + absolute(swizzle(temp, Z, Z, Z, Z)), + swizzle(temp, X, X, X, X), + 0); - emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Y, - swizzle(temp, X, X, X, X), - absolute(swizzle(temp, X, X, X, X)), - negate(swizzle(temp, X, X, X, X)), - 0); + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Y, + swizzle(temp, X, X, X, X), + absolute(swizzle(temp, X, X, X, X)), + negate(swizzle(temp, X, X, X, X)), + 0); - emit_arith(rp, PFS_OP_MAD, dest, mask, - swizzle(temp, Y, Y, Y, Y), - swizzle(cnst, W, W, W, W), - swizzle(temp, X, X, X, X), - flags); - } + emit_arith(rp, PFS_OP_MAD, dest, mask, + swizzle(temp, Y, Y, Y, Y), + swizzle(rp->const_sin[0], W, W, W, W), + swizzle(temp, X, X, X, X), + flags); + free_temp(rp, temp); break; case OPCODE_SLT: @@ -1739,7 +1835,7 @@ static void init_program(r300ContextPtr r300, struct r300_fragment_program *rp) rp->max_temp_idx = 0; rp->node[0].alu_end = -1; rp->node[0].tex_end = -1; - rp->const_sin = -1; + rp->const_sin[0] = -1; _mesa_memset(cs, 0, sizeof(*rp->cs)); for (i=0;i Date: Fri, 16 Feb 2007 19:46:54 +0100 Subject: nouveau: nv10: fix viewport scale and origin --- src/mesa/drivers/dri/nouveau/nv10_state.c | 45 ++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index d69c6824ed..e64fcb12f5 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -34,6 +34,29 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "mtypes.h" #include "colormac.h" +static void nv10ViewportScale(nouveauContextPtr nmesa) +{ + GLcontext *ctx = nmesa->glCtx; + GLuint w = ctx->Viewport.Width; + GLuint h = ctx->Viewport.Height; + + GLfloat max_depth = (ctx->Viewport.Near + ctx->Viewport.Far) * 0.5; + switch (ctx->DrawBuffer->_DepthBuffer->DepthBits) { + case 16: + max_depth *= 32767.0; + break; + case 24: + max_depth *= 16777215.0; + break; + } + + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X, 4); + OUT_RING_CACHEf ((((GLfloat) w) * 0.5) - 2048.0); + OUT_RING_CACHEf ((((GLfloat) h) * 0.5) - 2048.0); + OUT_RING_CACHEf (max_depth); + OUT_RING_CACHEf (0.0); +} + static void nv10AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); @@ -167,6 +190,8 @@ static void nv10DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval) BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2); OUT_RING_CACHEf(nearval); OUT_RING_CACHEf(farval); + + nv10ViewportScale(nmesa); } /** Specify the current buffer for writing */ @@ -628,18 +653,7 @@ static void nv10WindowMoved(nouveauContextPtr nmesa) OUT_RING_CACHE(0); } - /* viewport transform */ - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X, 4); - OUT_RING_CACHEf ((GLfloat) x); - OUT_RING_CACHEf ((GLfloat) (y+h)); - OUT_RING_CACHEf (0.0); - OUT_RING_CACHEf (0.0); - - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X, 4); - OUT_RING_CACHEf ((((GLfloat) w) * 0.5) - 2048.0); - OUT_RING_CACHEf ((((GLfloat) h) * 0.5) - 2048.0); - OUT_RING_CACHEf (16777215.0 * 0.5); - OUT_RING_CACHEf (0.0); + nv10ViewportScale(nmesa); } /* Initialise any card-specific non-GL related state */ @@ -700,6 +714,13 @@ static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color, OUT_RING_CACHE(color[0]->offset); OUT_RING_CACHE(depth ? depth->offset : color[0]->offset); + /* Always set to bottom left of buffer */ + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X, 4); + OUT_RING_CACHEf (0.0); + OUT_RING_CACHEf ((GLfloat) h); + OUT_RING_CACHEf (0.0); + OUT_RING_CACHEf (0.0); + return GL_TRUE; } -- cgit v1.2.3 From 9131536f00cca586be7dfc1cfbc47188c78e4920 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 16 Feb 2007 19:54:55 +0100 Subject: nouveau: nv10: rescale depth near and far --- src/mesa/drivers/dri/nouveau/nv10_state.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index e64fcb12f5..803dd962b5 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -187,9 +187,15 @@ static void nv10DepthMask(GLcontext *ctx, GLboolean flag) static void nv10DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + GLfloat depth_scale = 16777216.0; + if (ctx->DrawBuffer->_DepthBuffer->DepthBits == 16) { + depth_scale = 32768.0; + } + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2); - OUT_RING_CACHEf(nearval); - OUT_RING_CACHEf(farval); + OUT_RING_CACHEf(nearval * depth_scale); + OUT_RING_CACHEf(farval * depth_scale); nv10ViewportScale(nmesa); } -- cgit v1.2.3 From f942dc5522682b70fb05df5b2d5d732bb65e6fe2 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 16 Feb 2007 20:26:57 +0100 Subject: nouveau: nv10: set clear value for 16 and 24 bits depth --- src/mesa/drivers/dri/nouveau/nv10_state.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 803dd962b5..cc0f5a7220 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -121,16 +121,27 @@ static void nv10ClearColor(GLcontext *ctx, const GLfloat color[4]) static void nv10ClearDepth(GLcontext *ctx, GLclampd d) { - /* FIXME: check if 16 or 24/32 bits depth buffer */ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - nmesa->clear_value=((nmesa->clear_value&0x000000FF)|(((uint32_t)(d*0xFFFFFF))<<8)); + + switch (ctx->DrawBuffer->_DepthBuffer->DepthBits) { + case 16: + nmesa->clear_value = (uint32_t)(d*0x7FFF); + break; + case 24: + nmesa->clear_value = ((nmesa->clear_value&0x000000FF) | + (((uint32_t)(d*0xFFFFFF))<<8)); + break; + } } static void nv10ClearStencil(GLcontext *ctx, GLint s) { - /* FIXME: not valid for 16 bits depth buffer (0 stencil bits) */ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - nmesa->clear_value=((nmesa->clear_value&0xFFFFFF00)|(s&0x000000FF)); + + if (ctx->DrawBuffer->_DepthBuffer->DepthBits == 24) { + nmesa->clear_value = ((nmesa->clear_value&0xFFFFFF00)| + (s&0x000000FF)); + } } static void nv10ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) -- cgit v1.2.3 From 66d8e55184ff8ebfdfef174336dbb5560c45e735 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 16 Feb 2007 22:03:31 +0100 Subject: nouveau: nv20: update --- src/mesa/drivers/dri/nouveau/nv20_state.c | 208 +++++++++++++++++++++++++----- 1 file changed, 176 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv20_state.c b/src/mesa/drivers/dri/nouveau/nv20_state.c index 8e38d6eba0..bcca69daf0 100644 --- a/src/mesa/drivers/dri/nouveau/nv20_state.c +++ b/src/mesa/drivers/dri/nouveau/nv20_state.c @@ -41,8 +41,8 @@ static void nv20AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) CLAMPED_FLOAT_TO_UBYTE(ubRef, ref); BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC, 2); - OUT_RING_CACHE(func); /* NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC */ - OUT_RING_CACHE(ubRef); /* NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF */ + OUT_RING_CACHE(func); + OUT_RING_CACHE(ubRef); } static void nv20BlendColor(GLcontext *ctx, const GLfloat color[4]) @@ -76,6 +76,11 @@ static void nv20BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfac OUT_RING_CACHE((dfactorA<<16) | dfactorRGB); } +static void nv20Clear(GLcontext *ctx, GLbitfield mask) +{ + /* TODO */ +} + static void nv20ClearColor(GLcontext *ctx, const GLfloat color[4]) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); @@ -297,7 +302,11 @@ static void nv20Enable(GLcontext *ctx, GLenum cap, GLboolean state) // case GL_POST_COLOR_MATRIX_COLOR_TABLE: // case GL_POST_CONVOLUTION_COLOR_TABLE: // case GL_RESCALE_NORMAL: -// case GL_SCISSOR_TEST: + case GL_SCISSOR_TEST: + /* No enable bit, nv20Scissor will adjust to max range */ + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); + break; // case GL_SEPARABLE_2D: case GL_STENCIL_TEST: // TODO BACK and FRONT ? @@ -511,9 +520,22 @@ static void nv20PolygonMode(GLcontext *ctx, GLenum face, GLenum mode) } /** Set the scale and units used to calculate depth values */ -void (*PolygonOffset)(GLcontext *ctx, GLfloat factor, GLfloat units); +static void nv20PolygonOffset(GLcontext *ctx, GLfloat factor, GLfloat units) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR, 2); + OUT_RING_CACHEf(factor); + OUT_RING_CACHEf(units); +} + /** Set the polygon stippling pattern */ -void (*PolygonStipple)(GLcontext *ctx, const GLubyte *mask ); +static void nv20PolygonStipple(GLcontext *ctx, const GLubyte *mask ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(0), 32); + OUT_RING_CACHEp(mask, 32); +} + /* Specifies the current buffer for reading */ void (*ReadBuffer)( GLcontext *ctx, GLenum buffer ); /** Set rasterization mode */ @@ -522,6 +544,22 @@ void (*RenderMode)(GLcontext *ctx, GLenum mode ); /** Define the scissor box */ static void nv20Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) { + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + /* There's no scissor enable bit, so adjust the scissor to cover the + * maximum draw buffer bounds + */ + if (!ctx->Scissor.Enabled) { + x = y = 0; + w = h = 4095; + } else { + x += nmesa->drawX; + y += nmesa->drawY; + } + + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SCISSOR_X2_X1, 2); + OUT_RING_CACHE(((x+w-1) << 16) | x); + OUT_RING_CACHE(((y+h-1) << 16) | y); } /** Select flat or smooth shading */ @@ -576,22 +614,98 @@ void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname, void (*TexParameter)(GLcontext *ctx, GLenum target, struct gl_texture_object *texObj, GLenum pname, const GLfloat *params); -void (*TextureMatrix)(GLcontext *ctx, GLuint unit, const GLmatrix *mat); -/** Set the viewport */ -static void nv20Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +static void nv20TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) { - /* TODO: Where do the VIEWPORT_XFRM_* regs come in? */ - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2); - OUT_RING_CACHE((w << 16) | x); - OUT_RING_CACHE((h << 16) | y); + /* TODO */ +} + +/* Update anything that depends on the window position/size */ +static void nv20WindowMoved(nouveauContextPtr nmesa) +{ + GLcontext *ctx = nmesa->glCtx; + GLfloat *v = nmesa->viewport.m; + GLuint w = ctx->Viewport.Width; + GLuint h = ctx->Viewport.Height; + GLuint x = ctx->Viewport.X + nmesa->drawX; + GLuint y = ctx->Viewport.Y + nmesa->drawY; + int i; + + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2); + OUT_RING_CACHE((w << 16) | x); + OUT_RING_CACHE((h << 16) | y); + + BEGIN_RING_SIZE(NvSub3D, 0x02b4, 1); + OUT_RING(0); + + BEGIN_RING_CACHE(NvSub3D, + NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 2); + OUT_RING_CACHE((4095 << 16) | 0); + OUT_RING_CACHE((4095 << 16) | 0); + for (i=1; i<8; i++) { + BEGIN_RING_CACHE(NvSub3D, + NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 1); + OUT_RING_CACHE(0); + BEGIN_RING_CACHE(NvSub3D, + NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(i), 1); + OUT_RING_CACHE(0); + } + + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); + + /* TODO: recalc viewport scale coefs */ } /* Initialise any card-specific non-GL related state */ static GLboolean nv20InitCard(nouveauContextPtr nmesa) { - return GL_TRUE; + nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); + + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SET_OBJECT1, 2); + OUT_RING(NvDmaFB); /* 184 dma_object1 */ + OUT_RING(NvDmaFB); /* 188 dma_object2 */ + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SET_OBJECT3, 2); + OUT_RING(NvDmaFB); /* 194 dma_object3 */ + OUT_RING(NvDmaFB); /* 198 dma_object4 */ + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SET_OBJECT8, 1); + OUT_RING(NvDmaFB); /* 1a8 dma_object8 */ + + BEGIN_RING_SIZE(NvSub3D, 0x17e0, 3); + OUT_RINGf(0.0); + OUT_RINGf(0.0); + OUT_RINGf(1.0); + + BEGIN_RING_SIZE(NvSub3D, 0x1e6c, 1); + OUT_RING(0x0db6); + BEGIN_RING_SIZE(NvSub3D, 0x0290, 1); + OUT_RING(0x00100001); + BEGIN_RING_SIZE(NvSub3D, 0x09fc, 1); + OUT_RING(0); + BEGIN_RING_SIZE(NvSub3D, 0x1d80, 1); + OUT_RING(1); + BEGIN_RING_SIZE(NvSub3D, 0x09f8, 1); + OUT_RING(4); + + BEGIN_RING_SIZE(NvSub3D, 0x17ec, 3); + OUT_RINGf(0.0); + OUT_RINGf(1.0); + OUT_RINGf(0.0); + + BEGIN_RING_SIZE(NvSub3D, 0x1d88, 1); + OUT_RING(3); + + /* FIXME: More dma objects to setup ? */ + + BEGIN_RING_SIZE(NvSub3D, 0x1e98, 1); + OUT_RING(0); + + BEGIN_RING_SIZE(NvSub3D, 0x120, 3); + OUT_RING(0); + OUT_RING(1); + OUT_RING(2); + + return GL_TRUE; } /* Update buffer offset/pitch/format */ @@ -599,26 +713,57 @@ static GLboolean nv20BindBuffers(nouveauContextPtr nmesa, int num_color, nouveau_renderbuffer **color, nouveau_renderbuffer *depth) { - return GL_TRUE; -} + GLuint x, y, w, h; + GLuint pitch, format, depth_pitch; + + w = color[0]->mesa.Width; + h = color[0]->mesa.Height; + x = nmesa->drawX; + y = nmesa->drawY; + + if (num_color != 1) + return GL_FALSE; + + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 6); + OUT_RING_CACHE((w << 16) | x); + OUT_RING_CACHE((h << 16) | y); + depth_pitch = (depth ? depth->pitch : color[0]->pitch); + pitch = (depth_pitch<<16) | color[0]->pitch; + format = 0x128; + if (color[0]->mesa._ActualFormat != GL_RGBA8) { + format = 0x123; /* R5G6B5 color buffer */ + } + OUT_RING_CACHE(format); + OUT_RING_CACHE(pitch); + OUT_RING_CACHE(color[0]->offset); + OUT_RING_CACHE(depth ? depth->offset : color[0]->offset); + + if (depth) { + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH, 2); + /* TODO: use a different buffer */ + OUT_RING(depth->pitch); + OUT_RING(depth->offset); + } -/* Update anything that depends on the window position/size */ -static void nv20WindowMoved(nouveauContextPtr nmesa) -{ + /* Always set to bottom left of buffer */ + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X, 4); + OUT_RING_CACHEf (0.0); + OUT_RING_CACHEf ((GLfloat) h); + OUT_RING_CACHEf (0.0); + OUT_RING_CACHEf (0.0); + + return GL_TRUE; } void nv20InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - nmesa->hw_func.InitCard = nv20InitCard; - nmesa->hw_func.BindBuffers = nv20BindBuffers; - nmesa->hw_func.WindowMoved = nv20WindowMoved; - func->AlphaFunc = nv20AlphaFunc; func->BlendColor = nv20BlendColor; func->BlendEquationSeparate = nv20BlendEquationSeparate; func->BlendFuncSeparate = nv20BlendFuncSeparate; + func->Clear = nv20Clear; func->ClearColor = nv20ClearColor; func->ClearDepth = nv20ClearDepth; func->ClearStencil = nv20ClearStencil; @@ -641,22 +786,21 @@ void nv20InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) func->PointParameterfv = nv20PointParameterfv; func->PointSize = nv20PointSize; func->PolygonMode = nv20PolygonMode; -#if 0 func->PolygonOffset = nv20PolygonOffset; func->PolygonStipple = nv20PolygonStipple; - func->ReadBuffer = nv20ReadBuffer; - func->RenderMode = nv20RenderMode; -#endif +/* func->ReadBuffer = nv20ReadBuffer;*/ +/* func->RenderMode = nv20RenderMode;*/ func->Scissor = nv20Scissor; func->ShadeModel = nv20ShadeModel; func->StencilFuncSeparate = nv20StencilFuncSeparate; func->StencilMaskSeparate = nv20StencilMaskSeparate; func->StencilOpSeparate = nv20StencilOpSeparate; -#if 0 - func->TexGen = nv20TexGen; - func->TexParameter = nv20TexParameter; +/* func->TexGen = nv20TexGen;*/ +/* func->TexParameter = nv20TexParameter;*/ func->TextureMatrix = nv20TextureMatrix; -#endif - func->Viewport = nv20Viewport; + + nmesa->hw_func.InitCard = nv20InitCard; + nmesa->hw_func.BindBuffers = nv20BindBuffers; + nmesa->hw_func.WindowMoved = nv20WindowMoved; } -- cgit v1.2.3 From 0fccb646e0c83f6bb4c8b453cc2e915e8cee21f1 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 16 Feb 2007 22:09:42 +0100 Subject: nouveau: nv20: texture matrix --- src/mesa/drivers/dri/nouveau/nv20_state.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv20_state.c b/src/mesa/drivers/dri/nouveau/nv20_state.c index bcca69daf0..417590d729 100644 --- a/src/mesa/drivers/dri/nouveau/nv20_state.c +++ b/src/mesa/drivers/dri/nouveau/nv20_state.c @@ -617,7 +617,10 @@ void (*TexParameter)(GLcontext *ctx, GLenum target, static void nv20TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) { - /* TODO */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16); + /*XXX: This SHOULD work.*/ + OUT_RING_CACHEp(mat->m, 16); } /* Update anything that depends on the window position/size */ -- cgit v1.2.3 From 4cc4a753fa3c41e5ef1890a9a03c97d3c39b6535 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 16 Feb 2007 22:39:12 +0100 Subject: nouveau: nv10,20: wrong viewport clip setup --- src/mesa/drivers/dri/nouveau/nv10_state.c | 4 +++- src/mesa/drivers/dri/nouveau/nv20_state.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index cc0f5a7220..e0475bb3da 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -658,8 +658,10 @@ static void nv10WindowMoved(nouveauContextPtr nmesa) OUT_RING(0); BEGIN_RING_CACHE(NvSub3D, - NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 2); + NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 1); OUT_RING_CACHE(((w+x-1) << 16) | x | 0x08000800); + BEGIN_RING_CACHE(NvSub3D, + NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(0), 1); OUT_RING_CACHE(((h+y-1) << 16) | y | 0x08000800); for (i=1; i<8; i++) { BEGIN_RING_CACHE(NvSub3D, diff --git a/src/mesa/drivers/dri/nouveau/nv20_state.c b/src/mesa/drivers/dri/nouveau/nv20_state.c index 417590d729..030713c0db 100644 --- a/src/mesa/drivers/dri/nouveau/nv20_state.c +++ b/src/mesa/drivers/dri/nouveau/nv20_state.c @@ -642,8 +642,10 @@ static void nv20WindowMoved(nouveauContextPtr nmesa) OUT_RING(0); BEGIN_RING_CACHE(NvSub3D, - NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 2); + NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 1); OUT_RING_CACHE((4095 << 16) | 0); + BEGIN_RING_CACHE(NvSub3D, + NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(0), 1); OUT_RING_CACHE((4095 << 16) | 0); for (i=1; i<8; i++) { BEGIN_RING_CACHE(NvSub3D, -- cgit v1.2.3 From 21f2f7f26b5b9ab9f219f2bd22c68bcaa8cbdfe3 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 16 Feb 2007 22:39:28 +0100 Subject: nouveau: nv50: update --- src/mesa/drivers/dri/nouveau/nv50_state.c | 76 ++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv50_state.c b/src/mesa/drivers/dri/nouveau/nv50_state.c index d03c6bf6f2..818e268615 100644 --- a/src/mesa/drivers/dri/nouveau/nv50_state.c +++ b/src/mesa/drivers/dri/nouveau/nv50_state.c @@ -293,7 +293,11 @@ static void nv50Enable(GLcontext *ctx, GLenum cap, GLboolean state) // case GL_POST_COLOR_MATRIX_COLOR_TABLE: // case GL_POST_CONVOLUTION_COLOR_TABLE: // case GL_RESCALE_NORMAL: -// case GL_SCISSOR_TEST: + case GL_SCISSOR_TEST: + /* No enable bit, nv50Scissor will adjust to max range */ + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); + break; // case GL_SEPARABLE_2D: case GL_STENCIL_TEST: // TODO BACK and FRONT ? @@ -416,6 +420,21 @@ void (*RenderMode)(GLcontext *ctx, GLenum mode ); static void nv50Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + /* There's no scissor enable bit, so adjust the scissor to cover the + * maximum draw buffer bounds + */ + if (!ctx->Scissor.Enabled) { + x = y = 0; + w = h = 8191; + } else { + x += nmesa->drawX; + y += nmesa->drawY; + } + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS, 2); + OUT_RING_CACHE(((w) << 16) | x); + OUT_RING_CACHE(((h) << 16) | y); } /** Select flat or smooth shading */ @@ -503,10 +522,65 @@ static void nv50TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) static void nv50WindowMoved(nouveauContextPtr nmesa) { + GLcontext *ctx = nmesa->glCtx; + GLfloat *v = nmesa->viewport.m; + GLuint w = ctx->Viewport.Width; + GLuint h = ctx->Viewport.Height; + GLuint x = ctx->Viewport.X + nmesa->drawX; + GLuint y = ctx->Viewport.Y + nmesa->drawY; + int i; + + BEGIN_RING_CACHE(NvSub3D, + NV50_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 2); + OUT_RING_CACHE((8191 << 16) | 0); + OUT_RING_CACHE((8191 << 16) | 0); + for (i=1; i<8; i++) { + BEGIN_RING_CACHE(NvSub3D, + NV50_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 2); + OUT_RING_CACHE(0); + OUT_RING_CACHE(0); + } + + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); } static GLboolean nv50InitCard(nouveauContextPtr nmesa) { + int i,j; + + nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); + + BEGIN_RING_SIZE(NvSub3D, 0x1558, 1); + OUT_RING(1); + + BEGIN_RING_SIZE(NvSub3D, NV50_TCL_PRIMITIVE_3D_SET_OBJECT_1(0), 8); + for (i=0; i<8; i++) { + OUT_RING(NvDmaFB); + } + + BEGIN_RING_SIZE(NvSub3D, NV50_TCL_PRIMITIVE_3D_SET_OBJECT_0(0), 12); + for (i=0; i<12; i++) { + OUT_RING(NvDmaFB); + } + + BEGIN_RING_SIZE(NvSub3D, 0x121c, 1); + OUT_RING(1); + + for (i=0; i<8; i++) { + BEGIN_RING_SIZE(NvSub3D, 0x0200 + (i*0x20), 5); + for (j=0; j<5; j++) { + OUT_RING(0); + } + } + + BEGIN_RING_SIZE(NvSub3D, 0x0fe0, 5); + OUT_RING(0); + OUT_RING(0); + OUT_RING(0x16); + OUT_RING(0); + OUT_RING(0); + return GL_FALSE; } -- cgit v1.2.3 From 7ae8f388cf81c187f0cbfcc4997c93b28cf6c26a Mon Sep 17 00:00:00 2001 From: Sean D'Epagnier Date: Fri, 16 Feb 2007 17:44:13 -0700 Subject: Commiting a few minor fixes to glut fbdev (segfault on a separate stack) Updated all drivers that used the old _ac_ functions to use the new _vbo_ functions. I know this fixed the fbdev driver, it looks like it might fix some other drivers too. --- src/glut/fbdev/fbdev.c | 17 +- src/glut/fbdev/glut_fbdev.c | 2199 -------------------- src/mesa/drivers/beos/GLView.cpp | 6 +- src/mesa/drivers/directfb/idirectfbgl_mesa.c | 4 +- src/mesa/drivers/fbdev/glfbdev.c | 6 +- src/mesa/drivers/ggi/ggimesa.c | 4 +- src/mesa/drivers/glide/fxdd.c | 6 +- src/mesa/drivers/windows/gdi/mesa.def | 6 +- src/mesa/drivers/windows/gdi/wmesa.c | 8 +- src/mesa/drivers/windows/gldirect/dglcontext.c | 2 +- .../drivers/windows/gldirect/dx7/gld_driver_dx7.c | 4 +- .../drivers/windows/gldirect/dx7/gld_ext_dx7.c | 2 +- .../windows/gldirect/dx7/gld_primitive_dx7.c | 2 +- .../drivers/windows/gldirect/dx8/gld_driver_dx8.c | 4 +- .../drivers/windows/gldirect/dx8/gld_ext_dx8.c | 2 +- .../windows/gldirect/dx8/gld_primitive_dx8.c | 2 +- .../drivers/windows/gldirect/dx9/gld_driver_dx9.c | 4 +- .../drivers/windows/gldirect/dx9/gld_ext_dx9.c | 2 +- .../windows/gldirect/dx9/gld_primitive_dx9.c | 2 +- .../windows/gldirect/mesasw/gld_wgl_mesasw.c | 6 +- src/mesa/drivers/windows/icd/mesa.def | 6 +- 21 files changed, 55 insertions(+), 2239 deletions(-) delete mode 100644 src/glut/fbdev/glut_fbdev.c (limited to 'src') diff --git a/src/glut/fbdev/fbdev.c b/src/glut/fbdev/fbdev.c index 3b63cd70ea..80237f5bc7 100644 --- a/src/glut/fbdev/fbdev.c +++ b/src/glut/fbdev/fbdev.c @@ -173,6 +173,9 @@ void glutInit (int *argcp, char **argv) int RequiredWidth = 0, RequiredHeight; char *fbdev; + stack_t stack; + struct sigaction sa; + /* parse out args */ for (i = 1; i < *argcp;) { if (!strcmp(argv[i], "-geometry")) { @@ -239,7 +242,19 @@ void glutInit (int *argcp, char **argv) gettimeofday(&StartTime, 0); atexit(Cleanup); - signal(SIGSEGV, CrashHandler); + /* set up SIGSEGV to use alternate stack */ + stack.ss_flags = 0; + stack.ss_size = SIGSTKSZ; + if(!(stack.ss_sp = malloc(SIGSTKSZ))) + sprintf(exiterror, "Failed to allocate alternate stack for SIGSEGV!\n"); + + sigaltstack(&stack, NULL); + + sa.sa_handler = CrashHandler; + sa.sa_flags = SA_ONSTACK; + sigemptyset(&sa.sa_mask); + sigaction(SIGSEGV, &sa, NULL); + signal(SIGINT, CrashHandler); signal(SIGTERM, CrashHandler); signal(SIGABRT, CrashHandler); diff --git a/src/glut/fbdev/glut_fbdev.c b/src/glut/fbdev/glut_fbdev.c deleted file mode 100644 index 3ed8fe90e3..0000000000 --- a/src/glut/fbdev/glut_fbdev.c +++ /dev/null @@ -1,2199 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * Copyright (C) 1995-2006 Brian Paul - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* - * Library for glut using mesa fbdev driver - * - * Written by Sean D'Epagnier (c) 2006 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include - -#include "../../mesa/main/config.h" - -#define MULTIHEAD /* enable multihead hacks, - it allows the program to continue drawing - without reading input when a second fbdev - has keyboard focus it can cause - screen corruption that requires C-l to fix */ - -#define FBMODES "/etc/fb.modes" - -#define HAVE_GPM - -#ifdef HAVE_GPM -#include -static int GpmMouse; -#endif - -#define MOUSEDEV "/dev/gpmdata" - -static int CurrentVT; -static int ConsoleFD = - 1; - -/* save settings to restore on exit */ -static int OldKDMode = -1; -static int OldMode; -struct vt_mode OldVTMode; -struct termios OldTermios; - -static struct fb_fix_screeninfo FixedInfo; -static struct fb_var_screeninfo VarInfo, OrigVarInfo; -struct fb_cmap ColorMap; - -static int DesiredDepth = 0; - -static int FrameBufferFD = -1; -static caddr_t FrameBuffer = (caddr_t) -1; -static caddr_t BackBuffer = NULL; -static int DisplayMode; - -static int AccumSize = 16; /* per channel size of accumulation buffer */ -static int DepthSize = DEFAULT_SOFTWARE_DEPTH_BITS; -static int StencilSize = STENCIL_BITS; - -#define MENU_FONT_WIDTH 9 -#define MENU_FONT_HEIGHT 15 -#define MENU_FONT GLUT_BITMAP_9_BY_15 -#define SUBMENU_OFFSET 20 - -static int AttachedMenus[3]; -static int ActiveMenu; -static int SelectedMenu; -static int CurrentMenu; -static int NumMenus = 1; - -static struct { - int NumItems; - int x, y; - int width; - int selected; - struct { - int value; - int submenu; - char *name; - } *Items; - void (*func)(int); -} *Menus = NULL; - -struct GlutTimer { - int time; - void (*func)(int); - int value; - struct GlutTimer *next; -}; - -struct GlutTimer *GlutTimers = NULL; - -static struct timeval StartTime; - -static int KeyboardModifiers; -static int KeyboardLedState; - -static int MouseFD; -static int NumMouseButtons; -static int MouseX; -static int MouseY; -static double MouseSpeed = 0; -static int CurrentCursor = GLUT_CURSOR_LEFT_ARROW; -/* only display the mouse if there is a registered callback for it */ -static int MouseEnabled = 0; - -/* per window data */ -static GLFBDevContextPtr Context; -static GLFBDevBufferPtr Buffer; -static GLFBDevVisualPtr Visual; -static void (*DisplayFunc)(void) = NULL; -static void (*ReshapeFunc)(int width, int height) = NULL; -static void (*KeyboardFunc)(unsigned char key, int x, int y) = NULL; -static void (*MouseFunc)(int key, int state, int x, int y) = NULL; -static void (*MotionFunc)(int x, int y) = NULL; -static void (*PassiveMotionFunc)(int x, int y) = NULL; -static void (*VisibilityFunc)(int state) = NULL; -static void (*SpecialFunc)(int key, int x, int y) = NULL; -static void (*IdleFunc)(void) = NULL; -static void (*MenuStatusFunc)(int state, int x, int y) = NULL; -static void (*MenuStateFunc)(int state) = NULL; - -static int Redisplay; -static int Visible; -static int VisibleSwitch; -static int Active; -/* we have to poll to see if we are visible - on a framebuffer that is not active */ -static int VisiblePoll; -static int FramebufferIndex; - -static int RequiredWidth; -static int RequiredHeight; -static int InitialWidthHint; -static int InitialHeightHint; - -static char exiterror[256]; - -/* --------- Initialization ------------*/ -/* test if the active console is attached to the same framebuffer */ -static void TestVisible(void) { - struct fb_con2fbmap confb; - struct vt_stat st; - int ret; - ioctl(ConsoleFD, VT_GETSTATE, &st); - confb.console = st.v_active; - - ret = ioctl(FrameBufferFD, FBIOGET_CON2FBMAP, &confb); - - if(ret == -1 || confb.framebuffer == FramebufferIndex) { - VisibleSwitch = 1; - Visible = 0; - VisiblePoll = 0; - } -} - -static void VTSwitchHandler(int sig) -{ - struct vt_stat st; - switch(sig) { - case SIGUSR1: - ioctl(ConsoleFD, VT_RELDISP, 1); - Active = 0; -#ifdef MULTIHEAD - VisiblePoll = 1; - TestVisible(); -#else - VisibleSwitch = 1; - Visible = 0; -#endif - break; - case SIGUSR2: - ioctl(ConsoleFD, VT_GETSTATE, &st); - if(st.v_active) - ioctl(ConsoleFD, VT_RELDISP, VT_ACKACQ); - - /* this is a hack to turn the cursor off */ - ioctl(FrameBufferFD, FBIOPUT_VSCREENINFO, &VarInfo); - - /* restore color map */ - if(DisplayMode & GLUT_INDEX) { - ColorMap.start = 0; - ColorMap.len = 256; - - if (ioctl(FrameBufferFD, FBIOPUTCMAP, (void *) &ColorMap) < 0) - fprintf(stderr, "ioctl(FBIOPUTCMAP) failed!\n"); - } - - Active = 1; - Visible = 1; - VisibleSwitch = 1; - - Redisplay = 1; - - break; - } -} - -static void Cleanup(void) -{ - if(ConsoleFD >= 0) - if (tcsetattr(0, TCSANOW, &OldTermios) < 0) - fprintf(stderr, "tcsetattr failed\n"); - - if(ConsoleFD > 0) { - /* restore keyboard state */ - if (ioctl(ConsoleFD, VT_SETMODE, &OldVTMode) < 0) - fprintf(stderr, "Failed to set vtmode\n"); - - if (ioctl(ConsoleFD, KDSKBMODE, OldKDMode) < 0) - fprintf(stderr, "ioctl KDSKBMODE failed!\n"); - - if(ioctl(ConsoleFD, KDSETMODE, OldMode) < 0) - fprintf(stderr, "ioctl KDSETMODE failed!\n"); - - close(ConsoleFD); - } - - /* close mouse */ -#ifdef HAVE_GPM - if(GpmMouse) { - if(NumMouseButtons) - Gpm_Close(); - } else -#endif - if(MouseFD >= 0) - close(MouseFD); - - glFBDevMakeCurrent( NULL, NULL, NULL); - - glFBDevDestroyContext(Context); - glFBDevDestroyBuffer(Buffer); - glFBDevDestroyVisual(Visual); - - struct vt_mode VT; - - /* restore original variable screen info */ - if(FrameBufferFD != -1) { - if (ioctl(FrameBufferFD, FBIOPUT_VSCREENINFO, &OrigVarInfo)) - fprintf(stderr, "ioctl(FBIOPUT_VSCREENINFO failed): %s\n", - strerror(errno)); - - munmap(FrameBuffer, FixedInfo.smem_len); - close(FrameBufferFD); - } - - /* free allocated back buffer */ - if(DisplayMode & GLUT_DOUBLE) - free(BackBuffer); - - /* free menu items */ - int i, j; - - for(i = 1; i= *argcp - 1) { \ - fprintf(stderr, PARAM" requires a parameter\n"); \ - exit(0); \ - } - -void glutInit (int *argcp, char **argv) -{ - int i; - int nomouse = 0; - int nokeyboard = 0; - int usestdin = 0; - - /* parse out args */ - for (i = 1; i < *argcp;) { - if (!strcmp(argv[i], "-geometry")) { - REQPARAM("geometry"); - if(sscanf(argv[i+1], "%dx%d", &RequiredWidth, - &RequiredHeight) != 2) { - fprintf(stderr,"Please specify geometry as widthxheight\n"); - exit(0); - } - removeArgs(argcp, &argv[i], 2); - } else - if (!strcmp(argv[i], "-bpp")) { - REQPARAM("bpp"); - if(sscanf(argv[i+1], "%d", &DesiredDepth) != 1) { - fprintf(stderr, "Please specify a parameter for bpp\n"); - exit(0); - } - - removeArgs(argcp, &argv[i], 2); - } else - if (!strcmp(argv[i], "-vt")) { - REQPARAM("vt"); - if(sscanf(argv[i+1], "%d", &CurrentVT) != 1) { - fprintf(stderr, "Please specify a parameter for vt\n"); - exit(0); - } - removeArgs(argcp, &argv[i], 2); - } else - if (!strcmp(argv[i], "-mousespeed")) { - REQPARAM("mousespeed"); - if(sscanf(argv[i+1], "%lf", &MouseSpeed) != 1) { - fprintf(stderr, "Please specify a mouse speed, eg: 2.5\n"); - exit(0); - } - removeArgs(argcp, &argv[i], 2); - } else - if (!strcmp(argv[i], "-nomouse")) { - nomouse = 1; - removeArgs(argcp, &argv[i], 1); - } else - if (!strcmp(argv[i], "-nokeyboard")) { - nokeyboard = 1; - removeArgs(argcp, &argv[i], 1); - } else - if (!strcmp(argv[i], "-stdin")) { - usestdin = 1; - removeArgs(argcp, &argv[i], 1); - } else - if (!strcmp(argv[i], "-gpmmouse")) { -#ifdef HAVE_GPM - GpmMouse = 1; -#else - fprintf(stderr, "gpm support was not compiled\n"); - exit(0); -#endif - removeArgs(argcp, &argv[i], 1); - } else - if (!strcmp(argv[i], "--")) { - removeArgs(argcp, &argv[i], 1); - break; - } else - i++; - } - - gettimeofday(&StartTime, 0); - atexit(Cleanup); - - signal(SIGSEGV, CrashHandler); - signal(SIGINT, CrashHandler); - signal(SIGTERM, CrashHandler); - - if(nomouse == 0) - InitializeMouse(); - if(nokeyboard == 0) - InitializeVT(usestdin); -} - -void glutInitDisplayMode (unsigned int mode) -{ - DisplayMode = mode; -} - -void glutInitWindowPosition (int x, int y) -{ -} - -void glutInitWindowSize (int width, int height) -{ - InitialWidthHint = width; - InitialHeightHint = height; -} - -/* --------- Mouse Rendering ------------*/ -#include "cursors.h" -static int LastMouseX; -static int LastMouseY; -static unsigned char *MouseBuffer; - -static void EraseCursor(void) -{ - int off = LastMouseY * FixedInfo.line_length - + LastMouseX * VarInfo.bits_per_pixel / 8; - int stride = CURSOR_WIDTH * VarInfo.bits_per_pixel / 8; - int i; - - unsigned char *src = MouseBuffer; - - for(i = 0; i (int)VarInfo.xres - CURSOR_WIDTH) - LastMouseX = VarInfo.xres - CURSOR_WIDTH; - else - LastMouseX = x; - - if(y < 0) - LastMouseY = 0; - else - if(y > (int)VarInfo.yres - CURSOR_HEIGHT) - LastMouseY = VarInfo.yres - CURSOR_HEIGHT; - else - LastMouseY = y; - - int off = LastMouseY * FixedInfo.line_length - + LastMouseX * VarInfo.bits_per_pixel / 8; - int stride = CURSOR_WIDTH * VarInfo.bits_per_pixel / 8; - int i; - unsigned char *src = MouseBuffer; - for(i = 0; i= NUM_CURSORS) - return; - - int px = MouseX - CursorsXOffset[CurrentCursor]; - int py = MouseY - CursorsYOffset[CurrentCursor]; - - SaveCursor(px, py); - - int xoff = 0; - if(px < 0) - xoff = -px; - - int xlen = CURSOR_WIDTH; - if(px + CURSOR_WIDTH > VarInfo.xres) - xlen = VarInfo.xres - px; - - int yoff = 0; - if(py < 0) - yoff = -py; - - int ylen = CURSOR_HEIGHT; - if(py + CURSOR_HEIGHT > VarInfo.yres) - ylen = VarInfo.yres - py; - - int bypp = VarInfo.bits_per_pixel / 8; - - unsigned char *c = BackBuffer + FixedInfo.line_length * (py + yoff) - + (px + xoff) * bypp; - - unsigned char *d = Cursors[CurrentCursor] + (CURSOR_WIDTH * yoff + xoff)*4; - int i, j; - - int dstride = (CURSOR_WIDTH - xlen + xoff) * 4; - int cstride = FixedInfo.line_length - bypp * (xlen - xoff); - - switch(bypp) { - case 1: /* no support for 8bpp mouse yet */ - break; - case 2: - { - uint16_t *e = (void*)c; - cstride /= 2; - for(i = yoff; i < ylen; i++) { - for(j = xoff; j < xlen; j++) { - e[0] = ((((d[0] + (((int)(((e[0] >> 8) & 0xf8) - | ((c[0] >> 11) & 0x7)) * d[3]) >> 8)) & 0xf8) << 8) - | (((d[1] + (((int)(((e[0] >> 3) & 0xfc) - | ((e[0] >> 5) & 0x3)) * d[3]) >> 8)) & 0xfc) << 3) - | ((d[2] + (((int)(((e[0] << 3) & 0xf8) - | (e[0] & 0x7)) * d[3]) >> 8)) >> 3)); - - e++; - d+=4; - } - d += dstride; - e += cstride; - } - } - break; - case 3: - case 4: - for(i = yoff; i < ylen; i++) { - for(j = xoff; j < xlen; j++) { - c[0] = d[0] + (((int)c[0] * d[3]) >> 8); - c[1] = d[1] + (((int)c[1] * d[3]) >> 8); - c[2] = d[2] + (((int)c[2] * d[3]) >> 8); - - c+=bypp; - d+=4; - } - d += dstride; - c += cstride; - } break; - } -} - -#define MIN(x, y) x < y ? x : y -static void SwapCursor(void) -{ - int px = MouseX - CursorsXOffset[CurrentCursor]; - int py = MouseY - CursorsYOffset[CurrentCursor]; - - int minx = MIN(px, LastMouseX); - int sizex = abs(px - LastMouseX); - - int miny = MIN(py, LastMouseY); - int sizey = abs(py - LastMouseY); - - DrawCursor(); - /* now update the portion of the screen that has changed */ - - if(DisplayMode & GLUT_DOUBLE && (sizex || sizey)) { - if(minx < 0) - minx = 0; - if(miny < 0) - miny = 0; - - if(minx + sizex > VarInfo.xres) - sizex = VarInfo.xres - minx; - if(miny + sizey > VarInfo.yres) - sizey = VarInfo.yres - miny; - int off = FixedInfo.line_length * miny - + minx * VarInfo.bits_per_pixel / 8; - int stride = (sizex + CURSOR_WIDTH) * VarInfo.bits_per_pixel / 8; - int i; - for(i = 0; i< sizey + CURSOR_HEIGHT; i++) { - memcpy(FrameBuffer+off, BackBuffer+off, stride); - off += FixedInfo.line_length; - } - } -} - -/* --------- Menu Rendering ------------*/ -static double MenuProjection[16]; -static double MenuModelview[16]; - -static void InitMenuMatrices(void) -{ - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluOrtho2D(0.0,VarInfo.xres,VarInfo.yres,0.0); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glViewport(0,0,VarInfo.xres,VarInfo.yres); - glGetDoublev(GL_PROJECTION_MATRIX, MenuProjection); - glGetDoublev(GL_MODELVIEW_MATRIX, MenuModelview); -} - -static int DrawMenu(int menu, int x, int *y) -{ - int i; - int ret = 1; - for(i=0; i < Menus[menu].NumItems; i++) { - char *s = Menus[menu].Items[i].name; - int a =0; - if(MouseY >= *y && MouseY < *y + MENU_FONT_HEIGHT && - MouseX >= x && MouseX < x + Menus[menu].width) { - a = 1; - SelectedMenu = menu; - ret = 0; - Menus[menu].selected = i; - glColor3f(1,0,0); - } else - glColor3f(0,0,1); - - *y += MENU_FONT_HEIGHT; - glRasterPos2i(x, *y); - for(; *s; s++) - glutBitmapCharacter(MENU_FONT, *s); - - if(Menus[menu].selected == i) - if(Menus[menu].Items[i].submenu) - if(DrawMenu(Menus[menu].Items[i].submenu, x - + SUBMENU_OFFSET, y)) { - if(!a) - Menus[menu].selected = -1; - } else - ret = 0; - } - return ret; -} - -static void DrawMenus(void) -{ - /* save old settings */ - glPushAttrib(-1); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadMatrixd(MenuModelview); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadMatrixd(MenuProjection); - - glDisable(GL_DEPTH_TEST); - glDisable(GL_ALPHA_TEST); - glDisable(GL_LIGHTING); - glDisable(GL_FOG); - glDisable(GL_TEXTURE_2D); - // glEnable(GL_LOGIC_OP); - //glEnable(GL_COLOR_LOGIC_OP); - // glLogicOp(GL_XOR); - - int x = Menus[ActiveMenu].x; - int y = Menus[ActiveMenu].y; - - if(DrawMenu(ActiveMenu, x, &y)) - Menus[ActiveMenu].selected = -1; - - /* restore settings */ - - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - - glPopAttrib(); -} - -/* --------- Event Processing ------------*/ -#define MODIFIER(mod) \ - KeyboardModifiers = release ? KeyboardModifiers & ~mod \ - : KeyboardModifiers | mod; - -#define READKEY read(ConsoleFD, &code, 1) - -static void LedModifier(int led, int release) -{ - static int releaseflag = K_CAPS | K_NUM; - if(release) - releaseflag |= led; - else - if(releaseflag & led) { - KeyboardLedState ^= led; - releaseflag &= ~led; - } - ioctl(ConsoleFD, KDSKBLED, KeyboardLedState); - ioctl(ConsoleFD, KDSETLED, 0x80); -} - -static int ReadKey(void) -{ - int x; - unsigned char code; - int specialkey = 0; - if(READKEY == 0) - return 0; - - if(code == 0) - return 0; - - /* stdin input escape code based */ - if(ConsoleFD == 0) { - KeyboardModifiers = 0; - altset: - if(code == 27 && READKEY == 1) { - switch(code) { - case 79: /* function key */ - READKEY; - if(code == 50) { - READKEY; - shiftfunc: - KeyboardModifiers |= GLUT_ACTIVE_SHIFT; - specialkey = GLUT_KEY_F1 + code - 53; - READKEY; - } else { - READKEY; - specialkey = GLUT_KEY_F1 + code - 80; - } - break; - case 91: - READKEY; - switch(code) { - case 68: - specialkey = GLUT_KEY_LEFT; break; - case 65: - specialkey = GLUT_KEY_UP; break; - case 67: - specialkey = GLUT_KEY_RIGHT; break; - case 66: - specialkey = GLUT_KEY_DOWN; break; - case 53: - specialkey = GLUT_KEY_PAGE_UP; READKEY; break; - case 54: - specialkey = GLUT_KEY_PAGE_DOWN; READKEY; break; - case 49: - specialkey = GLUT_KEY_HOME; READKEY; break; - case 52: - specialkey = GLUT_KEY_END; READKEY; break; - case 50: - READKEY; - if(code != 126) - goto shiftfunc; - specialkey = GLUT_KEY_INSERT; - break; - case 51: - code = '\b'; goto stdkey; - case 91: - READKEY; - specialkey = GLUT_KEY_F1 + code - 65; - break; - default: - return 0; - } - break; - default: - KeyboardModifiers |= GLUT_ACTIVE_ALT; - goto altset; - } - } - stdkey: - if(specialkey) { - if(SpecialFunc) - SpecialFunc(specialkey, MouseX, MouseY); - } else { - if(code >= 1 && code <= 26) { - KeyboardModifiers |= GLUT_ACTIVE_CTRL; - code += 'a' - 1; - } - if((code >= 43 && code <= 34) || (code == 60) - || (code >= 62 && code <= 90) || (code == 94) - || (code == 95) || (code >= 123 && code <= 126)) - KeyboardModifiers |= GLUT_ACTIVE_SHIFT; - - if(KeyboardFunc) - KeyboardFunc(code, MouseX, MouseY); - } - return 1; - } - - /* linux kbd reading */ - struct kbentry entry; - entry.kb_table = 0; - if(KeyboardModifiers & GLUT_ACTIVE_SHIFT) - entry.kb_table |= K_SHIFTTAB; - - int release = code & 0x80; - code &= 0x7F; - - entry.kb_index = code; - - if (ioctl(ConsoleFD, KDGKBENT, &entry) < 0) { - sprintf(exiterror, "ioctl(KDGKBENT) failed.\n"); - exit(0); - } - - int labelval = entry.kb_value; - - switch(labelval) { - case K_SHIFT: - case K_SHIFTL: - MODIFIER(GLUT_ACTIVE_SHIFT); - return 0; - case K_CTRL: - MODIFIER(GLUT_ACTIVE_CTRL); - return 0; - case K_ALT: - case K_ALTGR: - MODIFIER(GLUT_ACTIVE_ALT); - return 0; - } - - if(!release && labelval >= K_F1 && labelval <= K_F12) - if(KeyboardModifiers & GLUT_ACTIVE_ALT) { - /* VT switch, we must do it */ - if(ioctl(ConsoleFD, VT_ACTIVATE, labelval - K_F1 + 1) < 0) - sprintf(exiterror, "Error switching console\n"); - return 0; - } - - switch(labelval) { - case K_CAPS: - LedModifier(LED_CAP, release); - return 0; - case K_NUM: - LedModifier(LED_NUM, release); - return 0; - case K_HOLD: /* scroll lock suspends glut */ - LedModifier(LED_SCR, release); - while(KeyboardLedState & LED_SCR) { - usleep(10000); - ReadKey(); - } - return 0; - } - - /* we could queue keypresses here */ - if(KeyboardLedState & LED_SCR) - return 0; - - if(release) - return 0; - - if(labelval >= K_F1 && labelval <= K_F12) - specialkey = GLUT_KEY_F1 + labelval - K_F1; - else - switch(labelval) { - case K_LEFT: - specialkey = GLUT_KEY_LEFT; break; - case K_UP: - specialkey = GLUT_KEY_UP; break; - case K_RIGHT: - specialkey = GLUT_KEY_RIGHT; break; - case K_DOWN: - specialkey = GLUT_KEY_DOWN; break; - case K_PGUP: - specialkey = GLUT_KEY_PAGE_UP; break; - case K_PGDN: - specialkey = GLUT_KEY_PAGE_DOWN; break; - case K_FIND: - specialkey = GLUT_KEY_HOME; break; - case K_SELECT: - specialkey = GLUT_KEY_END; break; - case K_INSERT: - specialkey = GLUT_KEY_INSERT; break; - case K_REMOVE: - labelval = '\b'; break; - case K_ENTER: - labelval = '\n'; break; - } - - if(specialkey) { - if(SpecialFunc) - SpecialFunc(specialkey, MouseX, MouseY); - } else - if(KeyboardFunc) { - char c = labelval; - if(KeyboardLedState & LED_CAP) { - if(c >= 'A' && c <= 'Z') - c += 'a' - 'A'; - else - if(c >= 'a' && c <= 'z') - c += 'A' - 'a'; - } - KeyboardFunc(c, MouseX, MouseY); - } - return 1; -} - -static void HandleMousePress(int button, int pressed) -{ - if(ActiveMenu && !pressed) { - if(MenuStatusFunc) - MenuStatusFunc(GLUT_MENU_NOT_IN_USE, MouseX, MouseY); - if(MenuStateFunc) - MenuStateFunc(GLUT_MENU_NOT_IN_USE); - if(SelectedMenu > 0) { - int selected = Menus[SelectedMenu].selected; - if(selected >= 0) - if(Menus[SelectedMenu].Items[selected].submenu == 0) - Menus[SelectedMenu].func(Menus[SelectedMenu].Items - [selected].value); - } - ActiveMenu = 0; - Redisplay = 1; - return; - } - - if(AttachedMenus[button] && pressed) { - ActiveMenu = AttachedMenus[button]; - if(MenuStatusFunc) - MenuStatusFunc(GLUT_MENU_IN_USE, MouseX, MouseY); - if(MenuStateFunc) - MenuStateFunc(GLUT_MENU_IN_USE); - Menus[ActiveMenu].x = MouseX - Menus[ActiveMenu].width/2; - Menus[ActiveMenu].y = MouseY - Menus[ActiveMenu].NumItems*MENU_FONT_HEIGHT/2; - Menus[ActiveMenu].selected = -1; - Redisplay = 1; - return; - } - - if(MouseFunc) - MouseFunc(button, pressed ? GLUT_DOWN : GLUT_UP, MouseX, MouseY); -} - -static int ReadMouse(void) -{ - int l, r, m; - static int ll, lm, lr; - signed char dx, dy; - -#ifdef HAVE_GPM - if(GpmMouse) { - Gpm_Event event; - struct pollfd pfd; - pfd.fd = gpm_fd; - pfd.events = POLLIN; - if(poll(&pfd, 1, 1) != 1) - return 0; - - if(Gpm_GetEvent(&event) != 1) - return 0; - - l = event.buttons & GPM_B_LEFT; - m = event.buttons & GPM_B_MIDDLE; - r = event.buttons & GPM_B_RIGHT; - - /* gpm is weird in that it gives a button number when the button - is released, with type set to GPM_UP, this is only a problem - if it is the last button released */ - - if(event.type & GPM_UP) - if(event.buttons == GPM_B_LEFT || event.buttons == GPM_B_MIDDLE || - event.buttons == GPM_B_RIGHT || event.buttons == GPM_B_FOURTH) - l = m = r = 0; - - dx = event.dx; - dy = event.dy; - } else -#endif - { - if(MouseFD == -1) - return 0; - - if(fcntl(MouseFD, F_SETFL, O_NONBLOCK) == -1) { - close(MouseFD); - MouseFD = -1; - return 0; - } - - char data[4]; - if(read(MouseFD, data, 4) != 4) - return 0; - - l = ((data[0] & 0x20) >> 3); - m = ((data[3] & 0x10) >> 3); - r = ((data[0] & 0x10) >> 4); - - dx = (((data[0] & 0x03) << 6) | (data[1] & 0x3F)); - dy = (((data[0] & 0x0C) << 4) | (data[2] & 0x3F)); - } - - MouseX += dx * MouseSpeed; - if(MouseX < 0) - MouseX = 0; - else - if(MouseX >= VarInfo.xres) - MouseX = VarInfo.xres - 1; - - MouseY += dy * MouseSpeed; - if(MouseY < 0) - MouseY = 0; - else - if(MouseY >= VarInfo.yres) - MouseY = VarInfo.yres - 1; - - if(l != ll) - HandleMousePress(GLUT_LEFT_BUTTON, l); - if(m != lm) - HandleMousePress(GLUT_MIDDLE_BUTTON, m); - if(r != lr) - HandleMousePress(GLUT_RIGHT_BUTTON, r); - - ll = l, lm = m, lr = r; - - if(dx || dy) { - if(l || m || r) { - if(MotionFunc) - MotionFunc(MouseX, MouseY); - } else - if(PassiveMotionFunc) - PassiveMotionFunc(MouseX, MouseY); - - EraseCursor(); - if(ActiveMenu) - Redisplay = 1; - else - SwapCursor(); - } - - return 1; -} - -static void RecieveEvents(void) -{ - while(ReadKey()); - - if(MouseEnabled) - while(ReadMouse()); -} - -static void ProcessTimers(void) -{ - if(GlutTimers && GlutTimers->time < glutGet(GLUT_ELAPSED_TIME)) { - struct GlutTimer *timer = GlutTimers; - timer->func(timer->value); - GlutTimers = timer->next; - free(timer); - } -} - -void glutMainLoop(void) -{ - if(ReshapeFunc) - ReshapeFunc(VarInfo.xres, VarInfo.yres); - - if(!DisplayFunc) { - sprintf(exiterror, "Fatal Error: No Display Function registered\n"); - exit(0); - } - - for(;;) { - ProcessTimers(); - - if(Active) - RecieveEvents(); - else - if(VisiblePoll) - TestVisible(); - - if(IdleFunc) - IdleFunc(); - - if(VisibleSwitch) { - VisibleSwitch = 0; - if(VisibilityFunc) - VisibilityFunc(Visible ? GLUT_VISIBLE : GLUT_NOT_VISIBLE); - } - - if(Visible && Redisplay) { - Redisplay = 0; - if(MouseEnabled) - EraseCursor(); - DisplayFunc(); - if(!(DisplayMode & GLUT_DOUBLE)) { - if(ActiveMenu) - DrawMenus(); - if(MouseEnabled) - DrawCursor(); - } - } - } -} - -/* ---------- Window Management ----------*/ -static void ParseFBModes(void) -{ - char buf[1024]; - struct fb_var_screeninfo vi = VarInfo; - - FILE *fbmodes = fopen(FBMODES, "r"); - - if(!fbmodes) { - sprintf(exiterror, "Warning: could not open " - FBMODES" using current mode\n"); - return; - } - - if(InitialWidthHint == 0 && InitialHeightHint == 0 - && RequiredWidth == 0) - return; /* use current mode */ - - while(fgets(buf, sizeof buf, fbmodes)) { - char *c; - int v; - - if(!(c = strstr(buf, "geometry"))) - continue; - v = sscanf(c, "geometry %d %d %d %d %d", &vi.xres, &vi.yres, - &vi.xres_virtual, &vi.yres_virtual, &vi.bits_per_pixel); - if(v != 5) - continue; - - /* now we have to decide what is best */ - if(RequiredWidth) { - if(RequiredWidth != vi.xres || RequiredHeight != vi.yres) - continue; - } else { - if(VarInfo.xres < vi.xres && VarInfo.xres < InitialWidthHint) - v++; - if(VarInfo.xres > vi.xres && vi.xres > InitialWidthHint) - v++; - - if(VarInfo.yres < vi.yres && VarInfo.yres < InitialHeightHint) - v++; - if(VarInfo.yres > vi.yres && vi.yres > InitialHeightHint) - v++; - - if(v < 7) - continue; - } - - fgets(buf, sizeof buf, fbmodes); - if(!(c = strstr(buf, "timings"))) - continue; - - v = sscanf(c, "timings %d %d %d %d %d %d %d", &vi.pixclock, - &vi.left_margin, &vi.right_margin, &vi.upper_margin, - &vi.lower_margin, &vi.hsync_len, &vi.vsync_len); - if(v != 7) - continue; - - VarInfo = vi; /* finally found a better mode */ - if(RequiredWidth) { - fclose(fbmodes); - return; - } - } - - fclose(fbmodes); - - if(RequiredWidth) { - sprintf(exiterror, "No mode (%dx%d) found in "FBMODES"\n", - RequiredWidth, RequiredHeight); - exit(0); - } -} - -int glutCreateWindow (const char *title) -{ - if(ConsoleFD == -1) { - int argc = 0; - char *argv[] = {NULL}; - glutInit(&argc, argv); - } - - if(Context) - return 0; - - char *fbdev = getenv("FRAMEBUFFER"); - if(fbdev) { -#ifdef MULTIHEAD - if(!sscanf(fbdev, "/dev/fb%d", &FramebufferIndex)) - if(!sscanf(fbdev, "/dev/fb/%d", &FramebufferIndex)) - sprintf(exiterror, "Could not determine Framebuffer index!\n"); -#endif - } else { - static char fb[128]; - FramebufferIndex = 0; - struct fb_con2fbmap confb; - int fd = open("/dev/fb0", O_RDWR); - confb.console = CurrentVT; - if(ioctl(fd, FBIOGET_CON2FBMAP, &confb) != -1) - FramebufferIndex = confb.framebuffer; - sprintf(fb, "/dev/fb%d", FramebufferIndex); - fbdev = fb; - close(fd); - } - - /* open the framebuffer device */ - FrameBufferFD = open(fbdev, O_RDWR); - if (FrameBufferFD < 0) { - sprintf(exiterror, "Error opening %s: %s\n", fbdev, strerror(errno)); - exit(0); - } - - /* Get the fixed screen info */ - if (ioctl(FrameBufferFD, FBIOGET_FSCREENINFO, &FixedInfo)) { - sprintf(exiterror, "error: ioctl(FBIOGET_FSCREENINFO) failed: %s\n", - strerror(errno)); - exit(0); - } - - /* get the variable screen info */ - if (ioctl(FrameBufferFD, FBIOGET_VSCREENINFO, &OrigVarInfo)) { - sprintf(exiterror, "error: ioctl(FBIOGET_VSCREENINFO) failed: %s\n", - strerror(errno)); - exit(0); - } - - /* operate on a copy */ - VarInfo = OrigVarInfo; - - /* set the depth, resolution, etc */ - ParseFBModes(); - - if(DisplayMode & GLUT_INDEX) - VarInfo.bits_per_pixel = 8; - else - if(VarInfo.bits_per_pixel == 8) - VarInfo.bits_per_pixel = 32; - - if (DesiredDepth) - VarInfo.bits_per_pixel = DesiredDepth; - - VarInfo.xoffset = 0; - VarInfo.yoffset = 0; - VarInfo.nonstd = 0; - VarInfo.vmode &= ~FB_VMODE_YWRAP; /* turn off scrolling */ - - /* set new variable screen info */ - if (ioctl(FrameBufferFD, FBIOPUT_VSCREENINFO, &VarInfo)) { - sprintf(exiterror, "ioctl(FBIOPUT_VSCREENINFO failed): %s\n", - strerror(errno)); - exit(0); - } - - /* reload the screen info to update offsets */ - if (ioctl(FrameBufferFD, FBIOGET_VSCREENINFO, &VarInfo)) { - sprintf(exiterror, "error: ioctl(FBIOGET_VSCREENINFO) failed: %s\n", - strerror(errno)); - exit(0); - } - - /* reload the fixed info to update color mode */ - if (ioctl(FrameBufferFD, FBIOGET_FSCREENINFO, &FixedInfo)) { - sprintf(exiterror, "error: ioctl(FBIOGET_FSCREENINFO) failed: %s\n", - strerror(errno)); - exit(0); - } - - if(DisplayMode & GLUT_INDEX) { - /* initialize colormap */ - if (FixedInfo.visual != FB_VISUAL_DIRECTCOLOR) { - static unsigned short red[256], green[256], blue[256]; - /* we're assuming 256 entries here */ - - ColorMap.start = 0; - ColorMap.len = 256; - ColorMap.red = red; - ColorMap.green = green; - ColorMap.blue = blue; - ColorMap.transp = NULL; - - if (ioctl(FrameBufferFD, FBIOGETCMAP, (void *) &ColorMap) < 0) - sprintf(exiterror, "ioctl(FBIOGETCMAP) failed!\n"); - - } else { - sprintf(exiterror, "error: Could not set 8 bit color mode\n"); - exit(0); - } - } - - /* mmap the framebuffer into our address space */ - FrameBuffer = mmap(0, FixedInfo.smem_len, PROT_READ | PROT_WRITE, - MAP_SHARED, FrameBufferFD, 0); - if (FrameBuffer == MAP_FAILED) { - sprintf(exiterror, "error: unable to mmap framebuffer: %s\n", - strerror(errno)); - exit(0); - } - - int attribs[9]; - int i; - - int mask = DisplayMode; - for(i=0; i<8 && mask; i++) { - if(mask & GLUT_DOUBLE) { - attribs[i] = GLFBDEV_DOUBLE_BUFFER; - mask &= ~GLUT_DOUBLE; - continue; - } - - if(mask & GLUT_INDEX) { - attribs[i] = GLFBDEV_COLOR_INDEX; - mask &= ~GLUT_INDEX; - continue; - } - - if(mask & GLUT_DEPTH) { - attribs[i] = GLFBDEV_DEPTH_SIZE; - attribs[++i] = DepthSize; - mask &= ~GLUT_DEPTH; - continue; - } - - if(mask & GLUT_STENCIL) { - attribs[i] = GLFBDEV_STENCIL_SIZE; - attribs[++i] = StencilSize; - mask &= ~GLUT_STENCIL; - continue; - } - - if(mask & GLUT_ACCUM) { - attribs[i] = GLFBDEV_ACCUM_SIZE; - attribs[++i] = AccumSize; - mask &= ~GLUT_ACCUM; - continue; - } - - if(mask & GLUT_ALPHA) - if(!(DisplayMode & GLUT_INDEX)) { - mask &= ~GLUT_ALPHA; - i--; - continue; - } - - sprintf(exiterror, "Invalid mode from glutInitDisplayMode\n"); - exit(0); - } - - attribs[i] = GLFBDEV_NONE; - - if(!(Visual = glFBDevCreateVisual( &FixedInfo, &VarInfo, attribs ))) { - sprintf(exiterror, "Failure to create Visual\n"); - exit(0); - } - - int size = VarInfo.xres_virtual * VarInfo.yres_virtual - * VarInfo.bits_per_pixel / 8; - if(DisplayMode & GLUT_DOUBLE) { - if(!(BackBuffer = malloc(size))) { - sprintf(exiterror, "Failed to allocate double buffer\n"); - exit(0); - } - } else - BackBuffer = FrameBuffer; - - if(!(Buffer = glFBDevCreateBuffer( &FixedInfo, &VarInfo, Visual, - FrameBuffer, BackBuffer, size))) { - sprintf(exiterror, "Failure to create Buffer\n"); - exit(0); - } - - if(!(Context = glFBDevCreateContext(Visual, NULL))) { - sprintf(exiterror, "Failure to create Context\n"); - exit(0); - } - - if(!glFBDevMakeCurrent( Context, Buffer, Buffer )) { - sprintf(exiterror, "Failure to Make Current\n"); - exit(0); - } - - Visible = 1; - VisibleSwitch = 1; - Redisplay = 1; - - /* set up mouse */ - if((MouseBuffer = malloc(CURSOR_WIDTH * CURSOR_HEIGHT - * VarInfo.bits_per_pixel / 8)) == NULL) { - sprintf(exiterror, "malloc failure\n"); - exit(0); - } - - MouseX = VarInfo.xres / 2; - MouseY = VarInfo.yres / 2; - - /* set up menus */ - InitMenuMatrices(); - return 1; -} - -int glutCreateSubWindow(int win, int x, int y, int width, int height) -{ - return 0; -} - -void glutSetWindow(int win) -{ -} - -int glutGetWindow(void) -{ - return 1; -} - -void glutDestroyWindow(int win) -{ -} - -void glutPostRedisplay(void) -{ - Redisplay = 1; -} - -void glutSwapBuffers(void) -{ - glFlush(); - - if(DisplayMode & GLUT_DOUBLE) { - if(ActiveMenu) - DrawMenus(); - if(MouseEnabled) - DrawCursor(); - glFBDevSwapBuffers(Buffer); - } -} - -void glutPositionWindow(int x, int y) -{ -} - -void glutReshapeWindow(int width, int height) -{ -} - -void glutFullScreen(void) -{ -} - -void glutPopWindow(void) -{ -} - -void glutPushWindow(void) -{ -} - -void glutShowWindow(void) -{ -} - -void glutHideWindow(void) -{ -} - -void glutIconifyWindow(void) -{ -} - -void glutSetWindowTitle(const char *name) -{ -} - -void glutSetIconTitle(const char *name) -{ -} - -void glutSetCursor(int cursor) -{ - if(cursor == GLUT_CURSOR_FULL_CROSSHAIR) - cursor = GLUT_CURSOR_CROSSHAIR; - CurrentCursor = cursor; - MouseEnabled = 1; - EraseCursor(); - SwapCursor(); -} - -/* --------- Overlays ------------*/ -void glutEstablishOverlay(void) -{ - exit(0); -} - -void glutUseLayer(GLenum layer) -{ -} - -void glutRemoveOverlay(void) -{ -} - -void glutPostOverlayRedisplay(void) -{ -} - -void glutShowOverlay(void) -{ -} - -void glutHideOverlay(void) -{ -} - -/* --------- Menus ------------*/ -int glutCreateMenu(void (*func)(int value)) -{ - MouseEnabled = 1; - CurrentMenu = NumMenus; - NumMenus++; - Menus = realloc(Menus, sizeof(*Menus) * NumMenus); - Menus[CurrentMenu].NumItems = 0; - Menus[CurrentMenu].Items = NULL; - Menus[CurrentMenu].func = func; - Menus[CurrentMenu].width = 0; - return CurrentMenu; -} - -void glutSetMenu(int menu) -{ - CurrentMenu = menu; -} - -int glutGetMenu(void) -{ - return CurrentMenu; -} - -void glutDestroyMenu(int menu) -{ - if(menu == CurrentMenu) - CurrentMenu = 0; -} - -static void NameMenuEntry(int entry, const char *name) -{ - int cm = CurrentMenu; - if(!(Menus[cm].Items[entry-1].name = realloc(Menus[cm].Items[entry-1].name, - strlen(name) + 1))) { - sprintf(exiterror, "realloc failed in NameMenuEntry\n"); - exit(0); - } - strcpy(Menus[cm].Items[entry-1].name, name); - if(strlen(name) * MENU_FONT_WIDTH > Menus[cm].width) - Menus[cm].width = strlen(name) * MENU_FONT_WIDTH; -} - -static int AddMenuItem(const char *name) -{ - int cm = CurrentMenu; - int item = Menus[cm].NumItems++; - if(!(Menus[cm].Items = realloc(Menus[cm].Items, - Menus[cm].NumItems * sizeof(*Menus[0].Items)))) { - sprintf(exiterror, "realloc failed in AddMenuItem\n"); - exit(0); - } - Menus[cm].Items[item].name = NULL; - NameMenuEntry(item+1, name); - return item; -} - -void glutAddMenuEntry(const char *name, int value) -{ - int item = AddMenuItem(name); - Menus[CurrentMenu].Items[item].value = value; - Menus[CurrentMenu].Items[item].submenu = 0; -} - -void glutAddSubMenu(const char *name, int menu) -{ - int item = AddMenuItem(name); - if(menu == CurrentMenu) { - sprintf(exiterror, "Recursive menus not supported\n"); - exit(0); - } - Menus[CurrentMenu].Items[item].submenu = menu; -} - -void glutChangeToMenuEntry(int entry, const char *name, int value) -{ - NameMenuEntry(entry, name); - Menus[CurrentMenu].Items[entry-1].value = value; - Menus[CurrentMenu].Items[entry-1].submenu = 0; -} - -void glutChangeToSubMenu(int entry, const char *name, int menu) -{ - NameMenuEntry(entry, name); - Menus[CurrentMenu].Items[entry-1].submenu = menu; -} - -void glutRemoveMenuItem(int entry) -{ - memmove(Menus[CurrentMenu].Items + entry - 1, - Menus[CurrentMenu].Items + entry, - sizeof(*Menus[0].Items) * (Menus[CurrentMenu].NumItems - entry)); - Menus[CurrentMenu].NumItems--; -} - -void glutAttachMenu(int button) -{ - AttachedMenus[button] = CurrentMenu; -} - -void glutDetachMenu(int button) -{ - AttachedMenus[button] = 0; -} - -/* --------- Callbacks ------------ */ -void glutDisplayFunc(void (*func)(void)) -{ - DisplayFunc = func; -} - -void glutOverlayDisplayFunc(void (*func)(void)) -{ -} - -void glutReshapeFunc(void (*func)(int width, int height)) -{ - ReshapeFunc = func; -} - -void glutKeyboardFunc(void (*func)(unsigned char key, int x, int y)) -{ - KeyboardFunc = func; -} - -void glutMouseFunc(void (*func)(int button, int state, int x, int y)) -{ - MouseEnabled = 1; - MouseFunc = func; -} - -void glutMotionFunc(void (*func)(int x, int y)) -{ - MouseEnabled = 1; - MotionFunc = func; -} - -void glutPassiveMotionFunc(void (*func)(int x, int y)) -{ - MouseEnabled = 1; - PassiveMotionFunc = func; -} - -void glutVisibilityFunc(void (*func)(int state)) -{ - VisibilityFunc = func; -} - -void glutEntryFunc(void (*func)(int state)) -{ -} - -void glutSpecialFunc(void (*func)(int key, int x, int y)) -{ - SpecialFunc = func; -} - -void glutSpaceballMotionFunc(void (*func)(int x, int y, int z)) -{ -} - -void glutSpaceballRotateFunc(void (*func)(int x, int y, int z)) -{ -} - -void glutButtonBoxFunc(void (*func)(int button, int state)) -{ -} - -void glutDialsFunc(void (*func)(int dial, int value)) -{ -} - -void glutTabletMotionFunc(void (*func)(int x, int y)) -{ -} - -void glutTabletButtonFunc(void (*func)(int button, int state, - int x, int y)) -{ -} - -void glutMenuStatusFunc(void (*func)(int status, int x, int y)) -{ - MenuStatusFunc = func; -} - -void glutMenuStateFunc(void (*func)(int status)) -{ - MenuStateFunc = func; -} - -void glutIdleFunc(void (*func)(void)) -{ - IdleFunc = func; -} - -void glutTimerFunc(unsigned int msecs, - void (*func)(int value), int value) -{ - struct GlutTimer *timer = malloc(sizeof *timer); - timer->time = glutGet(GLUT_ELAPSED_TIME) + msecs; - timer->func = func; - timer->value = value; - - struct GlutTimer **head = &GlutTimers; - while(*head && (*head)->time < timer->time) - head = &(*head)->next; - - timer->next = *head; - *head = timer; -} - -/* --------- Color Map ------------*/ -#define TOCMAP(x) (unsigned short)((x<0?0:x>1?1:x) * (GLfloat) (2<<16)) -#define FROMCMAP(x) (GLfloat)x / (GLfloat)(2<<16) - -void glutSetColor(int cell, GLfloat red, GLfloat green, GLfloat blue) -{ - if(cell >=0 && cell < 256) { - - ColorMap.red[cell] = TOCMAP(red); - ColorMap.green[cell] = TOCMAP(green); - ColorMap.blue[cell] = TOCMAP(blue); - - ColorMap.start = cell; - ColorMap.len = 1; - - if (ioctl(FrameBufferFD, FBIOPUTCMAP, (void *) &ColorMap) < 0) - fprintf(stderr, "ioctl(FBIOPUTCMAP) failed [%d]\n", cell); - } -} - -GLfloat glutGetColor(int cell, int component) -{ - if(!(DisplayMode & GLUT_INDEX)) - return -1.0; - - if(cell < 0 || cell > 256) - return -1.0; - - switch(component) { - case GLUT_RED: - return FROMCMAP(ColorMap.red[cell]); - case GLUT_GREEN: - return FROMCMAP(ColorMap.green[cell]); - case GLUT_BLUE: - return FROMCMAP(ColorMap.blue[cell]); - } - return -1.0; -} - -void glutCopyColormap(int win) -{ -} - -/* --------- State ------------*/ -void glutWarpPointer(int x, int y) -{ - if(x < 0) - x = 0; - if(x >= VarInfo.xres) - x = VarInfo.xres - 1; - MouseX = x; - - if(y < 0) - y = 0; - if(y >= VarInfo.yres) - y = VarInfo.yres - 1; - MouseY = y; - - EraseCursor(); - SwapCursor(); -} - -int glutGet(GLenum state) -{ - switch(state) { - case GLUT_WINDOW_X: - return 0; - case GLUT_WINDOW_Y: - return 0; - case GLUT_INIT_WINDOW_WIDTH: - case GLUT_WINDOW_WIDTH: - case GLUT_SCREEN_WIDTH: - return VarInfo.xres; - case GLUT_INIT_WINDOW_HEIGHT: - case GLUT_WINDOW_HEIGHT: - case GLUT_SCREEN_HEIGHT: - return VarInfo.yres; - case GLUT_WINDOW_BUFFER_SIZE: - return VarInfo.bits_per_pixel; - case GLUT_WINDOW_STENCIL_SIZE: - return StencilSize; - case GLUT_WINDOW_DEPTH_SIZE: - return DepthSize; - case GLUT_WINDOW_RED_SIZE: - return VarInfo.red.length; - case GLUT_WINDOW_GREEN_SIZE: - return VarInfo.green.length; - case GLUT_WINDOW_BLUE_SIZE: - return VarInfo.green.length; - case GLUT_WINDOW_ALPHA_SIZE: - return VarInfo.transp.length; - case GLUT_WINDOW_ACCUM_RED_SIZE: - case GLUT_WINDOW_ACCUM_GREEN_SIZE: - case GLUT_WINDOW_ACCUM_BLUE_SIZE: - case GLUT_WINDOW_ACCUM_ALPHA_SIZE: - return AccumSize; - case GLUT_WINDOW_DOUBLEBUFFER: - if(DisplayMode & GLUT_DOUBLE) - return 1; - return 0; - case GLUT_WINDOW_RGBA: - if(DisplayMode & GLUT_INDEX) - return 0; - return 1; - case GLUT_WINDOW_PARENT: - return 0; - case GLUT_WINDOW_NUM_CHILDREN: - return 0; - case GLUT_WINDOW_COLORMAP_SIZE: - if(DisplayMode & GLUT_INDEX) - return 256; - return 0; - case GLUT_WINDOW_NUM_SAMPLES: - return 0; - case GLUT_WINDOW_STEREO: - return 0; - case GLUT_WINDOW_CURSOR: - return CurrentCursor; - case GLUT_SCREEN_WIDTH_MM: - return VarInfo.width; - case GLUT_SCREEN_HEIGHT_MM: - return VarInfo.height; - case GLUT_MENU_NUM_ITEMS: - if(CurrentMenu) - return Menus[CurrentMenu].NumItems; - return 0; - case GLUT_DISPLAY_MODE_POSSIBLE: - if((DisplayMode & GLUT_MULTISAMPLE) - || (DisplayMode & GLUT_STEREO) - || (DisplayMode & GLUT_LUMINANCE) - || (DisplayMode & GLUT_ALPHA) && (DisplayMode & GLUT_INDEX)) - return 0; - return 1; - case GLUT_INIT_DISPLAY_MODE: - return DisplayMode; - case GLUT_INIT_WINDOW_X: - case GLUT_INIT_WINDOW_Y: - return 0; - case GLUT_ELAPSED_TIME: - { - static struct timeval tv; - gettimeofday(&tv, 0); - return 1000 * (tv.tv_sec - StartTime.tv_sec) - + (tv.tv_usec - StartTime.tv_usec) / 1000; - } - } -} - -int glutLayerGet(GLenum info) -{ - switch(info) { - case GLUT_OVERLAY_POSSIBLE: - return 0; - case GLUT_LAYER_IN_USE: - return GLUT_NORMAL; - case GLUT_HAS_OVERLAY: - return 0; - case GLUT_TRANSPARENT_INDEX: - return -1; - case GLUT_NORMAL_DAMAGED: - return Redisplay; - case GLUT_OVERLAY_DAMAGED: - return -1; - } - return -1; -} - -int glutDeviceGet(GLenum info) -{ - switch(info) { - case GLUT_HAS_KEYBOARD: - return 1; - case GLUT_HAS_MOUSE: - case GLUT_NUM_MOUSE_BUTTONS: - return NumMouseButtons; - case GLUT_HAS_SPACEBALL: - case GLUT_HAS_DIAL_AND_BUTTON_BOX: - case GLUT_HAS_TABLET: - return 0; - case GLUT_NUM_SPACEBALL_BUTTONS: - case GLUT_NUM_BUTTON_BOX_BUTTONS: - case GLUT_NUM_DIALS: - case GLUT_NUM_TABLET_BUTTONS: - return 0; - } - return -1; -} - -int glutGetModifiers(void){ - return KeyboardModifiers; -} - -/* ------------- extensions ------------ */ -int glutExtensionSupported(const char *extension) -{ - const char *exts = (const char *) glGetString(GL_EXTENSIONS); - const char *start = exts; - int len = strlen(extension); - - for(;;) { - const char *p = strstr(exts, extension); - if(!p) - break; - if((p == start || p[-1] == ' ') && (p[len] == ' ' || p[len] == 0)) - return 1; - exts = p + len; - } - return 0; -} - -void glutReportErrors(void) -{ - GLenum error; - - while ((error = glGetError()) != GL_NO_ERROR) - fprintf(stderr, "GL error: %s", gluErrorString(error)); -} - -static struct { - const char *name; - const GLUTproc address; -} glut_functions[] = { - { "glutInit", (const GLUTproc) glutInit }, - { "glutInitDisplayMode", (const GLUTproc) glutInitDisplayMode }, - { "glutInitWindowPosition", (const GLUTproc) glutInitWindowPosition }, - { "glutInitWindowSize", (const GLUTproc) glutInitWindowSize }, - { "glutMainLoop", (const GLUTproc) glutMainLoop }, - { "glutCreateWindow", (const GLUTproc) glutCreateWindow }, - { "glutCreateSubWindow", (const GLUTproc) glutCreateSubWindow }, - { "glutDestroyWindow", (const GLUTproc) glutDestroyWindow }, - { "glutPostRedisplay", (const GLUTproc) glutPostRedisplay }, - { "glutSwapBuffers", (const GLUTproc) glutSwapBuffers }, - { "glutGetWindow", (const GLUTproc) glutGetWindow }, - { "glutSetWindow", (const GLUTproc) glutSetWindow }, - { "glutSetWindowTitle", (const GLUTproc) glutSetWindowTitle }, - { "glutSetIconTitle", (const GLUTproc) glutSetIconTitle }, - { "glutPositionWindow", (const GLUTproc) glutPositionWindow }, - { "glutReshapeWindow", (const GLUTproc) glutReshapeWindow }, - { "glutPopWindow", (const GLUTproc) glutPopWindow }, - { "glutPushWindow", (const GLUTproc) glutPushWindow }, - { "glutIconifyWindow", (const GLUTproc) glutIconifyWindow }, - { "glutShowWindow", (const GLUTproc) glutShowWindow }, - { "glutHideWindow", (const GLUTproc) glutHideWindow }, - { "glutFullScreen", (const GLUTproc) glutFullScreen }, - { "glutSetCursor", (const GLUTproc) glutSetCursor }, - { "glutWarpPointer", (const GLUTproc) glutWarpPointer }, - { "glutEstablishOverlay", (const GLUTproc) glutEstablishOverlay }, - { "glutRemoveOverlay", (const GLUTproc) glutRemoveOverlay }, - { "glutUseLayer", (const GLUTproc) glutUseLayer }, - { "glutPostOverlayRedisplay", (const GLUTproc) glutPostOverlayRedisplay }, - { "glutShowOverlay", (const GLUTproc) glutShowOverlay }, - { "glutHideOverlay", (const GLUTproc) glutHideOverlay }, - { "glutCreateMenu", (const GLUTproc) glutCreateMenu }, - { "glutDestroyMenu", (const GLUTproc) glutDestroyMenu }, - { "glutGetMenu", (const GLUTproc) glutGetMenu }, - { "glutSetMenu", (const GLUTproc) glutSetMenu }, - { "glutAddMenuEntry", (const GLUTproc) glutAddMenuEntry }, - { "glutAddSubMenu", (const GLUTproc) glutAddSubMenu }, - { "glutChangeToMenuEntry", (const GLUTproc) glutChangeToMenuEntry }, - { "glutChangeToSubMenu", (const GLUTproc) glutChangeToSubMenu }, - { "glutRemoveMenuItem", (const GLUTproc) glutRemoveMenuItem }, - { "glutAttachMenu", (const GLUTproc) glutAttachMenu }, - { "glutDetachMenu", (const GLUTproc) glutDetachMenu }, - { "glutDisplayFunc", (const GLUTproc) glutDisplayFunc }, - { "glutReshapeFunc", (const GLUTproc) glutReshapeFunc }, - { "glutKeyboardFunc", (const GLUTproc) glutKeyboardFunc }, - { "glutMouseFunc", (const GLUTproc) glutMouseFunc }, - { "glutMotionFunc", (const GLUTproc) glutMotionFunc }, - { "glutPassiveMotionFunc", (const GLUTproc) glutPassiveMotionFunc }, - { "glutEntryFunc", (const GLUTproc) glutEntryFunc }, - { "glutVisibilityFunc", (const GLUTproc) glutVisibilityFunc }, - { "glutIdleFunc", (const GLUTproc) glutIdleFunc }, - { "glutTimerFunc", (const GLUTproc) glutTimerFunc }, - { "glutMenuStateFunc", (const GLUTproc) glutMenuStateFunc }, - { "glutSpecialFunc", (const GLUTproc) glutSpecialFunc }, - { "glutSpaceballRotateFunc", (const GLUTproc) glutSpaceballRotateFunc }, - { "glutButtonBoxFunc", (const GLUTproc) glutButtonBoxFunc }, - { "glutDialsFunc", (const GLUTproc) glutDialsFunc }, - { "glutTabletMotionFunc", (const GLUTproc) glutTabletMotionFunc }, - { "glutTabletButtonFunc", (const GLUTproc) glutTabletButtonFunc }, - { "glutMenuStatusFunc", (const GLUTproc) glutMenuStatusFunc }, - { "glutOverlayDisplayFunc", (const GLUTproc) glutOverlayDisplayFunc }, - { "glutSetColor", (const GLUTproc) glutSetColor }, - { "glutGetColor", (const GLUTproc) glutGetColor }, - { "glutCopyColormap", (const GLUTproc) glutCopyColormap }, - { "glutGet", (const GLUTproc) glutGet }, - { "glutDeviceGet", (const GLUTproc) glutDeviceGet }, - { "glutExtensionSupported", (const GLUTproc) glutExtensionSupported }, - { "glutGetModifiers", (const GLUTproc) glutGetModifiers }, - { "glutLayerGet", (const GLUTproc) glutLayerGet }, - { "glutGetProcAddress", (const GLUTproc) glutGetProcAddress }, - { "glutBitmapCharacter", (const GLUTproc) glutBitmapCharacter }, - { "glutBitmapWidth", (const GLUTproc) glutBitmapWidth }, - { "glutStrokeCharacter", (const GLUTproc) glutStrokeCharacter }, - { "glutStrokeWidth", (const GLUTproc) glutStrokeWidth }, - { "glutBitmapLength", (const GLUTproc) glutBitmapLength }, - { "glutStrokeLength", (const GLUTproc) glutStrokeLength }, - { "glutWireSphere", (const GLUTproc) glutWireSphere }, - { "glutSolidSphere", (const GLUTproc) glutSolidSphere }, - { "glutWireCone", (const GLUTproc) glutWireCone }, - { "glutSolidCone", (const GLUTproc) glutSolidCone }, - { "glutWireCube", (const GLUTproc) glutWireCube }, - { "glutSolidCube", (const GLUTproc) glutSolidCube }, - { "glutWireTorus", (const GLUTproc) glutWireTorus }, - { "glutSolidTorus", (const GLUTproc) glutSolidTorus }, - { "glutWireDodecahedron", (const GLUTproc) glutWireDodecahedron }, - { "glutSolidDodecahedron", (const GLUTproc) glutSolidDodecahedron }, - { "glutWireTeapot", (const GLUTproc) glutWireTeapot }, - { "glutSolidTeapot", (const GLUTproc) glutSolidTeapot }, - { "glutWireOctahedron", (const GLUTproc) glutWireOctahedron }, - { "glutSolidOctahedron", (const GLUTproc) glutSolidOctahedron }, - { "glutWireTetrahedron", (const GLUTproc) glutWireTetrahedron }, - { "glutSolidTetrahedron", (const GLUTproc) glutSolidTetrahedron }, - { "glutWireIcosahedron", (const GLUTproc) glutWireIcosahedron }, - { "glutSolidIcosahedron", (const GLUTproc) glutSolidIcosahedron }, - { "glutReportErrors", (const GLUTproc) glutReportErrors }, - { NULL, NULL } -}; - -GLUTproc glutGetProcAddress(const char *procName) -{ - /* Try GLUT functions first */ - int i; - for (i = 0; glut_functions[i].name; i++) { - if (strcmp(glut_functions[i].name, procName) == 0) - return glut_functions[i].address; - } - - /* Try core GL functions */ - return (GLUTproc) glFBDevGetProcAddress(procName); -} diff --git a/src/mesa/drivers/beos/GLView.cpp b/src/mesa/drivers/beos/GLView.cpp index 45473a8ef2..9e4a7ebe56 100644 --- a/src/mesa/drivers/beos/GLView.cpp +++ b/src/mesa/drivers/beos/GLView.cpp @@ -43,7 +43,7 @@ extern "C" { #include "texobj.h" #include "teximage.h" #include "texstore.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "swrast/s_context.h" @@ -344,7 +344,7 @@ BGLView::BGLView(BRect rect, char *name, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext(ctx); - _ac_CreateContext(ctx); + _vbo_CreateContext(ctx); _tnl_CreateContext(ctx); _swsetup_CreateContext(ctx); _swsetup_Wakeup(ctx); @@ -830,7 +830,7 @@ void MesaDriver::UpdateState( GLcontext *ctx, GLuint new_state ) _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); if (ctx->Color.DrawBuffer[0] == GL_FRONT) { diff --git a/src/mesa/drivers/directfb/idirectfbgl_mesa.c b/src/mesa/drivers/directfb/idirectfbgl_mesa.c index 9e76e0f6e0..88ac4bb31d 100644 --- a/src/mesa/drivers/directfb/idirectfbgl_mesa.c +++ b/src/mesa/drivers/directfb/idirectfbgl_mesa.c @@ -374,7 +374,7 @@ dfbUpdateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); } @@ -787,7 +787,7 @@ directfbgl_create_context( GLcontext *context, } _swrast_CreateContext( context ); - _ac_CreateContext( context ); + _vbo_CreateContext( context ); _tnl_CreateContext( context ); _swsetup_CreateContext( context ); _swsetup_Wakeup( context ); diff --git a/src/mesa/drivers/fbdev/glfbdev.c b/src/mesa/drivers/fbdev/glfbdev.c index bd9d3ac0ad..f9d57dbdd8 100644 --- a/src/mesa/drivers/fbdev/glfbdev.c +++ b/src/mesa/drivers/fbdev/glfbdev.c @@ -54,7 +54,7 @@ #include "texformat.h" #include "teximage.h" #include "texstore.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" @@ -143,7 +143,7 @@ update_state( GLcontext *ctx, GLuint new_state ) /* not much to do here - pass it on */ _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); } @@ -776,7 +776,7 @@ glFBDevCreateContext( const GLFBDevVisualPtr visual, GLFBDevContextPtr share ) /* Create module contexts */ glctx = (GLcontext *) &ctx->glcontext; _swrast_CreateContext( glctx ); - _ac_CreateContext( glctx ); + _vbo_CreateContext( glctx ); _tnl_CreateContext( glctx ); _swsetup_CreateContext( glctx ); _swsetup_Wakeup( glctx ); diff --git a/src/mesa/drivers/ggi/ggimesa.c b/src/mesa/drivers/ggi/ggimesa.c index 47d7f2bdb9..85592d98da 100644 --- a/src/mesa/drivers/ggi/ggimesa.c +++ b/src/mesa/drivers/ggi/ggimesa.c @@ -39,7 +39,7 @@ #include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "teximage.h" #include "texformat.h" #include "texstore.h" @@ -563,7 +563,7 @@ ggi_mesa_context_t ggiMesaCreateContext(ggi_visual_t vis) _mesa_enable_sw_extensions(ctx->gl_ctx); _swrast_CreateContext(ctx->gl_ctx); - _ac_CreateContext(ctx->gl_ctx); + _vbo_CreateContext(ctx->gl_ctx); _tnl_CreateContext(ctx->gl_ctx); _swsetup_CreateContext(ctx->gl_ctx); diff --git a/src/mesa/drivers/glide/fxdd.c b/src/mesa/drivers/glide/fxdd.c index f49c3889f6..43d3cd9405 100644 --- a/src/mesa/drivers/glide/fxdd.c +++ b/src/mesa/drivers/glide/fxdd.c @@ -1783,7 +1783,7 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa) /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext(ctx); - _ac_CreateContext(ctx); + _vbo_CreateContext(ctx); _tnl_CreateContext(ctx); _swsetup_CreateContext(ctx); @@ -1826,7 +1826,7 @@ fxDDDestroyFxMesaContext(fxMesaContext fxMesa) { _swsetup_DestroyContext(fxMesa->glCtx); _tnl_DestroyContext(fxMesa->glCtx); - _ac_DestroyContext(fxMesa->glCtx); + _vbo_DestroyContext(fxMesa->glCtx); _swrast_DestroyContext(fxMesa->glCtx); if (fxMesa->state) @@ -2101,7 +2101,7 @@ fxDDUpdateDDPointers(GLcontext * ctx, GLuint new_state) } _swrast_InvalidateState(ctx, new_state); - _ac_InvalidateState(ctx, new_state); + _vbo_InvalidateState(ctx, new_state); _tnl_InvalidateState(ctx, new_state); _swsetup_InvalidateState(ctx, new_state); diff --git a/src/mesa/drivers/windows/gdi/mesa.def b/src/mesa/drivers/windows/gdi/mesa.def index f0b275730c..8d65428121 100644 --- a/src/mesa/drivers/windows/gdi/mesa.def +++ b/src/mesa/drivers/windows/gdi/mesa.def @@ -859,9 +859,9 @@ EXPORTS wglGetExtensionsStringARB ; ; Mesa internals - mostly for OSMESA - _ac_CreateContext - _ac_DestroyContext - _ac_InvalidateState + _vbo_CreateContext + _vbo_DestroyContext + _vbo_InvalidateState _glapi_check_multithread _glapi_get_context _glapi_get_proc_address diff --git a/src/mesa/drivers/windows/gdi/wmesa.c b/src/mesa/drivers/windows/gdi/wmesa.c index 8c3229ab14..078b590af8 100644 --- a/src/mesa/drivers/windows/gdi/wmesa.c +++ b/src/mesa/drivers/windows/gdi/wmesa.c @@ -11,7 +11,7 @@ #include "framebuffer.h" #include "renderbuffer.h" #include "drivers/common/driverfuncs.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" @@ -1125,7 +1125,7 @@ static void wmesa_update_state(GLcontext *ctx, GLuint new_state) { _swrast_InvalidateState(ctx, new_state); _swsetup_InvalidateState(ctx, new_state); - _ac_InvalidateState(ctx, new_state); + _vbo_InvalidateState(ctx, new_state); _tnl_InvalidateState(ctx, new_state); /* TODO - This code is not complete yet because I @@ -1242,7 +1242,7 @@ WMesaContext WMesaCreateContext(HDC hDC, /* Initialize the software rasterizer and helper modules. */ if (!_swrast_CreateContext(ctx) || - !_ac_CreateContext(ctx) || + !_vbo_CreateContext(ctx) || !_tnl_CreateContext(ctx) || !_swsetup_CreateContext(ctx)) { _mesa_free_context_data(ctx); @@ -1285,7 +1285,7 @@ void WMesaDestroyContext( WMesaContext pwc ) _swsetup_DestroyContext(ctx); _tnl_DestroyContext(ctx); - _ac_DestroyContext(ctx); + _vbo_DestroyContext(ctx); _swrast_DestroyContext(ctx); _mesa_free_context_data(ctx); diff --git a/src/mesa/drivers/windows/gldirect/dglcontext.c b/src/mesa/drivers/windows/gldirect/dglcontext.c index 5dafe14518..4ad7a76e67 100644 --- a/src/mesa/drivers/windows/gldirect/dglcontext.c +++ b/src/mesa/drivers/windows/gldirect/dglcontext.c @@ -1453,7 +1453,7 @@ SkipPrimaryCreate: #ifdef _USE_GLD3_WGL // Init Mesa internals _swrast_CreateContext( lpCtx->glCtx ); - _ac_CreateContext( lpCtx->glCtx ); + _vbo_CreateContext( lpCtx->glCtx ); _tnl_CreateContext( lpCtx->glCtx ); _swsetup_CreateContext( lpCtx->glCtx ); diff --git a/src/mesa/drivers/windows/gldirect/dx7/gld_driver_dx7.c b/src/mesa/drivers/windows/gldirect/dx7/gld_driver_dx7.c index cad299540d..d5fa642800 100644 --- a/src/mesa/drivers/windows/gldirect/dx7/gld_driver_dx7.c +++ b/src/mesa/drivers/windows/gldirect/dx7/gld_driver_dx7.c @@ -52,7 +52,7 @@ #include "texformat.h" #include "teximage.h" #include "texstore.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast_setup/swrast_setup.h" #include "swrast_setup/ss_context.h" #include "tnl/tnl.h" @@ -868,7 +868,7 @@ void gld_update_state_DX7( return; _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); // SetupIndex will be used in the pipelines for choosing setup function diff --git a/src/mesa/drivers/windows/gldirect/dx7/gld_ext_dx7.c b/src/mesa/drivers/windows/gldirect/dx7/gld_ext_dx7.c index 6be41a80dd..ba60980bbe 100644 --- a/src/mesa/drivers/windows/gldirect/dx7/gld_ext_dx7.c +++ b/src/mesa/drivers/windows/gldirect/dx7/gld_ext_dx7.c @@ -58,7 +58,7 @@ #include "mtypes.h" #include "texformat.h" #include "texstore.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast_setup/swrast_setup.h" #include "swrast_setup/ss_context.h" #include "tnl/tnl.h" diff --git a/src/mesa/drivers/windows/gldirect/dx7/gld_primitive_dx7.c b/src/mesa/drivers/windows/gldirect/dx7/gld_primitive_dx7.c index 5da25003c0..c99ba0bba5 100644 --- a/src/mesa/drivers/windows/gldirect/dx7/gld_primitive_dx7.c +++ b/src/mesa/drivers/windows/gldirect/dx7/gld_primitive_dx7.c @@ -54,7 +54,7 @@ #include "mtypes.h" #include "texformat.h" #include "texstore.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "swrast_setup/ss_context.h" diff --git a/src/mesa/drivers/windows/gldirect/dx8/gld_driver_dx8.c b/src/mesa/drivers/windows/gldirect/dx8/gld_driver_dx8.c index 0a6d9f8555..7afa9190cd 100644 --- a/src/mesa/drivers/windows/gldirect/dx8/gld_driver_dx8.c +++ b/src/mesa/drivers/windows/gldirect/dx8/gld_driver_dx8.c @@ -52,7 +52,7 @@ #include "texformat.h" #include "teximage.h" #include "texstore.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast_setup/swrast_setup.h" #include "swrast_setup/ss_context.h" #include "tnl/tnl.h" @@ -850,7 +850,7 @@ void gld_update_state_DX8( return; _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); // SetupIndex will be used in the pipelines for choosing setup function diff --git a/src/mesa/drivers/windows/gldirect/dx8/gld_ext_dx8.c b/src/mesa/drivers/windows/gldirect/dx8/gld_ext_dx8.c index 108f12a9d1..b51bba9b3c 100644 --- a/src/mesa/drivers/windows/gldirect/dx8/gld_ext_dx8.c +++ b/src/mesa/drivers/windows/gldirect/dx8/gld_ext_dx8.c @@ -58,7 +58,7 @@ #include "mtypes.h" #include "texformat.h" #include "texstore.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast_setup/swrast_setup.h" #include "swrast_setup/ss_context.h" #include "tnl/tnl.h" diff --git a/src/mesa/drivers/windows/gldirect/dx8/gld_primitive_dx8.c b/src/mesa/drivers/windows/gldirect/dx8/gld_primitive_dx8.c index 700b520086..a5b5462f03 100644 --- a/src/mesa/drivers/windows/gldirect/dx8/gld_primitive_dx8.c +++ b/src/mesa/drivers/windows/gldirect/dx8/gld_primitive_dx8.c @@ -54,7 +54,7 @@ #include "mtypes.h" #include "texformat.h" #include "texstore.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "swrast_setup/ss_context.h" diff --git a/src/mesa/drivers/windows/gldirect/dx9/gld_driver_dx9.c b/src/mesa/drivers/windows/gldirect/dx9/gld_driver_dx9.c index 1b01cb1f7f..c191564d6e 100644 --- a/src/mesa/drivers/windows/gldirect/dx9/gld_driver_dx9.c +++ b/src/mesa/drivers/windows/gldirect/dx9/gld_driver_dx9.c @@ -52,7 +52,7 @@ #include "texformat.h" #include "teximage.h" #include "texstore.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast_setup/swrast_setup.h" #include "swrast_setup/ss_context.h" #include "tnl/tnl.h" @@ -876,7 +876,7 @@ void gld_update_state_DX9( return; _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); // SetupIndex will be used in the pipelines for choosing setup function diff --git a/src/mesa/drivers/windows/gldirect/dx9/gld_ext_dx9.c b/src/mesa/drivers/windows/gldirect/dx9/gld_ext_dx9.c index 745c987602..e8c73a6ff8 100644 --- a/src/mesa/drivers/windows/gldirect/dx9/gld_ext_dx9.c +++ b/src/mesa/drivers/windows/gldirect/dx9/gld_ext_dx9.c @@ -58,7 +58,7 @@ #include "mtypes.h" #include "texformat.h" #include "texstore.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast_setup/swrast_setup.h" #include "swrast_setup/ss_context.h" #include "tnl/tnl.h" diff --git a/src/mesa/drivers/windows/gldirect/dx9/gld_primitive_dx9.c b/src/mesa/drivers/windows/gldirect/dx9/gld_primitive_dx9.c index 65fd821276..403a9d5f86 100644 --- a/src/mesa/drivers/windows/gldirect/dx9/gld_primitive_dx9.c +++ b/src/mesa/drivers/windows/gldirect/dx9/gld_primitive_dx9.c @@ -54,7 +54,7 @@ #include "mtypes.h" #include "texformat.h" #include "texstore.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "swrast_setup/ss_context.h" diff --git a/src/mesa/drivers/windows/gldirect/mesasw/gld_wgl_mesasw.c b/src/mesa/drivers/windows/gldirect/mesasw/gld_wgl_mesasw.c index 0f11b4fe51..b590dc795a 100644 --- a/src/mesa/drivers/windows/gldirect/mesasw/gld_wgl_mesasw.c +++ b/src/mesa/drivers/windows/gldirect/mesasw/gld_wgl_mesasw.c @@ -54,7 +54,7 @@ #include "texformat.h" #include "texstore.h" #include "teximage.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "swrast/s_context.h" @@ -1321,7 +1321,7 @@ static void wmesa_update_state( { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); } @@ -1631,7 +1631,7 @@ BOOL gldInitialiseMesa_MesaSW( _mesa_enable_1_3_extensions(ctx); // _swrast_CreateContext( ctx ); -// _ac_CreateContext( ctx ); +// _vbo_CreateContext( ctx ); // _tnl_CreateContext( ctx ); // _swsetup_CreateContext( ctx ); diff --git a/src/mesa/drivers/windows/icd/mesa.def b/src/mesa/drivers/windows/icd/mesa.def index 1826192d30..465b380a0c 100644 --- a/src/mesa/drivers/windows/icd/mesa.def +++ b/src/mesa/drivers/windows/icd/mesa.def @@ -24,9 +24,9 @@ EXPORTS ; ; Mesa internals - mostly for OSMESA - _ac_CreateContext - _ac_DestroyContext - _ac_InvalidateState + _vbo_CreateContext + _vbo_DestroyContext + _vbo_InvalidateState _glapi_get_context _glapi_get_proc_address _mesa_buffer_data -- cgit v1.2.3 From d2b06403c6f06ee37f46c2a504983884382c8abc Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 19 Feb 2007 19:57:30 +0100 Subject: i915tex: Fix performance regression with new vbo code and latest drm. With current memory preferences, vbos ended up in AGP space where reading from them got a bit slow. Make sure buffer objects are initially created in system memory. --- src/mesa/drivers/dri/i915tex/intel_buffer_objects.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c index 31c41d8685..ba3c7f0c1f 100644 --- a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c @@ -50,7 +50,10 @@ intel_bufferobj_alloc(GLcontext * ctx, GLuint name, GLenum target) _mesa_initialize_buffer_object(&obj->Base, name, target); driGenBuffers(intel->intelScreen->regionPool, - "bufferobj", 1, &obj->buffer, 64, 0, 0); + "bufferobj", 1, &obj->buffer, 64, + DRM_BO_FLAG_MEM_LOCAL | + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, + 0); return &obj->Base; } -- cgit v1.2.3 From 20e851bb9a6737194bc0effcb155b2fdb23acaaa Mon Sep 17 00:00:00 2001 From: Christian Neumair Date: Tue, 20 Feb 2007 08:11:11 -0700 Subject: set log level w/ env var --- src/egl/main/egllog.c | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/egl/main/egllog.c b/src/egl/main/egllog.c index 59b1d2684e..dc1daaa996 100644 --- a/src/egl/main/egllog.c +++ b/src/egl/main/egllog.c @@ -6,13 +6,44 @@ #include #include #include +#include #include "egllog.h" #define MAXSTRING 1000 +#define FALLBACK_LOG_LEVEL _EGL_DEBUG +#define FALLBACK_LOG_LEVEL_STR "debug" +static EGLint ReportingLevel = -1; -/* XXX init this with an env var or something */ -static EGLint ReportingLevel = _EGL_DEBUG; + +static void +log_level_initialize (void) +{ + char *log_env = getenv ("EGL_LOG_LEVEL"); + + if (log_env == NULL) { + ReportingLevel = FALLBACK_LOG_LEVEL; + } + else if (strcasecmp (log_env, "fatal") == 0) { + ReportingLevel = _EGL_FATAL; + } + else if (strcasecmp (log_env, "warning") == 0) { + ReportingLevel = _EGL_WARNING; + } + else if (strcasecmp (log_env, "info") == 0) { + ReportingLevel = _EGL_INFO; + } + else if (strcasecmp (log_env, "debug") == 0) { + ReportingLevel = _EGL_DEBUG; + } + else { + fprintf (stderr, "Unrecognized EGL_LOG_LEVEL environment variable value. " + "Expected one of \"fatal\", \"warning\", \"info\", \"debug\". " + "Got \"%s\". Falling back to \"%s\".\n", + log_env, FALLBACK_LOG_LEVEL_STR); + ReportingLevel = FALLBACK_LOG_LEVEL; + } +} /** @@ -25,6 +56,12 @@ _eglLog(EGLint level, const char *fmtStr, ...) va_list args; char msg[MAXSTRING]; const char *levelStr; + static int log_level_initialized = 0; + + if (!log_level_initialized) { + log_level_initialize (); + log_level_initialized = 1; + } if (level <= ReportingLevel) { switch (level) { -- cgit v1.2.3 From d44027dbbd8837b2a32466b0617283649e770907 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 20 Feb 2007 12:48:50 -0500 Subject: Fix parallel make in r300 driver. --- src/mesa/drivers/dri/r300/Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile index 5abb91d987..2ee2328934 100644 --- a/src/mesa/drivers/dri/r300/Makefile +++ b/src/mesa/drivers/dri/r300/Makefile @@ -90,9 +90,11 @@ COMMON_SYMLINKS = \ include ../Makefile.template -$(SYMLINKS): +server: mkdir -p server - for i in $(SYMLINKS) ; do rm -f $$i && test -f ../radeon/$$i && ln -s ../../radeon/$$i $$i ; done + +$(SYMLINKS): server + @[ -e $@ ] || ln -sf ../../radeon/$@ server/ $(COMMON_SYMLINKS): @[ -e $@ ] || ln -sf ../radeon/$@ ./ -- cgit v1.2.3 From 102ad2e066b7a6fcd893db58c64ca685e49a3dfd Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 20 Feb 2007 23:04:21 +0100 Subject: nouveau: nv10: keep 24/8 depth/stencil value, don't check for depth bits --- src/mesa/drivers/dri/nouveau/nv10_state.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index e0475bb3da..09fc07556d 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -123,25 +123,25 @@ static void nv10ClearDepth(GLcontext *ctx, GLclampd d) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - switch (ctx->DrawBuffer->_DepthBuffer->DepthBits) { +/* switch (ctx->DrawBuffer->_DepthBuffer->DepthBits) { case 16: nmesa->clear_value = (uint32_t)(d*0x7FFF); break; - case 24: + case 24:*/ nmesa->clear_value = ((nmesa->clear_value&0x000000FF) | (((uint32_t)(d*0xFFFFFF))<<8)); - break; - } +/* break; + }*/ } static void nv10ClearStencil(GLcontext *ctx, GLint s) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - if (ctx->DrawBuffer->_DepthBuffer->DepthBits == 24) { +/* if (ctx->DrawBuffer->_DepthBuffer->DepthBits == 24) {*/ nmesa->clear_value = ((nmesa->clear_value&0xFFFFFF00)| (s&0x000000FF)); - } +/* }*/ } static void nv10ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) -- cgit v1.2.3 From 79870d100f90555b520af342cf59496236ff8f20 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 20 Feb 2007 23:13:48 +0100 Subject: nouveau: nv10: also check ctx->DrawBuffer in nv10ViewportScale --- src/mesa/drivers/dri/nouveau/nv10_state.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 09fc07556d..e204eba6ba 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -41,13 +41,18 @@ static void nv10ViewportScale(nouveauContextPtr nmesa) GLuint h = ctx->Viewport.Height; GLfloat max_depth = (ctx->Viewport.Near + ctx->Viewport.Far) * 0.5; - switch (ctx->DrawBuffer->_DepthBuffer->DepthBits) { - case 16: - max_depth *= 32767.0; - break; - case 24: - max_depth *= 16777215.0; - break; + if (ctx->DrawBuffer) { + switch (ctx->DrawBuffer->_DepthBuffer->DepthBits) { + case 16: + max_depth *= 32767.0; + break; + case 24: + max_depth *= 16777215.0; + break; + } + } else { + /* Default to 24 bits range */ + max_depth *= 16777215.0; } BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X, 4); -- cgit v1.2.3 From 440759c2cdfdd9a7fbc6500fca2afa519126c1a7 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 20 Feb 2007 23:17:09 +0100 Subject: nouveau: nv10: grr, ctx->DrawBuffer invalid? --- src/mesa/drivers/dri/nouveau/nv10_state.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index e204eba6ba..5f304ccab9 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -41,7 +41,7 @@ static void nv10ViewportScale(nouveauContextPtr nmesa) GLuint h = ctx->Viewport.Height; GLfloat max_depth = (ctx->Viewport.Near + ctx->Viewport.Far) * 0.5; - if (ctx->DrawBuffer) { +/* if (ctx->DrawBuffer) { switch (ctx->DrawBuffer->_DepthBuffer->DepthBits) { case 16: max_depth *= 32767.0; @@ -50,10 +50,10 @@ static void nv10ViewportScale(nouveauContextPtr nmesa) max_depth *= 16777215.0; break; } - } else { + } else {*/ /* Default to 24 bits range */ max_depth *= 16777215.0; - } +/* }*/ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X, 4); OUT_RING_CACHEf ((((GLfloat) w) * 0.5) - 2048.0); -- cgit v1.2.3 From f0bcee5db0523edaacbd1fb0eaa74b435ae7c188 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 20 Feb 2007 15:18:53 -0800 Subject: Delete two invalid assertions. These two assertions are invalid for a couple reasons. Primarily, when this code is compiled into the X-server, the symbols "glSecondaryColor3fEXT" and "glPointParameterivNV" do not exist. --- src/mesa/glapi/glapi.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/mesa/glapi/glapi.c b/src/mesa/glapi/glapi.c index d1ccc5fba6..348f12b3e7 100644 --- a/src/mesa/glapi/glapi.c +++ b/src/mesa/glapi/glapi.c @@ -1003,7 +1003,6 @@ _glapi_check_table(const struct _glapi_table *table) GLuint offset = (secondaryColor3fFunc - (char *) table) / sizeof(void *); assert(secondaryColor3fOffset == _gloffset_SecondaryColor3fEXT); assert(secondaryColor3fOffset == offset); - assert(_glapi_get_proc_address("glSecondaryColor3fEXT") == (_glapi_proc) &glSecondaryColor3fEXT); } { GLuint pointParameterivOffset = _glapi_get_proc_offset("glPointParameterivNV"); @@ -1011,7 +1010,6 @@ _glapi_check_table(const struct _glapi_table *table) GLuint offset = (pointParameterivFunc - (char *) table) / sizeof(void *); assert(pointParameterivOffset == _gloffset_PointParameterivNV); assert(pointParameterivOffset == offset); - assert(_glapi_get_proc_address("glPointParameterivNV") == (_glapi_proc) &glPointParameterivNV); } { GLuint setFenceOffset = _glapi_get_proc_offset("glSetFenceNV"); -- cgit v1.2.3 From 4a1d7d6641ab9e66edce9d98456b978fe90a0617 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 22 Feb 2007 19:33:50 +1100 Subject: r300: get rid of CB_DPATH legacy --- src/mesa/drivers/dri/r300/r300_context.h | 1 - src/mesa/drivers/dri/r300/r300_ioctl.c | 181 ------------------------------- src/mesa/drivers/dri/r300/r300_state.c | 6 - 3 files changed, 188 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 48b50bca65..a339b2f9c1 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -60,7 +60,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #endif //#define OPTIMIZE_ELTS -#define CB_DPATH struct r300_context; typedef struct r300_context r300ContextRec; diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c index 0774a2af6b..c5ad026045 100644 --- a/src/mesa/drivers/dri/r300/r300_ioctl.c +++ b/src/mesa/drivers/dri/r300/r300_ioctl.c @@ -70,10 +70,6 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer) drm_radeon_cmd_header_t *cmd = NULL; r300ContextPtr rmesa=r300; -#ifndef CB_DPATH - int i; -#endif - if (RADEON_DEBUG & DEBUG_IOCTL) fprintf(stderr, "%s: %s buffer (%i,%i %ix%i)\n", __FUNCTION__, buffer ? "back" : "front", @@ -89,168 +85,8 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer) cboffset += r300->radeon.radeonScreen->fbLocation; -#ifndef CB_DPATH - R300_STATECHANGE(r300, vir[0]); - ((drm_r300_cmd_header_t*)r300->hw.vir[0].cmd)->packet0.count = 1; - r300->hw.vir[0].cmd[1] = 0x21030003; - - R300_STATECHANGE(r300, vir[1]); - ((drm_r300_cmd_header_t*)r300->hw.vir[1].cmd)->packet0.count = 1; - r300->hw.vir[1].cmd[1] = 0xF688F688; - - R300_STATECHANGE(r300, vic); - r300->hw.vic.cmd[R300_VIC_CNTL_0] = 0x00000001; - r300->hw.vic.cmd[R300_VIC_CNTL_1] = 0x00000405; - - R300_STATECHANGE(r300, vof); - r300->hw.vof.cmd[R300_VOF_CNTL_0] = R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT - | R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT; - r300->hw.vof.cmd[R300_VOF_CNTL_1] = 0; /* no textures */ - - R300_STATECHANGE(r300, txe); - r300->hw.txe.cmd[R300_TXE_ENABLE] = 0; - - R300_STATECHANGE(r300, vpt); - r300->hw.vpt.cmd[R300_VPT_XSCALE] = r300PackFloat32(1.0); - r300->hw.vpt.cmd[R300_VPT_XOFFSET] = r300PackFloat32(dPriv->x); - r300->hw.vpt.cmd[R300_VPT_YSCALE] = r300PackFloat32(1.0); - r300->hw.vpt.cmd[R300_VPT_YOFFSET] = r300PackFloat32(dPriv->y); - r300->hw.vpt.cmd[R300_VPT_ZSCALE] = r300PackFloat32(1.0); - r300->hw.vpt.cmd[R300_VPT_ZOFFSET] = r300PackFloat32(0.0); - - R300_STATECHANGE(r300, at); - r300->hw.at.cmd[R300_AT_ALPHA_TEST] = 0; - - R300_STATECHANGE(r300, bld); - r300->hw.bld.cmd[R300_BLD_CBLEND] = 0; - r300->hw.bld.cmd[R300_BLD_ABLEND] = 0; - - if (r300->radeon.radeonScreen->cpp == 4) - cbpitch |= R300_COLOR_FORMAT_ARGB8888; - else - cbpitch |= R300_COLOR_FORMAT_RGB565; - - if (r300->radeon.sarea->tiling_enabled) - cbpitch |= R300_COLOR_TILE_ENABLE; - - R300_STATECHANGE(r300, cb); - r300->hw.cb.cmd[R300_CB_OFFSET] = cboffset; - r300->hw.cb.cmd[R300_CB_PITCH] = cbpitch; - - R300_STATECHANGE(r300, unk221C); - r300->hw.unk221C.cmd[1] = R300_221C_CLEAR; - - R300_STATECHANGE(r300, ps); - r300->hw.ps.cmd[R300_PS_POINTSIZE] = - ((dPriv->w * 6) << R300_POINTSIZE_X_SHIFT) | - ((dPriv->h * 6) << R300_POINTSIZE_Y_SHIFT); - - R300_STATECHANGE(r300, ri); - for(i = 1; i <= 8; ++i) - r300->hw.ri.cmd[i] = R300_RS_INTERP_USED; - - R300_STATECHANGE(r300, rc); - /* The second constant is needed to get glxgears display anything .. */ - r300->hw.rc.cmd[1] = (1 << R300_RS_CNTL_CI_CNT_SHIFT) | R300_RS_CNTL_0_UNKNOWN_18; - r300->hw.rc.cmd[2] = 0; - - R300_STATECHANGE(r300, rr); - ((drm_r300_cmd_header_t*)r300->hw.rr.cmd)->packet0.count = 1; - r300->hw.rr.cmd[1] = 0x00004000; - - R300_STATECHANGE(r300, cmk); - if (flags & CLEARBUFFER_COLOR) { - r300->hw.cmk.cmd[R300_CMK_COLORMASK] = - (ctx->Color.ColorMask[BCOMP] ? R300_COLORMASK0_B : 0) | - (ctx->Color.ColorMask[GCOMP] ? R300_COLORMASK0_G : 0) | - (ctx->Color.ColorMask[RCOMP] ? R300_COLORMASK0_R : 0) | - (ctx->Color.ColorMask[ACOMP] ? R300_COLORMASK0_A : 0); - } else { - r300->hw.cmk.cmd[R300_CMK_COLORMASK] = 0; - } - - R300_STATECHANGE(r300, fp); - r300->hw.fp.cmd[R300_FP_CNTL0] = 0; /* 1 pass, no textures */ - r300->hw.fp.cmd[R300_FP_CNTL1] = 0; /* no temporaries */ - r300->hw.fp.cmd[R300_FP_CNTL2] = 0; /* no offset, one ALU instr */ - r300->hw.fp.cmd[R300_FP_NODE0] = 0; - r300->hw.fp.cmd[R300_FP_NODE1] = 0; - r300->hw.fp.cmd[R300_FP_NODE2] = 0; - r300->hw.fp.cmd[R300_FP_NODE3] = R300_PFS_NODE_OUTPUT_COLOR; - - R300_STATECHANGE(r300, fpi[0]); - R300_STATECHANGE(r300, fpi[1]); - R300_STATECHANGE(r300, fpi[2]); - R300_STATECHANGE(r300, fpi[3]); - ((drm_r300_cmd_header_t*)r300->hw.fpi[0].cmd)->packet0.count = 1; - ((drm_r300_cmd_header_t*)r300->hw.fpi[1].cmd)->packet0.count = 1; - ((drm_r300_cmd_header_t*)r300->hw.fpi[2].cmd)->packet0.count = 1; - ((drm_r300_cmd_header_t*)r300->hw.fpi[3].cmd)->packet0.count = 1; - - /* MOV o0, t0 */ - r300->hw.fpi[0].cmd[1] = FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO)); - r300->hw.fpi[1].cmd[1] = FP_SELC(0,NO,XYZ,FP_TMP(0),0,0); - r300->hw.fpi[2].cmd[1] = FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO)); - r300->hw.fpi[3].cmd[1] = FP_SELA(0,NO,W,FP_TMP(0),0,0); - - R300_STATECHANGE(r300, pvs); - r300->hw.pvs.cmd[R300_PVS_CNTL_1] = - (0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT) | - (0 << R300_PVS_CNTL_1_POS_END_SHIFT) | - (1 << R300_PVS_CNTL_1_PROGRAM_END_SHIFT); - r300->hw.pvs.cmd[R300_PVS_CNTL_2] = 0; /* no parameters */ - r300->hw.pvs.cmd[R300_PVS_CNTL_3] = - (1 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT); - - R300_STATECHANGE(r300, vpi); - ((drm_r300_cmd_header_t*)r300->hw.vpi.cmd)->packet0.count = 8; - - /* MOV o0, i0; */ - r300->hw.vpi.cmd[1] = VP_OUT(ADD,OUT,0,XYZW); - r300->hw.vpi.cmd[2] = VP_IN(IN,0); - r300->hw.vpi.cmd[3] = VP_ZERO(); - r300->hw.vpi.cmd[4] = 0; - - /* MOV o1, i1; */ - r300->hw.vpi.cmd[5] = VP_OUT(ADD,OUT,1,XYZW); - r300->hw.vpi.cmd[6] = VP_IN(IN,1); - r300->hw.vpi.cmd[7] = VP_ZERO(); - r300->hw.vpi.cmd[8] = 0; - - R300_STATECHANGE(r300, zs); - r300->hw.zs.cmd[R300_ZS_CNTL_0] = 0; - r300->hw.zs.cmd[R300_ZS_CNTL_1] = 0; - if (flags & CLEARBUFFER_DEPTH) { - r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_RB3D_Z_WRITE_ONLY; - r300->hw.zs.cmd[R300_ZS_CNTL_1] |= (R300_ZS_ALWAYS<hw.zs.cmd[R300_ZS_CNTL_0] |= R300_RB3D_Z_DISABLED_1; // disable - } - - R300_STATECHANGE(r300, zs); - if (flags & CLEARBUFFER_STENCIL) { - r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_RB3D_STENCIL_ENABLE; - r300->hw.zs.cmd[R300_ZS_CNTL_1] |= - (R300_ZS_ALWAYS<hw.zs.cmd[R300_ZS_CNTL_2] = r300->state.stencil.clear; - } - - /* Make sure we have enough space */ - r300EnsureCmdBufSpace(r300, r300->hw.max_state_size + 9+8, __FUNCTION__); - - r300EmitState(r300); -#else -#if 1 cp_wait(r300, R300_WAIT_3D | R300_WAIT_3D_CLEAN); end_3d(rmesa); -#endif R300_STATECHANGE(r300, cb); reg_start(R300_RB3D_COLOROFFSET0, 0); @@ -313,8 +149,6 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer) e32(r300->state.stencil.clear); } -#endif - cmd2 = (drm_r300_cmd_header_t*)r300AllocCmdBuf(r300, 9, __FUNCTION__); cmd2[0].packet3.cmd_type = R300_CMD_PACKET3; cmd2[0].packet3.packet = R300_CMD_PACKET3_CLEAR; @@ -327,7 +161,6 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer) cmd2[7].u = r300PackFloat32(ctx->Color.ClearColor[2]); cmd2[8].u = r300PackFloat32(ctx->Color.ClearColor[3]); -#if 1 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0); e32(0x0000000a); @@ -335,10 +168,8 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer) reg_start(0x4f18,0); e32(0x00000003); cp_wait(rmesa, R300_WAIT_3D | R300_WAIT_3D_CLEAN); -#endif } -#ifdef CB_DPATH static void r300EmitClearState(GLcontext * ctx) { r300ContextPtr r300 = R300_CONTEXT(ctx); @@ -472,7 +303,6 @@ static void r300EmitClearState(GLcontext * ctx) /*reg_start(0x4500,0); e32(2560-1);*/ } -#endif /** * Buffer clear @@ -524,12 +354,10 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask) swapped = r300->radeon.doPageFlip && (r300->radeon.sarea->pfCurrentPage == 1); -#ifdef CB_DPATH /* Make sure it fits there. */ r300EnsureCmdBufSpace(r300, 421*3, __FUNCTION__); if(flags || bits) r300EmitClearState(ctx); -#endif if (flags & BUFFER_BIT_FRONT_LEFT) { r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, swapped); @@ -544,15 +372,6 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask) if (bits) r300ClearBuffer(r300, bits, 0); -#ifndef CB_DPATH - /* Recalculate the hardware state. This could be done more efficiently, - * but do keep it like this for now. - */ - r300ResetHwState(r300); - - /* r300ClearBuffer has trampled all over the hardware state.. */ - r300->hw.all_dirty=GL_TRUE; -#endif } diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 906dfceb48..b30ece160a 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -1768,9 +1768,7 @@ void r300UpdateShaderStates(r300ContextPtr rmesa) GLcontext *ctx; ctx = rmesa->radeon.glCtx; -#ifdef CB_DPATH r300UpdateTextureState(ctx); -#endif r300SetupPixelShader(rmesa); r300_setup_textures(ctx); @@ -1895,10 +1893,6 @@ static void r300InvalidateState(GLcontext * ctx, GLuint new_state) r300UpdateStateParameters(ctx, new_state); -#ifndef CB_DPATH - /* Go inefficiency! */ - r300ResetHwState(r300); -#endif #ifdef HW_VBOS if(new_state & _NEW_ARRAY) r300->state.VB.lock_uptodate = GL_FALSE; -- cgit v1.2.3 From 5e66843733c8123e73cadc1bc5c6111d64abaf25 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Fri, 23 Feb 2007 01:43:13 +0100 Subject: r200 fix broken (by new input handling) fogcoord --- src/mesa/drivers/dri/r200/r200_maos_arrays.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/r200/r200_maos_arrays.c b/src/mesa/drivers/dri/r200/r200_maos_arrays.c index 6a6c30a2b0..3162b508c2 100644 --- a/src/mesa/drivers/dri/r200/r200_maos_arrays.c +++ b/src/mesa/drivers/dri/r200/r200_maos_arrays.c @@ -420,14 +420,14 @@ void r200EmitArrays( GLcontext *ctx, GLubyte *vimap_rev ) if (!rmesa->tcl.vertex_data[i].buf) { if (ctx->VertexProgram._Enabled) emit_vector( ctx, - &(rmesa->tcl.vertex_data[attrib]), + &(rmesa->tcl.vertex_data[i]), (char *)VB->AttribPtr[attrib]->data, 1, VB->AttribPtr[attrib]->stride, count); else emit_vecfog( ctx, - &(rmesa->tcl.vertex_data[attrib]), + &(rmesa->tcl.vertex_data[i]), (char *)VB->AttribPtr[attrib]->data, VB->AttribPtr[attrib]->stride, count); -- cgit v1.2.3 From 3f8c5969ffea5485aa119f4d766cdfee7d4aadeb Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 23 Feb 2007 15:15:50 -0800 Subject: Fix GLAPIENTRYP for OS X. Fix build problems related to incorrect define of GLAPIENTRYP on OS X. Reported by bushing on IRC. --- src/mesa/glapi/gl_table.py | 6 +++++- src/mesa/glapi/glapitable.h | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/glapi/gl_table.py b/src/mesa/glapi/gl_table.py index 52b4be1d2b..69f7bd7c7b 100644 --- a/src/mesa/glapi/gl_table.py +++ b/src/mesa/glapi/gl_table.py @@ -49,7 +49,11 @@ class PrintGlTable(gl_XML.gl_print_base): def printRealHeader(self): print '#ifndef GLAPIENTRYP' - print '#define GLAPIENTRYP' + print '# ifndef GLAPIENTRY' + print '# define GLAPIENTRY' + print '# endif' + print '' + print '# define GLAPIENTRYP GLAPIENTRY *' print '#endif' print '' print 'typedef void (*_glapi_proc)(void); /* generic function pointer */' diff --git a/src/mesa/glapi/glapitable.h b/src/mesa/glapi/glapitable.h index 55548adcd3..4af0c2d43b 100644 --- a/src/mesa/glapi/glapitable.h +++ b/src/mesa/glapi/glapitable.h @@ -30,7 +30,11 @@ # define _GLAPI_TABLE_H_ #ifndef GLAPIENTRYP -#define GLAPIENTRYP +# ifndef GLAPIENTRY +# define GLAPIENTRY +# endif + +# define GLAPIENTRYP GLAPIENTRY * #endif typedef void (*_glapi_proc)(void); /* generic function pointer */ -- cgit v1.2.3 From 5cd30a2b202d12240eac60825f9882838fd66779 Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 24 Feb 2007 18:10:41 -0700 Subject: make src ptr const --- src/mesa/drivers/dri/i915tex/intel_regions.c | 5 +++-- src/mesa/drivers/dri/i915tex/intel_regions.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/intel_regions.c b/src/mesa/drivers/dri/i915tex/intel_regions.c index 1205b180ca..a114bdf896 100644 --- a/src/mesa/drivers/dri/i915tex/intel_regions.c +++ b/src/mesa/drivers/dri/i915tex/intel_regions.c @@ -217,7 +217,8 @@ _mesa_copy_rect(GLubyte * dst, GLuint dst_y, GLuint width, GLuint height, - GLubyte * src, GLuint src_pitch, GLuint src_x, GLuint src_y) + const GLubyte * src, + GLuint src_pitch, GLuint src_x, GLuint src_y) { GLuint i; @@ -253,7 +254,7 @@ intel_region_data(intelScreenPrivate *intelScreen, struct intel_region *dst, GLuint dst_offset, GLuint dstx, GLuint dsty, - void *src, GLuint src_pitch, + const void *src, GLuint src_pitch, GLuint srcx, GLuint srcy, GLuint width, GLuint height) { struct intel_context *intel = intelScreenContext(intelScreen); diff --git a/src/mesa/drivers/dri/i915tex/intel_regions.h b/src/mesa/drivers/dri/i915tex/intel_regions.h index 1415bace69..d938c107a4 100644 --- a/src/mesa/drivers/dri/i915tex/intel_regions.h +++ b/src/mesa/drivers/dri/i915tex/intel_regions.h @@ -103,7 +103,7 @@ void intel_region_data(intelScreenPrivate *intelScreen, struct intel_region *dest, GLuint dest_offset, GLuint destx, GLuint desty, - void *src, GLuint src_stride, + const void *src, GLuint src_stride, GLuint srcx, GLuint srcy, GLuint width, GLuint height); /* Copy rectangular sub-regions -- cgit v1.2.3 From aeaad937b92ac0f5286343ed75c5c9f6876e2650 Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 24 Feb 2007 18:11:09 -0700 Subject: clean-up, comment code --- src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c index 2b1077aee0..93372f4dcc 100644 --- a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c @@ -309,8 +309,13 @@ intel_miptree_image_data(struct intel_context *intel, height = dst->level[level].height; if(dst->compressed) height /= 4; - intel_region_data(intel->intelScreen, dst->region, dst_offset + dst_depth_offset[i], 0, 0, src, src_row_pitch, 0, 0, /* source x,y */ - dst->level[level].width, height); + intel_region_data(intel->intelScreen, dst->region, + dst_offset + dst_depth_offset[i], /* dst_offset */ + 0, 0, /* dstx, dsty */ + src, + src_row_pitch, + 0, 0, /* source x, y */ + dst->level[level].width, height); /* width, height */ src += src_image_pitch; } -- cgit v1.2.3 From 53170942e37ccdf58e06a2cfbfeef6c0ec086ee6 Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 24 Feb 2007 18:14:53 -0700 Subject: Fix broken cubemap mipmap layout (the cubemap.c demo was segfaulting). In i915_miptree_layout() change the width, height parameters that are passed to intel_miptree_set_level_info(). As it was, the width, height values were larger than the source image dimensions and we segfaulted in memcpy() when copying the original texture data into the texture buffer region. This fix should probably be checked by someone more familiar with the code (Keith?) --- src/mesa/drivers/dri/i915tex/i915_tex_layout.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/i915_tex_layout.c b/src/mesa/drivers/dri/i915tex/i915_tex_layout.c index 333fefef85..c844f5351d 100644 --- a/src/mesa/drivers/dri/i915tex/i915_tex_layout.c +++ b/src/mesa/drivers/dri/i915tex/i915_tex_layout.c @@ -62,15 +62,23 @@ i915_miptree_layout(struct intel_mipmap_tree * mt) case GL_TEXTURE_CUBE_MAP:{ const GLuint dim = mt->width0; GLuint face; + GLuint lvlWidth = mt->width0, lvlHeight = mt->height0; + + assert(lvlWidth == lvlHeight); /* cubemap images are square */ /* double pitch for cube layouts */ mt->pitch = ((dim * mt->cpp * 2 + 3) & ~3) / mt->cpp; mt->total_height = dim * 4; - for (level = mt->first_level; level <= mt->last_level; level++) + for (level = mt->first_level; level <= mt->last_level; level++) { intel_miptree_set_level_info(mt, level, 6, 0, 0, - mt->pitch, mt->total_height, 1); + /*OLD: mt->pitch, mt->total_height,*/ + lvlWidth, lvlHeight, + 1); + lvlWidth /= 2; + lvlHeight /= 2; + } for (face = 0; face < 6; face++) { GLuint x = initial_offsets[face][0] * dim; -- cgit v1.2.3 From c080123998f28d9317331aec7ddfcd1074b29daf Mon Sep 17 00:00:00 2001 From: Aapo Tahkola Date: Mon, 26 Feb 2007 01:51:39 +0200 Subject: Fix #10071 - wrong max_index in vbo draw_prims. (Papadakos Panagiotis) --- src/mesa/vbo/vbo_exec_draw.c | 2 +- src/mesa/vbo/vbo_save_draw.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c index 2b52d7a1ff..d8f167b357 100644 --- a/src/mesa/vbo/vbo_exec_draw.c +++ b/src/mesa/vbo/vbo_exec_draw.c @@ -218,7 +218,7 @@ void vbo_exec_vtx_flush( struct vbo_exec_context *exec ) exec->vtx.prim_count, NULL, 0, - exec->vtx.vert_count ); + exec->vtx.vert_count - 1); } } diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c index a50d1cd904..bc59a0d821 100644 --- a/src/mesa/vbo/vbo_save_draw.c +++ b/src/mesa/vbo/vbo_save_draw.c @@ -218,7 +218,7 @@ void vbo_save_playback_vertex_list( GLcontext *ctx, void *data ) node->prim_count, NULL, 0, /* Node is a VBO, so this is ok */ - node->count ); + node->count - 1); } /* Copy to current? -- cgit v1.2.3