summaryrefslogtreecommitdiff
path: root/dist/Mesa/src/mesa/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'dist/Mesa/src/mesa/drivers')
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/common/xmlpool/sv.po226
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/i965/brw_exec_generic.c530
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/intel/intel_tex_layout.c102
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/intel/intel_tex_layout.h41
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/Makefile53
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c616
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h77
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_buffers.c434
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_buffers.h48
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_card.c17
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_card.h49
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_card_list.h232
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_context.c378
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_context.h236
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_ctrlreg.h44
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_dri.h28
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_driver.c146
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_driver.h42
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_fifo.c142
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_fifo.h195
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_lock.c81
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_lock.h69
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_msg.h67
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_object.c117
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_object.h47
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_query.c198
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_query.h38
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_reg.h1505
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_screen.c382
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_screen.h61
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_shader.c833
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_shader.h454
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c1050
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_shader_1.c16
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c264
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_span.c125
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_span.h39
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_state.c345
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_state.h50
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_state_cache.c69
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_state_cache.h29
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c127
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_swtcl.h55
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_sync.c194
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_sync.h67
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_tex.c49
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_tex.h38
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nv04_state.c540
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nv04_swtcl.c619
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nv04_swtcl.h12
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nv10_state.c798
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nv10_swtcl.c656
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nv10_swtcl.h40
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nv20_shader.h121
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nv20_state.c824
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nv20_vertprog.c447
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nv30_fragprog.c742
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nv30_shader.h379
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nv30_state.c980
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nv30_vertprog.c367
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nv40_fragprog.c224
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nv40_shader.h467
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nv40_vertprog.c778
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/nouveau/nv50_state.c641
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/r300/r300_emit.c627
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/r300/r300_mem.c385
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/r300/r300_mem.h37
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/r300/r300_vertprog.c1305
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/r300/r300_vertprog.h89
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/unichrome/server/via_regs.h1
-rw-r--r--dist/Mesa/src/mesa/drivers/x11/xm_glide.c276
-rw-r--r--dist/Mesa/src/mesa/drivers/x11/xm_glide.h40
-rw-r--r--dist/Mesa/src/mesa/drivers/x11/xm_image.c133
-rw-r--r--dist/Mesa/src/mesa/drivers/x11/xm_image.h84
74 files changed, 21617 insertions, 0 deletions
diff --git a/dist/Mesa/src/mesa/drivers/dri/common/xmlpool/sv.po b/dist/Mesa/src/mesa/drivers/dri/common/xmlpool/sv.po
new file mode 100644
index 000000000..ba32b2ff1
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/common/xmlpool/sv.po
@@ -0,0 +1,226 @@
+# Swedish translation of DRI driver options.
+# Copyright (C) Free Software Foundation, Inc.
+# This file is distributed under the same license as the Mesa package.
+# Daniel Nylander <po@danielnylander.se>, 2006.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Mesa DRI\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2005-04-11 23:19+0200\n"
+"PO-Revision-Date: 2006-09-18 10:56+0100\n"
+"Last-Translator: Daniel Nylander <po@danielnylander.se>\n"
+"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: t_options.h:53
+msgid "Debugging"
+msgstr "Felsökning"
+
+#: t_options.h:57
+msgid "Disable 3D acceleration"
+msgstr "Inaktivera 3D-accelerering"
+
+#: t_options.h:62
+msgid "Show performance boxes"
+msgstr "Visa prestandarutor"
+
+#: t_options.h:69
+msgid "Image Quality"
+msgstr "Bildkvalitet"
+
+#: t_options.h:77
+msgid "Texture color depth"
+msgstr "Färgdjup för texturer"
+
+#: t_options.h:78
+msgid "Prefer frame buffer color depth"
+msgstr "Föredra färgdjupet för framebuffer"
+
+#: t_options.h:79
+msgid "Prefer 32 bits per texel"
+msgstr "Föredra 32 bitar per texel"
+
+#: t_options.h:80
+msgid "Prefer 16 bits per texel"
+msgstr "Föredra 16 bitar per texel"
+
+#: t_options.h:81
+msgid "Force 16 bits per texel"
+msgstr "Tvinga 16 bitar per texel"
+
+#: t_options.h:87
+msgid "Initial maximum value for anisotropic texture filtering"
+msgstr "Initialt maximalt värde för anisotropisk texturfiltrering"
+
+#: t_options.h:92
+msgid "Forbid negative texture LOD bias"
+msgstr "Förbjud negativ LOD-kompensation för texturer"
+
+#: t_options.h:97
+msgid "Enable S3TC texture compression even if software support is not available"
+msgstr "Aktivera S3TC-texturkomprimering även om programvarustöd saknas"
+
+#: t_options.h:104
+msgid "Initial color reduction method"
+msgstr "Initial färgminskningsmetod"
+
+#: t_options.h:105
+msgid "Round colors"
+msgstr "Avrunda färger"
+
+#: t_options.h:106
+msgid "Dither colors"
+msgstr "Utjämna färger"
+
+#: t_options.h:114
+msgid "Color rounding method"
+msgstr "Färgavrundningsmetod"
+
+#: t_options.h:115
+msgid "Round color components downward"
+msgstr "Avrunda färdkomponenter nedåt"
+
+#: t_options.h:116
+msgid "Round to nearest color"
+msgstr "Avrunda till närmsta färg"
+
+#: t_options.h:125
+msgid "Color dithering method"
+msgstr "Färgutjämningsmetod"
+
+#: t_options.h:126
+msgid "Horizontal error diffusion"
+msgstr "Horisontell felspridning"
+
+#: t_options.h:127
+msgid "Horizontal error diffusion, reset error at line start"
+msgstr "Horisontell felspridning, återställ fel vid radbörjan"
+
+#: t_options.h:128
+msgid "Ordered 2D color dithering"
+msgstr "Ordnad 2D-färgutjämning"
+
+#: t_options.h:134
+msgid "Floating point depth buffer"
+msgstr "Buffert för flytande punktdjup"
+
+#: t_options.h:140
+msgid "Performance"
+msgstr "Prestanda"
+
+#: t_options.h:148
+msgid "TCL mode (Transformation, Clipping, Lighting)"
+msgstr "TCL-läge (Transformation, Clipping, Lighting)"
+
+#: t_options.h:149
+msgid "Use software TCL pipeline"
+msgstr "Använd programvaru-TCL-rörledning"
+
+#: t_options.h:150
+msgid "Use hardware TCL as first TCL pipeline stage"
+msgstr "Använd maskinvaru-TCL som första TCL-rörledningssteg"
+
+#: t_options.h:151
+msgid "Bypass the TCL pipeline"
+msgstr "Kringgå TCL-rörledningen"
+
+#: t_options.h:152
+msgid "Bypass the TCL pipeline with state-based machine code generated on-the-fly"
+msgstr "Kringgå TCL-rörledningen med tillståndsbaserad maskinkod som direktgenereras"
+
+#: t_options.h:161
+msgid "Method to limit rendering latency"
+msgstr "Metod för att begränsa renderingslatens"
+
+#: t_options.h:162
+msgid "Busy waiting for the graphics hardware"
+msgstr "Upptagen med att vänta på grafikhårdvaran"
+
+#: t_options.h:163
+msgid "Sleep for brief intervals while waiting for the graphics hardware"
+msgstr "Sov i korta intervall under väntan på grafikhårdvaran"
+
+#: t_options.h:164
+msgid "Let the graphics hardware emit a software interrupt and sleep"
+msgstr "Låt grafikhårdvaran sända ut ett programvaruavbrott och sov"
+
+#: t_options.h:174
+msgid "Synchronization with vertical refresh (swap intervals)"
+msgstr "Synkronisering med vertikal uppdatering (växlingsintervall)"
+
+#: t_options.h:175
+msgid "Never synchronize with vertical refresh, ignore application's choice"
+msgstr "Synkronisera aldrig med vertikal uppdatering, ignorera programmets val"
+
+#: t_options.h:176
+msgid "Initial swap interval 0, obey application's choice"
+msgstr "Initialt växlingsintervall 0, följ programmets val"
+
+#: t_options.h:177
+msgid "Initial swap interval 1, obey application's choice"
+msgstr "Initialt växlingsintervall 1, följ programmets val"
+
+#: t_options.h:178
+msgid "Always synchronize with vertical refresh, application chooses the minimum swap interval"
+msgstr "Synkronisera alltid med vertikal uppdatering, programmet väljer den minsta växlingsintervallen"
+
+#: t_options.h:186
+msgid "Use HyperZ to boost performance"
+msgstr "Använd HyperZ för att maximera prestandan"
+
+#: t_options.h:191
+msgid "Number of texture units used"
+msgstr "Antal använda texturenheter"
+
+#: t_options.h:196
+msgid "Support larger textures not guaranteed to fit into graphics memory"
+msgstr "Stöd för större texturer är inte garanterat att passa i grafikminnet"
+
+#: t_options.h:197
+msgid "No"
+msgstr "Nej"
+
+#: t_options.h:198
+msgid "At least 1 texture must fit under worst-case assumptions"
+msgstr "Åtminstone en textur måste passa för antaget sämsta förhållande"
+
+#: t_options.h:199
+msgid "Announce hardware limits"
+msgstr "Annonsera hårdvarubegränsningar"
+
+#: t_options.h:205
+msgid "Texture filtering quality vs. speed, AKA “brilinear” texture filtering"
+msgstr "Texturfiltreringskvalitet mot hastighet, även kallad \"brilinear\"-texturfiltrering"
+
+#: t_options.h:213
+msgid "Used types of texture memory"
+msgstr "Använda typer av texturminne"
+
+#: t_options.h:214
+msgid "All available memory"
+msgstr "Allt tillgängligt minne"
+
+#: t_options.h:215
+msgid "Only card memory (if available)"
+msgstr "Endast kortminne (om tillgängligt)"
+
+#: t_options.h:216
+msgid "Only GART (AGP/PCIE) memory (if available)"
+msgstr "Endast GART-minne (AGP/PCIE) (om tillgängligt)"
+
+#: t_options.h:224
+msgid "Features that are not hardware-accelerated"
+msgstr "Funktioner som inte är hårdvaruaccelererade"
+
+#: t_options.h:228
+msgid "Enable extension GL_ARB_vertex_program"
+msgstr "Aktivera tillägget GL_ARB_vertex_program"
+
+#: t_options.h:233
+msgid "Enable extension GL_NV_vertex_program"
+msgstr "Aktivera tillägget GL_NV_vertex_program"
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/i965/brw_exec_generic.c b/dist/Mesa/src/mesa/drivers/dri/i965/brw_exec_generic.c
new file mode 100644
index 000000000..11d1ef76f
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/i965/brw_exec_generic.c
@@ -0,0 +1,530 @@
+/**************************************************************************
+
+Copyright 2004 Tungsten Graphics Inc., Cedar Park, Texas.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "glheader.h"
+#include "context.h"
+#include "macros.h"
+#include "vtxfmt.h"
+#include "dlist.h"
+#include "state.h"
+#include "light.h"
+#include "api_arrayelt.h"
+#include "api_noop.h"
+
+#include "brw_exec.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 ); \
+ struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; \
+ \
+ if ((ATTR) == 0) { \
+ GLuint i; \
+ \
+ if (N>0) exec->vtx.vbptr[0] = v[0]; \
+ if (N>1) exec->vtx.vbptr[1] = v[1]; \
+ if (N>2) exec->vtx.vbptr[2] = v[2]; \
+ if (N>3) exec->vtx.vbptr[3] = v[3]; \
+ \
+ for (i = N; 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 ); \
+ } \
+ else { \
+ GLfloat *dest = exec->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 )
+
+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 )
+
+void brw_exec_generic_attr_table_init( brw_attrfv_func (*tab)[4] )
+{
+ 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 );
+}
+
+/* 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 ); \
+ struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; \
+ exec->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) )
+
+#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)
+
+
+static void GLAPIENTRY brw_Vertex2f( GLfloat x, GLfloat y )
+{
+ DISPATCH_ATTR2F( BRW_ATTRIB_POS, x, y );
+}
+
+static void GLAPIENTRY brw_Vertex2fv( const GLfloat *v )
+{
+ DISPATCH_ATTR2FV( BRW_ATTRIB_POS, v );
+}
+
+static void GLAPIENTRY brw_Vertex3f( GLfloat x, GLfloat y, GLfloat z )
+{
+ DISPATCH_ATTR3F( BRW_ATTRIB_POS, x, y, z );
+}
+
+static void GLAPIENTRY brw_Vertex3fv( const GLfloat *v )
+{
+ DISPATCH_ATTR3FV( BRW_ATTRIB_POS, v );
+}
+
+static void GLAPIENTRY brw_Vertex4f( GLfloat x, GLfloat y, GLfloat z,
+ GLfloat w )
+{
+ DISPATCH_ATTR4F( BRW_ATTRIB_POS, x, y, z, w );
+}
+
+static void GLAPIENTRY brw_Vertex4fv( const GLfloat *v )
+{
+ DISPATCH_ATTR4FV( BRW_ATTRIB_POS, v );
+}
+
+static void GLAPIENTRY brw_TexCoord1f( GLfloat x )
+{
+ DISPATCH_ATTR1F( BRW_ATTRIB_TEX0, x );
+}
+
+static void GLAPIENTRY brw_TexCoord1fv( const GLfloat *v )
+{
+ DISPATCH_ATTR1FV( BRW_ATTRIB_TEX0, v );
+}
+
+static void GLAPIENTRY brw_TexCoord2f( GLfloat x, GLfloat y )
+{
+ DISPATCH_ATTR2F( BRW_ATTRIB_TEX0, x, y );
+}
+
+static void GLAPIENTRY brw_TexCoord2fv( const GLfloat *v )
+{
+ DISPATCH_ATTR2FV( BRW_ATTRIB_TEX0, v );
+}
+
+static void GLAPIENTRY brw_TexCoord3f( GLfloat x, GLfloat y, GLfloat z )
+{
+ DISPATCH_ATTR3F( BRW_ATTRIB_TEX0, x, y, z );
+}
+
+static void GLAPIENTRY brw_TexCoord3fv( const GLfloat *v )
+{
+ DISPATCH_ATTR3FV( BRW_ATTRIB_TEX0, v );
+}
+
+static void GLAPIENTRY brw_TexCoord4f( GLfloat x, GLfloat y, GLfloat z,
+ GLfloat w )
+{
+ DISPATCH_ATTR4F( BRW_ATTRIB_TEX0, x, y, z, w );
+}
+
+static void GLAPIENTRY brw_TexCoord4fv( const GLfloat *v )
+{
+ DISPATCH_ATTR4FV( BRW_ATTRIB_TEX0, v );
+}
+
+static void GLAPIENTRY brw_Normal3f( GLfloat x, GLfloat y, GLfloat z )
+{
+ DISPATCH_ATTR3F( BRW_ATTRIB_NORMAL, x, y, z );
+}
+
+static void GLAPIENTRY brw_Normal3fv( const GLfloat *v )
+{
+ DISPATCH_ATTR3FV( BRW_ATTRIB_NORMAL, v );
+}
+
+static void GLAPIENTRY brw_FogCoordfEXT( GLfloat x )
+{
+ DISPATCH_ATTR1F( BRW_ATTRIB_FOG, x );
+}
+
+static void GLAPIENTRY brw_FogCoordfvEXT( const GLfloat *v )
+{
+ DISPATCH_ATTR1FV( BRW_ATTRIB_FOG, v );
+}
+
+static void GLAPIENTRY brw_Color3f( GLfloat x, GLfloat y, GLfloat z )
+{
+ DISPATCH_ATTR3F( BRW_ATTRIB_COLOR0, x, y, z );
+}
+
+static void GLAPIENTRY brw_Color3fv( const GLfloat *v )
+{
+ DISPATCH_ATTR3FV( BRW_ATTRIB_COLOR0, v );
+}
+
+static void GLAPIENTRY brw_Color4f( GLfloat x, GLfloat y, GLfloat z,
+ GLfloat w )
+{
+ DISPATCH_ATTR4F( BRW_ATTRIB_COLOR0, x, y, z, w );
+}
+
+static void GLAPIENTRY brw_Color4fv( const GLfloat *v )
+{
+ DISPATCH_ATTR4FV( BRW_ATTRIB_COLOR0, v );
+}
+
+static void GLAPIENTRY brw_SecondaryColor3fEXT( GLfloat x, GLfloat y,
+ GLfloat z )
+{
+ DISPATCH_ATTR3F( BRW_ATTRIB_COLOR1, x, y, z );
+}
+
+static void GLAPIENTRY brw_SecondaryColor3fvEXT( const GLfloat *v )
+{
+ DISPATCH_ATTR3FV( BRW_ATTRIB_COLOR1, v );
+}
+
+static void GLAPIENTRY brw_MultiTexCoord1f( GLenum target, GLfloat x )
+{
+ GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0;
+ DISPATCH_ATTR1F( attr, x );
+}
+
+static void GLAPIENTRY brw_MultiTexCoord1fv( GLenum target,
+ const GLfloat *v )
+{
+ GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0;
+ DISPATCH_ATTR1FV( attr, v );
+}
+
+static void GLAPIENTRY brw_MultiTexCoord2f( GLenum target, GLfloat x,
+ GLfloat y )
+{
+ GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0;
+ DISPATCH_ATTR2F( attr, x, y );
+}
+
+static void GLAPIENTRY brw_MultiTexCoord2fv( GLenum target,
+ const GLfloat *v )
+{
+ GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0;
+ DISPATCH_ATTR2FV( attr, v );
+}
+
+static void GLAPIENTRY brw_MultiTexCoord3f( GLenum target, GLfloat x,
+ GLfloat y, GLfloat z)
+{
+ GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0;
+ DISPATCH_ATTR3F( attr, x, y, z );
+}
+
+static void GLAPIENTRY brw_MultiTexCoord3fv( GLenum target,
+ const GLfloat *v )
+{
+ GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0;
+ DISPATCH_ATTR3FV( attr, v );
+}
+
+static void GLAPIENTRY brw_MultiTexCoord4f( GLenum target, GLfloat x,
+ GLfloat y, GLfloat z,
+ GLfloat w )
+{
+ GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0;
+ DISPATCH_ATTR4F( attr, x, y, z, w );
+}
+
+static void GLAPIENTRY brw_MultiTexCoord4fv( GLenum target,
+ const GLfloat *v )
+{
+ GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0;
+ DISPATCH_ATTR4FV( attr, v );
+}
+
+
+static void GLAPIENTRY brw_VertexAttrib1fNV( GLuint index, GLfloat x )
+{
+ if (index >= BRW_ATTRIB_FIRST_MATERIAL) index = ERROR_ATTRIB;
+ DISPATCH_ATTR1F( index, x );
+}
+
+static void GLAPIENTRY brw_VertexAttrib1fvNV( GLuint index,
+ const GLfloat *v )
+{
+ if (index >= BRW_ATTRIB_FIRST_MATERIAL) index = ERROR_ATTRIB;
+ DISPATCH_ATTR1FV( index, v );
+}
+
+static void GLAPIENTRY brw_VertexAttrib2fNV( GLuint index, GLfloat x,
+ GLfloat y )
+{
+ if (index >= BRW_ATTRIB_FIRST_MATERIAL) index = ERROR_ATTRIB;
+ DISPATCH_ATTR2F( index, x, y );
+}
+
+static void GLAPIENTRY brw_VertexAttrib2fvNV( GLuint index,
+ const GLfloat *v )
+{
+ if (index >= BRW_ATTRIB_FIRST_MATERIAL) index = ERROR_ATTRIB;
+ DISPATCH_ATTR2FV( index, v );
+}
+
+static void GLAPIENTRY brw_VertexAttrib3fNV( GLuint index, GLfloat x,
+ GLfloat y, GLfloat z )
+{
+ if (index >= BRW_ATTRIB_FIRST_MATERIAL) index = ERROR_ATTRIB;
+ DISPATCH_ATTR3F( index, x, y, z );
+}
+
+static void GLAPIENTRY brw_VertexAttrib3fvNV( GLuint index,
+ const GLfloat *v )
+{
+ if (index >= BRW_ATTRIB_FIRST_MATERIAL) index = ERROR_ATTRIB;
+ DISPATCH_ATTR3FV( index, v );
+}
+
+static void GLAPIENTRY brw_VertexAttrib4fNV( GLuint index, GLfloat x,
+ GLfloat y, GLfloat z,
+ GLfloat w )
+{
+ if (index >= BRW_ATTRIB_FIRST_MATERIAL) index = ERROR_ATTRIB;
+ DISPATCH_ATTR4F( index, x, y, z, w );
+}
+
+static void GLAPIENTRY brw_VertexAttrib4fvNV( GLuint index,
+ const GLfloat *v )
+{
+ if (index >= BRW_ATTRIB_FIRST_MATERIAL) index = ERROR_ATTRIB;
+ DISPATCH_ATTR4FV( index, v );
+}
+
+
+/*
+ * XXX adjust index
+ */
+
+static void GLAPIENTRY brw_VertexAttrib1fARB( GLuint index, GLfloat x )
+{
+ if (index >= BRW_ATTRIB_FIRST_MATERIAL) index = ERROR_ATTRIB;
+ DISPATCH_ATTR1F( index, x );
+}
+
+static void GLAPIENTRY brw_VertexAttrib1fvARB( GLuint index,
+ const GLfloat *v )
+{
+ if (index >= BRW_ATTRIB_FIRST_MATERIAL) index = ERROR_ATTRIB;
+ DISPATCH_ATTR1FV( index, v );
+}
+
+static void GLAPIENTRY brw_VertexAttrib2fARB( GLuint index, GLfloat x,
+ GLfloat y )
+{
+ if (index >= BRW_ATTRIB_FIRST_MATERIAL) index = ERROR_ATTRIB;
+ DISPATCH_ATTR2F( index, x, y );
+}
+
+static void GLAPIENTRY brw_VertexAttrib2fvARB( GLuint index,
+ const GLfloat *v )
+{
+ if (index >= BRW_ATTRIB_FIRST_MATERIAL) index = ERROR_ATTRIB;
+ DISPATCH_ATTR2FV( index, v );
+}
+
+static void GLAPIENTRY brw_VertexAttrib3fARB( GLuint index, GLfloat x,
+ GLfloat y, GLfloat z )
+{
+ if (index >= BRW_ATTRIB_FIRST_MATERIAL) index = ERROR_ATTRIB;
+ DISPATCH_ATTR3F( index, x, y, z );
+}
+
+static void GLAPIENTRY brw_VertexAttrib3fvARB( GLuint index,
+ const GLfloat *v )
+{
+ if (index >= BRW_ATTRIB_FIRST_MATERIAL) index = ERROR_ATTRIB;
+ DISPATCH_ATTR3FV( index, v );
+}
+
+static void GLAPIENTRY brw_VertexAttrib4fARB( GLuint index, GLfloat x,
+ GLfloat y, GLfloat z,
+ GLfloat w )
+{
+ if (index >= BRW_ATTRIB_FIRST_MATERIAL) index = ERROR_ATTRIB;
+ DISPATCH_ATTR4F( index, x, y, z, w );
+}
+
+static void GLAPIENTRY brw_VertexAttrib4fvARB( GLuint index,
+ const GLfloat *v )
+{
+ if (index >= BRW_ATTRIB_FIRST_MATERIAL) index = ERROR_ATTRIB;
+ DISPATCH_ATTR4FV( index, v );
+}
+
+
+/* Install the generic versions of the 2nd level dispatch
+ * functions. Some of these have a codegen alternative.
+ */
+void brw_exec_vtx_generic_init( struct brw_exec_context *exec )
+{
+ GLvertexformat *vfmt = &exec->vtxfmt;
+
+ 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->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->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;
+}
diff --git a/dist/Mesa/src/mesa/drivers/dri/intel/intel_tex_layout.c b/dist/Mesa/src/mesa/drivers/dri/intel/intel_tex_layout.c
new file mode 100644
index 000000000..fcb5cc390
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/intel/intel_tex_layout.c
@@ -0,0 +1,102 @@
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+ /*
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ * Michel Dänzer <michel@tungstengraphics.com>
+ */
+
+#include "intel_mipmap_tree.h"
+#include "intel_tex_layout.h"
+#include "macros.h"
+
+
+static int align(int value, int alignment)
+{
+ return (value + alignment - 1) & ~(alignment - 1);
+}
+
+void i945_miptree_layout_2d( struct intel_mipmap_tree *mt )
+{
+ GLint align_h = 2, align_w = 4;
+ GLuint level;
+ GLuint x = 0;
+ GLuint y = 0;
+ GLuint width = mt->width0;
+ GLuint height = mt->height0;
+
+ mt->pitch = mt->width0;
+
+ /* May need to adjust pitch to accomodate the placement of
+ * the 2nd mipmap. This occurs when the alignment
+ * constraints of mipmap placement push the right edge of the
+ * 2nd mipmap out past the width of its parent.
+ */
+ if (mt->first_level != mt->last_level) {
+ GLuint mip1_width = align(minify(mt->width0), align_w)
+ + minify(minify(mt->width0));
+
+ if (mip1_width > mt->width0)
+ mt->pitch = mip1_width;
+ }
+
+ /* Pitch must be a whole number of dwords, even though we
+ * express it in texels.
+ */
+ mt->pitch = align(mt->pitch * mt->cpp, 4) / 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,
+ height, 1);
+
+ if (mt->compressed)
+ img_height = MAX2(1, height/4);
+ else
+ img_height = align(height, align_h);
+
+
+ /* Because the images are packed better, the final offset
+ * might not be the maximal one:
+ */
+ mt->total_height = MAX2(mt->total_height, y + img_height);
+
+ /* Layout_below: step right after second mipmap.
+ */
+ if (level == mt->first_level + 1) {
+ x += align(width, align_w);
+ }
+ else {
+ y += img_height;
+ }
+
+ width = minify(width);
+ height = minify(height);
+ }
+}
diff --git a/dist/Mesa/src/mesa/drivers/dri/intel/intel_tex_layout.h b/dist/Mesa/src/mesa/drivers/dri/intel/intel_tex_layout.h
new file mode 100644
index 000000000..1e37f8f52
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/intel/intel_tex_layout.h
@@ -0,0 +1,41 @@
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+ /*
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ * Michel Dänzer <michel@tungstengraphics.com>
+ */
+
+#include "macros.h"
+
+
+static GLuint minify( GLuint d )
+{
+ return MAX2(1, d>>1);
+}
+
+extern void i945_miptree_layout_2d( struct intel_mipmap_tree *mt );
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/Makefile b/dist/Mesa/src/mesa/drivers/dri/nouveau/Makefile
new file mode 100644
index 000000000..20d2de5ee
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/Makefile
@@ -0,0 +1,53 @@
+# src/mesa/drivers/dri/nouveau/Makefile
+
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = nouveau_dri.so
+
+MINIGLX_SOURCES =
+
+DRIVER_SOURCES = \
+ nouveau_bufferobj.c \
+ nouveau_buffers.c \
+ nouveau_card.c \
+ nouveau_context.c \
+ nouveau_driver.c \
+ nouveau_fifo.c \
+ nouveau_lock.c \
+ nouveau_object.c \
+ nouveau_screen.c \
+ nouveau_span.c \
+ nouveau_state.c \
+ nouveau_state_cache.c \
+ nouveau_shader.c \
+ nouveau_shader_0.c \
+ nouveau_shader_1.c \
+ nouveau_shader_2.c \
+ nouveau_tex.c \
+ nouveau_swtcl.c \
+ nouveau_sync.c \
+ nouveau_query.c \
+ nv04_state.c \
+ nv04_swtcl.c \
+ nv10_state.c \
+ nv10_swtcl.c \
+ nv20_state.c \
+ nv20_vertprog.c \
+ nv30_state.c \
+ nv30_fragprog.c \
+ nv30_vertprog.c \
+ nv40_fragprog.c \
+ nv40_vertprog.c \
+ nv50_state.c
+
+C_SOURCES = \
+ $(COMMON_SOURCES) \
+ $(DRIVER_SOURCES)
+
+ASM_SOURCES =
+
+
+include ../Makefile.template
+
+symlinks:
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c
new file mode 100644
index 000000000..684ed7b01
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c
@@ -0,0 +1,616 @@
+#include "bufferobj.h"
+#include "enums.h"
+
+#include "nouveau_bufferobj.h"
+#include "nouveau_buffers.h"
+#include "nouveau_context.h"
+#include "nouveau_drm.h"
+#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)
+
+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_bo_gpu_ref(GLcontext *ctx, struct gl_buffer_object *bo)
+{
+ nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo;
+
+ assert(nbo->mapped == GL_FALSE);
+
+ 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; i<dirty->nr_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; i<nr_dirty; i++) {
+ nouveau_bufferobj_region *r = &dirty->dirty[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; i<nr_dirty; i++) {
+ nouveau_bufferobj_region *r = &dirty->dirty[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)
+{
+}
+
+static struct gl_buffer_object *
+nouveauNewBufferObject(GLcontext *ctx, GLuint buffer, GLenum target)
+{
+ nouveau_buffer_object *nbo;
+
+ nbo = CALLOC_STRUCT(nouveau_buffer_object_t);
+ if (nbo)
+ _mesa_initialize_buffer_object(&nbo->mesa, buffer, target);
+ DEBUG("bo=%p\n", nbo);
+
+ return nbo ? &nbo->mesa : NULL;
+}
+
+static void
+nouveauDeleteBuffer(GLcontext *ctx, struct gl_buffer_object *obj)
+{
+ nouveau_buffer_object *nbo = (nouveau_buffer_object *)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);
+
+ _mesa_delete_buffer_object(ctx, obj);
+}
+
+static void
+nouveauBufferData(GLcontext *ctx, GLenum target, GLsizeiptrARB size,
+ const GLvoid *data, GLenum usage,
+ struct gl_buffer_object *obj)
+{
+ GLuint gpu_flags;
+
+ 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),
+ 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;
+ }
+ nouveau_bo_init_storage(ctx, gpu_flags, size, data, usage, obj);
+}
+
+static void
+nouveauBufferSubData(GLcontext *ctx, GLenum target, GLintptrARB offset,
+ GLsizeiptrARB size, const GLvoid *data,
+ struct gl_buffer_object *obj)
+{
+ GLvoid *out;
+
+ DEBUG("target=%s, offset=0x%x, size=%d, data=%p, obj=%p\n",
+ _mesa_lookup_enum_by_nr(target),
+ (GLuint)offset, (GLuint)size, data, 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);
+}
+
+static void
+nouveauGetBufferSubData(GLcontext *ctx, GLenum target, GLintptrARB offset,
+ GLsizeiptrARB size, GLvoid *data,
+ struct gl_buffer_object *obj)
+{
+ const GLvoid *in;
+
+ DEBUG("target=%s, offset=0x%x, size=%d, data=%p, obj=%p\n",
+ _mesa_lookup_enum_by_nr(target),
+ (GLuint)offset, (GLuint)size, data, 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)
+{
+ DEBUG("target=%s, access=%s, obj=%p\n",
+ _mesa_lookup_enum_by_nr(target),
+ _mesa_lookup_enum_by_nr(access),
+ obj
+ );
+
+ /* Already mapped.. */
+ if (obj->Pointer)
+ return NULL;
+
+ /* 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.
+ */
+ obj->Pointer = nouveau_bo_map(ctx, GL_READ_WRITE_ARB, obj);
+
+ /* 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 (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);
+ }
+
+ return obj->Pointer;
+}
+
+static GLboolean
+nouveauUnmapBuffer(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj)
+{
+ DEBUG("target=%s, obj=%p\n", _mesa_lookup_enum_by_nr(target), obj);
+
+ assert(obj->Pointer);
+
+ nouveau_bo_unmap(ctx, obj);
+ obj->Pointer = NULL;
+ return GL_TRUE;
+}
+
+void
+nouveauInitBufferObjects(GLcontext *ctx)
+{
+ ctx->Driver.BindBuffer = nouveauBindBuffer;
+ ctx->Driver.NewBufferObject = nouveauNewBufferObject;
+ ctx->Driver.DeleteBuffer = nouveauDeleteBuffer;
+ ctx->Driver.BufferData = nouveauBufferData;
+ ctx->Driver.BufferSubData = nouveauBufferSubData;
+ ctx->Driver.GetBufferSubData = nouveauGetBufferSubData;
+ ctx->Driver.MapBuffer = nouveauMapBuffer;
+ ctx->Driver.UnmapBuffer = nouveauUnmapBuffer;
+}
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h
new file mode 100644
index 000000000..932450fd8
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h
@@ -0,0 +1,77 @@
+#ifndef __NOUVEAU_BUFFEROBJ_H__
+#define __NOUVEAU_BUFFEROBJ_H__
+
+#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;
+ nouveau_bufferobj_dirty gpu_dirty;
+
+ /* Memory used for CPU access to the buffer */
+ GLuint cpu_mem_flags;
+ nouveau_mem * cpu_mem;
+ GLvoid * cpu_mem_sys;
+ nouveau_bufferobj_dirty cpu_dirty;
+} nouveau_buffer_object;
+
+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);
+
+#endif
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_buffers.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_buffers.c
new file mode 100644
index 000000000..b54f68f40
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_buffers.c
@@ -0,0 +1,434 @@
+#include "utils.h"
+#include "framebuffer.h"
+#include "renderbuffer.h"
+#include "fbobject.h"
+
+#include "nouveau_context.h"
+#include "nouveau_buffers.h"
+#include "nouveau_object.h"
+#include "nouveau_fifo.h"
+#include "nouveau_reg.h"
+#include "nouveau_msg.h"
+
+#define MAX_MEMFMT_LENGTH 32768
+
+/* Unstrided blit using NV_MEMORY_TO_MEMORY_FORMAT */
+GLboolean
+nouveau_memformat_flat_emit(GLcontext *ctx,
+ nouveau_mem *dst, nouveau_mem *src,
+ GLuint dst_offset, GLuint src_offset,
+ GLuint size)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ uint32_t src_handle, dst_handle;
+ GLuint count;
+
+ if (src_offset + size > src->size) {
+ MESSAGE("src out of nouveau_mem bounds\n");
+ return GL_FALSE;
+ }
+ if (dst_offset + size > dst->size) {
+ MESSAGE("dst out of nouveau_mem bounds\n");
+ return GL_FALSE;
+ }
+
+ src_handle = (src->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaAGP;
+ dst_handle = (dst->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaAGP;
+ src_offset += nouveau_mem_gpu_offset_get(ctx, src);
+ dst_offset += nouveau_mem_gpu_offset_get(ctx, dst);
+
+ BEGIN_RING_SIZE(NvSubMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_OBJECT_IN, 2);
+ OUT_RING (src_handle);
+ OUT_RING (dst_handle);
+
+ count = (size / MAX_MEMFMT_LENGTH) + ((size % MAX_MEMFMT_LENGTH) ? 1 : 0);
+
+ while (count--) {
+ GLuint length = (size > MAX_MEMFMT_LENGTH) ? MAX_MEMFMT_LENGTH : size;
+
+ BEGIN_RING_SIZE(NvSubMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
+ OUT_RING (src_offset);
+ OUT_RING (dst_offset);
+ OUT_RING (0); /* pitch in */
+ OUT_RING (0); /* pitch out */
+ OUT_RING (length); /* line length */
+ OUT_RING (1); /* number of lines */
+ OUT_RING ((1 << 8) /* dst_inc */ | (1 << 0) /* src_inc */);
+ OUT_RING (0); /* buffer notify? */
+ FIRE_RING();
+
+ src_offset += length;
+ dst_offset += length;
+ size -= length;
+ }
+
+ return GL_TRUE;
+}
+
+void
+nouveau_mem_free(GLcontext *ctx, nouveau_mem *mem)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ drm_nouveau_mem_free_t memf;
+
+ if (NOUVEAU_DEBUG & DEBUG_MEM) {
+ fprintf(stderr, "%s: type=0x%x, offset=0x%x, size=0x%x\n",
+ __func__, mem->type, (GLuint)mem->offset, (GLuint)mem->size);
+ }
+
+ if (mem->map)
+ drmUnmap(mem->map, mem->size);
+ memf.flags = mem->type;
+ memf.region_offset = mem->offset;
+ drmCommandWrite(nmesa->driFd, DRM_NOUVEAU_MEM_FREE, &memf, sizeof(memf));
+ FREE(mem);
+}
+
+nouveau_mem *
+nouveau_mem_alloc(GLcontext *ctx, int type, GLuint size, GLuint align)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ drm_nouveau_mem_alloc_t mema;
+ nouveau_mem *mem;
+ int ret;
+
+ if (NOUVEAU_DEBUG & DEBUG_MEM) {
+ fprintf(stderr, "%s: requested: type=0x%x, size=0x%x, align=0x%x\n",
+ __func__, type, (GLuint)size, align);
+ }
+
+ mem = CALLOC(sizeof(nouveau_mem));
+ if (!mem)
+ return NULL;
+
+ mema.flags = type;
+ mema.size = mem->size = size;
+ mema.alignment = align;
+ mem->map = NULL;
+ ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_MEM_ALLOC,
+ &mema, sizeof(mema));
+ if (ret) {
+ FREE(mem);
+ return NULL;
+ }
+ mem->offset = mema.region_offset;
+ mem->type = mema.flags;
+
+ if (NOUVEAU_DEBUG & DEBUG_MEM) {
+ fprintf(stderr, "%s: actual: type=0x%x, offset=0x%x, size=0x%x\n",
+ __func__, mem->type, (GLuint)mem->offset, (GLuint)mem->size);
+ }
+
+ if (type & NOUVEAU_MEM_MAPPED)
+ ret = drmMap(nmesa->driFd, mem->offset, mem->size, &mem->map);
+ if (ret) {
+ mem->map = NULL;
+ nouveau_mem_free(ctx, mem);
+ mem = NULL;
+ }
+
+ return mem;
+}
+
+uint32_t
+nouveau_mem_gpu_offset_get(GLcontext *ctx, nouveau_mem *mem)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ if (mem->type & NOUVEAU_MEM_FB)
+ return (uint32_t)mem->offset - nmesa->vram_phys;
+ else if (mem->type & NOUVEAU_MEM_AGP)
+ return (uint32_t)mem->offset - nmesa->agp_phys;
+ else
+ return 0xDEADF00D;
+}
+
+static GLboolean
+nouveau_renderbuffer_pixelformat(nouveau_renderbuffer *nrb,
+ GLenum internalFormat)
+{
+ nrb->mesa.InternalFormat = internalFormat;
+
+ /*TODO: We probably want to extend this a bit, and maybe make
+ * card-specific?
+ */
+ switch (internalFormat) {
+ case GL_RGBA:
+ case GL_RGBA8:
+ nrb->mesa._BaseFormat = GL_RGBA;
+ nrb->mesa._ActualFormat= GL_RGBA8;
+ nrb->mesa.DataType = GL_UNSIGNED_BYTE;
+ nrb->mesa.RedBits = 8;
+ nrb->mesa.GreenBits = 8;
+ nrb->mesa.BlueBits = 8;
+ nrb->mesa.AlphaBits = 8;
+ nrb->cpp = 4;
+ break;
+ case GL_RGB:
+ case GL_RGB5:
+ nrb->mesa._BaseFormat = GL_RGB;
+ nrb->mesa._ActualFormat= GL_RGB5;
+ nrb->mesa.DataType = GL_UNSIGNED_BYTE;
+ nrb->mesa.RedBits = 5;
+ nrb->mesa.GreenBits = 6;
+ nrb->mesa.BlueBits = 5;
+ nrb->mesa.AlphaBits = 0;
+ nrb->cpp = 2;
+ break;
+ case GL_DEPTH_COMPONENT16:
+ nrb->mesa._BaseFormat = GL_DEPTH_COMPONENT;
+ nrb->mesa._ActualFormat= GL_DEPTH_COMPONENT16;
+ nrb->mesa.DataType = GL_UNSIGNED_SHORT;
+ nrb->mesa.DepthBits = 16;
+ nrb->cpp = 2;
+ break;
+ case GL_DEPTH_COMPONENT24:
+ nrb->mesa._BaseFormat = GL_DEPTH_COMPONENT;
+ nrb->mesa._ActualFormat= GL_DEPTH24_STENCIL8_EXT;
+ nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT;
+ nrb->mesa.DepthBits = 24;
+ nrb->cpp = 4;
+ break;
+ case GL_STENCIL_INDEX8_EXT:
+ nrb->mesa._BaseFormat = GL_STENCIL_INDEX;
+ nrb->mesa._ActualFormat= GL_DEPTH24_STENCIL8_EXT;
+ nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT;
+ nrb->mesa.StencilBits = 8;
+ nrb->cpp = 4;
+ break;
+ case GL_DEPTH24_STENCIL8_EXT:
+ nrb->mesa._BaseFormat = GL_DEPTH_STENCIL_EXT;
+ nrb->mesa._ActualFormat= GL_DEPTH24_STENCIL8_EXT;
+ nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT;
+ nrb->mesa.DepthBits = 24;
+ nrb->mesa.StencilBits = 8;
+ nrb->cpp = 4;
+ break;
+ default:
+ return GL_FALSE;
+ break;
+ }
+
+ return GL_TRUE;
+}
+
+static GLboolean
+nouveau_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLenum internalFormat,
+ GLuint width,
+ GLuint height)
+{
+ nouveau_renderbuffer *nrb = (nouveau_renderbuffer*)rb;
+
+ if (!nouveau_renderbuffer_pixelformat(nrb, internalFormat)) {
+ fprintf(stderr, "%s: unknown internalFormat\n", __func__);
+ return GL_FALSE;
+ }
+
+ /* If this buffer isn't statically alloc'd, we may need to ask the
+ * drm for more memory */
+ if (!nrb->dPriv && (rb->Width != width || rb->Height != height)) {
+ GLuint pitch;
+
+ /* align pitches to 64 bytes */
+ pitch = ((width * nrb->cpp) + 63) & ~63;
+
+ if (nrb->mem)
+ nouveau_mem_free(ctx, nrb->mem);
+ nrb->mem = nouveau_mem_alloc(ctx,
+ NOUVEAU_MEM_FB | NOUVEAU_MEM_MAPPED,
+ pitch*height,
+ 0);
+ if (!nrb->mem)
+ return GL_FALSE;
+
+ /* update nouveau_renderbuffer info */
+ nrb->offset = nouveau_mem_gpu_offset_get(ctx, nrb->mem);
+ nrb->pitch = pitch;
+ }
+
+ rb->Width = width;
+ rb->Height = height;
+ rb->InternalFormat = internalFormat;
+ return GL_TRUE;
+}
+
+static void
+nouveau_renderbuffer_delete(struct gl_renderbuffer *rb)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ nouveau_renderbuffer *nrb = (nouveau_renderbuffer*)rb;
+
+ if (nrb->mem)
+ nouveau_mem_free(ctx, nrb->mem);
+ FREE(nrb);
+}
+
+nouveau_renderbuffer *
+nouveau_renderbuffer_new(GLenum internalFormat, GLvoid *map,
+ GLuint offset, GLuint pitch,
+ __DRIdrawablePrivate *dPriv)
+{
+ nouveau_renderbuffer *nrb;
+
+ nrb = CALLOC_STRUCT(nouveau_renderbuffer_t);
+ if (nrb) {
+ _mesa_init_renderbuffer(&nrb->mesa, 0);
+
+ nouveau_renderbuffer_pixelformat(nrb, internalFormat);
+
+ nrb->mesa.AllocStorage = nouveau_renderbuffer_storage;
+ nrb->mesa.Delete = nouveau_renderbuffer_delete;
+
+ nrb->dPriv = dPriv;
+ nrb->offset = offset;
+ nrb->pitch = pitch;
+ nrb->map = map;
+ }
+
+ return nrb;
+}
+
+static void
+nouveau_cliprects_drawable_set(nouveauContextPtr nmesa,
+ nouveau_renderbuffer *nrb)
+{
+ __DRIdrawablePrivate *dPriv = nrb->dPriv;
+
+ nmesa->numClipRects = dPriv->numClipRects;
+ nmesa->pClipRects = dPriv->pClipRects;
+ nmesa->drawX = dPriv->x;
+ nmesa->drawY = dPriv->y;
+}
+
+static void
+nouveau_cliprects_renderbuffer_set(nouveauContextPtr nmesa,
+ nouveau_renderbuffer *nrb)
+{
+ nmesa->numClipRects = 1;
+ nmesa->pClipRects = &nmesa->osClipRect;
+ nmesa->osClipRect.x1 = 0;
+ nmesa->osClipRect.y1 = 0;
+ nmesa->osClipRect.x2 = nrb->mesa.Width;
+ nmesa->osClipRect.y2 = nrb->mesa.Height;
+ nmesa->drawX = 0;
+ nmesa->drawY = 0;
+}
+
+void
+nouveau_window_moved(GLcontext *ctx)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nouveau_renderbuffer *nrb;
+
+ nrb = (nouveau_renderbuffer *)ctx->DrawBuffer->_ColorDrawBuffers[0][0];
+ if (!nrb)
+ return;
+
+ if (!nrb->dPriv)
+ nouveau_cliprects_renderbuffer_set(nmesa, nrb);
+ else
+ nouveau_cliprects_drawable_set(nmesa, nrb);
+
+ /* Viewport depends on window size/position, nouveauCalcViewport
+ * will take care of calling the hw-specific WindowMoved
+ */
+ ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y,
+ ctx->Viewport.Width, ctx->Viewport.Height);
+ /* Scissor depends on window position */
+ ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
+ ctx->Scissor.Width, ctx->Scissor.Height);
+}
+
+GLboolean
+nouveau_build_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nouveau_renderbuffer *color[MAX_DRAW_BUFFERS];
+ nouveau_renderbuffer *depth;
+
+ _mesa_update_framebuffer(ctx);
+ _mesa_update_draw_buffer_bounds(ctx);
+
+ color[0] = (nouveau_renderbuffer *)fb->_ColorDrawBuffers[0][0];
+ if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped)
+ depth = (nouveau_renderbuffer *)fb->_DepthBuffer->Wrapped;
+ else
+ depth = (nouveau_renderbuffer *)fb->_DepthBuffer;
+
+ if (!nmesa->hw_func.BindBuffers(nmesa, 1, color, depth))
+ return GL_FALSE;
+ nouveau_window_moved(ctx);
+
+ return GL_TRUE;
+}
+
+static void
+nouveauDrawBuffer(GLcontext *ctx, GLenum buffer)
+{
+ nouveau_build_framebuffer(ctx, ctx->DrawBuffer);
+}
+
+static struct gl_framebuffer *
+nouveauNewFramebuffer(GLcontext *ctx, GLuint name)
+{
+ return _mesa_new_framebuffer(ctx, name);
+}
+
+static struct gl_renderbuffer *
+nouveauNewRenderbuffer(GLcontext *ctx, GLuint name)
+{
+ nouveau_renderbuffer *nrb;
+
+ nrb = CALLOC_STRUCT(nouveau_renderbuffer_t);
+ if (nrb) {
+ _mesa_init_renderbuffer(&nrb->mesa, name);
+
+ nrb->mesa.AllocStorage = nouveau_renderbuffer_storage;
+ nrb->mesa.Delete = nouveau_renderbuffer_delete;
+ }
+ return &nrb->mesa;
+}
+
+static void
+nouveauBindFramebuffer(GLcontext *ctx, GLenum target, struct gl_framebuffer *fb)
+{
+ nouveau_build_framebuffer(ctx, fb);
+}
+
+static void
+nouveauFramebufferRenderbuffer(GLcontext *ctx,
+ struct gl_framebuffer *fb,
+ GLenum attachment,
+ struct gl_renderbuffer *rb)
+{
+ _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
+ nouveau_build_framebuffer(ctx, fb);
+}
+
+static void
+nouveauRenderTexture(GLcontext *ctx,
+ struct gl_framebuffer *fb,
+ struct gl_renderbuffer_attachment *att)
+{
+}
+
+static void
+nouveauFinishRenderTexture(GLcontext *ctx,
+ struct gl_renderbuffer_attachment *att)
+{
+}
+
+void
+nouveauInitBufferFuncs(struct dd_function_table *func)
+{
+ func->DrawBuffer = nouveauDrawBuffer;
+
+ func->NewFramebuffer = nouveauNewFramebuffer;
+ func->NewRenderbuffer = nouveauNewRenderbuffer;
+ func->BindFramebuffer = nouveauBindFramebuffer;
+ func->FramebufferRenderbuffer = nouveauFramebufferRenderbuffer;
+ func->RenderTexture = nouveauRenderTexture;
+ func->FinishRenderTexture = nouveauFinishRenderTexture;
+}
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_buffers.h b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_buffers.h
new file mode 100644
index 000000000..d86455184
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_buffers.h
@@ -0,0 +1,48 @@
+#ifndef __NOUVEAU_BUFFERS_H__
+#define __NOUVEAU_BUFFERS_H__
+
+#include <stdint.h>
+#include "mtypes.h"
+#include "utils.h"
+#include "renderbuffer.h"
+
+typedef struct nouveau_mem_t {
+ int type;
+ uint64_t offset;
+ uint64_t size;
+ void* map;
+} nouveau_mem;
+
+extern nouveau_mem *nouveau_mem_alloc(GLcontext *ctx, int type,
+ GLuint size, GLuint align);
+extern void nouveau_mem_free(GLcontext *ctx, nouveau_mem *mem);
+extern uint32_t nouveau_mem_gpu_offset_get(GLcontext *ctx, nouveau_mem *mem);
+
+extern GLboolean nouveau_memformat_flat_emit(GLcontext *ctx,
+ nouveau_mem *dst,
+ nouveau_mem *src,
+ GLuint dst_offset,
+ GLuint src_offset,
+ GLuint size);
+
+typedef struct nouveau_renderbuffer_t {
+ struct gl_renderbuffer mesa; /* must be first! */
+ __DRIdrawablePrivate *dPriv;
+
+ nouveau_mem *mem;
+ void * map;
+
+ int cpp;
+ uint32_t offset;
+ uint32_t pitch;
+} nouveau_renderbuffer;
+
+extern nouveau_renderbuffer *nouveau_renderbuffer_new(GLenum internalFormat,
+ GLvoid *map, GLuint offset, GLuint pitch, __DRIdrawablePrivate *dPriv);
+extern void nouveau_window_moved(GLcontext *ctx);
+extern GLboolean nouveau_build_framebuffer(GLcontext *, struct gl_framebuffer *);
+extern nouveau_renderbuffer *nouveau_current_draw_buffer(GLcontext *ctx);
+
+extern void nouveauInitBufferFuncs(struct dd_function_table *func);
+
+#endif
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_card.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_card.c
new file mode 100644
index 000000000..91f12f0d7
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_card.c
@@ -0,0 +1,17 @@
+
+#include "nouveau_card.h"
+#include "nouveau_reg.h"
+#include "nouveau_drm.h"
+#include "nouveau_card_list.h"
+
+
+nouveau_card* nouveau_card_lookup(uint32_t device_id)
+{
+ int i;
+ for(i=0;i<sizeof(nouveau_card_list)/sizeof(nouveau_card)-1;i++)
+ if (nouveau_card_list[i].id==(device_id&0xffff))
+ return &(nouveau_card_list[i]);
+ return NULL;
+}
+
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_card.h b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_card.h
new file mode 100644
index 000000000..8a4c5f224
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_card.h
@@ -0,0 +1,49 @@
+/**************************************************************************
+
+Copyright 2006 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.
+
+**************************************************************************/
+
+
+#ifndef __NOUVEAU_CARD_H__
+#define __NOUVEAU_CARD_H__
+
+#include "dri_util.h"
+#include "drm.h"
+#include "nouveau_drm.h"
+
+typedef struct nouveau_card_t {
+ uint16_t id; /* last 4 digits of pci id, last digit is always 0 */
+ char* name; /* the user-friendly card name */
+ uint32_t class_3d; /* the object class this card uses for 3D */
+ uint32_t type; /* the major card family */
+ uint32_t flags;
+}
+nouveau_card;
+
+#define NV_HAS_LMA 0x00000001
+
+extern nouveau_card* nouveau_card_lookup(uint32_t device_id);
+
+#endif
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_card_list.h b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_card_list.h
new file mode 100644
index 000000000..8ec5c4a18
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_card_list.h
@@ -0,0 +1,232 @@
+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_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},
+{0x0043, "NV40.3", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0044, "GeForce 6800 XT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0045, "GeForce 6800 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0046, "GeForce 6800 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0047, "GeForce 6800 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0048, "GeForce 6800 XT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0049, "NV40GL", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x004D, "Quadro FX 4000", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x004E, "Quadro FX 4000", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0090, "GeForce 7800 GTX", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0091, "GeForce 7800 GTX", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0092, "GeForce 7800 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0093, "GeForce 7800 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{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_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},
+{0x00C3, "Geforce 6800 XT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00C8, "GeForce Go 6800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00C9, "GeForce Go 6800 Ultra", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00CC, "Quadro FX Go1400", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00CD, "Quadro FX 3450/4000 SDI", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00CE, "Quadro FX 1400", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00F0, "GeForce 6800/GeForce 6800 Ultra", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00F1, "GeForce 6600/GeForce 6600 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00F2, "GeForce 6600/GeForce 6600 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00F3, "GeForce 6200", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00F4, "GeForce 6600 LE", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00F5, "GeForce 7800 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{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|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|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},
+{0x0103, "Quadro", NV10_TCL_PRIMITIVE_3D, NV_10, 0},
+{0x0110, "GeForce2 MX/MX 400", NV11_TCL_PRIMITIVE_3D, NV_11, 0},
+{0x0111, "GeForce2 MX 100 DDR/200 DDR", NV11_TCL_PRIMITIVE_3D, NV_11, 0},
+{0x0112, "GeForce2 Go", NV11_TCL_PRIMITIVE_3D, NV_11, 0},
+{0x0113, "Quadro2 MXR/EX/Go", NV11_TCL_PRIMITIVE_3D, NV_11, 0},
+{0x0140, "GeForce 6600 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0141, "GeForce 6600", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0142, "GeForce 6600 PCIe", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0144, "GeForce Go 6600", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0145, "GeForce 6610 XL", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0146, "Geforce Go 6600TE/6200TE", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{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},
+{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},
+{0x0151, "GeForce2 Ti", NV11_TCL_PRIMITIVE_3D, NV_15, 0},
+{0x0152, "GeForce2 Ultra, Bladerunner", NV11_TCL_PRIMITIVE_3D, NV_15, 0},
+{0x0153, "Quadro2 Pro", NV11_TCL_PRIMITIVE_3D, NV_15, 0},
+{0x0161, "GeForce 6200 TurboCache(TM)", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x0162, "GeForce 6200 SE TurboCache (TM)", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x0163, "GeForce 6200 LE", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x0164, "GeForce Go 6200", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x0165, "Quadro NVS 285", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x0166, "GeForce Go 6400", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x0167, "GeForce Go 6200 TurboCache", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x0168, "GeForce Go 6200 TurboCache", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x0170, "GeForce4 MX 460", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0171, "GeForce4 MX 440", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0172, "GeForce4 MX 420", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0173, "GeForce4 MX 440-SE", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0174, "GeForce4 440 Go", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0175, "GeForce4 420 Go", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0176, "GeForce4 420 Go 32M", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0177, "GeForce4 460 Go", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0178, "Quadro4 550 XGL", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0179, "GeForce4 420 Go 32M", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x017A, "Quadro4 200/400 NVS", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x017B, "Quadro4 550 XGL", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x017C, "Quadro4 500 GoGL", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x017D, "GeForce4 410 Go 16M", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0181, "GeForce4 MX 440 AGP 8x", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0182, "GeForce4 MX 440SE AGP 8x", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0183, "GeForce4 MX 420 AGP 8x", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0185, "GeForce4 MX 4000 AGP 8x", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0186, "GeForce4 448 Go", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0187, "GeForce4 488 Go", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0188, "Quadro4 580 XGL", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x018A, "Quadro4 NVS AGP 8x", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x018B, "Quadro4 380 XGL", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x018C, "Quadro NVS 50 PCI", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x018D, "GeForce4 448 Go", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0191, "GeForce 8800 GTX", NV30_TCL_PRIMITIVE_3D|0x5000, NV_50, 0},
+{0x0193, "GeForce 8800 GTS", NV30_TCL_PRIMITIVE_3D|0x5000, NV_50, 0},
+{0x01A0, "GeForce2 MX Integrated Graphics", NV11_TCL_PRIMITIVE_3D, NV_11, 0},
+{0x01D1, "GeForce 7300 LE", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x01D6, "GeForce Go 7200", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x01D7, "Quadro NVS 110M / GeForce Go 7300", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x01D8, "GeForce Go 7400", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{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, 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},
+{0x0218, "GeForce 6800 XT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{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|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},
+{0x0298, "GeForce Go 7900 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0299, "GeForce Go 7900 GTX", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x029A, "Quadro FX 2500M", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x029B, "Quadro FX 1500M", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x029C, "Quadro FX 5500", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{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, NV_20, 0},
+{0x02E1, "GeForce 7600 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 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|0x0400, NV_30, 0},
+{0x0334, "GeForce FX 5900ZT", NV30_TCL_PRIMITIVE_3D|0x0400, 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},
+{0x0398, "GeForce Go 7600", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x03D0, "GeForce 6100 nForce 430", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x03D1, "GeForce 6100 nForce 405", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x03D2, "GeForce 6100 nForce 400", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x03D5, "GeForce 6100 nForce 420", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x0008, "NV1", 0, NV_03, 0},
+{0x0009, "DAC64", 0, NV_03, 0},
+{0x0018, "Riva128", 0, NV_03, 0},
+{0x0019, "Riva128ZX", 0, NV_03, 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},
+};
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_context.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_context.c
new file mode 100644
index 000000000..8e11eb613
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_context.c
@@ -0,0 +1,378 @@
+/**************************************************************************
+
+Copyright 2006 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 "glheader.h"
+#include "context.h"
+#include "simple_list.h"
+#include "imports.h"
+#include "matrix.h"
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "framebuffer.h"
+
+#include "tnl/tnl.h"
+#include "tnl/t_pipeline.h"
+#include "tnl/t_vp_build.h"
+
+#include "drivers/common/driverfuncs.h"
+
+#include "nouveau_context.h"
+#include "nouveau_driver.h"
+//#include "nouveau_state.h"
+#include "nouveau_span.h"
+#include "nouveau_object.h"
+#include "nouveau_fifo.h"
+#include "nouveau_tex.h"
+#include "nouveau_msg.h"
+#include "nouveau_reg.h"
+#include "nouveau_lock.h"
+#include "nouveau_query.h"
+#include "nv04_swtcl.h"
+#include "nv10_swtcl.h"
+
+#include "vblank.h"
+#include "utils.h"
+#include "texmem.h"
+#include "xmlpool.h" /* for symbolic values of enum-type options */
+
+#ifndef NOUVEAU_DEBUG
+int NOUVEAU_DEBUG = 0;
+#endif
+
+static const struct dri_debug_control debug_control[] =
+{
+ { "shaders" , DEBUG_SHADERS },
+ { "mem" , DEBUG_MEM },
+ { "bufferobj" , DEBUG_BUFFEROBJ },
+ { NULL , 0 }
+};
+
+#define need_GL_ARB_vertex_program
+#define need_GL_ARB_occlusion_query
+#include "extension_helper.h"
+
+const struct dri_extension common_extensions[] =
+{
+ { NULL, 0 }
+};
+
+const struct dri_extension nv10_extensions[] =
+{
+ { NULL, 0 }
+};
+
+const struct dri_extension nv20_extensions[] =
+{
+ { NULL, 0 }
+};
+
+const struct dri_extension nv30_extensions[] =
+{
+ { "GL_ARB_fragment_program", NULL },
+ { NULL, 0 }
+};
+
+const struct dri_extension nv40_extensions[] =
+{
+ /* ARB_vp can be moved to nv20/30 once the shader backend has been
+ * written for those cards.
+ */
+ { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions },
+ { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions},
+ { NULL, 0 }
+};
+
+const struct dri_extension nv50_extensions[] =
+{
+ { NULL, 0 }
+};
+
+/* Create the device specific context.
+ */
+GLboolean nouveauCreateContext( const __GLcontextModes *glVisual,
+ __DRIcontextPrivate *driContextPriv,
+ void *sharedContextPrivate )
+{
+ GLcontext *ctx, *shareCtx;
+ __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+ struct dd_function_table functions;
+ nouveauContextPtr nmesa;
+ nouveauScreenPtr screen;
+
+ /* Allocate the context */
+ nmesa = (nouveauContextPtr) CALLOC( sizeof(*nmesa) );
+ if ( !nmesa )
+ return GL_FALSE;
+
+ nmesa->driContext = driContextPriv;
+ nmesa->driScreen = sPriv;
+ nmesa->driDrawable = NULL;
+ nmesa->hHWContext = driContextPriv->hHWContext;
+ nmesa->driHwLock = &sPriv->pSAREA->lock;
+ nmesa->driFd = sPriv->fd;
+
+ nmesa->screen = (nouveauScreenPtr)(sPriv->private);
+ screen=nmesa->screen;
+
+ /* Create the hardware context */
+ if (!nouveauDRMGetParam(nmesa, NOUVEAU_GETPARAM_FB_PHYSICAL,
+ &nmesa->vram_phys))
+ return GL_FALSE;
+ if (!nouveauDRMGetParam(nmesa, NOUVEAU_GETPARAM_FB_SIZE,
+ &nmesa->vram_size))
+ return GL_FALSE;
+ if (!nouveauDRMGetParam(nmesa, NOUVEAU_GETPARAM_AGP_PHYSICAL,
+ &nmesa->agp_phys))
+ return GL_FALSE;
+ if (!nouveauDRMGetParam(nmesa, NOUVEAU_GETPARAM_AGP_SIZE,
+ &nmesa->agp_size))
+ return GL_FALSE;
+ if (!nouveauFifoInit(nmesa))
+ return GL_FALSE;
+ nouveauObjectInit(nmesa);
+
+
+ /* Init default driver functions then plug in our nouveau-specific functions
+ * (the texture functions are especially important)
+ */
+ _mesa_init_driver_functions( &functions );
+ nouveauDriverInitFunctions( &functions );
+ nouveauTexInitFunctions( &functions );
+
+ /* Allocate the Mesa context */
+ if (sharedContextPrivate)
+ shareCtx = ((nouveauContextPtr) sharedContextPrivate)->glCtx;
+ else
+ shareCtx = NULL;
+ nmesa->glCtx = _mesa_create_context(glVisual, shareCtx,
+ &functions, (void *) nmesa);
+ if (!nmesa->glCtx) {
+ FREE(nmesa);
+ return GL_FALSE;
+ }
+ driContextPriv->driverPrivate = nmesa;
+ ctx = nmesa->glCtx;
+
+ /* Parse configuration files */
+ driParseConfigFiles (&nmesa->optionCache, &screen->optionCache,
+ screen->driScreen->myNum, "nouveau");
+
+ nmesa->sarea = (drm_nouveau_sarea_t *)((char *)sPriv->pSAREA +
+ screen->sarea_priv_offset);
+
+ /* Enable any supported extensions */
+ driInitExtensions(ctx, common_extensions, GL_TRUE);
+ if (nmesa->screen->card->type >= NV_10)
+ driInitExtensions(ctx, nv10_extensions, GL_FALSE);
+ if (nmesa->screen->card->type >= NV_20)
+ driInitExtensions(ctx, nv20_extensions, GL_FALSE);
+ if (nmesa->screen->card->type >= NV_30)
+ driInitExtensions(ctx, nv30_extensions, GL_FALSE);
+ if (nmesa->screen->card->type >= NV_40)
+ driInitExtensions(ctx, nv40_extensions, GL_FALSE);
+ if (nmesa->screen->card->type >= NV_50)
+ driInitExtensions(ctx, nv50_extensions, GL_FALSE);
+
+ nmesa->current_primitive = -1;
+
+ nouveauShaderInitFuncs(ctx);
+ /* Install Mesa's fixed-function texenv shader support */
+ if (nmesa->screen->card->type >= NV_40)
+ ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
+
+ /* Initialize the swrast */
+ _swrast_CreateContext( ctx );
+ _vbo_CreateContext( ctx );
+ _tnl_CreateContext( ctx );
+ _swsetup_CreateContext( ctx );
+
+ _math_matrix_ctr(&nmesa->viewport);
+
+ nouveauDDInitStateFuncs( ctx );
+ nouveauSpanInitFunctions( ctx );
+ nouveauDDInitState( nmesa );
+ switch(nmesa->screen->card->type)
+ {
+ case NV_03:
+ //nv03TriInitFunctions( ctx );
+ break;
+ case NV_04:
+ case NV_05:
+ nv04TriInitFunctions( ctx );
+ break;
+ case NV_10:
+ case NV_20:
+ case NV_30:
+ case NV_40:
+ case NV_44:
+ case NV_50:
+ default:
+ nv10TriInitFunctions( ctx );
+ break;
+ }
+
+ nouveauInitBufferObjects(ctx);
+ if (!nouveauSyncInitFuncs(ctx))
+ return GL_FALSE;
+ nouveauQueryInitFuncs(ctx);
+ nmesa->hw_func.InitCard(nmesa);
+ nouveauInitState(ctx);
+
+ driContextPriv->driverPrivate = (void *)nmesa;
+
+ NOUVEAU_DEBUG = driParseDebugString( getenv( "NOUVEAU_DEBUG" ),
+ debug_control );
+
+ if (driQueryOptionb(&nmesa->optionCache, "no_rast")) {
+ fprintf(stderr, "disabling 3D acceleration\n");
+ FALLBACK(nmesa, NOUVEAU_FALLBACK_DISABLE, 1);
+ }
+
+ return GL_TRUE;
+}
+
+/* Destroy the device specific context. */
+void nouveauDestroyContext( __DRIcontextPrivate *driContextPriv )
+{
+ nouveauContextPtr nmesa = (nouveauContextPtr) driContextPriv->driverPrivate;
+
+ assert(nmesa);
+ if ( nmesa ) {
+ /* free the option cache */
+ driDestroyOptionCache (&nmesa->optionCache);
+
+ FREE( nmesa );
+ }
+
+}
+
+
+/* Force the context `c' to be the current context and associate with it
+ * buffer `b'.
+ */
+GLboolean nouveauMakeCurrent( __DRIcontextPrivate *driContextPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ __DRIdrawablePrivate *driReadPriv )
+{
+ if ( driContextPriv ) {
+ nouveauContextPtr nmesa = (nouveauContextPtr) driContextPriv->driverPrivate;
+ struct gl_framebuffer *draw_fb =
+ (struct gl_framebuffer*)driDrawPriv->driverPrivate;
+ struct gl_framebuffer *read_fb =
+ (struct gl_framebuffer*)driReadPriv->driverPrivate;
+
+ driDrawableInitVBlank(driDrawPriv, nmesa->vblank_flags, &nmesa->vblank_seq );
+ nmesa->driDrawable = driDrawPriv;
+
+ _mesa_resize_framebuffer(nmesa->glCtx, draw_fb,
+ driDrawPriv->w, driDrawPriv->h);
+ if (draw_fb != read_fb) {
+ _mesa_resize_framebuffer(nmesa->glCtx, draw_fb,
+ driReadPriv->w,
+ driReadPriv->h);
+ }
+ _mesa_make_current(nmesa->glCtx, draw_fb, read_fb);
+
+ nouveau_build_framebuffer(nmesa->glCtx,
+ driDrawPriv->driverPrivate);
+ } else {
+ _mesa_make_current( NULL, NULL, NULL );
+ }
+
+ return GL_TRUE;
+}
+
+
+/* Force the context `c' to be unbound from its buffer.
+ */
+GLboolean nouveauUnbindContext( __DRIcontextPrivate *driContextPriv )
+{
+ return GL_TRUE;
+}
+
+static void nouveauDoSwapBuffers(nouveauContextPtr nmesa,
+ __DRIdrawablePrivate *dPriv)
+{
+ struct gl_framebuffer *fb;
+ nouveau_renderbuffer *src, *dst;
+ drm_clip_rect_t *box;
+ int nbox, i;
+
+ fb = (struct gl_framebuffer *)dPriv->driverPrivate;
+ dst = (nouveau_renderbuffer*)
+ fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
+ src = (nouveau_renderbuffer*)
+ fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
+
+#ifdef ALLOW_MULTI_SUBCHANNEL
+ LOCK_HARDWARE(nmesa);
+ nbox = dPriv->numClipRects;
+ box = dPriv->pClipRects;
+
+ if (nbox) {
+ BEGIN_RING_SIZE(NvSubCtxSurf2D,
+ NV10_CONTEXT_SURFACES_2D_FORMAT, 4);
+ if (src->mesa._ActualFormat == GL_RGBA8)
+ OUT_RING (6); /* X8R8G8B8 */
+ else
+ OUT_RING (4); /* R5G6B5 */
+ OUT_RING ((dst->pitch << 16) | src->pitch);
+ OUT_RING (src->offset);
+ OUT_RING (dst->offset);
+ }
+
+ for (i=0; i<nbox; i++, box++) {
+ BEGIN_RING_SIZE(NvSubImageBlit, NV10_IMAGE_BLIT_SET_POINT, 3);
+ OUT_RING (((box->y1 - dPriv->y) << 16) |
+ (box->x1 - dPriv->x));
+ OUT_RING ((box->y1 << 16) | box->x1);
+ OUT_RING (((box->y2 - box->y1) << 16) |
+ (box->x2 - box->x1));
+ }
+ FIRE_RING();
+
+ UNLOCK_HARDWARE(nmesa);
+#endif
+}
+
+void nouveauSwapBuffers(__DRIdrawablePrivate *dPriv)
+{
+ if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
+ nouveauContextPtr nmesa = dPriv->driContextPriv->driverPrivate;
+
+ if (nmesa->glCtx->Visual.doubleBufferMode) {
+ _mesa_notifySwapBuffers(nmesa->glCtx);
+ nouveauDoSwapBuffers(nmesa, dPriv);
+ }
+
+ }
+}
+
+void nouveauCopySubBuffer(__DRIdrawablePrivate *dPriv,
+ int x, int y, int w, int h)
+{
+}
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_context.h b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_context.h
new file mode 100644
index 000000000..87e4479da
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_context.h
@@ -0,0 +1,236 @@
+/**************************************************************************
+
+Copyright 2006 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.
+
+**************************************************************************/
+
+
+
+#ifndef __NOUVEAU_CONTEXT_H__
+#define __NOUVEAU_CONTEXT_H__
+
+#include "dri_util.h"
+#include "drm.h"
+#include "nouveau_drm.h"
+
+#include "mtypes.h"
+#include "tnl/t_vertex.h"
+
+#include "nouveau_screen.h"
+#include "nouveau_state_cache.h"
+#include "nouveau_buffers.h"
+#include "nouveau_shader.h"
+#include "nouveau_sync.h"
+
+#include "xmlconfig.h"
+
+typedef struct nouveau_fifo_t{
+ int channel;
+ u_int32_t* buffer;
+ u_int32_t* mmio;
+ u_int32_t put_base;
+ u_int32_t current;
+ u_int32_t put;
+ u_int32_t free;
+ u_int32_t max;
+}
+nouveau_fifo;
+
+#define TAG(x) nouveau##x
+#include "tnl_dd/t_dd_vertex.h"
+#undef TAG
+
+/* Subpixel offsets for window coordinates (triangles): */
+#define SUBPIXEL_X (0.0F)
+#define SUBPIXEL_Y (0.125F)
+
+struct nouveau_context;
+
+typedef void (*nouveau_tri_func)( struct nouveau_context*,
+ nouveauVertex *,
+ nouveauVertex *,
+ nouveauVertex * );
+
+typedef void (*nouveau_line_func)( struct nouveau_context*,
+ nouveauVertex *,
+ nouveauVertex * );
+
+typedef void (*nouveau_point_func)( struct nouveau_context*,
+ nouveauVertex * );
+
+typedef struct nouveau_hw_func_t {
+ /* Initialise any card-specific non-GL related state */
+ GLboolean (*InitCard)(struct nouveau_context *);
+ /* Update buffer offset/pitch/format */
+ GLboolean (*BindBuffers)(struct nouveau_context *, int num_color,
+ nouveau_renderbuffer **color,
+ nouveau_renderbuffer *depth);
+ /* Update anything that depends on the window position/size */
+ void (*WindowMoved)(struct nouveau_context *);
+} nouveau_hw_func;
+
+typedef struct nouveau_context {
+ /* Mesa context */
+ GLcontext *glCtx;
+
+ /* The per-context fifo */
+ nouveau_fifo fifo;
+
+ /* The read-only regs */
+ volatile unsigned char* mmio;
+
+ /* Physical addresses of AGP/VRAM apertures */
+ uint64_t vram_phys;
+ uint64_t vram_size;
+ uint64_t agp_phys;
+ uint64_t agp_size;
+
+ /* 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;
+
+ /* FIXME : do we want to put all state into a separate struct ? */
+ /* State for tris */
+ GLuint color_offset;
+ GLuint specular_offset;
+
+ /* Vertex state */
+ GLuint vertex_size;
+ GLubyte *verts;
+ struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX];
+ GLuint vertex_attr_count;
+
+ /* Color buffer clear value */
+ uint32_t clear_color_value;
+
+ /* Depth/stencil clear value */
+ uint32_t clear_value;
+
+ /* Light state */
+ GLboolean lighting_enabled;
+ uint32_t enabled_lights;
+
+ /* Cached state */
+ nouveau_state_cache state_cache;
+
+ /* The drawing fallbacks */
+ GLuint Fallback;
+ nouveau_tri_func draw_tri;
+ nouveau_line_func draw_line;
+ nouveau_point_func draw_point;
+
+ /* Cliprects information */
+ GLuint numClipRects;
+ drm_clip_rect_t *pClipRects;
+ drm_clip_rect_t osClipRect;
+ GLuint drawX, drawY;
+
+ /* The rendering context information */
+ GLenum current_primitive; /* the current primitive enum */
+ DECLARE_RENDERINPUTS(render_inputs_bitset); /* the current render inputs */
+
+ /* Shader state */
+ nvsFunc VPfunc;
+ nvsFunc FPfunc;
+ nouveauShader *current_fragprog;
+ nouveauShader *current_vertprog;
+ nouveauShader *passthrough_vp;
+ nouveauShader *passthrough_fp;
+
+ nouveauScreenRec *screen;
+ drm_nouveau_sarea_t *sarea;
+
+ __DRIcontextPrivate *driContext; /* DRI context */
+ __DRIscreenPrivate *driScreen; /* DRI screen */
+ __DRIdrawablePrivate *driDrawable; /* DRI drawable bound to this ctx */
+ GLint lastStamp;
+
+ drm_context_t hHWContext;
+ drm_hw_lock_t *driHwLock;
+ int driFd;
+
+ /* 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;
+
+}nouveauContextRec, *nouveauContextPtr;
+
+
+#define NOUVEAU_CONTEXT(ctx) ((nouveauContextPtr)(ctx->DriverCtx))
+
+/* Flags for software fallback cases: */
+#define NOUVEAU_FALLBACK_TEXTURE 0x0001
+#define NOUVEAU_FALLBACK_DRAW_BUFFER 0x0002
+#define NOUVEAU_FALLBACK_READ_BUFFER 0x0004
+#define NOUVEAU_FALLBACK_STENCIL 0x0008
+#define NOUVEAU_FALLBACK_RENDER_MODE 0x0010
+#define NOUVEAU_FALLBACK_LOGICOP 0x0020
+#define NOUVEAU_FALLBACK_SEP_SPECULAR 0x0040
+#define NOUVEAU_FALLBACK_BLEND_EQ 0x0080
+#define NOUVEAU_FALLBACK_BLEND_FUNC 0x0100
+#define NOUVEAU_FALLBACK_PROJTEX 0x0200
+#define NOUVEAU_FALLBACK_DISABLE 0x0400
+
+
+extern GLboolean nouveauCreateContext( const __GLcontextModes *glVisual,
+ __DRIcontextPrivate *driContextPriv,
+ void *sharedContextPrivate );
+
+extern void nouveauDestroyContext( __DRIcontextPrivate * );
+
+extern GLboolean nouveauMakeCurrent( __DRIcontextPrivate *driContextPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ __DRIdrawablePrivate *driReadPriv );
+
+extern GLboolean nouveauUnbindContext( __DRIcontextPrivate *driContextPriv );
+
+extern void nouveauSwapBuffers(__DRIdrawablePrivate *dPriv);
+
+extern void nouveauCopySubBuffer(__DRIdrawablePrivate *dPriv,
+ int x, int y, int w, int h);
+
+/* Debugging utils: */
+extern int NOUVEAU_DEBUG;
+
+#define DEBUG_SHADERS 0x00000001
+#define DEBUG_MEM 0x00000002
+#define DEBUG_BUFFEROBJ 0x00000004
+
+#endif /* __NOUVEAU_CONTEXT_H__ */
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_ctrlreg.h b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_ctrlreg.h
new file mode 100644
index 000000000..c9b2d5900
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_ctrlreg.h
@@ -0,0 +1,44 @@
+/**************************************************************************
+
+Copyright 2006 Stephane Marchesin, Sylvain Munaut
+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.
+
+**************************************************************************/
+
+
+
+
+#define NV03_STATUS 0x004006b0
+#define NV04_STATUS 0x00400700
+
+#define NV03_FIFO_REGS_SIZE 0x10000
+# define NV03_FIFO_REGS_DMAPUT 0x00000040
+# define NV03_FIFO_REGS_DMAGET 0x00000044
+
+/* Fifo commands. These are not regs, neither masks */
+#define NV03_FIFO_CMD_JUMP 0x20000000
+#define NV03_FIFO_CMD_JUMP_OFFSET_MASK 0x1ffffffc
+#define NV03_FIFO_CMD_REWIND (NV03_FIFO_CMD_JUMP | (0 & NV03_FIFO_CMD_JUMP_OFFSET_MASK))
+
+
+#define NONINC_METHOD 0x40000000
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_dri.h b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_dri.h
new file mode 100644
index 000000000..ce3c3fb9c
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_dri.h
@@ -0,0 +1,28 @@
+#ifndef _NOUVEAU_DRI_
+#define _NOUVEAU_DRI_
+
+#include "xf86drm.h"
+#include "drm.h"
+#include "nouveau_drm.h"
+
+typedef struct {
+ uint32_t device_id; /**< \brief PCI device ID */
+ uint32_t width; /**< \brief width in pixels of display */
+ uint32_t height; /**< \brief height in scanlines of display */
+ uint32_t depth; /**< \brief depth of display (8, 15, 16, 24) */
+ uint32_t bpp; /**< \brief bit depth of display (8, 16, 24, 32) */
+
+ uint32_t bus_type; /**< \brief ths bus type */
+ uint32_t bus_mode; /**< \brief bus mode (used for AGP, maybe also for PCI-E ?) */
+
+ uint32_t front_offset; /**< \brief front buffer offset */
+ uint32_t front_pitch; /**< \brief front buffer pitch */
+ uint32_t back_offset; /**< \brief private back buffer offset */
+ uint32_t back_pitch; /**< \brief private back buffer pitch */
+ uint32_t depth_offset; /**< \brief private depth buffer offset */
+ uint32_t depth_pitch; /**< \brief private depth buffer pitch */
+
+} NOUVEAUDRIRec, *NOUVEAUDRIPtr;
+
+#endif
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_driver.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_driver.c
new file mode 100644
index 000000000..00956aa8f
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_driver.c
@@ -0,0 +1,146 @@
+/**************************************************************************
+
+Copyright 2006 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_state.h"
+#include "nouveau_lock.h"
+#include "nouveau_fifo.h"
+#include "nouveau_driver.h"
+#include "swrast/swrast.h"
+
+#include "context.h"
+#include "framebuffer.h"
+
+#include "utils.h"
+
+/* Wrapper for DRM_NOUVEAU_GETPARAM ioctl */
+GLboolean nouveauDRMGetParam(nouveauContextPtr nmesa,
+ unsigned int param,
+ uint64_t* value)
+{
+ drm_nouveau_getparam_t getp;
+
+ getp.param = param;
+ if (!value || drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_GETPARAM,
+ &getp, sizeof(getp)))
+ return GL_FALSE;
+ *value = getp.value;
+ return GL_TRUE;
+}
+
+/* Wrapper for DRM_NOUVEAU_GETPARAM ioctl */
+GLboolean nouveauDRMSetParam(nouveauContextPtr nmesa,
+ unsigned int param,
+ uint64_t value)
+{
+ drm_nouveau_setparam_t setp;
+
+ setp.param = param;
+ setp.value = value;
+ if (drmCommandWrite(nmesa->driFd, DRM_NOUVEAU_SETPARAM, &setp,
+ sizeof(setp)))
+ return GL_FALSE;
+ return GL_TRUE;
+}
+
+/* Return the width and height of the current color buffer */
+static void nouveauGetBufferSize( GLframebuffer *buffer,
+ GLuint *width, GLuint *height )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ LOCK_HARDWARE( nmesa );
+ *width = nmesa->driDrawable->w;
+ *height = nmesa->driDrawable->h;
+ UNLOCK_HARDWARE( nmesa );
+}
+
+/* glGetString */
+static const GLubyte *nouveauGetString( GLcontext *ctx, GLenum name )
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ static char buffer[128];
+ const char * card_name = "Unknown";
+ GLuint agp_mode = 0;
+
+ switch ( name ) {
+ case GL_VENDOR:
+ return (GLubyte *)DRIVER_AUTHOR;
+
+ case GL_RENDERER:
+ card_name=nmesa->screen->card->name;
+
+ switch(nmesa->screen->bus_type)
+ {
+ case NV_PCI:
+ case NV_PCIE:
+ default:
+ agp_mode=0;
+ break;
+ case NV_AGP:
+ agp_mode=nmesa->screen->agp_mode;
+ break;
+ }
+ driGetRendererString( buffer, card_name, DRIVER_DATE,
+ agp_mode );
+ return (GLubyte *)buffer;
+ default:
+ return NULL;
+ }
+}
+
+/* glFlush */
+static void nouveauFlush( GLcontext *ctx )
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ FIRE_RING();
+}
+
+/* glFinish */
+static void nouveauFinish( GLcontext *ctx )
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nouveauFlush( ctx );
+ nouveauWaitForIdle( nmesa );
+}
+
+/* glClear */
+static void nouveauClear( GLcontext *ctx, GLbitfield mask )
+{
+ // XXX we really should do something here...
+}
+
+void nouveauDriverInitFunctions( struct dd_function_table *functions )
+{
+ functions->GetBufferSize = nouveauGetBufferSize;
+ functions->ResizeBuffers = _mesa_resize_framebuffer;
+ functions->GetString = nouveauGetString;
+ functions->Flush = nouveauFlush;
+ functions->Finish = nouveauFinish;
+ functions->Clear = nouveauClear;
+}
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_driver.h b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_driver.h
new file mode 100644
index 000000000..6164012b5
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_driver.h
@@ -0,0 +1,42 @@
+/**************************************************************************
+
+Copyright 2006 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.
+
+**************************************************************************/
+
+
+
+#ifndef __NOUVEAU_DRIVER_H__
+#define __NOUVEAU_DRIVER_H__
+
+#define DRIVER_DATE "20060219"
+#define DRIVER_AUTHOR "Stephane Marchesin"
+
+extern void nouveauDriverInitFunctions( struct dd_function_table *functions );
+extern GLboolean nouveauDRMGetParam(nouveauContextPtr nmesa, unsigned int param,
+ uint64_t *value);
+extern GLboolean nouveauDRMSetParam(nouveauContextPtr nmesa, unsigned int param,
+ uint64_t value);
+
+#endif /* __NOUVEAU_DRIVER_H__ */
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_fifo.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_fifo.c
new file mode 100644
index 000000000..bd2b2eddd
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_fifo.c
@@ -0,0 +1,142 @@
+/**************************************************************************
+
+Copyright 2006 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 "vblank.h"
+#include <errno.h>
+#include "mtypes.h"
+#include "macros.h"
+#include "dd.h"
+#include "swrast/swrast.h"
+#include "nouveau_context.h"
+#include "nouveau_msg.h"
+#include "nouveau_fifo.h"
+#include "nouveau_lock.h"
+#include "nouveau_object.h"
+#include "nouveau_sync.h"
+
+#ifdef NOUVEAU_RING_DEBUG
+int nouveau_fifo_remaining=0;
+#endif
+
+
+#define RING_SKIPS 8
+
+void WAIT_RING(nouveauContextPtr nmesa,u_int32_t size)
+{
+#ifdef NOUVEAU_RING_DEBUG
+ return;
+#endif
+ u_int32_t fifo_get;
+ while(nmesa->fifo.free < size+1) {
+ fifo_get = NV_FIFO_READ_GET();
+
+ if(nmesa->fifo.put >= fifo_get) {
+ nmesa->fifo.free = nmesa->fifo.max - nmesa->fifo.current;
+ if(nmesa->fifo.free < size+1) {
+ OUT_RING(NV03_FIFO_CMD_JUMP | nmesa->fifo.put_base);
+ if(fifo_get <= RING_SKIPS) {
+ if(nmesa->fifo.put <= RING_SKIPS) /* corner case - will be idle */
+ NV_FIFO_WRITE_PUT(RING_SKIPS + 1);
+ do { fifo_get = NV_FIFO_READ_GET(); }
+ while(fifo_get <= RING_SKIPS);
+ }
+ NV_FIFO_WRITE_PUT(RING_SKIPS);
+ nmesa->fifo.current = nmesa->fifo.put = RING_SKIPS;
+ nmesa->fifo.free = fifo_get - (RING_SKIPS + 1);
+ }
+ } else
+ nmesa->fifo.free = fifo_get - nmesa->fifo.current - 1;
+ }
+}
+
+/*
+ * Wait for the channel to be idle
+ */
+void nouveauWaitForIdleLocked(nouveauContextPtr nmesa)
+{
+ /* Wait for FIFO idle */
+ FIRE_RING();
+ while(RING_AHEAD()>0);
+
+ /* Wait on notifier to indicate all commands in the channel have
+ * been completed.
+ */
+ nouveau_notifier_wait_nop(nmesa->glCtx, nmesa->syncNotifier, NvSub3D);
+}
+
+void nouveauWaitForIdle(nouveauContextPtr nmesa)
+{
+ LOCK_HARDWARE(nmesa);
+ nouveauWaitForIdleLocked(nmesa);
+ UNLOCK_HARDWARE(nmesa);
+}
+
+// here we call the fifo initialization ioctl and fill in stuff accordingly
+GLboolean nouveauFifoInit(nouveauContextPtr nmesa)
+{
+ drm_nouveau_fifo_alloc_t fifo_init;
+ int i;
+
+#ifdef NOUVEAU_RING_DEBUG
+ return GL_TRUE;
+#endif
+
+ int ret;
+ ret=drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_FIFO_ALLOC, &fifo_init, sizeof(fifo_init));
+ if (ret) {
+ FATAL("Fifo initialization ioctl failed (returned %d)\n",ret);
+ return GL_FALSE;
+ }
+
+ ret = drmMap(nmesa->driFd, fifo_init.cmdbuf, fifo_init.cmdbuf_size, &nmesa->fifo.buffer);
+ if (ret) {
+ FATAL("Unable to map the fifo (returned %d)\n",ret);
+ return GL_FALSE;
+ }
+ ret = drmMap(nmesa->driFd, fifo_init.ctrl, fifo_init.ctrl_size, &nmesa->fifo.mmio);
+ if (ret) {
+ FATAL("Unable to map the control regs (returned %d)\n",ret);
+ return GL_FALSE;
+ }
+
+ /* Setup our initial FIFO tracking params */
+ nmesa->fifo.channel = fifo_init.channel;
+ nmesa->fifo.put_base = fifo_init.put_base;
+ nmesa->fifo.current = 0;
+ nmesa->fifo.put = 0;
+ nmesa->fifo.max = (fifo_init.cmdbuf_size >> 2) - 1;
+ nmesa->fifo.free = nmesa->fifo.max - nmesa->fifo.current;
+
+ for (i=0; i<RING_SKIPS; i++)
+ OUT_RING(0);
+ nmesa->fifo.free -= RING_SKIPS;
+
+ MESSAGE("Fifo init ok. Using context %d\n", fifo_init.channel);
+ return GL_TRUE;
+}
+
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_fifo.h
new file mode 100644
index 000000000..23325dcea
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_fifo.h
@@ -0,0 +1,195 @@
+/**************************************************************************
+
+Copyright 2006 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.
+
+**************************************************************************/
+
+
+
+#ifndef __NOUVEAU_FIFO_H__
+#define __NOUVEAU_FIFO_H__
+
+#include "nouveau_context.h"
+#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) 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
+ *
+ * - Begin a ring section with BEGIN_RING_SIZE (if you know the full size in advance)
+ * - Output stuff to the ring with either OUT_RINGp (outputs a raw mem chunk), OUT_RING (1 uint32_t) or OUT_RINGf (1 float)
+ * - RING_AVAILABLE returns the available fifo (in uint32_ts)
+ * - RING_AHEAD returns how much ahead of the last submission point we are
+ * - FIRE_RING fires whatever we have that wasn't fired before
+ * - WAIT_RING waits for size (in uint32_ts) to be available in the fifo
+ */
+
+/* Enable for ring debugging. Prints out writes to the ring buffer
+ * but does not actually write to it.
+ */
+#ifdef NOUVEAU_RING_DEBUG
+
+extern int nouveau_fifo_remaining;
+
+#define OUT_RINGp(ptr,sz) do { \
+uint32_t* p=(uint32_t*)(ptr); \
+int i; printf("OUT_RINGp: (size 0x%x dwords)\n",sz); for(i=0;i<sz;i++) printf(" 0x%08x %f\n", *(p+i), *((float*)(p+i))); \
+nouveau_fifo_remaining-=sz; \
+}while(0)
+
+#define OUT_RING(n) do { \
+ printf("OUT_RINGn: 0x%08x (%s)\n", n, __func__); \
+ nouveau_fifo_remaining--; \
+}while(0)
+
+#define OUT_RINGf(n) do { \
+ printf("OUT_RINGf: %.04f (%s)\n", n, __func__); \
+ nouveau_fifo_remaining--; \
+}while(0)
+
+#define BEGIN_RING_SIZE(subchannel,tag,size) do { \
+ if (nouveau_fifo_remaining!=0) \
+ printf("RING ERROR : remaining %d\n",nouveau_fifo_remaining); \
+ nouveau_state_cache_flush(nmesa); \
+ if (nmesa->fifo.free <= (size)) \
+ WAIT_RING(nmesa,(size)); \
+ OUT_RING( ((size)<<18) | ((subchannel) << 13) | (tag)); \
+ nmesa->fifo.free -= ((size) + 1); \
+ nouveau_fifo_remaining=size; \
+}while(0)
+
+#else
+
+#define OUT_RINGp(ptr,sz) do{ \
+ if (NOUVEAU_RING_TRACE) { \
+ uint32_t* p=(uint32_t*)(ptr); \
+ int i; printf("OUT_RINGp: (size 0x%x dwords) (%s)\n",sz, __func__); for(i=0;i<sz;i++) printf(" [0x%08x] 0x%08x %f\n", (nmesa->fifo.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)
+
+#define BEGIN_RING_SIZE(subchannel,tag,size) do { \
+ nouveau_state_cache_flush(nmesa); \
+ if (nmesa->fifo.free <= (size)) \
+ WAIT_RING(nmesa,(size)); \
+ OUT_RING( ((size)<<18) | ((subchannel) << 13) | (tag)); \
+ nmesa->fifo.free -= ((size) + 1); \
+}while(0)
+
+#endif
+
+extern void WAIT_RING(nouveauContextPtr nmesa,u_int32_t size);
+extern void nouveau_state_cache_flush(nouveauContextPtr nmesa);
+extern void nouveau_state_cache_init(nouveauContextPtr nmesa);
+
+#ifdef NOUVEAU_STATE_CACHE_DISABLE
+#define BEGIN_RING_CACHE(subc,tag,size) BEGIN_RING_SIZE((subc), (tag), (size))
+#define OUT_RING_CACHE(n) OUT_RING((n))
+#define OUT_RING_CACHEf(n) OUT_RINGf((n))
+#define OUT_RING_CACHEp(ptr, sz) OUT_RINGp((ptr), (sz))
+#else
+#define BEGIN_RING_CACHE(subchannel,tag,size) do { \
+ nmesa->state_cache.dirty=1; \
+ nmesa->state_cache.current_pos=((tag)/4); \
+}while(0)
+
+#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++; \
+}while(0)
+
+#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++; \
+}while(0)
+
+#define OUT_RING_CACHEp(ptr,sz) do { \
+uint32_t* p=(uint32_t*)(ptr); \
+int i; for(i=0;i<sz;i++) OUT_RING_CACHE(*(p+i)); \
+}while(0)
+#endif
+
+#define RING_AVAILABLE() (nmesa->fifo.free-1)
+
+#define RING_AHEAD() ((nmesa->fifo.put<=nmesa->fifo.current)?(nmesa->fifo.current-nmesa->fifo.put):nmesa->fifo.max-nmesa->fifo.put+nmesa->fifo.current)
+
+#define FIRE_RING() do { \
+ if (nmesa->fifo.current!=nmesa->fifo.put) { \
+ nmesa->fifo.put=nmesa->fifo.current; \
+ NV_FIFO_WRITE_PUT(nmesa->fifo.put); \
+ } \
+}while(0)
+
+extern void nouveauWaitForIdle(nouveauContextPtr nmesa);
+extern void nouveauWaitForIdleLocked(nouveauContextPtr nmesa);
+extern GLboolean nouveauFifoInit(nouveauContextPtr nmesa);
+
+#endif /* __NOUVEAU_FIFO_H__ */
+
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_lock.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_lock.c
new file mode 100644
index 000000000..c119d14dd
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_lock.c
@@ -0,0 +1,81 @@
+/**************************************************************************
+
+Copyright 2006 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_lock.h"
+
+#include "drirenderbuffer.h"
+#include "framebuffer.h"
+
+
+/* Update the hardware state. This is called if another context has
+ * grabbed the hardware lock, which includes the X server. This
+ * function also updates the driver's window state after the X server
+ * moves, resizes or restacks a window -- the change will be reflected
+ * in the drawable position and clip rects. Since the X server grabs
+ * the hardware lock when it changes the window state, this routine will
+ * automatically be called after such a change.
+ */
+void nouveauGetLock( nouveauContextPtr nmesa, GLuint flags )
+{
+ __DRIdrawablePrivate *dPriv = nmesa->driDrawable;
+ __DRIscreenPrivate *sPriv = nmesa->driScreen;
+ drm_nouveau_sarea_t *sarea = nmesa->sarea;
+
+ drmGetLock( nmesa->driFd, nmesa->hHWContext, flags );
+
+ /* The window might have moved, so we might need to get new clip
+ * rects.
+ *
+ * NOTE: This releases and regrabs the hw lock to allow the X server
+ * to respond to the DRI protocol request for new drawable info.
+ * 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 timestamps don't match, the window has been changed */
+ if (nmesa->lastStamp != dPriv->lastStamp) {
+ struct gl_framebuffer *fb = (struct gl_framebuffer *)dPriv->driverPrivate;
+
+ /* _mesa_resize_framebuffer will take care of calling the renderbuffer's
+ * AllocStorage function if we need more memory to hold it */
+ if (fb->Width != dPriv->w || fb->Height != dPriv->h) {
+ _mesa_resize_framebuffer(nmesa->glCtx, fb, dPriv->w, dPriv->h);
+ /* resize buffers, will call nouveau_window_moved */
+ nouveau_build_framebuffer(nmesa->glCtx, fb);
+ } else {
+ nouveau_window_moved(nmesa->glCtx);
+ }
+
+ nmesa->lastStamp = dPriv->lastStamp;
+ }
+
+ nmesa->numClipRects = dPriv->numClipRects;
+ nmesa->pClipRects = dPriv->pClipRects;
+
+}
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_lock.h b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_lock.h
new file mode 100644
index 000000000..38bb00142
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_lock.h
@@ -0,0 +1,69 @@
+/**************************************************************************
+
+Copyright 2006 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.
+
+**************************************************************************/
+
+
+#ifndef __NOUVEAU_LOCK_H__
+#define __NOUVEAU_LOCK_H__
+
+#include "nouveau_context.h"
+
+extern void nouveauGetLock( nouveauContextPtr nmesa, GLuint flags );
+
+/*
+ * !!! We may want to separate locks from locks with validation. This
+ * could be used to improve performance for those things commands that
+ * do not do any drawing !!!
+ */
+
+/* Lock the hardware and validate our state.
+ */
+#define LOCK_HARDWARE( nmesa ) \
+ do { \
+ char __ret = 0; \
+ DEBUG_CHECK_LOCK(); \
+ DRM_CAS( nmesa->driHwLock, nmesa->hHWContext, \
+ (DRM_LOCK_HELD | nmesa->hHWContext), __ret ); \
+ if ( __ret ) \
+ nouveauGetLock( nmesa, 0 ); \
+ DEBUG_LOCK(); \
+ } while (0)
+
+/* Unlock the hardware.
+ */
+#define UNLOCK_HARDWARE( nmesa ) \
+ do { \
+ DRM_UNLOCK( nmesa->driFd, \
+ nmesa->driHwLock, \
+ nmesa->hHWContext ); \
+ DEBUG_RESET(); \
+ } while (0)
+
+#define DEBUG_LOCK()
+#define DEBUG_RESET()
+#define DEBUG_CHECK_LOCK()
+
+
+#endif /* __NOUVEAU_LOCK_H__ */
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_msg.h b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_msg.h
new file mode 100644
index 000000000..5dea2189c
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_msg.h
@@ -0,0 +1,67 @@
+/*
+Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
+Copyright 2006 Stephane Marchesin. 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 <keith@tungstengraphics.com>
+ * Nicolai Haehnle <prefect_@gmx.net>
+ */
+
+
+#ifndef __NOUVEAU_MSG_H__
+#define __NOUVEAU_MSG_H__
+
+#define WARN_ONCE(a, ...) do {\
+ static int warn##__LINE__=1;\
+ if(warn##__LINE__){\
+ fprintf(stderr, "*********************************WARN_ONCE*********************************\n");\
+ fprintf(stderr, "File %s function %s line %d\n", __FILE__, __FUNCTION__, __LINE__);\
+ fprintf(stderr, a, ## __VA_ARGS__);\
+ fprintf(stderr, "***************************************************************************\n");\
+ warn##__LINE__=0;\
+ } \
+ }while(0)
+
+#define MESSAGE(a, ...) do{\
+ fprintf(stderr, "************************************INFO***********************************\n");\
+ fprintf(stderr, "File %s function %s line %d\n", __FILE__, __FUNCTION__, __LINE__); \
+ fprintf(stderr, a, ## __VA_ARGS__);\
+ fprintf(stderr, "***************************************************************************\n");\
+ }while(0)
+
+#define FATAL(a, ...) do{\
+ fprintf(stderr, "***********************************FATAL***********************************\n");\
+ fprintf(stderr, "File %s function %s line %d\n", __FILE__, __FUNCTION__, __LINE__); \
+ fprintf(stderr, a, ## __VA_ARGS__);\
+ fprintf(stderr, "***************************************************************************\n");\
+ }while(0)
+
+#endif /* __NOUVEAU_MSG_H__ */
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_object.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_object.c
new file mode 100644
index 000000000..b71acff43
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_object.c
@@ -0,0 +1,117 @@
+
+#include "nouveau_fifo.h"
+#include "nouveau_object.h"
+#include "nouveau_reg.h"
+
+
+GLboolean nouveauCreateContextObject(nouveauContextPtr nmesa,
+ uint32_t handle, int class)
+{
+ drm_nouveau_object_init_t cto;
+ int ret;
+
+ cto.channel = nmesa->fifo.channel;
+ cto.handle = handle;
+ cto.class = class;
+ ret = drmCommandWrite(nmesa->driFd, DRM_NOUVEAU_OBJECT_INIT, &cto, sizeof(cto));
+
+ return ret == 0;
+}
+
+GLboolean nouveauCreateDmaObject(nouveauContextPtr nmesa,
+ uint32_t handle,
+ int class,
+ uint32_t offset,
+ uint32_t size,
+ int target,
+ int access)
+{
+ drm_nouveau_dma_object_init_t dma;
+ int ret;
+
+ dma.channel = nmesa->fifo.channel;
+ dma.class = class;
+ dma.handle = handle;
+ dma.target = target;
+ dma.access = access;
+ dma.offset = offset;
+ dma.size = size;
+ ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_DMA_OBJECT_INIT,
+ &dma, sizeof(dma));
+ return ret == 0;
+}
+
+GLboolean nouveauCreateDmaObjectFromMem(nouveauContextPtr nmesa,
+ uint32_t handle, int class,
+ nouveau_mem *mem,
+ int access)
+{
+ uint32_t offset = mem->offset;
+ int target = mem->type & (NOUVEAU_MEM_FB | NOUVEAU_MEM_AGP);
+
+ if (!target)
+ return GL_FALSE;
+
+ if (target & NOUVEAU_MEM_FB)
+ offset -= nmesa->vram_phys;
+ else if (target & NOUVEAU_MEM_AGP)
+ offset -= nmesa->agp_phys;
+
+ return nouveauCreateDmaObject(nmesa, handle, class,
+ offset, mem->size,
+ target, access);
+}
+
+void nouveauObjectOnSubchannel(nouveauContextPtr nmesa, int subchannel, int handle)
+{
+ BEGIN_RING_SIZE(subchannel, 0, 1);
+ OUT_RING(handle);
+}
+
+void nouveauObjectInit(nouveauContextPtr nmesa)
+{
+#ifdef NOUVEAU_RING_DEBUG
+ return;
+#endif
+
+/* We need to know vram size.. and AGP size (and even if the card is AGP..) */
+ nouveauCreateDmaObject( nmesa, NvDmaFB, NV_DMA_IN_MEMORY,
+ 0, nmesa->vram_size,
+ NOUVEAU_MEM_FB,
+ NOUVEAU_MEM_ACCESS_RW);
+ nouveauCreateDmaObject( nmesa, NvDmaAGP, NV_DMA_IN_MEMORY,
+ 0, nmesa->agp_size,
+ NOUVEAU_MEM_AGP,
+ NOUVEAU_MEM_ACCESS_RW);
+
+ nouveauCreateContextObject(nmesa, Nv3D, nmesa->screen->card->class_3d);
+ if (nmesa->screen->card->type>=NV_10) {
+ nouveauCreateContextObject(nmesa, NvCtxSurf2D, NV10_CONTEXT_SURFACES_2D);
+ nouveauCreateContextObject(nmesa, NvImageBlit, NV10_IMAGE_BLIT);
+ } else {
+ nouveauCreateContextObject(nmesa, NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D);
+ nouveauCreateContextObject(nmesa, NvCtxSurf3D, NV04_CONTEXT_SURFACES_3D);
+ nouveauCreateContextObject(nmesa, NvImageBlit, NV_IMAGE_BLIT);
+ }
+ nouveauCreateContextObject(nmesa, NvMemFormat, NV_MEMORY_TO_MEMORY_FORMAT);
+
+#ifdef ALLOW_MULTI_SUBCHANNEL
+ nouveauObjectOnSubchannel(nmesa, NvSubCtxSurf2D, NvCtxSurf2D);
+ BEGIN_RING_SIZE(NvSubCtxSurf2D, NV10_CONTEXT_SURFACES_2D_SET_DMA_IN_MEMORY0, 2);
+ OUT_RING(NvDmaFB);
+ OUT_RING(NvDmaFB);
+
+ nouveauObjectOnSubchannel(nmesa, NvSubImageBlit, NvImageBlit);
+ BEGIN_RING_SIZE(NvSubImageBlit, NV10_IMAGE_BLIT_SET_CONTEXT_SURFACES_2D, 1);
+ OUT_RING(NvCtxSurf2D);
+ BEGIN_RING_SIZE(NvSubImageBlit, NV10_IMAGE_BLIT_SET_OPERATION, 1);
+ OUT_RING(3); /* SRCCOPY */
+
+ nouveauObjectOnSubchannel(nmesa, NvSubMemFormat, NvMemFormat);
+#endif
+
+ nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D);
+}
+
+
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_object.h b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_object.h
new file mode 100644
index 000000000..0be9b4309
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_object.h
@@ -0,0 +1,47 @@
+#ifndef __NOUVEAU_OBJECT_H__
+#define __NOUVEAU_OBJECT_H__
+
+#include "nouveau_context.h"
+
+#define ALLOW_MULTI_SUBCHANNEL
+
+void nouveauObjectInit(nouveauContextPtr nmesa);
+
+enum DMAObjects {
+ Nv3D = 0x80000019,
+ NvCtxSurf2D = 0x80000020,
+ NvImageBlit = 0x80000021,
+ NvMemFormat = 0x80000022,
+ NvCtxSurf3D = 0x80000023,
+ NvDmaFB = 0xD0FB0001,
+ NvDmaAGP = 0xD0AA0001,
+ NvSyncNotify = 0xD0000001,
+ NvQueryNotify = 0xD0000002
+};
+
+enum DMASubchannel {
+ NvSubCtxSurf2D = 0,
+ NvSubImageBlit = 1,
+ NvSubMemFormat = 2,
+ NvSubCtxSurf3D = 3,
+ NvSub3D = 7,
+};
+
+extern void nouveauObjectOnSubchannel(nouveauContextPtr nmesa, int subchannel, int handle);
+
+extern GLboolean nouveauCreateContextObject(nouveauContextPtr nmesa,
+ uint32_t handle, int class);
+extern GLboolean nouveauCreateDmaObject(nouveauContextPtr nmesa,
+ uint32_t handle,
+ int class,
+ uint32_t offset,
+ uint32_t size,
+ int target,
+ int access);
+extern GLboolean nouveauCreateDmaObjectFromMem(nouveauContextPtr nmesa,
+ uint32_t handle,
+ int class,
+ nouveau_mem *mem,
+ int access);
+
+#endif
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_query.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_query.c
new file mode 100644
index 000000000..de3f5b037
--- /dev/null
+++ b/dist/Mesa/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; i<nmesa->query_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/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_query.h b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_query.h
new file mode 100644
index 000000000..3ded41417
--- /dev/null
+++ b/dist/Mesa/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/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_reg.h b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_reg.h
new file mode 100644
index 000000000..8758b538c
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_reg.h
@@ -0,0 +1,1505 @@
+/*
+ Autogenerated file, do not edit !
+
+**************************************************************************
+
+ Copyright (C) 2006 :
+ Dmitry Baryshkov,
+ Laurent Carlier,
+ Matthieu Castet,
+ Dawid Gajownik,
+ Jeremy Kolb,
+ Stephane Loeuillet,
+ Patrice Mandin,
+ Stephane Marchesin,
+ Serge Martin,
+ Sylvain Munaut,
+ Ben Skeggs,
+ Erik Waling,
+ koala_br,
+ sturmflut.
+
+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.
+
+**************************************************************************
+
+ Created from objects.c rev. 1.398
+*/
+
+#ifndef _NOUVEAU_REG_H
+#define _NOUVEAU_REG_H
+
+/******************************************
+Object NV01_CONTEXT_CLIP_RECTANGLE used on: NV03 NV04 NV10 NV15 NV20 NV40 G70
+*/
+#define NV01_CONTEXT_CLIP_RECTANGLE 0x00000019
+# define NV01_CONTEXT_CLIP_RECTANGLE_SET_POINT 0x00000300 /* Parameters: x y */
+# define NV01_CONTEXT_CLIP_RECTANGLE_SET_SIZE 0x00000304 /* Parameters: width height */
+
+/******************************************
+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
+# define NV_MEMORY_TO_MEMORY_FORMAT_OBJECT_OUT 0x00000188
+# define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN 0x0000030c
+# define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_OUT 0x00000310
+# define NV_MEMORY_TO_MEMORY_FORMAT_PITCH_IN 0x00000314
+# 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
+*/
+#define NV03_PRIMITIVE_RASTER_OP 0x00000043
+# define NV03_PRIMITIVE_RASTER_OP_NOTIFY 0x00000100
+# define NV03_PRIMITIVE_RASTER_OP_DMA_NOTIFY 0x00000180
+# define NV03_PRIMITIVE_RASTER_OP_LOGIC_OP 0x00000300 /* Parameters: logic_op */
+
+/******************************************
+Object NV04_GDI_RECTANGLE_TEXT used on: NV04 NV10 NV15 NV20 NV30 NV40 G70
+*/
+#define NV04_GDI_RECTANGLE_TEXT 0x0000004a
+# define NV04_GDI_RECTANGLE_TEXT_SET_DMA_NOTIFY 0x00000180
+# define NV04_GDI_RECTANGLE_TEXT_PATTERN 0x00000188
+# define NV04_GDI_RECTANGLE_TEXT_ROP5 0x0000018c
+# define NV04_GDI_RECTANGLE_TEXT_SURFACE 0x00000198
+# define NV04_GDI_RECTANGLE_TEXT_OPERATION 0x000002fc
+# define NV04_GDI_RECTANGLE_TEXT_FORMAT 0x00000300
+# define NV04_GDI_RECTANGLE_TEXT_BLOCK_LEVEL1_TL 0x000005f4 /* Parameters: left top */
+# define NV04_GDI_RECTANGLE_TEXT_BLOCK_LEVEL1_BR 0x000005f8 /* Parameters: right bottom */
+# define NV04_GDI_RECTANGLE_TEXT_FILL_VALUE 0x000005fc
+# define NV04_GDI_RECTANGLE_TEXT_BLOCK_LEVEL2_TL 0x00000600 /* Parameters: left top */
+# define NV04_GDI_RECTANGLE_TEXT_BLOCK_LEVEL2_BR 0x00000604 /* Parameters: right bottom */
+
+/******************************************
+Object NV04_SWIZZLED_SURFACE used on: NV04 NV10 NV15
+*/
+#define NV04_SWIZZLED_SURFACE 0x00000052
+# define NV04_SWIZZLED_SURFACE_DMA_NOTIFY 0x00000180
+# define NV04_SWIZZLED_SURFACE_DMA_IMAGE 0x00000184
+# define NV04_SWIZZLED_SURFACE_FORMAT 0x00000300 /* Parameters: log2(height) log2(width) color */
+# define NV04_SWIZZLED_SURFACE_OFFSET 0x00000304
+
+/******************************************
+Object NV04_CONTEXT_SURFACES_3D used on: NV04
+*/
+#define NV04_CONTEXT_SURFACES_3D 0x00000053
+# define NV04_CONTEXT_SURFACES_3D_DMA_NOTIFY 0x00000180
+# define NV04_CONTEXT_SURFACES_3D_DMA_COLOR 0x00000184
+# define NV04_CONTEXT_SURFACES_3D_DMA_ZETA 0x00000188
+# define NV04_CONTEXT_SURFACES_3D_CLIP_HORIZONTAL 0x000002f8 /* Parameters: x width */
+# define NV04_CONTEXT_SURFACES_3D_CLIP_VERTICAL 0x000002fc /* Parameters: y height */
+# define NV04_CONTEXT_SURFACES_3D_FORMAT 0x00000300 /* Parameters: color type width height */
+# define NV04_CONTEXT_SURFACES_3D_CLIP_SIZE 0x00000304 /* Parameters: width height */
+# define NV04_CONTEXT_SURFACES_3D_PITCH 0x00000308 /* Parameters: color zeta */
+# define NV04_CONTEXT_SURFACES_3D_OFFSET_COLOR 0x0000030c
+# define NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA 0x00000310
+
+/******************************************
+Object NV04_DX5_TEXTURED_TRIANGLE used on: NV04
+*/
+#define NV04_DX5_TEXTURED_TRIANGLE 0x00000054
+# define NV04_DX5_TEXTURED_TRIANGLE_NOP 0x00000100
+# define NV04_DX5_TEXTURED_TRIANGLE_NOTIFY 0x00000104
+# define NV04_DX5_TEXTURED_TRIANGLE_DMA_NOTIFY 0x00000180
+# define NV04_DX5_TEXTURED_TRIANGLE_DMA_1 0x00000184
+# define NV04_DX5_TEXTURED_TRIANGLE_DMA_2 0x00000188
+# define NV04_DX5_TEXTURED_TRIANGLE_SURFACE 0x0000018c
+# define NV04_DX5_TEXTURED_TRIANGLE_COLOR_KEY 0x00000300
+# define NV04_DX5_TEXTURED_TRIANGLE_TEXTURE_OFFSET 0x00000304
+# define NV04_DX5_TEXTURED_TRIANGLE_TEXTURE_FORMAT 0x00000308 /* Parameters: color mipmaps log(u) log(v) wrap_s wrap_t */
+# define NV04_DX5_TEXTURED_TRIANGLE_TEXTURE_FILTER 0x0000030c /* Parameters: magfilter minfilter lodbias */
+# define NV04_DX5_TEXTURED_TRIANGLE_BLEND 0x00000310 /* Parameters: texture benable dst src */
+# define NV04_DX5_TEXTURED_TRIANGLE_CONTROL 0x00000314 /* Parameters: alpharef alphafunc alphaenable zenable zwrite zfunc cullmode */
+# define NV04_DX5_TEXTURED_TRIANGLE_FOG_COLOR 0x00000318
+# define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX( d) (0x00000400 + d * 0x0020)
+# define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SY( d) (0x00000404 + d * 0x0020)
+# define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SZ( d) (0x00000408 + d * 0x0020)
+# define NV04_DX5_TEXTURED_TRIANGLE_INV_W( d) (0x0000040c + d * 0x0020)
+# define NV04_DX5_TEXTURED_TRIANGLE_COLOR( d) (0x00000410 + d * 0x0020)
+# define NV04_DX5_TEXTURED_TRIANGLE_SPECULAR( d) (0x00000414 + d * 0x0020)
+# define NV04_DX5_TEXTURED_TRIANGLE_TEXTURE_S( d) (0x00000418 + d * 0x0020)
+# define NV04_DX5_TEXTURED_TRIANGLE_TEXTURE_T( d) (0x0000041c + d * 0x0020)
+# define NV04_DX5_TEXTURED_TRIANGLE_DRAW 0x00000600 /* Parameters: v0 v1 v2 v3 v4 v5 */
+
+/******************************************
+Object NV04_DX6_MULTITEX_TRIANGLE used on: NV04 NV10 NV15
+*/
+#define NV04_DX6_MULTITEX_TRIANGLE 0x00000055
+# define NV04_DX6_MULTITEX_TRIANGLE_NOP 0x00000100
+# define NV04_DX6_MULTITEX_TRIANGLE_NOTIFY 0x00000104
+# define NV04_DX6_MULTITEX_TRIANGLE_DMA_NOTIFY 0x00000180
+# define NV04_DX6_MULTITEX_TRIANGLE_DMA_1 0x00000184
+# define NV04_DX6_MULTITEX_TRIANGLE_DMA_2 0x00000188
+# define NV04_DX6_MULTITEX_TRIANGLE_SURFACE 0x0000018c
+# define NV04_DX6_MULTITEX_TRIANGLE_OFFSET0 0x00000308
+# define NV04_DX6_MULTITEX_TRIANGLE_OFFSET1 0x0000030c
+# define NV04_DX6_MULTITEX_TRIANGLE_FORMAT0 0x00000310 /* Parameters: color mipmaps log(u) log(v) wrap_s wrap_t */
+# define NV04_DX6_MULTITEX_TRIANGLE_FORMAT1 0x00000314 /* Parameters: color mipmaps log(u) log(v) wrap_s wrap_t */
+# define NV04_DX6_MULTITEX_TRIANGLE_FILTER0 0x00000318 /* Parameters: magfilter minfilter lodbias */
+# define NV04_DX6_MULTITEX_TRIANGLE_FILTER1 0x0000031c /* Parameters: magfilter minfilter lodbias */
+# define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_ALPHA 0x00000320
+# define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_COLOR 0x00000324
+# define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_ALPHA 0x0000032c
+# define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_COLOR 0x00000330
+# define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_FACTOR 0x00000334
+# define NV04_DX6_MULTITEX_TRIANGLE_BLEND 0x00000338 /* Parameters: benable dst src */
+# define NV04_DX6_MULTITEX_TRIANGLE_CONTROL0 0x0000033c /* Parameters: red_write green_write blue_write alpha_write alpha_write stencil_write alpharef alphafunc alphaenable zenable zwrite zfunc cullmode */
+# define NV04_DX6_MULTITEX_TRIANGLE_CONTROL1 0x00000340 /* Parameters: stencil_enable stencil_mask_write stencil_mask_read stencilref stencilfunc */
+# define NV04_DX6_MULTITEX_TRIANGLE_CONTROL2 0x00000344 /* Parameters: stencil_fail stencil_zfail stencil_zpass */
+# define NV04_DX6_MULTITEX_TRIANGLE_FOG_COLOR 0x00000348
+# define NV04_DX6_MULTITEX_TRIANGLE_TLVERTEX_SX( d) (0x00000400 + d * 0x0028)
+# define NV04_DX6_MULTITEX_TRIANGLE_TLVERTEX_SY( d) (0x00000404 + d * 0x0028)
+# define NV04_DX6_MULTITEX_TRIANGLE_TLVERTEX_SZ( d) (0x00000408 + d * 0x0028)
+# define NV04_DX6_MULTITEX_TRIANGLE_INV_W( d) (0x0000040c + d * 0x0028)
+# define NV04_DX6_MULTITEX_TRIANGLE_COLOR( d) (0x00000410 + d * 0x0028)
+# define NV04_DX6_MULTITEX_TRIANGLE_SPECULAR( d) (0x00000414 + d * 0x0028)
+# define NV04_DX6_MULTITEX_TRIANGLE_TEXTURE0_S( d) (0x00000418 + d * 0x0028)
+# define NV04_DX6_MULTITEX_TRIANGLE_TEXTURE0_T( d) (0x0000041c + d * 0x0028)
+# define NV04_DX6_MULTITEX_TRIANGLE_TEXTURE1_S( d) (0x00000420 + d * 0x0028)
+# define NV04_DX6_MULTITEX_TRIANGLE_TEXTURE1_T( d) (0x00000424 + d * 0x0028)
+# define NV04_DX6_MULTITEX_TRIANGLE_DRAW 0x00000540 /* Parameters: v0 v1 v2 v3 v4 v5 */
+
+/******************************************
+Object NV04_COLOR_KEY used on: NV04 NV10 NV15 NV20 NV40
+*/
+#define NV04_COLOR_KEY 0x00000057
+# define NV04_COLOR_KEY_SET_DMA_NOTIFY 0x00000180
+# define NV04_COLOR_KEY_FORMAT 0x00000300
+# define NV04_COLOR_KEY_VALUE 0x00000304
+
+/******************************************
+Object NV04_SOLID_LINE used on: NV04
+*/
+#define NV04_SOLID_LINE 0x0000005c
+# define NV04_SOLID_LINE_CLIP_RECTANGLE 0x00000184
+# define NV04_SOLID_LINE_PATTERN 0x00000188
+# define NV04_SOLID_LINE_ROP 0x0000018c
+# define NV04_SOLID_LINE_SURFACE 0x00000198
+# define NV04_SOLID_LINE_OPERATION 0x000002fc
+# define NV04_SOLID_LINE_COLOR_FORMAT 0x00000300
+# define NV04_SOLID_LINE_COLOR_VALUE 0x00000304
+# define NV04_SOLID_LINE_START 0x00000400 /* Parameters: x y */
+# define NV04_SOLID_LINE_END 0x00000400 /* Parameters: x y */
+
+/******************************************
+Object NV04_UNK005E used on: NV04
+*/
+#define NV04_UNK005E 0x0000005e
+# define NV04_UNK005E_SET_SURFACE 0x00000198
+# define NV04_UNK005E_UNK02fc 0x000002fc
+# define NV04_UNK005E_UNK0300 0x00000300
+# define NV04_UNK005E_COUNTER 0x00000304
+
+/******************************************
+Object NV05_SCALED_IMAGE_FROM_MEMORY used on: NV04
+*/
+#define NV05_SCALED_IMAGE_FROM_MEMORY 0x00000063
+# define NV05_SCALED_IMAGE_FROM_MEMORY_SURFACE 0x00000198
+# define NV05_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION 0x000002fc
+# define NV05_SCALED_IMAGE_FROM_MEMORY_OPERATION 0x00000304
+
+/******************************************
+Object NV04_SCALED_IMAGE_FROM_MEMORY used on: NV04
+*/
+#define NV04_SCALED_IMAGE_FROM_MEMORY 0x00000077
+# define NV04_SCALED_IMAGE_FROM_MEMORY_DMA_NOTIFY 0x00000180
+# define NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE 0x00000184
+# define NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE 0x00000198
+# define NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT 0x00000300
+# define NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION 0x00000304
+# define NV04_SCALED_IMAGE_FROM_MEMORY_CLIP_POS 0x00000308 /* Parameters: x y */
+# define NV04_SCALED_IMAGE_FROM_MEMORY_CLIP_SIZE 0x0000030c /* Parameters: width height */
+# define NV04_SCALED_IMAGE_FROM_MEMORY_OUT_POS 0x00000310 /* Parameters: x y */
+# define NV04_SCALED_IMAGE_FROM_MEMORY_OUT_SIZE 0x00000314 /* Parameters: width height */
+# define NV04_SCALED_IMAGE_FROM_MEMORY_DU_DX 0x00000318 /* Parameters: int frac*0x100000 */
+# define NV04_SCALED_IMAGE_FROM_MEMORY_DV_DY 0x0000031c /* Parameters: int frac*0x100000 */
+# define NV04_SCALED_IMAGE_FROM_MEMORY_SIZE 0x00000400 /* Parameters: width height */
+# define NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT 0x00000404 /* Parameters: pitch origin filter */
+# define NV04_SCALED_IMAGE_FROM_MEMORY_OFFSET 0x00000408
+# define NV04_SCALED_IMAGE_FROM_MEMORY_POINT 0x0000040c /* Parameters: u_int u_frac*0x10 v_int v_frac*0x10 */
+
+/******************************************
+Object NV_IMAGE_FROM_CPU used on: NV04
+*/
+#define NV_IMAGE_FROM_CPU 0x00000061
+# define NV_IMAGE_FROM_CPU_DMA_NOTIFY 0x00000180
+# define NV_IMAGE_FROM_CPU_CLIP_RECTANGLE 0x00000188
+# define NV_IMAGE_FROM_CPU_PATTERN 0x0000018c
+# define NV_IMAGE_FROM_CPU_ROP 0x00000190
+# define NV_IMAGE_FROM_CPU_SURFACE 0x0000019c
+# define NV_IMAGE_FROM_CPU_OPERATION 0x000002fc
+# define NV_IMAGE_FROM_CPU_FORMAT 0x00000300
+
+/******************************************
+Object NV05_IMAGE_FROM_CPU used on: NV04
+*/
+#define NV05_IMAGE_FROM_CPU 0x00000065
+# define NV05_IMAGE_FROM_CPU_DMA_NOTIFY 0x00000180
+# define NV05_IMAGE_FROM_CPU_CLIP_RECTANGLE 0x00000188
+# define NV05_IMAGE_FROM_CPU_PATTERN 0x0000018c
+# define NV05_IMAGE_FROM_CPU_ROP 0x00000190
+# define NV05_IMAGE_FROM_CPU_SURFACE 0x0000019c
+# define NV05_IMAGE_FROM_CPU_OPERATION 0x000002fc
+# define NV05_IMAGE_FROM_CPU_FORMAT 0x00000300
+# define NV05_IMAGE_FROM_CPU_POINT 0x00000304 /* Parameters: x y */
+# define NV05_IMAGE_FROM_CPU_SIZE_OUT 0x00000308 /* Parameters: x y */
+# define NV05_IMAGE_FROM_CPU_SIZE_IN 0x0000030c /* Parameters: x y */
+# define NV05_IMAGE_FROM_CPU_COLOR( d) (0x00000400 + d * 0x0004)
+
+/******************************************
+Object NV_IMAGE_BLIT used on: NV04 NV10 NV15 NV20 NV40
+*/
+#define NV_IMAGE_BLIT 0x0000005f
+# define NV_IMAGE_BLIT_DMA_NOTIFY 0x00000180
+# define NV_IMAGE_BLIT_COLOR_KEY 0x00000184
+# define NV_IMAGE_BLIT_CLIP_RECTANGLE 0x00000188
+# define NV_IMAGE_BLIT_PATTERN 0x0000018c
+# define NV_IMAGE_BLIT_ROP5 0x00000190
+# define NV_IMAGE_BLIT_SURFACE 0x0000019c
+# define NV_IMAGE_BLIT_OPERATION 0x000002fc
+# define NV_IMAGE_BLIT_POINT_IN 0x00000300 /* Parameters: x y */
+# define NV_IMAGE_BLIT_POINT_OUT 0x00000304 /* Parameters: x y */
+# define NV_IMAGE_BLIT_SIZE 0x00000308 /* Parameters: width height */
+
+/******************************************
+Object NV10_TCL_PRIMITIVE_3D used on: NV10
+*/
+#define NV10_TCL_PRIMITIVE_3D 0x00000056
+
+/******************************************
+Object NV17_TCL_PRIMITIVE_3D used on: NV15
+*/
+#define NV17_TCL_PRIMITIVE_3D 0x00000099
+
+/******************************************
+Object NV11_TCL_PRIMITIVE_3D used on: NV15
+*/
+#define NV11_TCL_PRIMITIVE_3D 0x00000096
+# define NV10_TCL_PRIMITIVE_3D_NOP 0x00000100
+# define NV10_TCL_PRIMITIVE_3D_NOTIFY 0x00000104
+# define NV10_TCL_PRIMITIVE_3D_SET_DMA_NOTIFY 0x00000180
+# define NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY0 0x00000184
+# define NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY1 0x00000188
+# define NV10_TCL_PRIMITIVE_3D_SET_DISPLAY_LIST 0x0000018c
+# define NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY2 0x00000194
+# define NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY3 0x00000198
+# define NV17_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY4 0x000001ac
+# define NV17_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY5 0x000001b0
+# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ 0x00000200 /* Parameters: width x */
+# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_VERT 0x00000204 /* Parameters: height y */
+# define NV10_TCL_PRIMITIVE_3D_BUFFER_FORMAT 0x00000208 /* Parameters: type color */
+# define NV10_TCL_PRIMITIVE_3D_BUFFER_PITCH 0x0000020c /* Parameters: depth/stencil buffer pitch color buffer pitch */
+# define NV10_TCL_PRIMITIVE_3D_COLOR_OFFSET 0x00000210
+# define NV10_TCL_PRIMITIVE_3D_DEPTH_OFFSET 0x00000214
+# define NV10_TCL_PRIMITIVE_3D_TX_OFFSET(d) (0x00000218 + d * 0x0004)
+# define NV10_TCL_PRIMITIVE_3D_TX_FORMAT(d) (0x00000220 + d * 0x0004) /* Parameters: wrap_t wrap_s log2(height) log2(width) lod npot format cube_map */
+# define NV10_TCL_PRIMITIVE_3D_TX_ENABLE(d) (0x00000228 + d * 0x0004) /* Parameters: enable anisotropy */
+# 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_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_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
+# define NV10_TCL_PRIMITIVE_3D_FOG_COLOR 0x000002a8 /* Parameters: a b g r */
+# define NV17_TCL_PRIMITIVE_3D_COLOR_MASK_ENABLE 0x000002bc
+# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(d) (0x000002c0 + d * 0x0004) /* Parameters: x2 x1 */
+# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(d) (0x000002e0 + d * 0x0004) /* Parameters: y2 y1 */
+# define NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE 0x00000300
+# define NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE 0x00000304
+# define NV10_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE 0x00000308
+# define NV10_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE 0x0000030c
+# define NV10_TCL_PRIMITIVE_3D_DITHER_ENABLE 0x00000310
+# define NV10_TCL_PRIMITIVE_3D_LIGHTING_ENABLE 0x00000314
+# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETERS_ENABLE 0x00000318
+# define NV10_TCL_PRIMITIVE_3D_POINT_SMOOTH_ENABLE 0x0000031c
+# define NV10_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE 0x00000320
+# define NV10_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE 0x00000324
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_WEIGHT_ENABLE 0x00000328
+# define NV10_TCL_PRIMITIVE_3D_STENCIL_ENABLE 0x0000032c
+# define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE 0x00000330
+# define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE 0x00000334
+# define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE 0x00000338
+# define NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC 0x0000033c
+# define NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF 0x00000340
+# define NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC 0x00000344
+# define NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_DST 0x00000348
+# 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: 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
+# define NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_REF 0x00000368
+# define NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_MASK 0x0000036c
+# define NV10_TCL_PRIMITIVE_3D_STENCIL_OP_FAIL 0x00000370
+# define NV10_TCL_PRIMITIVE_3D_STENCIL_OP_ZFAIL 0x00000374
+# define NV10_TCL_PRIMITIVE_3D_STENCIL_OP_ZPASS 0x00000378
+# define NV10_TCL_PRIMITIVE_3D_SHADE_MODEL 0x0000037c
+# define NV10_TCL_PRIMITIVE_3D_LINE_WIDTH 0x00000380
+# define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR 0x00000384
+# define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_UNITS 0x00000388
+# define NV10_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT 0x0000038c
+# define NV10_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK 0x00000390
+# define NV10_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR 0x00000394
+# define NV10_TCL_PRIMITIVE_3D_DEPTH_RANGE_FAR 0x00000398
+# 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_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)
+# define NV10_TCL_PRIMITIVE_3D_VIEW_MATRIX_ENABLE 0x000003e8 /* Parameters: projection modelview0 modelview1 */
+# define NV10_TCL_PRIMITIVE_3D_POINT_SIZE 0x000003ec
+# define NV10_TCL_PRIMITIVE_3D_MODELVIEW0_MATRIX( d) (0x00000400 + d * 0x0004)
+# define NV10_TCL_PRIMITIVE_3D_MODELVIEW1_MATRIX( d) (0x00000440 + d * 0x0004)
+# define NV10_TCL_PRIMITIVE_3D_INVERSE_MODELVIEW0_MATRIX( d) (0x00000480 + d * 0x0004)
+# define NV10_TCL_PRIMITIVE_3D_INVERSE_MODELVIEW1_MATRIX( d) (0x000004c0 + d * 0x0004)
+# define NV10_TCL_PRIMITIVE_3D_PROJECTION_MATRIX( d) (0x00000500 + d * 0x0004)
+# define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_A(d) (0x00000600 + d * 0x0010)
+# define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_B(d) (0x00000604 + d * 0x0010)
+# define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_C(d) (0x00000608 + d * 0x0010)
+# define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_D(d) (0x0000060c + d * 0x0010)
+# define NV10_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT 0x00000680
+# define NV10_TCL_PRIMITIVE_3D_FOG_EQUATION_LINEAR 0x00000684
+# define NV10_TCL_PRIMITIVE_3D_FOG_EQUATION_QUADRATIC 0x00000688
+# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_A 0x000006a0
+# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_B 0x000006a4
+# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_C 0x000006a8
+# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_D 0x000006ac
+# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_E 0x000006b0
+# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_F 0x000006b4
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R 0x000006c4
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_G 0x000006c8
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_B 0x000006cc
+# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X 0x000006e8
+# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_Y 0x000006ec
+# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_Z 0x000006f0
+# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_W 0x000006f4
+# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_A 0x000006f8
+# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_B 0x000006fc
+# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_C 0x00000700
+# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_D 0x00000704
+# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_E 0x00000708
+# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_F 0x0000070c
+# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_G 0x00000710
+# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_H 0x00000714
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(d) (0x00000800 + d * 0x0080)
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_G(d) (0x00000804 + d * 0x0080)
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_B(d) (0x00000808 + d * 0x0080)
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(d) (0x0000080c + d * 0x0080)
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_G(d) (0x00000810 + d * 0x0080)
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_B(d) (0x00000814 + d * 0x0080)
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(d) (0x00000818 + d * 0x0080)
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_G(d) (0x0000081c + d * 0x0080)
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_B(d) (0x00000820 + d * 0x0080)
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_X(d) (0x00000828 + d * 0x0080)
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_Y(d) (0x0000082c + d * 0x0080)
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_Z(d) (0x00000830 + d * 0x0080)
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_X(d) (0x00000834 + d * 0x0080)
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_Y(d) (0x00000838 + d * 0x0080)
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_Z(d) (0x0000083c + d * 0x0080)
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(d) (0x00000840 + d * 0x0080)
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(d) (0x00000844 + d * 0x0080)
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(d) (0x00000848 + d * 0x0080)
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(d) (0x0000084c + d * 0x0080)
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_Y(d) (0x00000850 + d * 0x0080)
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_Z(d) (0x00000854 + d * 0x0080)
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(d) (0x00000858 + d * 0x0080)
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(d) (0x0000085c + d * 0x0080)
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_Y(d) (0x00000860 + d * 0x0080)
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_Z(d) (0x00000864 + d * 0x0080)
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(d) (0x00000868 + d * 0x0080)
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(d) (0x0000086c + d * 0x0080)
+# define NV10_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(d) (0x00000870 + d * 0x0080)
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_X 0x00000c00
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_Y 0x00000c04
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_Z 0x00000c08
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_4F_X 0x00000c18
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_4F_Y 0x00000c1c
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_4F_Z 0x00000c20
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_4F_W 0x00000c24
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_X 0x00000c30
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_Y 0x00000c34
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_Z 0x00000c38
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_XY 0x00000c40 /* Parameters: y x */
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_Z 0x00000c44 /* Parameters: z */
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4F_R 0x00000c50
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4F_G 0x00000c54
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4F_B 0x00000c58
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4F_A 0x00000c5c
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_3F_R 0x00000c60
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_3F_G 0x00000c64
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_3F_B 0x00000c68
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4I 0x00000c6c /* Parameters: a b g r */
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_R 0x00000c80
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_G 0x00000c84
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_B 0x00000c88
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL2_3I 0x00000c8c /* Parameters: a b g r */
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_S 0x00000c90
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_T 0x00000c94
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_2I 0x00000c98 /* Parameters: t s */
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_S 0x00000ca0
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_T 0x00000ca4
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_R 0x00000ca8
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_Q 0x00000cac
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4I_ST 0x00000cb0 /* Parameters: t s */
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4I_RQ 0x00000cb4 /* Parameters: q r */
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_S 0x00000cb8
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_T 0x00000cbc
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_2I 0x00000cc0 /* Parameters: t s */
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_S 0x00000cc8
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_T 0x00000ccc
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_R 0x00000cd0
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_Q 0x00000cd4
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4I_ST 0x00000cd8 /* Parameters: t s */
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4I_RQ 0x00000cdc /* Parameters: q r */
+# 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) /* 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 */
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_COL 0x00000d08
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_COL 0x00000d0c /* Parameters: stride fields type */
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_COL2 0x00000d10
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_COL2 0x00000d14 /* Parameters: stride fields type */
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_TX0 0x00000d18
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_TX0 0x00000d1c /* Parameters: stride fields type */
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_TX1 0x00000d20
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_TX1 0x00000d24 /* Parameters: stride fields type */
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_NOR 0x00000d28
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_NOR 0x00000d2c /* Parameters: stride fields type */
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_WGH 0x00000d30
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_WGH 0x00000d34 /* Parameters: stride fields type */
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_FOG 0x00000d38
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_FOG 0x00000d3c /* Parameters: stride fields type */
+# define NV10_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE 0x00000d40
+# define NV10_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP 0x00000d44
+# define NV17_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH 0x00000d5c /* Parameters: pitch */
+# define NV17_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_OFFSET 0x00000d60
+# define NV17_TCL_PRIMITIVE_3D_LMA_DEPTH_FILL_VALUE 0x00000d68
+# define NV17_TCL_PRIMITIVE_3D_LMA_DEPTH_CLEAR_ENABLE 0x00000d6c
+# define NV10_TCL_PRIMITIVE_3D_BEGIN_END 0x00000dfc
+# define NV10_TCL_PRIMITIVE_3D_INDEX_DATA 0x00000e00 /* Parameters: index1 index0 */
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_BUFFER_BEGIN_END 0x000013fc
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_BUFFER_DRAW_ARRAYS 0x00001400 /* Parameters: count-1 first */
+# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X 0x00001638
+# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_Y 0x0000163c
+# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_Z 0x00001640
+# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_W 0x00001644
+# define NV17_TCL_PRIMITIVE_3D_LMA_DEPTH_ENABLE 0x00001658
+# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_DATA 0x00001800
+
+/******************************************
+Object NV10_IMAGE_FROM_CPU used on: NV10 NV15 NV20 NV30 NV40 G70
+*/
+#define NV10_IMAGE_FROM_CPU 0x0000008a
+# define NV10_IMAGE_FROM_CPU_SET_DMA_NOTIFY 0x00000180
+# define NV10_IMAGE_FROM_CPU_SET_CONTEXT_CLIP_RECTANGLE 0x00000188
+# define NV10_IMAGE_FROM_CPU_SET_IMAGE_PATTERN 0x0000018c
+# define NV10_IMAGE_FROM_CPU_SET_RASTER_OP 0x00000190
+# define NV10_IMAGE_FROM_CPU_SET_CONTEXT_SURFACES_2D 0x0000019c
+# define NV10_IMAGE_FROM_CPU_OPERATION 0x000002fc
+# define NV10_IMAGE_FROM_CPU_FORMAT 0x00000300
+# define NV10_IMAGE_FROM_CPU_POINT 0x00000304 /* Parameters: x y */
+# define NV10_IMAGE_FROM_CPU_SIZE_OUT 0x00000308 /* Parameters: width height */
+# define NV10_IMAGE_FROM_CPU_SIZE_IN 0x0000030c /* Parameters: width height */
+# define NV10_IMAGE_FROM_CPU_HLINE 0x00000400
+
+/******************************************
+Object NV10_PRIMITIVE_2D used on: NV10 NV15 NV20 NV30 NV40 G70
+*/
+#define NV10_PRIMITIVE_2D 0x0000007b
+# define NV10_PRIMITIVE_2D_SET_DMA_NOTIFY 0x00000180
+# define NV10_PRIMITIVE_2D_SET_SURFACE 0x00000184
+# define NV10_PRIMITIVE_2D_SET_FORMAT 0x00000300
+# define NV10_PRIMITIVE_2D_SET_POINT 0x00000304 /* Parameters: x y */
+# define NV10_PRIMITIVE_2D_SET_SIZE 0x00000308 /* Parameters: width height */
+# define NV10_PRIMITIVE_2D_SET_CLIP_HORIZ 0x0000030c /* Parameters: width x */
+# define NV10_PRIMITIVE_2D_SET_CLIP_VERT 0x00000310 /* Parameters: height y */
+# define NV10_PRIMITIVE_2D_SET_DATA( d) (0x00000400 + d * 0x0004)
+
+/******************************************
+Object NV10_IMAGE_BLIT used on: NV10 NV15 NV20 NV30 NV40 G70
+*/
+#define NV10_IMAGE_BLIT 0x0000009f
+# define NV10_IMAGE_BLIT_NOP 0x00000100
+# define NV10_IMAGE_BLIT_NOTIFY 0x00000104
+# define NV10_IMAGE_BLIT_SET_DMA_NOTIFY 0x00000180
+# define NV10_IMAGE_BLIT_SET_CONTEXT_CLIP_RECTANGLE 0x00000188
+# define NV10_IMAGE_BLIT_SET_IMAGE_PATTERN 0x0000018c
+# define NV10_IMAGE_BLIT_SET_RASTER_OP 0x00000190
+# define NV10_IMAGE_BLIT_SET_CONTEXT_SURFACES_2D 0x0000019c
+# define NV10_IMAGE_BLIT_SET_OPERATION 0x000002fc
+# define NV10_IMAGE_BLIT_SET_POINT 0x00000300 /* Parameters: x y */
+# define NV10_IMAGE_BLIT_SET_PITCH 0x00000304 /* Parameters: skip */
+# define NV10_IMAGE_BLIT_SET_SIZE 0x00000308 /* Parameters: width height */
+
+/******************************************
+Object NV10_VIDEO_DISPLAY used on: NV10 NV15 NV20 NV30 NV40 G70
+*/
+#define NV10_VIDEO_DISPLAY 0x0000007c
+# define NV10_VIDEO_DISPLAY_COUNTER 0x00000050
+# define NV10_VIDEO_DISPLAY_SET_DMA_FROM_MEMORY 0x00000180
+# define NV10_VIDEO_DISPLAY_SET_DMA_IN_MEMORY0 0x00000184
+# define NV10_VIDEO_DISPLAY_SET_DMA_IN_MEMORY1 0x00000188
+# define NV10_VIDEO_DISPLAY_SET_OBJECT3 0x0000019c
+# define NV10_VIDEO_DISPLAY_SIZE 0x000002f8 /* Parameters: height width */
+# define NV10_VIDEO_DISPLAY_OFFSET 0x00000300
+
+/******************************************
+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
+
+/******************************************
+Object NV10_SCALED_IMAGE_FROM_MEMORY used on: NV10 NV15 NV20 NV30 NV40 G70
+*/
+#define NV10_SCALED_IMAGE_FROM_MEMORY 0x00000089
+# define NV10_SCALED_IMAGE_FROM_MEMORY_COUNTER 0x00000050
+# define NV10_SCALED_IMAGE_FROM_MEMORY_SET_DMA_IN_MEMORY 0x00000184
+# define NV10_SCALED_IMAGE_FROM_MEMORY_SET_RASTER_OP 0x0000018c
+# define NV10_SCALED_IMAGE_FROM_MEMORY_SET_IMAGE_PATTERN 0x00000188
+# define NV10_SCALED_IMAGE_FROM_MEMORY_SET_SURFACE 0x00000198
+# define NV10_SCALED_IMAGE_FROM_MEMORY_OPERATION 0x00000304
+# define NV10_SCALED_IMAGE_FROM_MEMORY_CLIP_POS 0x00000308 /* Parameters: x y */
+# define NV10_SCALED_IMAGE_FROM_MEMORY_CLIP_SIZE 0x0000030c /* Parameters: width height */
+# define NV10_SCALED_IMAGE_FROM_MEMORY_OUT_POS 0x00000310 /* Parameters: x y */
+# define NV10_SCALED_IMAGE_FROM_MEMORY_OUT_SIZE 0x00000314 /* Parameters: width height */
+# define NV10_SCALED_IMAGE_FROM_MEMORY_SIZE 0x00000400 /* Parameters: width height */
+# define NV10_SCALED_IMAGE_FROM_MEMORY_FORMAT 0x00000404 /* Parameters: pitch */
+# define NV10_SCALED_IMAGE_FROM_MEMORY_OFFSET 0x00000408
+# define NV10_SCALED_IMAGE_FROM_MEMORY_POINT 0x0000040c /* Parameters: u_int u_frac*0x10 v_int v_frac*0x10 */
+
+/******************************************
+Object NV10_CONTEXT_SURFACES_2D used on: NV10 NV15 NV20 NV30 NV40 G70
+*/
+#define NV10_CONTEXT_SURFACES_2D 0x00000062
+# define NV10_CONTEXT_SURFACES_2D_SET_DMA_NOTIFY 0x00000180
+# define NV10_CONTEXT_SURFACES_2D_SET_DMA_IN_MEMORY0 0x00000184
+# define NV10_CONTEXT_SURFACES_2D_SET_DMA_IN_MEMORY1 0x00000188
+# define NV10_CONTEXT_SURFACES_2D_FORMAT 0x00000300 /* Parameters: color type width height */
+# define NV10_CONTEXT_SURFACES_2D_PITCH 0x00000304 /* Parameters: src dst */
+# define NV10_CONTEXT_SURFACES_2D_OFFSET_SRC 0x00000308
+# define NV10_CONTEXT_SURFACES_2D_OFFSET_DST 0x0000030c
+
+/******************************************
+Object NV04_CONTEXT_SURFACES_2D used on: NV04 NV10 NV15
+*/
+#define NV04_CONTEXT_SURFACES_2D 0x00000042
+# define NV04_CONTEXT_SURFACES_2D_NOTIFY 0x00000104
+# define NV04_CONTEXT_SURFACES_2D_SET_DMA_NOTIFY 0x00000180
+# define NV04_CONTEXT_SURFACES_2D_SET_DMA_IMAGE_SRC 0x00000184
+# define NV04_CONTEXT_SURFACES_2D_SET_DMA_IMAGE_DST 0x00000188
+# define NV04_CONTEXT_SURFACES_2D_FORMAT 0x00000300
+# define NV04_CONTEXT_SURFACES_2D_PITCH 0x00000304 /* Parameters: src dst */
+# define NV04_CONTEXT_SURFACES_2D_OFFSET_SRC 0x00000308
+# define NV04_CONTEXT_SURFACES_2D_OFFSET_DST 0x0000030c
+
+/******************************************
+Object NV04_IMAGE_PATTERN used on: NV04 NV10 NV15 NV20 NV30 NV40 G70
+*/
+#define NV04_IMAGE_PATTERN 0x00000044
+# define NV04_IMAGE_PATTERN_COLOR_FORMAT 0x00000300
+# define NV04_IMAGE_PATTERN_MONO_FORMAT 0x00000304
+# define NV04_IMAGE_PATTERN_SELECT 0x0000030c
+# define NV04_IMAGE_PATTERN_MONOCHROME_SHAPE 0x00000308
+# define NV04_IMAGE_PATTERN_MONOCHROME_COLOR0 0x00000310
+# define NV04_IMAGE_PATTERN_MONOCHROME_COLOR1 0x00000314
+# define NV04_IMAGE_PATTERN_MONOCHROME_PATTERN0 0x00000318
+# define NV04_IMAGE_PATTERN_MONOCHROME_PATTERN1 0x0000031c
+
+/******************************************
+Object NV20_SWIZZLED_SURFACE used on: NV20 NV30 NV40 G70
+*/
+#define NV20_SWIZZLED_SURFACE 0x0000009e
+# define NV20_SWIZZLED_SURFACE_SET_OBJECT0 0x00000180
+# define NV20_SWIZZLED_SURFACE_SET_OBJECT1 0x00000184
+# define NV20_SWIZZLED_SURFACE_FORMAT 0x00000300 /* Parameters: log2(height) log2(width) color */
+# define NV20_SWIZZLED_SURFACE_OFFSET 0x00000304
+
+/******************************************
+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
+# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT3 0x00000194
+# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT4 0x00000198
+# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT5 0x0000019c
+# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT6 0x000001a0
+# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT7 0x000001a4
+# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT8 0x000001a8
+# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT9 0x000001ac
+# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT10 0x000001b0
+# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ 0x00000200 /* Parameters: width x */
+# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_VERT 0x00000204 /* Parameters: height y */
+# define NV20_TCL_PRIMITIVE_3D_BUFFER_FORMAT 0x00000208 /* Parameters: type color */
+# define NV20_TCL_PRIMITIVE_3D_BUFFER_PITCH 0x0000020c /* Parameters: depth/stencil buffer pitch color buffer pitch */
+# define NV20_TCL_PRIMITIVE_3D_COLOR_OFFSET 0x00000210
+# define NV20_TCL_PRIMITIVE_3D_DEPTH_OFFSET 0x00000214
+# define NV20_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH 0x0000022c /* Parameters: pitch */
+# define NV20_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_OFFSET 0x00000230
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_CONTROL 0x00000294
+# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_CONTROL 0x00000298 /* Parameters: back_specular back_ambient back_diffuse back_emission front_specular front_ambient front_diffuse front_emission */
+# 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
+# define NV20_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE 0x0000030c
+# define NV20_TCL_PRIMITIVE_3D_DITHER_ENABLE 0x00000310
+# define NV20_TCL_PRIMITIVE_3D_LIGHTING_ENABLE 0x00000314
+# define NV20_TCL_PRIMITIVE_3D_POINT_SMOOTH_ENABLE 0x0000031c
+# define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETERS_ENABLE 0x00000318
+# define NV20_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE 0x00000320
+# define NV20_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE 0x00000324
+# define NV20_TCL_PRIMITIVE_3D_STENCIL_ENABLE 0x0000032c
+# define NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE 0x00000330
+# define NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE 0x00000334
+# define NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE 0x00000338
+# define NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC 0x0000033c
+# define NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF 0x00000340
+# define NV20_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC 0x00000344
+# define NV20_TCL_PRIMITIVE_3D_BLEND_FUNC_DST 0x00000348
+# define NV20_TCL_PRIMITIVE_3D_BLEND_COLOR 0x0000034c /* Parameters: a r g b */
+# define NV20_TCL_PRIMITIVE_3D_BLEND_EQUATION 0x00000350
+# define NV20_TCL_PRIMITIVE_3D_DEPTH_FUNC 0x00000354
+# define NV20_TCL_PRIMITIVE_3D_COLOR_MASK 0x00000358 /* Parameters: a r g b */
+# define NV20_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE 0x0000035c
+# define NV20_TCL_PRIMITIVE_3D_STENCIL_MASK 0x00000360
+# define NV20_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC 0x00000364
+# define NV20_TCL_PRIMITIVE_3D_STENCIL_FUNC_REF 0x00000368
+# define NV20_TCL_PRIMITIVE_3D_STENCIL_FUNC_MASK 0x0000036c
+# define NV20_TCL_PRIMITIVE_3D_STENCIL_OP_FAIL 0x00000370
+# define NV20_TCL_PRIMITIVE_3D_STENCIL_OP_ZFAIL 0x00000374
+# define NV20_TCL_PRIMITIVE_3D_STENCIL_OP_ZPASS 0x00000378
+# define NV20_TCL_PRIMITIVE_3D_SHADE_MODEL 0x0000037c
+# define NV20_TCL_PRIMITIVE_3D_LINE_WIDTH 0x00000380
+# define NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR 0x00000384
+# define NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_UNITS 0x00000388
+# define NV20_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT 0x0000038c
+# define NV20_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK 0x00000390
+# define NV20_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR 0x00000394
+# define NV20_TCL_PRIMITIVE_3D_DEPTH_RANGE_FAR 0x00000398
+# 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_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)
+# define NV20_TCL_PRIMITIVE_3D_TX_MATRIX_ENABLE(d) (0x00000420 + d * 0x0004)
+# define NV20_TCL_PRIMITIVE_3D_POINT_SIZE 0x0000043c
+# define NV20_TCL_PRIMITIVE_3D_MODELVIEW_MATRIX( d) (0x00000480 + d * 0x0004)
+# define NV20_TCL_PRIMITIVE_3D_INVERSE_MODELVIEW_MATRIX( d) (0x00000580 + d * 0x0004)
+# define NV20_TCL_PRIMITIVE_3D_PROJECTION_MATRIX( d) (0x00000680 + d * 0x0004)
+# define NV20_TCL_PRIMITIVE_3D_TX_MATRIX(x,y) (0x000006c0 + y * 0x0010 + x * 0x0004)
+# define NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_A(d) (0x00000840 + d * 0x0010)
+# define NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_B(d) (0x00000844 + d * 0x0010)
+# define NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_C(d) (0x00000848 + d * 0x0010)
+# define NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_D(d) (0x0000084c + d * 0x0010)
+# define NV20_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT 0x000009c0
+# define NV20_TCL_PRIMITIVE_3D_FOG_EQUATION_LINEAR 0x000009c4
+# define NV20_TCL_PRIMITIVE_3D_FOG_EQUATION_QUADRATIC 0x000009c8
+# define NV20_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_A 0x000009e0
+# define NV20_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_B 0x000009e4
+# define NV20_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_C 0x000009e8
+# define NV20_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_D 0x000009ec
+# 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
+# define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_D 0x00000a3c
+# define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_E 0x00000a40
+# 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
+# define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_INST3 0x00000b0c
+# define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_X 0x00000b80
+# define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_Y 0x00000b84
+# define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_Z 0x00000b88
+# define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_W 0x00000b8c
+# define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_ID 0x00001ea4
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R 0x00000a10
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_G 0x00000a14
+# 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 */
+# define NV20_TCL_PRIMITIVE_3D_RC_COLOR0 0x00001e20 /* Parameters: a r g b */
+# define NV20_TCL_PRIMITIVE_3D_RC_COLOR1 0x00001e24 /* Parameters: a r g b */
+# define NV20_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 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)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_POSITION_Y(d) (0x00001060 + d * 0x0080)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_POSITION_Z(d) (0x00001064 + d * 0x0080)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_X(d) (0x00001028 + d * 0x0080)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_Y(d) (0x0000102c + d * 0x0080)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_Z(d) (0x00001030 + d * 0x0080)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_X(d) (0x00001034 + d * 0x0080)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_Y(d) (0x00001038 + d * 0x0080)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_Z(d) (0x0000103c + d * 0x0080)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(d) (0x00001000 + d * 0x0080)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_G(d) (0x00001004 + d * 0x0080)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_B(d) (0x00001008 + d * 0x0080)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(d) (0x0000100c + d * 0x0080)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_G(d) (0x00001010 + d * 0x0080)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_B(d) (0x00001014 + d * 0x0080)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(d) (0x00001018 + d * 0x0080)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_G(d) (0x0000101c + d * 0x0080)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_B(d) (0x00001020 + d * 0x0080)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_BACK_SIDE_PRODUCT_AMBIENT(d) (0x00000c00 + d * 0x0040)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_BACK_SIDE_PRODUCT_DIFFUSE(d) (0x00000c0c + d * 0x0040)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_BACK_SIDE_PRODUCT_SPECULAR(d) (0x00000c18 + d * 0x0040)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(d) (0x00001068 + d * 0x0080)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(d) (0x0000106c + d * 0x0080)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(d) (0x00001070 + d * 0x0080)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(d) (0x00001040 + d * 0x0080)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(d) (0x00001044 + d * 0x0080)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(d) (0x00001048 + d * 0x0080)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(d) (0x0000104c + d * 0x0080)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_Y(d) (0x00001050 + d * 0x0080)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_Z(d) (0x00001054 + d * 0x0080)
+# define NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(d) (0x00001058 + d * 0x0080)
+# define NV20_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_A 0x00001e28
+# define NV20_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_B 0x00001e2c
+# define NV20_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_C 0x00001e30
+# define NV20_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_D 0x00001e34
+# define NV20_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_E 0x00001e38
+# define NV20_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_F 0x00001e3c
+# define NV20_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE 0x0000147c
+# define NV20_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(d) (0x00001480 + d * 0x0004)
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_POS_3F_X 0x00001500
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_POS_3F_Y 0x00001504
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_POS_3F_Z 0x00001508
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_POS_4F_X 0x00001518
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_POS_4F_Y 0x0000151c
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_POS_4F_Z 0x00001520
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_POS_4F_W 0x00001524
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_POS_4I_XY 0x00001528 /* Parameters: y x */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_POS_4I_ZW 0x0000152c /* Parameters: w z */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_X 0x00001530
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_Y 0x00001534
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_Z 0x00001538
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_XY 0x00001540 /* Parameters: y x */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_Z 0x00001544 /* Parameters: z */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL_4F_R 0x00001550
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL_4F_G 0x00001554
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL_4F_B 0x00001558
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL_4F_A 0x0000155c
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL_3F_R 0x00001560
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL_3F_G 0x00001564
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL_3F_B 0x00001568
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL_4I 0x0000156c /* Parameters: a b g r */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_R 0x00001580
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_G 0x00001584
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_B 0x00001588
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL2_3I 0x0000158c /* Parameters: a b g r */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_S 0x00001590
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_T 0x00001594
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX0_2I 0x00001598 /* Parameters: t s */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_S 0x000015a0
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_T 0x000015a4
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_R 0x000015a8
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_Q 0x000015ac
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX0_4I_ST 0x000015b0 /* Parameters: t s */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX0_4I_RQ 0x000015b4 /* Parameters: q r */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_S 0x000015b8
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_T 0x000015bc
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX1_2I 0x000015c0 /* Parameters: t s */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_S 0x000015c8
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_T 0x000015cc
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_R 0x000015d0
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_Q 0x000015d4
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX1_4I_ST 0x000015d8 /* Parameters: t s */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX1_4I_RQ 0x000015dc /* Parameters: q r */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX2_2F_S 0x000015e0
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX2_2F_T 0x000015e4
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX2_2I 0x000015e8 /* Parameters: t s */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX2_4F_S 0x000015f0
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX2_4F_T 0x000015f4
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX2_4F_R 0x000015f8
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX2_4F_Q 0x000015fc
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX2_4I_ST 0x00001600 /* Parameters: t s */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX2_4I_RQ 0x00001604 /* Parameters: q r */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX3_2F_S 0x00001608
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX3_2F_T 0x0000160c
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX3_2I 0x00001610 /* Parameters: t s */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX3_4F_S 0x00001620
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX3_4F_T 0x00001624
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX3_4F_R 0x00001628
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX3_4F_Q 0x0000162c
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX3_4I_ST 0x00001630 /* Parameters: t s */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX3_4I_RQ 0x00001634 /* Parameters: q r */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_FOG_1F 0x00001698
+# define NV20_TCL_PRIMITIVE_3D_EDGE_FLAG 0x000016bc
+# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR0_POS 0x00001720 /* Parameters: enabled? offset */
+# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR1_WGH 0x00001724 /* Parameters: enabled? offset */
+# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR2_NOR 0x00001728 /* Parameters: enabled? offset */
+# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR3_COL 0x0000172c /* Parameters: enabled? offset */
+# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR4_COL2 0x00001730 /* Parameters: enabled? offset */
+# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR5_FOG 0x00001734 /* Parameters: enabled? offset */
+# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR6 0x00001738 /* Parameters: enabled? offset */
+# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR7 0x0000173c /* Parameters: enabled? offset */
+# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR8_TX0 0x00001740 /* Parameters: enabled? offset */
+# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR9_TX1 0x00001744 /* Parameters: enabled? offset */
+# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR10_TX2 0x00001748 /* Parameters: enabled? offset */
+# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR11_TX3 0x0000174c /* Parameters: enabled? offset */
+# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR12_TX4 0x00001750 /* Parameters: enabled? offset */
+# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR13_TX5 0x00001754 /* Parameters: enabled? offset */
+# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR14_TX6 0x00001758 /* Parameters: enabled? offset */
+# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR15_TX7 0x0000175c /* Parameters: enabled? offset */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR( d) (0x00001760 + d * 0x0004)
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR0_POS 0x00001760 /* Parameters: stride fields type */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR1_WGH 0x00001764 /* Parameters: stride fields type */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR2_NOR 0x00001768 /* Parameters: stride fields type */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR3_COL 0x0000176c /* Parameters: stride fields type */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR4_COL2 0x00001770 /* Parameters: stride fields type */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR5_FOG 0x00001774 /* Parameters: stride fields type */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR6 0x00001778 /* Parameters: stride fields type */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR7 0x0000177c /* Parameters: stride fields type */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR8_TX0 0x00001780 /* Parameters: stride fields type */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR9_TX1 0x00001784 /* Parameters: stride fields type */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR10_TX2 0x00001788 /* Parameters: stride fields type */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR11_TX3 0x0000178c /* Parameters: stride fields type */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR12_TX4 0x00001790 /* Parameters: stride fields type */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR13_TX5 0x00001794 /* Parameters: stride fields type */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR14_TX6 0x00001798 /* Parameters: stride fields type */
+# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR15_TX7 0x0000179c /* Parameters: stride fields type */
+# 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_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
+# 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
+*/
+#define NV30_TCL_PRIMITIVE_3D 0x00000097
+# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT0 0x00000180
+# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT1 0x00000184
+# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT2 0x00000188
+# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT3 0x0000018c
+# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT4 0x00000194
+# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT5 0x00000198
+# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT6 0x000001a4
+# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT7 0x000001a8
+# 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_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
+# define NV30_TCL_PRIMITIVE_3D_COLOR1_OFFSET 0x00000218
+# define NV30_TCL_PRIMITIVE_3D_BUFFER1_PITCH 0x0000021c /* Parameters: color1 buffer pitch */
+# define NV30_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH 0x0000022c /* Parameters: pitch */
+# define NV30_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_OFFSET 0x00000230
+# define NV30_TCL_PRIMITIVE_3D_TX_MATRIX_ENABLE(d) (0x00000240 + d * 0x0004)
+# define NV30_TCL_PRIMITIVE_3D_BUFFER2_PITCH 0x00000280
+# define NV30_TCL_PRIMITIVE_3D_BUFFER3_PITCH 0x00000284
+# define NV30_TCL_PRIMITIVE_3D_BUFFER2_OFFSET 0x00000288
+# define NV30_TCL_PRIMITIVE_3D_BUFFER3_OFFSET 0x0000028c
+# define NV30_TCL_PRIMITIVE_3D_DITHER_ENABLE 0x00000300
+# define NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE 0x00000304
+# define NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC 0x00000308
+# define NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF 0x0000030c
+# define NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE 0x00000310
+# define NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC 0x00000314
+# define NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_DST 0x00000318
+# define NV30_TCL_PRIMITIVE_3D_BLEND_COLOR 0x0000031c /* Parameters: a r g b */
+# define NV30_TCL_PRIMITIVE_3D_BLEND_EQUATION 0x00000320
+# define NV30_TCL_PRIMITIVE_3D_COLOR_MASK 0x00000324 /* Parameters: a r g b */
+# define NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_ENABLE 0x00000328
+# define NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_MASK 0x0000032c
+# define NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_FUNC 0x00000330
+# define NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_REF 0x00000334
+# define NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_MASK 0x00000338
+# define NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_FAIL 0x0000033c
+# define NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_ZFAIL 0x00000340
+# define NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_ZPASS 0x00000344
+# define NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_ENABLE 0x00000348
+# define NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_MASK 0x0000034c
+# define NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_FUNC 0x00000350
+# define NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_REF 0x00000354
+# define NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_MASK 0x00000358
+# define NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_FAIL 0x0000035c
+# define NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_ZFAIL 0x00000360
+# 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
+# define NV30_TCL_PRIMITIVE_3D_DEPTH_RANGE_FAR 0x00000398
+# 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_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)
+# define NV30_TCL_PRIMITIVE_3D_PROJECTION_MATRIX( d) (0x00000680 + d * 0x0004)
+# define NV30_TCL_PRIMITIVE_3D_TX_MATRIX(x,y) (0x000006c0 + y * 0x0010 + x * 0x0004)
+# define NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM 0x000008e4
+# define NV30_TCL_PRIMITIVE_3D_FOG_COORD_DIST 0x000008c8
+# define NV30_TCL_PRIMITIVE_3D_FOG_MODE 0x000008cc
+# 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_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 */
+# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_OFS1 0x000002c4 /* Parameters: height y_offset */
+# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_0 0x00000a00 /* Parameters: width x_offset */
+# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_1 0x00000a04 /* Parameters: height y_offset */
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R 0x00000a10
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_G 0x00000a14
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_B 0x00000a18
+# define NV30_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS 0x000008c0 /* Parameters: width x_offset */
+# define NV30_TCL_PRIMITIVE_3D_SCISSOR_HEIGHT_YPOS 0x000008c4 /* Parameters: height y_offset */
+# define NV30_TCL_PRIMITIVE_3D_POINT_SPRITE 0x00001ee8 /* Parameters: coord_replace r_mode enable */
+# define NV30_TCL_PRIMITIVE_3D_POINT_SIZE 0x00001ee0
+# define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_A 0x00001ec0
+# define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_B 0x00001ec4
+# define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_C 0x00001ec8
+# define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_D 0x00001ecc
+# define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_E 0x00001ed0
+# 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
+# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_UNK0_0x0 0x00000a2c
+# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_PX_DIV2 0x00000a30
+# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_PY_DIV2 0x00000a34
+# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_FMN_DIV2 0x00000a38
+# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_UNK1_0x0 0x00000a3c
+# define NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE 0x00000a60
+# define NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE 0x00000a64
+# define NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE 0x00000a68
+# define NV30_TCL_PRIMITIVE_3D_DEPTH_FUNC 0x00000a6c
+# define NV30_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE 0x00000a70
+# define NV30_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE 0x00000a74
+# define NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR 0x00000a78
+# define NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_UNITS 0x00000a7c
+# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_INST0 0x00000b80
+# 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)
+# define NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_B(d) (0x00000e04 + d * 0x0010)
+# define NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_C(d) (0x00000e08 + d * 0x0010)
+# define NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_D(d) (0x00000e0c + d * 0x0010)
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(d) (0x00001000 + d * 0x0040)
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_G(d) (0x00001004 + d * 0x0040)
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_B(d) (0x00001008 + d * 0x0040)
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(d) (0x0000100c + d * 0x0040)
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_G(d) (0x00001010 + d * 0x0040)
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_B(d) (0x00001014 + d * 0x0040)
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(d) (0x00001018 + d * 0x0040)
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_G(d) (0x0000101c + d * 0x0040)
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_B(d) (0x00001020 + d * 0x0040)
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_X(d) (0x00001028 + d * 0x0080)
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_Y(d) (0x0000102c + d * 0x0080)
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_Z(d) (0x00001030 + d * 0x0080)
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_X(d) (0x00001034 + d * 0x0080)
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_Y(d) (0x00001038 + d * 0x0080)
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_Z(d) (0x0000103c + d * 0x0080)
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(d) (0x00001228 + d * 0x0040)
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(d) (0x0000122c + d * 0x0040)
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(d) (0x00001230 + d * 0x0040)
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(d) (0x00001200 + d * 0x0040)
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(d) (0x00001204 + d * 0x0040)
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(d) (0x00001208 + d * 0x0040)
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(d) (0x0000120c + d * 0x0040)
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_Y(d) (0x00001210 + d * 0x0040)
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_Z(d) (0x00001214 + d * 0x0040)
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(d) (0x00001218 + d * 0x0040)
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(d) (0x0000121c + d * 0x0040)
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_POSITION_Y(d) (0x00001220 + d * 0x0040)
+# define NV30_TCL_PRIMITIVE_3D_LIGHT_POSITION_Z(d) (0x00001224 + d * 0x0040)
+# define NV30_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_A 0x00001400
+# define NV30_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_B 0x00001404
+# define NV30_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_C 0x00001408
+# define NV30_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_D 0x0000140c
+# 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_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
+# define NV30_TCL_PRIMITIVE_3D_FRONT_FACE 0x00001834
+# define NV30_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE 0x00001838
+# define NV30_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE 0x0000183c
+# define NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH 0x00001d8c
+# define NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB 0x00001d90 /* Parameters: a r g b */
+# define NV30_TCL_PRIMITIVE_3D_CLEAR_WHICH_BUFFERS 0x00001d94
+# define NV30_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_A 0x00001e20
+# define NV30_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_B 0x00001e24
+# define NV30_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_C 0x00001e28
+# define NV30_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_D 0x00001e2c
+# define NV30_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_E 0x00001e30
+# define NV30_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_F 0x00001e34
+# define NV30_TCL_PRIMITIVE_3D_DO_VERTICES 0x00001dac
+# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_FROM_ID 0x00001e9c
+# define NV30_TCL_PRIMITIVE_3D_VP_PROGRAM_START_ID 0x00001ea0
+# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_ID 0x00001efc
+# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P0_X 0x00001f00
+# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P0_Y 0x00001f04
+# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P0_Z 0x00001f08
+# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P0_W 0x00001f0c
+# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P1_X 0x00001f10
+# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P1_Y 0x00001f14
+# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P1_Z 0x00001f18
+# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P1_W 0x00001f1c
+# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P2_X 0x00001f20
+# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P2_Y 0x00001f24
+# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P2_Z 0x00001f28
+# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P2_W 0x00001f2c
+# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P3_X 0x00001f30
+# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P3_Y 0x00001f34
+# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P3_Z 0x00001f38
+# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P3_W 0x00001f3c
+# define NV30_TCL_PRIMITIVE_3D_VTX_ATTR_3X(d) (0x00001500 + d * 0x0010)
+# define NV30_TCL_PRIMITIVE_3D_VTX_ATTR_3Y(d) (0x00001504 + d * 0x0010)
+# define NV30_TCL_PRIMITIVE_3D_VTX_ATTR_3Z(d) (0x00001508 + d * 0x0010)
+# define NV30_TCL_PRIMITIVE_3D_VTX_ATTR_3W(d) (0x0000150c + d * 0x0010)
+# define NV30_TCL_PRIMITIVE_3D_VTX_ATTR_4X(d) (0x00001c00 + d * 0x0010)
+# 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: 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
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_T 0x000018c4
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_S 0x000018c8
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_T 0x000018cc
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX2_2F_S 0x000018d0
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX2_2F_T 0x000018d4
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX3_2F_S 0x000018d8
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX3_2F_T 0x000018dc
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX0_2I 0x00001920 /* Parameters: t s */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX1_2I 0x00001924 /* Parameters: t s */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX2_2I 0x00001928 /* Parameters: t s */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX3_2I 0x0000192c /* Parameters: t s */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_COL_4I 0x0000194c /* Parameters: a b g r */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_COL2_3I 0x00001950 /* Parameters: a b g r */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX0_4I_ST 0x000019c0 /* Parameters: t s */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX0_4I_RQ 0x000019c4 /* Parameters: q r */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX1_4I_ST 0x000019c8 /* Parameters: t s */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX1_4I_RQ 0x000019cc /* Parameters: q r */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX2_4I_ST 0x000019d0 /* Parameters: t s */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX2_4I_RQ 0x000019d4 /* Parameters: q r */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX3_4I_ST 0x000019d8 /* Parameters: t s */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX3_4I_RQ 0x000019dc /* Parameters: q r */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_FOG_1F 0x00001e54
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_UNK_0 0x00001718
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR( d) (0x00001740 + d * 0x0004)
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR0_POS 0x00001740 /* Parameters: stride fields type */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR1_WGH 0x00001744 /* Parameters: stride fields type */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR2_NOR 0x00001748 /* Parameters: stride fields type */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR3_COL 0x0000174c /* Parameters: stride fields type */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR4_COL2 0x00001750 /* Parameters: stride fields type */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR5_FOG 0x00001754 /* Parameters: stride fields type */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR6 0x00001758 /* Parameters: stride fields type */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR7 0x0000175c /* Parameters: stride fields type */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR8_TX0 0x00001760 /* Parameters: stride fields type */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR9_TX1 0x00001764 /* Parameters: stride fields type */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR10_TX2 0x00001768 /* Parameters: stride fields type */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR11_TX3 0x0000176c /* Parameters: stride fields type */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR12_TX4 0x00001770 /* Parameters: stride fields type */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR13_TX5 0x00001774 /* Parameters: stride fields type */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR14_TX6 0x00001778 /* Parameters: stride fields type */
+# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR15_TX7 0x0000177c /* Parameters: stride fields type */
+# 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_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 */
+# define NV30_TCL_PRIMITIVE_3D_TX_WRAP_UNIT(d) (0x00001a08 + d * 0x0020) /* Parameters: wrap_s wrap_t wrap_r */
+# define NV30_TCL_PRIMITIVE_3D_TX_ENABLE_UNIT(d) (0x00001a0c + d * 0x0020) /* Parameters: nv40_enable nv30_enable anisotropy */
+# define NV30_TCL_PRIMITIVE_3D_TX_SWIZZLE_UNIT(d) (0x00001a10 + d * 0x0020)
+# define NV30_TCL_PRIMITIVE_3D_TX_FILTER_UNIT(d) (0x00001a14 + d * 0x0020) /* Parameters: filter_min filter_mag */
+# define NV30_TCL_PRIMITIVE_3D_TX_XY_DIM_UNIT(d) (0x00001a18 + d * 0x0020) /* Parameters: width height */
+# 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
+# define NV30_TCL_PRIMITIVE_3D_SET_DISPLAY_LIST_MEM_OFFSET 0x0000181c
+# define NV30_TCL_PRIMITIVE_3D_EXECUTE_DISPLAY_LIST 0x00001824 /* Parameters: length start offset */
+# define NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT 0x00001828
+# define NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK 0x0000182c
+# define NV30_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE 0x0000147c
+# define NV30_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN( d) (0x00001480 + d * 0x0004)
+# define NV30_TCL_PRIMITIVE_3D_SET_CLIPPING_PLANES 0x00001478
+# define NV30_TCL_PRIMITIVE_3D_VP_IN_REG 0x00001ff0 /* Parameters: vertex pos weight normal primary color secondary color fogcoord texture coords 0 texture ccords 1 texture coords 2 texture coords 3 texture coords 4 texture coords 5 texture coords 6 texture coords 7 */
+# define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG 0x00001ff4 /* Parameters: primary color secondary color backface primary color backface secondary color fogcoord pointsize clip plane 0 clip plane 1 clip plane 2 clip plane 3 clip plane 4 clip plane 5 texture coords 0 texture coords 1 texture coords 2 texture coords 3 texture coords 4 texture coords 5 texture coords 6 texture coords 7 */
+
+/******************************************
+Object NV30_CLEAR_BUFFER used on: NV30 NV40 G70
+*/
+#define NV30_CLEAR_BUFFER 0x00000066
+# define NV30_CLEAR_BUFFER_SET_DMA_NOTIFY 0x00000180
+# define NV30_CLEAR_BUFFER_SET_IMAGE_PATTERN 0x00000188
+# define NV30_CLEAR_BUFFER_SET_RASTER_OP 0x0000018c
+# 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
+*/
+#define NV_DMA_FROM_MEMORY 0x00000002
+
+/******************************************
+Object NV_DMA_TO_MEMORY used on: NV03 NV04 NV10 NV15 NV20 NV30 NV40 G70
+*/
+#define NV_DMA_TO_MEMORY 0x00000003
+
+/******************************************
+Object NV_DMA_IN_MEMORY used on: NV03 NV04 NV10 NV15 NV20 NV30 NV40 G70
+*/
+#define NV_DMA_IN_MEMORY 0x0000003d
+
+/******************************************
+Object NvType0046 used on: NV04
+*/
+#define NvType0046 0x00000046
+# define NvType0046_DMA_NOTIFY 0x00000180
+# define NvType0046_DMA_MEM_1 0x00000184
+# define NvType0046_DMA_MEM_2 0x00000188
+# define NvType0046_DMA_3 0x0000018c
+# define NvType0046_DMA_4 0x00000190
+# define NvType0046_OBJ_5 0x00000194
+# define NvType0046_OBJ_6 0x00000198
+# define NvType0046_PITCH1 0x00000304
+# define NvType0046_PITCH2 0x0000030c
+# define NvType0046_SIZE 0x00000340 /* Parameters: width height */
+# define NvType0046_WIDTH 0x00000344 /* Parameters: visible_width blank_width */
+# define NvType0046_HSYNC 0x00000348 /* Parameters: hsync_start hsync_len */
+# define NvType0046_HEIGHT 0x0000034c /* Parameters: visible_height blank_height */
+# define NvType0046_VSYNC 0x00000350 /* Parameters: vsync_start vsync_len */
+# define NvType0046_FULL_SIZE 0x00000354 /* Parameters: full_width full_height */
+# define NvType0046_PIXEL_CLK 0x00000358
+# define NvType0046_FLAGS 0x0000035c /* Parameters: doublescan -hsync -vsync depth */
+
+/******************************************
+Object NvType0047 used on: NV04
+*/
+#define NvType0047 0x00000047
+# define NvType0047_DMA_NOTIFY 0x00000180
+# define NvType0047_UNK19C 0x0000019c
+# define NvType0047_UNK1A0 0x000001a0
+
+/******************************************
+Object NvType0049 used on: NV04
+*/
+#define NvType0049 0x00000049
+# define NvType0049_DMA_NOTIFY 0x00000180
+# define NvType0049_DMA_MEM_1 0x00000184
+# define NvType0049_DMA_MEM_2 0x00000188
+
+/******************************************
+Object NvType004D used on: NV04
+*/
+#define NvType004D 0x0000004d
+# define NvType004D_DMA_NOTIFY 0x00000180
+# define NvType004D_DMA_MEM_1 0x00000184
+# define NvType004D_DMA_MEM_2 0x00000188
+# define NvType004D_DMA_MEM_3 0x0000018c
+# define NvType004D_DMA_MEM_4 0x00000190
+
+#endif /* _NOUVEAU_REG_H */
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_screen.c
new file mode 100644
index 000000000..7a4b9f1cd
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_screen.c
@@ -0,0 +1,382 @@
+/**************************************************************************
+
+Copyright 2006 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 "glheader.h"
+#include "imports.h"
+#include "mtypes.h"
+#include "framebuffer.h"
+#include "renderbuffer.h"
+
+#include "nouveau_context.h"
+#include "nouveau_screen.h"
+#include "nouveau_object.h"
+#include "nouveau_span.h"
+
+#include "utils.h"
+#include "context.h"
+#include "vblank.h"
+#include "drirenderbuffer.h"
+
+#include "GL/internal/dri_interface.h"
+
+#include "xmlpool.h"
+
+PUBLIC const char __driConfigOptions[] =
+DRI_CONF_BEGIN
+ DRI_CONF_SECTION_DEBUG
+ DRI_CONF_NO_RAST(false)
+ DRI_CONF_SECTION_END
+DRI_CONF_END;
+static const GLuint __driNConfigOptions = 1;
+
+extern const struct dri_extension common_extensions[];
+extern const struct dri_extension nv10_extensions[];
+extern const struct dri_extension nv20_extensions[];
+extern const struct dri_extension nv30_extensions[];
+extern const struct dri_extension nv40_extensions[];
+extern const struct dri_extension nv50_extensions[];
+
+static nouveauScreenPtr nouveauCreateScreen(__DRIscreenPrivate *sPriv)
+{
+ nouveauScreenPtr screen;
+ NOUVEAUDRIPtr dri_priv=(NOUVEAUDRIPtr)sPriv->pDevPriv;
+
+ /* allocate screen */
+ screen = (nouveauScreenPtr) CALLOC( sizeof(*screen) );
+ if ( !screen ) {
+ __driUtilMessage("%s: Could not allocate memory for screen structure",__FUNCTION__);
+ return NULL;
+ }
+
+ screen->card=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);
+
+ screen->fbFormat = dri_priv->bpp / 8;
+ screen->frontOffset = dri_priv->front_offset;
+ screen->frontPitch = dri_priv->front_pitch;
+ screen->backOffset = dri_priv->back_offset;
+ screen->backPitch = dri_priv->back_pitch;
+ screen->depthOffset = dri_priv->depth_offset;
+ screen->depthPitch = dri_priv->depth_pitch;
+
+ screen->driScreen = sPriv;
+ return screen;
+}
+
+static void
+nouveauDestroyScreen(__DRIscreenPrivate *sPriv)
+{
+ nouveauScreenPtr screen = (nouveauScreenPtr)sPriv->private;
+
+ if (!screen) return;
+
+ /* free all option information */
+ driDestroyOptionInfo (&screen->optionCache);
+
+ FREE(screen);
+ sPriv->private = NULL;
+}
+
+static GLboolean nouveauInitDriver(__DRIscreenPrivate *sPriv)
+{
+ sPriv->private = (void *) nouveauCreateScreen( sPriv );
+ if ( !sPriv->private ) {
+ nouveauDestroyScreen( sPriv );
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+/**
+ * Create the Mesa framebuffer and renderbuffers for a given window/drawable.
+ *
+ * \todo This function (and its interface) will need to be updated to support
+ * pbuffers.
+ */
+static GLboolean
+nouveauCreateBuffer(__DRIscreenPrivate *driScrnPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ const __GLcontextModes *mesaVis,
+ GLboolean isPixmap)
+{
+ nouveauScreenPtr screen = (nouveauScreenPtr) driScrnPriv->private;
+ nouveau_renderbuffer *nrb;
+ struct gl_framebuffer *fb;
+ const GLboolean swAccum = mesaVis->accumRedBits > 0;
+ const GLboolean swStencil = mesaVis->stencilBits > 0 && mesaVis->depthBits != 24;
+ GLenum color_format = screen->fbFormat == 4 ? GL_RGBA8 : GL_RGB5;
+
+ if (isPixmap)
+ return GL_FALSE; /* not implemented */
+
+ fb = _mesa_create_framebuffer(mesaVis);
+ if (!fb)
+ return GL_FALSE;
+
+ /* Front buffer */
+ nrb = nouveau_renderbuffer_new(color_format,
+ driScrnPriv->pFB + screen->frontOffset,
+ screen->frontOffset,
+ screen->frontPitch * screen->fbFormat,
+ driDrawPriv);
+ nouveauSpanSetFunctions(nrb, mesaVis);
+ _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &nrb->mesa);
+
+ if (0 /* unified buffers if we choose to support them.. */) {
+ } else {
+ if (mesaVis->doubleBufferMode) {
+ nrb = nouveau_renderbuffer_new(color_format, NULL,
+ 0, 0,
+ NULL);
+ nouveauSpanSetFunctions(nrb, mesaVis);
+ _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &nrb->mesa);
+ }
+
+ if (mesaVis->depthBits == 24 && mesaVis->stencilBits == 8) {
+ nrb = nouveau_renderbuffer_new(GL_DEPTH24_STENCIL8_EXT, NULL,
+ 0, 0,
+ NULL);
+ nouveauSpanSetFunctions(nrb, mesaVis);
+ _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &nrb->mesa);
+ _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &nrb->mesa);
+ } else if (mesaVis->depthBits == 24) {
+ nrb = nouveau_renderbuffer_new(GL_DEPTH_COMPONENT24, NULL,
+ 0, 0,
+ NULL);
+ nouveauSpanSetFunctions(nrb, mesaVis);
+ _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &nrb->mesa);
+ } else if (mesaVis->depthBits == 16) {
+ nrb = nouveau_renderbuffer_new(GL_DEPTH_COMPONENT16, NULL,
+ 0, 0,
+ NULL);
+ nouveauSpanSetFunctions(nrb, mesaVis);
+ _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &nrb->mesa);
+ }
+ }
+
+ _mesa_add_soft_renderbuffers(fb,
+ GL_FALSE, /* color */
+ GL_FALSE, /* depth */
+ swStencil,
+ swAccum,
+ GL_FALSE, /* alpha */
+ GL_FALSE /* aux */);
+
+ driDrawPriv->driverPrivate = (void *) fb;
+ return (driDrawPriv->driverPrivate != NULL);
+}
+
+
+static void
+nouveauDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+{
+ _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)));
+}
+
+static int
+nouveauGetSwapInfo(__DRIdrawablePrivate *dpriv, __DRIswapInfo *sInfo)
+{
+ return -1;
+}
+
+static const struct __DriverAPIRec nouveauAPI = {
+ .InitDriver = nouveauInitDriver,
+ .DestroyScreen = nouveauDestroyScreen,
+ .CreateContext = nouveauCreateContext,
+ .DestroyContext = nouveauDestroyContext,
+ .CreateBuffer = nouveauCreateBuffer,
+ .DestroyBuffer = nouveauDestroyBuffer,
+ .SwapBuffers = nouveauSwapBuffers,
+ .MakeCurrent = nouveauMakeCurrent,
+ .UnbindContext = nouveauUnbindContext,
+ .GetSwapInfo = nouveauGetSwapInfo,
+ .GetMSC = driGetMSC32,
+ .WaitForMSC = driWaitForMSC32,
+ .WaitForSBC = NULL,
+ .SwapBuffersMSC = NULL,
+ .CopySubBuffer = nouveauCopySubBuffer
+};
+
+
+static __GLcontextModes *
+nouveauFillInModes( 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;
+ int i;
+
+ static const struct {
+ GLenum format;
+ GLenum type;
+ } fb_format_array[] = {
+ { GL_RGB , GL_UNSIGNED_SHORT_5_6_5 },
+ { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV },
+ { GL_BGR , GL_UNSIGNED_INT_8_8_8_8_REV },
+ };
+
+ /* 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[4] = { 0, 16, 24, 24 };
+ u_int8_t stencil_bits_array[4] = { 0, 0, 0, 8 };
+
+ depth_buffer_factor = 4;
+ back_buffer_factor = (have_back_buffer) ? 3 : 1;
+
+ num_modes = ((pixel_bits==16) ? 1 : 2) *
+ depth_buffer_factor * back_buffer_factor * 4;
+ modes = (*dri_interface->createContextModes)(num_modes,
+ sizeof(__GLcontextModes));
+ m = modes;
+
+ for (i=((pixel_bits==16)?0:1);i<((pixel_bits==16)?1:3);i++) {
+ if (!driFillInModes(&m, fb_format_array[i].format,
+ fb_format_array[i].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_array[i].format,
+ fb_format_array[i].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;
+ }
+ }
+
+ 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, 2, 0 };
+ static const __DRIversion dri_expected = { 4, 0, 0 };
+ static const __DRIversion drm_expected = { 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL };
+#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 6
+#error nouveau_drm.h version doesn't match expected version
+#endif
+ dri_interface = interface;
+
+ if (!driCheckDriDdxDrmVersions2("nouveau",
+ dri_version, & dri_expected,
+ ddx_version, & ddx_expected,
+ drm_version, & drm_expected)) {
+ return NULL;
+ }
+
+ // 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;
+ }
+
+ psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
+ ddx_version, dri_version, drm_version,
+ frame_buffer, pSAREA, fd,
+ internal_api_version, &nouveauAPI);
+ if ( psp != NULL ) {
+ NOUVEAUDRIPtr dri_priv = (NOUVEAUDRIPtr)psp->pDevPriv;
+
+ *driver_modes = nouveauFillInModes(dri_priv->bpp,
+ (dri_priv->bpp == 16) ? 16 : 24,
+ (dri_priv->bpp == 16) ? 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, common_extensions, GL_FALSE );
+ driInitExtensions( NULL, nv10_extensions, GL_FALSE );
+ driInitExtensions( NULL, nv10_extensions, GL_FALSE );
+ driInitExtensions( NULL, nv30_extensions, GL_FALSE );
+ driInitExtensions( NULL, nv40_extensions, GL_FALSE );
+ driInitExtensions( NULL, nv50_extensions, GL_FALSE );
+ }
+
+ return (void *) psp;
+}
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_screen.h b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_screen.h
new file mode 100644
index 000000000..decdafa86
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_screen.h
@@ -0,0 +1,61 @@
+/**************************************************************************
+
+Copyright 2006 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.
+
+**************************************************************************/
+
+
+#ifndef __NOUVEAU_SCREEN_H__
+#define __NOUVEAU_SCREEN_H__
+
+#include "xmlconfig.h"
+
+#include "nouveau_dri.h"
+#include "nouveau_card.h"
+
+typedef struct {
+ nouveau_card* card;
+ u_int32_t bus_type;
+ u_int32_t agp_mode;
+
+ GLint fbFormat;
+
+ GLuint frontOffset;
+ GLuint frontPitch;
+ GLuint backOffset;
+ GLuint backPitch;
+
+ GLuint depthOffset;
+ GLuint depthPitch;
+ GLuint spanOffset;
+
+ __DRIscreenPrivate *driScreen;
+ unsigned int sarea_priv_offset;
+
+ /* Configuration cache with default values for all contexts */
+ driOptionCache optionCache;
+
+} nouveauScreenRec, *nouveauScreenPtr;
+
+
+#endif /* __NOUVEAU_SCREEN_H__ */
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_shader.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_shader.c
new file mode 100644
index 000000000..b6837c5de
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_shader.c
@@ -0,0 +1,833 @@
+/*
+ * 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 <darktama@iinet.net.au>
+ */
+
+#include "glheader.h"
+#include "macros.h"
+#include "enums.h"
+#include "extensions.h"
+
+#include "shader/program.h"
+#include "shader/prog_instruction.h"
+/*#include "shader/arbprogparse.h"*/
+#include "tnl/tnl.h"
+
+#include "nouveau_context.h"
+#include "nouveau_shader.h"
+
+/*****************************************************************************
+ * Mesa entry points
+ */
+static void
+nouveauBindProgram(GLcontext *ctx, GLenum target, struct gl_program *prog)
+{
+ NVSDBG("target=%s, prog=%p\n", _mesa_lookup_enum_by_nr(target), prog);
+}
+
+static struct gl_program *
+nouveauNewProgram(GLcontext *ctx, GLenum target, GLuint id)
+{
+ nouveauShader *nvs;
+
+ NVSDBG("target=%s, id=%d\n", _mesa_lookup_enum_by_nr(target), id);
+
+ nvs = CALLOC_STRUCT(_nouveauShader);
+ NVSDBG("prog=%p\n", nvs);
+ switch (target) {
+ case GL_VERTEX_PROGRAM_ARB:
+ return _mesa_init_vertex_program(ctx, &nvs->mesa.vp, target, id);
+ case GL_FRAGMENT_PROGRAM_ARB:
+ return _mesa_init_fragment_program(ctx, &nvs->mesa.fp, target, id);
+ default:
+ _mesa_problem(ctx, "Unsupported shader target");
+ break;
+ }
+
+ FREE(nvs);
+ return NULL;
+}
+
+static void
+nouveauDeleteProgram(GLcontext *ctx, struct gl_program *prog)
+{
+ nouveauShader *nvs = (nouveauShader *)prog;
+
+ NVSDBG("prog=%p\n", prog);
+
+ if (nvs->translated)
+ FREE(nvs->program);
+ _mesa_delete_program(ctx, prog);
+}
+
+static void
+nouveauProgramStringNotify(GLcontext *ctx, GLenum target,
+ struct gl_program *prog)
+{
+ nouveauShader *nvs = (nouveauShader *)prog;
+
+ NVSDBG("target=%s, prog=%p\n", _mesa_lookup_enum_by_nr(target), prog);
+
+ if (nvs->translated)
+ FREE(nvs->program);
+
+ nvs->error = GL_FALSE;
+ nvs->translated = GL_FALSE;
+
+ _tnl_program_string(ctx, target, prog);
+}
+
+static GLboolean
+nouveauIsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog)
+{
+ nouveauShader *nvs = (nouveauShader *)prog;
+
+ NVSDBG("target=%s, prog=%p\n", _mesa_lookup_enum_by_nr(target), prog);
+
+ return nvs->translated;
+}
+
+GLboolean
+nvsUpdateShader(GLcontext *ctx, nouveauShader *nvs)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ struct gl_program_parameter_list *plist;
+ int i;
+
+ NVSDBG("prog=%p\n", nvs);
+
+ /* Translate to HW format now if necessary */
+ if (!nvs->translated) {
+ /* Mesa ASM shader -> nouveauShader */
+ if (!nouveau_shader_pass0(ctx, nvs))
+ return GL_FALSE;
+ /* Basic dead code elimination + register usage info */
+ if (!nouveau_shader_pass1(nvs))
+ return GL_FALSE;
+ /* nouveauShader -> HW bytecode, HW register alloc */
+ if (!nouveau_shader_pass2(nvs))
+ return GL_FALSE;
+ assert(nvs->translated);
+ assert(nvs->program);
+ }
+
+ /* Update state parameters */
+ plist = nvs->mesa.vp.Base.Parameters;
+ _mesa_load_state_parameters(ctx, plist);
+ for (i=0; i<nvs->param_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 (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);
+ }
+ }
+
+ /* Upload program to hardware, this must come after state param update
+ * as >=NV30 fragprogs inline consts into the bytecode.
+ */
+ if (!nvs->on_hardware) {
+ nouveauShader **current;
+
+ if (nvs->mesa.vp.Base.Target == GL_VERTEX_PROGRAM_ARB)
+ current = &nmesa->current_vertprog;
+ else
+ current = &nmesa->current_fragprog;
+ if (*current) (*current)->on_hardware = 0;
+
+ nvs->func->UploadToHW(ctx, nvs);
+ nvs->on_hardware = 1;
+
+ *current = nvs;
+ }
+
+ return GL_TRUE;
+}
+
+nouveauShader *
+nvsBuildTextShader(GLcontext *ctx, GLenum target, const char *text)
+{
+ nouveauShader *nvs;
+
+ nvs = CALLOC_STRUCT(_nouveauShader);
+ if (!nvs)
+ return NULL;
+
+ if (target == GL_VERTEX_PROGRAM_ARB) {
+ _mesa_init_vertex_program(ctx, &nvs->mesa.vp, GL_VERTEX_PROGRAM_ARB, 0);
+ _mesa_parse_arb_vertex_program(ctx,
+ GL_VERTEX_PROGRAM_ARB,
+ text,
+ strlen(text),
+ &nvs->mesa.vp);
+ } else if (target == GL_FRAGMENT_PROGRAM_ARB) {
+ _mesa_init_fragment_program(ctx, &nvs->mesa.fp, GL_FRAGMENT_PROGRAM_ARB, 0);
+ _mesa_parse_arb_fragment_program(ctx,
+ GL_FRAGMENT_PROGRAM_ARB,
+ text,
+ strlen(text),
+ &nvs->mesa.fp);
+ }
+
+ nouveau_shader_pass0(ctx, nvs);
+ nouveau_shader_pass1(nvs);
+ nouveau_shader_pass2(nvs);
+
+ return nvs;
+}
+
+static void
+nvsBuildPassthroughVP(GLcontext *ctx)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ const char *vp_text =
+ "!!ARBvp1.0\n"
+ "OPTION ARB_position_invariant;"
+ ""
+ "MOV result.color, vertex.color;\n"
+ "MOV result.texcoord[0], vertex.texcoord[0];\n"
+ "MOV result.texcoord[1], vertex.texcoord[1];\n"
+ "MOV result.texcoord[2], vertex.texcoord[2];\n"
+ "MOV result.texcoord[3], vertex.texcoord[3];\n"
+ "MOV result.texcoord[4], vertex.texcoord[4];\n"
+ "MOV result.texcoord[5], vertex.texcoord[5];\n"
+ "MOV result.texcoord[6], vertex.texcoord[6];\n"
+ "MOV result.texcoord[7], vertex.texcoord[7];\n"
+ "END";
+
+ nmesa->passthrough_vp = nvsBuildTextShader(ctx,
+ GL_VERTEX_PROGRAM_ARB,
+ 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)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ switch (nmesa->screen->card->type) {
+ case NV_20:
+ NV20VPInitShaderFuncs(&nmesa->VPfunc);
+ break;
+ case NV_30:
+ NV30VPInitShaderFuncs(&nmesa->VPfunc);
+ NV30FPInitShaderFuncs(&nmesa->FPfunc);
+ break;
+ case NV_40:
+ case NV_44:
+ NV40VPInitShaderFuncs(&nmesa->VPfunc);
+ NV40FPInitShaderFuncs(&nmesa->FPfunc);
+ break;
+ case NV_50:
+ default:
+ return;
+ }
+
+ /* Build a vertex program that simply passes through all attribs.
+ * Needed to do swtcl on nv40
+ */
+ 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;
+ ctx->Const.VertexProgram.MaxNativeTexIndirections =
+ ctx->Const.VertexProgram.MaxNativeTexInstructions;
+ ctx->Const.VertexProgram.MaxNativeAttribs = nmesa->VPfunc.MaxAttrib;
+ ctx->Const.VertexProgram.MaxNativeTemps = nmesa->VPfunc.MaxTemp;
+ ctx->Const.VertexProgram.MaxNativeAddressRegs = nmesa->VPfunc.MaxAddress;
+ ctx->Const.VertexProgram.MaxNativeParameters = nmesa->VPfunc.MaxConst;
+
+ if (nmesa->screen->card->type >= NV_30) {
+ ctx->Const.FragmentProgram.MaxNativeInstructions = nmesa->FPfunc.MaxInst;
+ ctx->Const.FragmentProgram.MaxNativeAluInstructions = nmesa->FPfunc.MaxInst;
+ ctx->Const.FragmentProgram.MaxNativeTexInstructions = nmesa->FPfunc.MaxInst;
+ ctx->Const.FragmentProgram.MaxNativeTexIndirections =
+ ctx->Const.FragmentProgram.MaxNativeTexInstructions;
+ ctx->Const.FragmentProgram.MaxNativeAttribs = nmesa->FPfunc.MaxAttrib;
+ ctx->Const.FragmentProgram.MaxNativeTemps = nmesa->FPfunc.MaxTemp;
+ ctx->Const.FragmentProgram.MaxNativeAddressRegs = nmesa->FPfunc.MaxAddress;
+ ctx->Const.FragmentProgram.MaxNativeParameters = nmesa->FPfunc.MaxConst;
+ }
+
+ ctx->Driver.NewProgram = nouveauNewProgram;
+ ctx->Driver.BindProgram = nouveauBindProgram;
+ ctx->Driver.DeleteProgram = nouveauDeleteProgram;
+ ctx->Driver.ProgramStringNotify = nouveauProgramStringNotify;
+ ctx->Driver.IsProgramNative = nouveauIsProgramNative;
+}
+
+
+/*****************************************************************************
+ * Disassembly support structs
+ */
+#define CHECK_RANGE(idx, arr) ((idx)<sizeof(_##arr)/sizeof(const char *)) \
+ ? _##arr[(idx)] : #arr"_OOB"
+
+#define NODS (1<<0)
+#define BRANCH_TR (1<<1)
+#define BRANCH_EL (1<<2)
+#define BRANCH_EN (1<<3)
+#define BRANCH_RE (1<<4)
+#define BRANCH_ALL (BRANCH_TR|BRANCH_EL|BRANCH_EN)
+#define COUNT_INC (1<<4)
+#define COUNT_IND (1<<5)
+#define COUNT_NUM (1<<6)
+#define COUNT_ALL (COUNT_INC|COUNT_IND|COUNT_NUM)
+#define TI_UNIT (1<<7)
+struct _opcode_info
+{
+ const char *name;
+ int numsrc;
+ int flags;
+};
+
+static struct _opcode_info ops[] = {
+ [NVS_OP_ABS] = {"ABS", 1, 0},
+ [NVS_OP_ADD] = {"ADD", 2, 0},
+ [NVS_OP_ARA] = {"ARA", 1, 0},
+ [NVS_OP_ARL] = {"ARL", 1, 0},
+ [NVS_OP_ARR] = {"ARR", 1, 0},
+ [NVS_OP_BRA] = {"BRA", 0, NODS | BRANCH_TR},
+ [NVS_OP_BRK] = {"BRK", 0, NODS},
+ [NVS_OP_CAL] = {"CAL", 0, NODS | BRANCH_TR},
+ [NVS_OP_CMP] = {"CMP", 2, 0},
+ [NVS_OP_COS] = {"COS", 1, 0},
+ [NVS_OP_DIV] = {"DIV", 2, 0},
+ [NVS_OP_DDX] = {"DDX", 1, 0},
+ [NVS_OP_DDY] = {"DDY", 1, 0},
+ [NVS_OP_DP2] = {"DP2", 2, 0},
+ [NVS_OP_DP2A] = {"DP2A", 3, 0},
+ [NVS_OP_DP3] = {"DP3", 2, 0},
+ [NVS_OP_DP4] = {"DP4", 2, 0},
+ [NVS_OP_DPH] = {"DPH", 2, 0},
+ [NVS_OP_DST] = {"DST", 2, 0},
+ [NVS_OP_EX2] = {"EX2", 1, 0},
+ [NVS_OP_EXP] = {"EXP", 1, 0},
+ [NVS_OP_FLR] = {"FLR", 1, 0},
+ [NVS_OP_FRC] = {"FRC", 1, 0},
+ [NVS_OP_IF] = {"IF", 0, NODS | BRANCH_EL | BRANCH_EN},
+ [NVS_OP_KIL] = {"KIL", 1, 0},
+ [NVS_OP_LG2] = {"LG2", 1, 0},
+ [NVS_OP_LIT] = {"LIT", 1, 0},
+ [NVS_OP_LOG] = {"LOG", 1, 0},
+ [NVS_OP_LOOP] = {"LOOP", 0, NODS | COUNT_ALL | BRANCH_EN},
+ [NVS_OP_LRP] = {"LRP", 3, 0},
+ [NVS_OP_MAD] = {"MAD", 3, 0},
+ [NVS_OP_MAX] = {"MAX", 2, 0},
+ [NVS_OP_MIN] = {"MIN", 2, 0},
+ [NVS_OP_MOV] = {"MOV", 1, 0},
+ [NVS_OP_MUL] = {"MUL", 2, 0},
+ [NVS_OP_NRM] = {"NRM", 1, 0},
+ [NVS_OP_PK2H] = {"PK2H", 1, 0},
+ [NVS_OP_PK2US] = {"PK2US", 1, 0},
+ [NVS_OP_PK4B] = {"PK4B", 1, 0},
+ [NVS_OP_PK4UB] = {"PK4UB", 1, 0},
+ [NVS_OP_POW] = {"POW", 2, 0},
+ [NVS_OP_POPA] = {"POPA", 0, 0},
+ [NVS_OP_PUSHA] = {"PUSHA", 1, NODS},
+ [NVS_OP_RCC] = {"RCC", 1, 0},
+ [NVS_OP_RCP] = {"RCP", 1, 0},
+ [NVS_OP_REP] = {"REP", 0, NODS | BRANCH_EN | COUNT_NUM},
+ [NVS_OP_RET] = {"RET", 0, NODS},
+ [NVS_OP_RFL] = {"RFL", 1, 0},
+ [NVS_OP_RSQ] = {"RSQ", 1, 0},
+ [NVS_OP_SCS] = {"SCS", 1, 0},
+ [NVS_OP_SEQ] = {"SEQ", 2, 0},
+ [NVS_OP_SFL] = {"SFL", 2, 0},
+ [NVS_OP_SGE] = {"SGE", 2, 0},
+ [NVS_OP_SGT] = {"SGT", 2, 0},
+ [NVS_OP_SIN] = {"SIN", 1, 0},
+ [NVS_OP_SLE] = {"SLE", 2, 0},
+ [NVS_OP_SLT] = {"SLT", 2, 0},
+ [NVS_OP_SNE] = {"SNE", 2, 0},
+ [NVS_OP_SSG] = {"SSG", 1, 0},
+ [NVS_OP_STR] = {"STR", 2, 0},
+ [NVS_OP_SUB] = {"SUB", 2, 0},
+ [NVS_OP_TEX] = {"TEX", 1, TI_UNIT},
+ [NVS_OP_TXB] = {"TXB", 1, TI_UNIT},
+ [NVS_OP_TXD] = {"TXD", 3, TI_UNIT},
+ [NVS_OP_TXL] = {"TXL", 1, TI_UNIT},
+ [NVS_OP_TXP] = {"TXP", 1, TI_UNIT},
+ [NVS_OP_UP2H] = {"UP2H", 1, 0},
+ [NVS_OP_UP2US] = {"UP2US", 1, 0},
+ [NVS_OP_UP4B] = {"UP4B", 1, 0},
+ [NVS_OP_UP4UB] = {"UP4UB", 1, 0},
+ [NVS_OP_X2D] = {"X2D", 3, 0},
+ [NVS_OP_XPD] = {"XPD", 2, 0},
+ [NVS_OP_NOP] = {"NOP", 0, NODS},
+};
+
+static struct _opcode_info *
+_get_op_info(int op)
+{
+ if (op >= (sizeof(ops) / sizeof(struct _opcode_info)))
+ return NULL;
+ if (ops[op].name == NULL)
+ return NULL;
+ return &ops[op];
+}
+
+static const char *_SFR_STRING[] = {
+ [NVS_FR_POSITION] = "position",
+ [NVS_FR_WEIGHT] = "weight",
+ [NVS_FR_NORMAL] = "normal",
+ [NVS_FR_COL0] = "color",
+ [NVS_FR_COL1] = "color.secondary",
+ [NVS_FR_BFC0] = "bfc",
+ [NVS_FR_BFC1] = "bfc.secondary",
+ [NVS_FR_FOGCOORD] = "fogcoord",
+ [NVS_FR_POINTSZ] = "pointsize",
+ [NVS_FR_TEXCOORD0] = "texcoord[0]",
+ [NVS_FR_TEXCOORD1] = "texcoord[1]",
+ [NVS_FR_TEXCOORD2] = "texcoord[2]",
+ [NVS_FR_TEXCOORD3] = "texcoord[3]",
+ [NVS_FR_TEXCOORD4] = "texcoord[4]",
+ [NVS_FR_TEXCOORD5] = "texcoord[5]",
+ [NVS_FR_TEXCOORD6] = "texcoord[6]",
+ [NVS_FR_TEXCOORD7] = "texcoord[7]",
+ [NVS_FR_FRAGDATA0] = "data[0]",
+ [NVS_FR_FRAGDATA1] = "data[1]",
+ [NVS_FR_FRAGDATA2] = "data[2]",
+ [NVS_FR_FRAGDATA3] = "data[3]",
+ [NVS_FR_CLIP0] = "clip_plane[0]",
+ [NVS_FR_CLIP1] = "clip_plane[1]",
+ [NVS_FR_CLIP2] = "clip_plane[2]",
+ [NVS_FR_CLIP3] = "clip_plane[3]",
+ [NVS_FR_CLIP4] = "clip_plane[4]",
+ [NVS_FR_CLIP5] = "clip_plane[5]",
+ [NVS_FR_CLIP6] = "clip_plane[6]",
+ [NVS_FR_FACING] = "facing",
+};
+
+#define SFR_STRING(idx) CHECK_RANGE((idx), SFR_STRING)
+
+static const char *_SWZ_STRING[] = {
+ [NVS_SWZ_X] = "x",
+ [NVS_SWZ_Y] = "y",
+ [NVS_SWZ_Z] = "z",
+ [NVS_SWZ_W] = "w"
+};
+
+#define SWZ_STRING(idx) CHECK_RANGE((idx), SWZ_STRING)
+
+static const char *_NVS_PREC_STRING[] = {
+ [NVS_PREC_FLOAT32] = "R",
+ [NVS_PREC_FLOAT16] = "H",
+ [NVS_PREC_FIXED12] = "X",
+ [NVS_PREC_UNKNOWN] = "?"
+};
+
+#define NVS_PREC_STRING(idx) CHECK_RANGE((idx), NVS_PREC_STRING)
+
+static const char *_NVS_COND_STRING[] = {
+ [NVS_COND_FL] = "FL",
+ [NVS_COND_LT] = "LT",
+ [NVS_COND_EQ] = "EQ",
+ [NVS_COND_LE] = "LE",
+ [NVS_COND_GT] = "GT",
+ [NVS_COND_NE] = "NE",
+ [NVS_COND_GE] = "GE",
+ [NVS_COND_TR] = "TR",
+ [NVS_COND_UNKNOWN] = "??"
+};
+
+#define NVS_COND_STRING(idx) CHECK_RANGE((idx), NVS_COND_STRING)
+
+/*****************************************************************************
+ * ShaderFragment dumping
+ */
+static void
+nvsDumpIndent(int lvl)
+{
+ while (lvl--)
+ printf(" ");
+}
+
+static void
+nvsDumpSwizzle(nvsSwzComp *swz)
+{
+ printf(".%s%s%s%s",
+ SWZ_STRING(swz[0]),
+ SWZ_STRING(swz[1]), SWZ_STRING(swz[2]), SWZ_STRING(swz[3])
+ );
+}
+
+static void
+nvsDumpReg(nvsInstruction * inst, nvsRegister * reg)
+{
+ if (reg->negate)
+ printf("-");
+ if (reg->abs)
+ printf("abs(");
+
+ switch (reg->file) {
+ case NVS_FILE_TEMP:
+ printf("R%d", reg->index);
+ nvsDumpSwizzle(reg->swizzle);
+ break;
+ case NVS_FILE_ATTRIB:
+ printf("attrib.%s", SFR_STRING(reg->index));
+ nvsDumpSwizzle(reg->swizzle);
+ break;
+ case NVS_FILE_ADDRESS:
+ printf("A%d", reg->index);
+ break;
+ case NVS_FILE_CONST:
+ if (reg->indexed)
+ printf("const[A%d.%s + %d]",
+ reg->addr_reg, SWZ_STRING(reg->addr_comp), reg->index);
+ else
+ printf("const[%d]", reg->index);
+ nvsDumpSwizzle(reg->swizzle);
+ break;
+ default:
+ printf("UNKNOWN_FILE");
+ break;
+ }
+
+ if (reg->abs)
+ printf(")");
+}
+
+static void
+nvsDumpInstruction(nvsInstruction * inst, int slot, int lvl)
+{
+ struct _opcode_info *opr = &ops[inst->op];
+ int i;
+
+ nvsDumpIndent(lvl);
+ printf("%s ", opr->name);
+
+ if (!opr->flags & NODS) {
+ switch (inst->dest.file) {
+ case NVS_FILE_RESULT:
+ printf("result.%s", SFR_STRING(inst->dest.index));
+ break;
+ case NVS_FILE_TEMP:
+ printf("R%d", inst->dest.index);
+ break;
+ case NVS_FILE_ADDRESS:
+ printf("A%d", inst->dest.index);
+ break;
+ default:
+ printf("UNKNOWN_DST_FILE");
+ break;
+ }
+
+ if (inst->mask != SMASK_ALL) {
+ printf(".");
+ if (inst->mask & SMASK_X)
+ printf("x");
+ if (inst->mask & SMASK_Y)
+ printf("y");
+ if (inst->mask & SMASK_Z)
+ printf("z");
+ if (inst->mask & SMASK_W)
+ printf("w");
+ }
+
+ if (opr->numsrc)
+ printf(", ");
+ }
+
+ for (i = 0; i < opr->numsrc; i++) {
+ nvsDumpReg(inst, &inst->src[i]);
+ if (i != opr->numsrc - 1)
+ printf(", ");
+ }
+ if (opr->flags & TI_UNIT)
+ printf(", texture[%d]", inst->tex_unit);
+
+ printf("\n");
+}
+
+void
+nvsDumpFragmentList(nvsFragmentHeader *f, int lvl)
+{
+ while (f) {
+ switch (f->type) {
+ case NVS_INSTRUCTION:
+ nvsDumpInstruction((nvsInstruction*)f, 0, lvl);
+ break;
+ default:
+ fprintf(stderr, "%s: Only NVS_INSTRUCTION fragments can be in"
+ "nvsFragmentList!\n", __func__);
+ return;
+ }
+ f = f->next;
+ }
+}
+
+/*****************************************************************************
+ * HW shader disassembly
+ */
+static void
+nvsDisasmHWShaderOp(nvsFunc * shader, int merged)
+{
+ struct _opcode_info *opi;
+ nvsOpcode op;
+ nvsRegFile file;
+ nvsSwzComp swz[4];
+ int i;
+
+ op = shader->GetOpcode(shader, merged);
+ opi = _get_op_info(op);
+ if (!opi) {
+ printf("NO OPINFO!");
+ return;
+ }
+
+ printf("%s", opi->name);
+ if (shader->GetPrecision &&
+ (!(opi->flags & BRANCH_ALL)) && (!(opi->flags * NODS)) &&
+ (op != NVS_OP_NOP))
+ printf("%s", NVS_PREC_STRING(shader->GetPrecision(shader)));
+ if (shader->SupportsConditional && shader->SupportsConditional(shader)) {
+ if (shader->GetConditionUpdate(shader)) {
+ printf("C%d", shader->GetCondRegID(shader));
+ }
+ }
+ if (shader->GetSaturate && shader->GetSaturate(shader))
+ printf("_SAT");
+
+ if (!(opi->flags & NODS)) {
+ int mask = shader->GetDestMask(shader, merged);
+
+ switch (shader->GetDestFile(shader, merged)) {
+ case NVS_FILE_ADDRESS:
+ printf(" A%d", shader->GetDestID(shader, merged));
+ break;
+ case NVS_FILE_TEMP:
+ printf(" R%d", shader->GetDestID(shader, merged));
+ break;
+ case NVS_FILE_RESULT:
+ printf(" result.%s", (SFR_STRING(shader->GetDestID(shader, merged))));
+ break;
+ default:
+ printf(" BAD_RESULT_FILE");
+ break;
+ }
+
+ if (mask != SMASK_ALL) {
+ printf(".");
+ if (mask & SMASK_X) printf("x");
+ if (mask & SMASK_Y) printf("y");
+ if (mask & SMASK_Z) printf("z");
+ if (mask & SMASK_W) printf("w");
+ }
+ }
+
+ if (shader->SupportsConditional && shader->SupportsConditional(shader) &&
+ shader->GetConditionTest(shader)) {
+ shader->GetCondRegSwizzle(shader, swz);
+
+ printf(" (%s%d.%s%s%s%s)",
+ NVS_COND_STRING(shader->GetCondition(shader)),
+ shader->GetCondRegID(shader),
+ SWZ_STRING(swz[NVS_SWZ_X]),
+ SWZ_STRING(swz[NVS_SWZ_Y]),
+ SWZ_STRING(swz[NVS_SWZ_Z]),
+ SWZ_STRING(swz[NVS_SWZ_W])
+ );
+ }
+
+ /* looping */
+ if (opi->flags & COUNT_ALL) {
+ printf(" { ");
+ if (opi->flags & COUNT_NUM) {
+ printf("%d", shader->GetLoopCount(shader));
+ }
+ if (opi->flags & COUNT_IND) {
+ printf(", %d", shader->GetLoopInitial(shader));
+ }
+ if (opi->flags & COUNT_INC) {
+ printf(", %d", shader->GetLoopIncrement(shader));
+ }
+ printf(" }");
+ }
+
+ /* branching */
+ if (opi->flags & BRANCH_TR)
+ printf(" %d", shader->GetBranch(shader));
+ if (opi->flags & BRANCH_EL)
+ printf(" ELSE %d", shader->GetBranchElse(shader));
+ if (opi->flags & BRANCH_EN)
+ printf(" END %d", shader->GetBranchEnd(shader));
+
+ if (!(opi->flags & NODS) && opi->numsrc)
+ printf(",");
+ printf(" ");
+
+ for (i = 0; i < opi->numsrc; i++) {
+ if (shader->GetSourceAbs(shader, merged, i))
+ printf("abs(");
+ if (shader->GetSourceNegate(shader, merged, i))
+ printf("-");
+
+ file = shader->GetSourceFile(shader, merged, i);
+ switch (file) {
+ case NVS_FILE_TEMP:
+ printf("R%d", shader->GetSourceID(shader, merged, i));
+ break;
+ case NVS_FILE_CONST:
+ if (shader->GetSourceIndexed(shader, merged, i)) {
+ printf("c[A%d.%s + 0x%x]",
+ shader->GetRelAddressRegID(shader),
+ SWZ_STRING(shader->GetRelAddressSwizzle(shader)),
+ shader->GetSourceID(shader, merged, i)
+ );
+ } else {
+ float val[4];
+
+ if (shader->GetSourceConstVal) {
+ shader->GetSourceConstVal(shader, merged, i, val);
+ printf("{ %.02f, %.02f, %.02f, %.02f }",
+ val[0], val[1], val[2], val[3]);
+ } else {
+ printf("c[0x%x]", shader->GetSourceID(shader, merged, i));
+ }
+ }
+ break;
+ case NVS_FILE_ATTRIB:
+ if (shader->GetSourceIndexed(shader, merged, i)) {
+ printf("attrib[A%d.%s + %d]",
+ shader->GetRelAddressRegID(shader),
+ SWZ_STRING(shader->GetRelAddressSwizzle(shader)),
+ shader->GetSourceID(shader, merged, i)
+ );
+ }
+ else {
+ printf("attrib.%s",
+ SFR_STRING(shader->GetSourceID(shader, merged, i))
+ );
+ }
+ break;
+ case NVS_FILE_ADDRESS:
+ printf("A%d", shader->GetRelAddressRegID(shader));
+ break;
+ default:
+ printf("UNKNOWN_SRC_FILE");
+ break;
+ }
+
+ shader->GetSourceSwizzle(shader, merged, i, swz);
+ if (file != NVS_FILE_ADDRESS &&
+ (swz[NVS_SWZ_X] != NVS_SWZ_X || swz[NVS_SWZ_Y] != NVS_SWZ_Y ||
+ swz[NVS_SWZ_Z] != NVS_SWZ_Z || swz[NVS_SWZ_W] != NVS_SWZ_W)) {
+ printf(".%s%s%s%s", SWZ_STRING(swz[NVS_SWZ_X]),
+ SWZ_STRING(swz[NVS_SWZ_Y]),
+ SWZ_STRING(swz[NVS_SWZ_Z]),
+ SWZ_STRING(swz[NVS_SWZ_W]));
+ }
+
+ if (shader->GetSourceAbs(shader, merged, i))
+ printf(")");
+ if (shader->GetSourceScale) {
+ int scale = shader->GetSourceScale(shader, merged, i);
+ if (scale > 1)
+ printf("{scaled %dx}", scale);
+ }
+ if (i < (opi->numsrc - 1))
+ printf(", ");
+ }
+
+ if (shader->IsLastInst(shader))
+ printf(" + END");
+}
+
+void
+nvsDisasmHWShader(nvsPtr nvs)
+{
+ nvsFunc *shader = nvs->func;
+ unsigned int iaddr = 0;
+
+ if (!nvs->program) {
+ fprintf(stderr, "No HW program present");
+ return;
+ }
+
+ shader->inst = nvs->program;
+ while (1) {
+ if (shader->inst >= (nvs->program + nvs->program_size)) {
+ fprintf(stderr, "Reached end of program, but HW inst has no END");
+ break;
+ }
+
+ printf("\t0x%08x:\n", shader->inst[0]);
+ printf("\t0x%08x:\n", shader->inst[1]);
+ printf("\t0x%08x:\n", shader->inst[2]);
+ printf("\t0x%08x:", shader->inst[3]);
+
+ printf("\n\t\tINST %d.0: ", iaddr);
+ nvsDisasmHWShaderOp(shader, 0);
+ if (shader->HasMergedInst(shader)) {
+ printf("\n\t\tINST %d.1: ", iaddr);
+ nvsDisasmHWShaderOp(shader, 1);
+ }
+ printf("\n");
+
+ if (shader->IsLastInst(shader))
+ break;
+
+ shader->inst += shader->GetOffsetNext(shader);
+ iaddr++;
+ }
+
+ printf("\n");
+}
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_shader.h
new file mode 100644
index 000000000..7125a2ae8
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_shader.h
@@ -0,0 +1,454 @@
+#ifndef __SHADER_COMMON_H__
+#define __SHADER_COMMON_H__
+
+#include "mtypes.h"
+#include "bufferobj.h"
+
+#define NVSDBG(fmt, args...) do { \
+ if (NOUVEAU_DEBUG & DEBUG_SHADERS) { \
+ fprintf(stderr, "%s: "fmt, __func__, ##args); \
+ } \
+} while(0)
+
+typedef struct _nvsFunc nvsFunc;
+
+#define NVS_MAX_TEMPS 32
+#define NVS_MAX_ATTRIBS 16
+#define NVS_MAX_CONSTS 256
+#define NVS_MAX_ADDRESS 2
+#define NVS_MAX_INSNS 4096
+
+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;
+} nvsFragmentHeader;
+
+typedef union {
+ struct {
+ GLboolean uses_kil;
+ GLuint num_regs;
+ } NV30FP;
+ struct {
+ uint32_t vp_in_reg;
+ uint32_t vp_out_reg;
+ uint32_t clip_enables;
+ } NV30VP;
+} nvsCardPriv;
+
+typedef struct _nouveauShader {
+ union {
+ struct gl_vertex_program vp;
+ struct gl_fragment_program fp;
+ } mesa;
+ GLcontext *ctx;
+ nvsFunc *func;
+
+ /* State of the final program */
+ GLboolean error;
+ GLboolean translated;
+ GLboolean on_hardware;
+ unsigned int *program;
+ unsigned int program_size;
+ unsigned int program_alloc_size;
+ unsigned int program_start_id;
+ unsigned int program_current;
+ struct gl_buffer_object *program_buffer;
+ int inst_count;
+
+ nvsCardPriv card_priv;
+ 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
+ * makes use of it.
+ */
+ int *hw_index;
+ int hw_index_cnt;
+ } params[NVS_MAX_CONSTS];
+ int param_high;
+
+ /* Pass-private data */
+ void *pass_rec;
+
+ nvsFragmentHeader *program_tree;
+} nouveauShader, *nvsPtr;
+
+typedef enum {
+ NVS_FILE_NONE,
+ NVS_FILE_TEMP,
+ NVS_FILE_ATTRIB,
+ NVS_FILE_CONST,
+ NVS_FILE_RESULT,
+ NVS_FILE_ADDRESS,
+ NVS_FILE_UNKNOWN
+} nvsRegFile;
+
+typedef enum {
+ NVS_OP_UNKNOWN = 0,
+ NVS_OP_NOP,
+ NVS_OP_ABS, NVS_OP_ADD, NVS_OP_ARA, NVS_OP_ARL, NVS_OP_ARR,
+ NVS_OP_BRA, NVS_OP_BRK,
+ NVS_OP_CAL, NVS_OP_CMP, NVS_OP_COS,
+ NVS_OP_DDX, NVS_OP_DDY, NVS_OP_DIV, NVS_OP_DP2, NVS_OP_DP2A, NVS_OP_DP3,
+ NVS_OP_DP4, NVS_OP_DPH, NVS_OP_DST,
+ NVS_OP_EX2, NVS_OP_EXP,
+ NVS_OP_FLR, NVS_OP_FRC,
+ NVS_OP_IF,
+ NVS_OP_KIL,
+ NVS_OP_LG2, NVS_OP_LIT, NVS_OP_LOG, NVS_OP_LOOP, NVS_OP_LRP,
+ NVS_OP_MAD, NVS_OP_MAX, NVS_OP_MIN, NVS_OP_MOV, NVS_OP_MUL,
+ NVS_OP_NRM,
+ NVS_OP_PK2H, NVS_OP_PK2US, NVS_OP_PK4B, NVS_OP_PK4UB, NVS_OP_POW,
+ NVS_OP_POPA, NVS_OP_PUSHA,
+ NVS_OP_RCC, NVS_OP_RCP, NVS_OP_REP, NVS_OP_RET, NVS_OP_RFL, NVS_OP_RSQ,
+ NVS_OP_SCS, NVS_OP_SEQ, NVS_OP_SFL, NVS_OP_SGE, NVS_OP_SGT, NVS_OP_SIN,
+ NVS_OP_SLE, NVS_OP_SLT, NVS_OP_SNE, NVS_OP_SSG, NVS_OP_STR, NVS_OP_SUB,
+ NVS_OP_SWZ,
+ NVS_OP_TEX, NVS_OP_TXB, NVS_OP_TXD, NVS_OP_TXL, NVS_OP_TXP,
+ NVS_OP_UP2H, NVS_OP_UP2US, NVS_OP_UP4B, NVS_OP_UP4UB,
+ NVS_OP_X2D, NVS_OP_XPD,
+ NVS_OP_EMUL
+} nvsOpcode;
+
+typedef enum {
+ NVS_PREC_FLOAT32,
+ NVS_PREC_FLOAT16,
+ NVS_PREC_FIXED12,
+ NVS_PREC_UNKNOWN
+} nvsPrecision;
+
+typedef enum {
+ NVS_SWZ_X = 0,
+ NVS_SWZ_Y = 1,
+ NVS_SWZ_Z = 2,
+ NVS_SWZ_W = 3
+} nvsSwzComp;
+
+typedef enum {
+ 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;
+
+typedef enum {
+ NVS_COND_FL, NVS_COND_LT, NVS_COND_EQ, NVS_COND_LE, NVS_COND_GT,
+ NVS_COND_NE, NVS_COND_GE, NVS_COND_TR, NVS_COND_UN,
+ NVS_COND_UNKNOWN
+} nvsCond;
+
+typedef struct {
+ nvsRegFile file;
+ unsigned int index;
+
+ unsigned int indexed;
+ unsigned int addr_reg;
+ nvsSwzComp addr_comp;
+
+ nvsSwzComp swizzle[4];
+ int negate;
+ int abs;
+} nvsRegister;
+
+static const nvsRegister nvr_unused = {
+ .file = NVS_FILE_ATTRIB,
+ .index = 0,
+ .indexed = 0,
+ .addr_reg = 0,
+ .addr_comp = NVS_SWZ_X,
+ .swizzle = {NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W},
+ .negate = 0,
+ .abs = 0,
+};
+
+typedef enum {
+ NVS_TEX_TARGET_1D,
+ NVS_TEX_TARGET_2D,
+ NVS_TEX_TARGET_3D,
+ NVS_TEX_TARGET_CUBE,
+ NVS_TEX_TARGET_RECT,
+ 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;
+
+ nvsOpcode op;
+ unsigned int saturate;
+
+ nvsRegister dest;
+ unsigned int mask;
+ nvsScale dest_scale;
+
+ nvsRegister src[3];
+
+ unsigned int tex_unit;
+ nvsTexTarget tex_target;
+
+ nvsCond cond;
+ nvsSwzComp cond_swizzle[4];
+ int cond_reg;
+ int cond_test;
+ 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)
+#define SMASK_W (1<<3)
+#define SMASK_ALL (SMASK_X|SMASK_Y|SMASK_Z|SMASK_W)
+
+#define SPOS_ADDRESS 3
+struct _op_xlat {
+ unsigned int NV;
+ nvsOpcode SOP;
+ int srcpos[3];
+};
+#define MOD_OPCODE(t,hw,sop,s0,s1,s2) do { \
+ t[hw].NV = hw; \
+ t[hw].SOP = sop; \
+ t[hw].srcpos[0] = s0; \
+ t[hw].srcpos[1] = s1; \
+ t[hw].srcpos[2] = s2; \
+} while(0)
+
+extern unsigned int NVVP_TX_VOP_COUNT;
+extern unsigned int NVVP_TX_NVS_OP_COUNT;
+extern struct _op_xlat NVVP_TX_VOP[];
+extern struct _op_xlat NVVP_TX_SOP[];
+
+extern unsigned int NVFP_TX_AOP_COUNT;
+extern unsigned int NVFP_TX_BOP_COUNT;
+extern struct _op_xlat NVFP_TX_AOP[];
+extern struct _op_xlat NVFP_TX_BOP[];
+
+extern void NV20VPTXSwizzle(int hwswz, nvsSwzComp *swz);
+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;
+ unsigned int MaxAddress;
+ unsigned int MaxConst;
+ unsigned int caps;
+
+ unsigned int *inst;
+ void (*UploadToHW) (GLcontext *, nouveauShader *);
+ void (*UpdateConst) (GLcontext *, nouveauShader *, int);
+
+ struct _op_xlat*(*GetOPTXRec) (nvsFunc *, int merged);
+ struct _op_xlat*(*GetOPTXFromSOP) (nvsOpcode, int *id);
+
+ void (*InitInstruction) (nvsFunc *);
+ int (*SupportsOpcode) (nvsFunc *, nvsOpcode);
+ int (*SupportsResultScale) (nvsFunc *, nvsScale);
+ void (*SetOpcode) (nvsFunc *, unsigned int opcode,
+ int slot);
+ void (*SetCCUpdate) (nvsFunc *);
+ void (*SetCondition) (nvsFunc *, int on, nvsCond, int reg,
+ 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 *);
+ 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 *);
+
+ int (*GetOpcodeSlot) (nvsFunc *, int merged);
+ unsigned int (*GetOpcodeHW) (nvsFunc *, int slot);
+ nvsOpcode (*GetOpcode) (nvsFunc *, int merged);
+
+ nvsPrecision (*GetPrecision) (nvsFunc *);
+ int (*GetSaturate) (nvsFunc *);
+
+ nvsRegFile (*GetDestFile) (nvsFunc *, int merged);
+ unsigned int (*GetDestID) (nvsFunc *, int merged);
+ unsigned int (*GetDestMask) (nvsFunc *, int merged);
+
+ unsigned int (*GetSourceHW) (nvsFunc *, int merged, int pos);
+ nvsRegFile (*GetSourceFile) (nvsFunc *, int merged, int pos);
+ int (*GetSourceID) (nvsFunc *, int merged, int pos);
+ int (*GetTexImageUnit) (nvsFunc *);
+ int (*GetSourceNegate) (nvsFunc *, int merged, int pos);
+ int (*GetSourceAbs) (nvsFunc *, int merged, int pos);
+ void (*GetSourceSwizzle) (nvsFunc *, int merged, int pos,
+ nvsSwzComp *swz);
+ int (*GetSourceIndexed) (nvsFunc *, int merged, int pos);
+ void (*GetSourceConstVal) (nvsFunc *, int merged, int pos,
+ float *val);
+ int (*GetSourceScale) (nvsFunc *, int merged, int pos);
+
+ int (*GetRelAddressRegID) (nvsFunc *);
+ nvsSwzComp (*GetRelAddressSwizzle) (nvsFunc *);
+
+ int (*SupportsConditional) (nvsFunc *);
+ int (*GetConditionUpdate) (nvsFunc *);
+ int (*GetConditionTest) (nvsFunc *);
+ nvsCond (*GetCondition) (nvsFunc *);
+ void (*GetCondRegSwizzle) (nvsFunc *, nvsSwzComp *swz);
+ int (*GetCondRegID) (nvsFunc *);
+ int (*GetBranch) (nvsFunc *);
+ int (*GetBranchElse) (nvsFunc *);
+ int (*GetBranchEnd) (nvsFunc *);
+
+ int (*GetLoopCount) (nvsFunc *);
+ int (*GetLoopInitial) (nvsFunc *);
+ int (*GetLoopIncrement) (nvsFunc *);
+};
+
+static inline nvsRegister
+nvsNegate(nvsRegister reg)
+{
+ reg.negate = !reg.negate;
+ return reg;
+}
+
+static inline nvsRegister
+nvsAbs(nvsRegister reg)
+{
+ reg.abs = 1;
+ return reg;
+}
+
+static inline nvsRegister
+nvsSwizzle(nvsRegister reg, nvsSwzComp x, nvsSwzComp y,
+ nvsSwzComp z, nvsSwzComp w)
+{
+ nvsSwzComp sc[4] = { x, y, z, w };
+ nvsSwzComp oc[4];
+ int i;
+
+ for (i=0;i<4;i++)
+ oc[i] = reg.swizzle[i];
+ for (i=0;i<4;i++)
+ reg.swizzle[i] = oc[sc[i]];
+ return reg;
+}
+
+#define nvsProgramError(nvs,fmt,args...) do { \
+ fprintf(stderr, "nvsProgramError (%s): "fmt, __func__, ##args); \
+ (nvs)->error = GL_TRUE; \
+ (nvs)->translated = GL_FALSE; \
+} while(0)
+
+extern GLboolean nvsUpdateShader(GLcontext *ctx, nouveauShader *nvs);
+extern void nvsDisasmHWShader(nvsPtr);
+extern void nvsDumpFragmentList(nvsFragmentHeader *f, int lvl);
+extern nouveauShader *nvsBuildTextShader(GLcontext *ctx, GLenum target,
+ const char *text);
+
+extern void NV20VPInitShaderFuncs(nvsFunc *);
+extern void NV30VPInitShaderFuncs(nvsFunc *);
+extern void NV40VPInitShaderFuncs(nvsFunc *);
+
+extern void NV30FPInitShaderFuncs(nvsFunc *);
+extern void NV40FPInitShaderFuncs(nvsFunc *);
+
+extern void nouveauShaderInitFuncs(GLcontext *ctx);
+
+extern GLboolean nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs);
+extern GLboolean nouveau_shader_pass1(nvsPtr nvs);
+extern GLboolean nouveau_shader_pass2(nvsPtr nvs);
+
+#endif
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c
new file mode 100644
index 000000000..8c203cc66
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c
@@ -0,0 +1,1050 @@
+/*
+ * 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 <darktama@iinet.net.au>
+ */
+
+#include "glheader.h"
+#include "macros.h"
+#include "enums.h"
+
+#include "shader/prog_instruction.h"
+#include "shader/prog_parameter.h"
+#include "shader/prog_statevars.h"
+#include "shader/programopt.h"
+
+#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,
+ 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_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_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
+};
+
+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;
+};
+
+#define X NVS_SWZ_X
+#define Y NVS_SWZ_Y
+#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,
+ int pos)
+{
+ 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
+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 GLboolean
+pass0_opcode_is_tex(enum prog_opcode op)
+{
+ switch (op) {
+ case OPCODE_TEX:
+ case OPCODE_TXB:
+ case OPCODE_TXD:
+ case OPCODE_TXL:
+ case OPCODE_TXP:
+ return GL_TRUE;
+ default:
+ break;
+ }
+
+ return GL_FALSE;
+}
+
+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 pass0_rec *rec = nvs->pass_rec;
+ struct gl_program *mesa = (struct gl_program *)&nvs->mesa.vp.Base;
+ int i;
+
+ *reg = nvr_unused;
+
+ switch (src->File) {
+ case PROGRAM_INPUT:
+ reg->file = NVS_FILE_ATTRIB;
+ if (mesa->Target == GL_VERTEX_PROGRAM_ARB) {
+ for (i=0; i<NVS_MAX_ATTRIBS; i++) {
+ if (nvs->vp_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] :
+ NVS_FR_UNKNOWN;
+ }
+ break;
+ case PROGRAM_STATE_VAR:
+ 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;
+ }
+ 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, nvsFragmentHeader *parent, int fpos,
+ nvsOpcode op, nvsRegister dst,
+ unsigned int mask, int saturate,
+ nvsRegister src0, nvsRegister src1, nvsRegister src2)
+{
+ 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->dest_scale = NVS_SCALE_1X;
+ 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, nvsFragmentHeader *parent, int fpos,
+ 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;
+ nvsInstruction *nvsinst;
+ nvsRegister sr, dr = nvr_unused;
+ nvsRegister sm1const, sm2const;
+
+ if (!rec->swzconst_done) {
+ struct gl_program *prog = &nvs->mesa.vp.Base;
+ GLuint swizzle;
+ rec->swzconst_id = _mesa_add_unnamed_constant(prog->Parameters,
+ sc, 4, &swizzle);
+ /* XXX what about swizzle? */
+ 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);
+ 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)
+ 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);
+ ARITHu(NVS_OP_MAD, dr, SMASK_ALL, 0, sr, sm1const, sm2const);
+ } else {
+ /* SWIZZLE_ZERO || arbitrary negate */
+ ARITHu(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, 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<<c))
+ SET_SWZ(sm_2, c, SWIZZLE_Z); /* -1.0 */
+ else
+ SET_SWZ(sm_2, c, SWIZZLE_X); /* 1.0 */
+ SET_SWZ(src->Swizzle, c, SWIZZLE_X);
+ } else {
+ if (src->NegateBase & (1<<c))
+ SET_SWZ(sm_1, c, SWIZZLE_Z); /* -[xyzw] */
+ else
+ SET_SWZ(sm_1, c, SWIZZLE_X); /*[xyzw]*/
+ SET_SWZ(sm_2, c, SWIZZLE_Y);
+ }
+ }
+
+ /* Unless we're multiplying by 1.0 or -1.0 on all components,
+ * and we're adding nothing to any component we have to
+ * emulate the swizzle.
+ */
+ 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, 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.
+ */
+ continue;
+ }
+
+ /* HW can't use more than one ATTRIB or PARAM in a single
+ * instruction */
+ switch (src->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
+pass0_emulate_instruction(nouveauShader *nvs,
+ nvsFragmentHeader *parent, int fpos,
+ struct prog_instruction *inst)
+{
+ nvsFunc *shader = nvs->func;
+ nvsRegister src[3], dest, temp;
+ nvsInstruction *nvsinst;
+ 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)
+ ARITH(NVS_OP_MOV, dest, mask, sat,
+ nvsAbs(src[0]), nvr_unused, nvr_unused);
+ else
+ 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.
+ *XXX: might have to worry with GLSL however...
+ */
+ /* MOVC0 temp, src */
+ 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;
+ /* KIL_NV (LT0.xyzw) temp */
+ 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, SWIZZLE_NOOP);
+ break;
+ case OPCODE_LRP:
+ pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
+ 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 */
+ 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 */
+ 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 */
+ 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");
+ return GL_FALSE;
+ }
+ break;
+ case OPCODE_RSQ:
+ 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);
+ nvsinst->dest_scale = NVS_SCALE_INV_2X;
+ ARITH (NVS_OP_EX2, dest, mask, sat,
+ nvsNegate(nvsSwizzle(temp, X, X, X, X)),
+ nvr_unused, nvr_unused);
+ break;
+ case OPCODE_SCS:
+ if (mask & SMASK_X)
+ ARITH(NVS_OP_COS, dest, SMASK_X, sat,
+ nvsSwizzle(src[0], X, X, X, X),
+ nvr_unused, nvr_unused);
+ if (mask & SMASK_Y)
+ ARITH(NVS_OP_SIN, dest, SMASK_Y, sat,
+ nvsSwizzle(src[0], X, X, X, X),
+ nvr_unused, nvr_unused);
+ break;
+ case OPCODE_SUB:
+ 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);
+ 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\","
+ "and no emulation found\n",
+ _mesa_opcode_string(inst->Opcode));
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+static GLboolean
+pass0_translate_arith(nouveauShader *nvs, struct gl_program *prog,
+ int ipos, int fpos,
+ nvsFragmentHeader *parent)
+{
+ 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);
+
+ 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;
+ if (pass0_opcode_is_tex(inst->Opcode))
+ nvsinst->tex_target =
+ pass0_make_tex_target(inst->TexSrcTarget);
+ else
+ nvsinst->tex_target = NVS_TEX_TARGET_UNKNOWN;
+
+ ret = GL_TRUE;
+ } else
+ ret = pass0_emulate_instruction(nvs, parent, fpos, inst);
+
+ return ret;
+}
+
+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 OPCODE_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;
+}
+
+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; i<NVS_MAX_ATTRIBS; i++)
+ nvs->vp_attrib_map[i] = -1;
+
+ while (inputs_read) {
+ int in = ffs(inputs_read) - 1;
+ int hw;
+ inputs_read &= ~(1<<in);
+
+ if (vp->IsNVProgram) {
+ /* NVvp: must alias */
+ if (in >= VERT_ATTRIB_GENERIC0)
+ hw = in - VERT_ATTRIB_GENERIC0;
+ else
+ hw = in;
+ } else {
+ /* ARBvp: may alias (but we won't)
+ * GL2.0: must not alias
+ */
+ if (in >= VERT_ATTRIB_GENERIC0)
+ hw = ffs(~input_alloc) - 1;
+ else
+ hw = in;
+ input_alloc |= (1<<hw);
+ }
+
+ nvs->vp_attrib_map[hw] = in;
+ }
+
+ if (NOUVEAU_DEBUG & DEBUG_SHADERS) {
+ printf("vtxprog attrib map:\n");
+ for (i=0; i<NVS_MAX_ATTRIBS; i++) {
+ printf(" hw:%d = attrib:%d\n",
+ i, nvs->vp_attrib_map[i]);
+ }
+ }
+}
+
+static void
+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];
+ gl_state_index tokens[STATE_LENGTH]
+ = { STATE_MODELVIEW_MATRIX, 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[2] = tokens[3] = 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<<i)))
+ continue;
+
+ /* Point a const at a user clipping plane */
+ tokens[0] = STATE_CLIPPLANE;
+ tokens[1] = i;
+ id = _mesa_add_state_reference(prog->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;
+ 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++;
+ }
+}
+
+static GLboolean
+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:
+ * 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;
+ for (i=0; i<plist->NumParameters; i++) {
+ int hw = rec->mesa_const_base + i;
+
+ if (hw > NVS_MAX_CONSTS) {
+ nvsProgramError(nvs, "hw = %d > NVS_MAX_CONSTS!\n", hw);
+ return GL_FALSE;
+ }
+
+ 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:
+ nvsProgramError(nvs, "hit bad type=%d on param %d\n",
+ plist->Parameters[i].Type, i);
+ 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 = GL_FALSE;
+
+ NVSDBG("start: nvs=%p\n", nvs);
+
+ /* Previously detected an error, and haven't recieved new program
+ * string, so fail immediately.
+ */
+ if (nvs->error) {
+ NVSDBG("failed previous compile attempt, not retrying\n");
+ return 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_rebase_mesa_consts(nvs);
+
+ if (!prog->String && ctx->Transform.ClipPlanesEnabled)
+ pass0_vp_insert_ff_clip_planes(ctx, nvs);
+
+ pass0_build_attrib_map(nvs, vp);
+ break;
+ case GL_FRAGMENT_PROGRAM_ARB:
+ nvs->func = &nmesa->FPfunc;
+
+ if (fp->FogOption != GL_NONE)
+ _mesa_append_fog_code(ctx, fp);
+ pass0_rebase_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;
+
+ ret = pass0_translate_instructions(nvs, 0, 0, nvs->program_tree);
+ if (ret)
+ ret = pass0_resolve_mesa_consts(nvs);
+
+ /*XXX: if (!ret) DESTROY TREE!!! */
+
+ FREE(rec);
+ return ret;
+}
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_shader_1.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_shader_1.c
new file mode 100644
index 000000000..78c1401f7
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_shader_1.c
@@ -0,0 +1,16 @@
+#include "glheader.h"
+#include "macros.h"
+#include "enums.h"
+
+#include "nouveau_context.h"
+#include "nouveau_shader.h"
+
+GLboolean
+nouveau_shader_pass1(nvsPtr nvs)
+{
+ NVSDBG("start: nvs=%p\n", nvs);
+
+ return GL_TRUE;
+}
+
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c
new file mode 100644
index 000000000..cd27daca8
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c
@@ -0,0 +1,264 @@
+/*
+ * 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 <darktama@iinet.net.au>
+ */
+
+#include "glheader.h"
+#include "macros.h"
+#include "enums.h"
+
+#include "shader/prog_parameter.h"
+#include "shader/prog_print.h"
+
+#include "nouveau_context.h"
+#include "nouveau_shader.h"
+#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];
+};
+
+static int
+pass2_alloc_hw_temp(nvsPtr nvs)
+{
+ struct pass2_rec *rec = nvs->pass_rec;
+ int i;
+
+ for (i=0; i<nvs->func->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;
+
+ 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;
+}
+
+static void
+pass2_add_instruction(nvsPtr nvs, nvsInstruction *inst,
+ 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]);
+
+ shader->SetSource(shader, &reg, 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);
+ shader->SetResult(shader, &reg, inst->mask, slot);
+
+ if (inst->dest_scale != NVS_SCALE_1X) {
+ shader->SetResultScale(shader, inst->dest_scale);
+ }
+}
+
+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; i<instsz; i++)
+ nvs->program[nvs->program_current++] = hw_inst[i];
+ nvs->program_size = nvs->program_current;
+ 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)
+{
+ struct pass2_rec *rec;
+ int i;
+
+ NVSDBG("start: nvs=%p\n", nvs);
+
+ rec = calloc(1, sizeof(struct pass2_rec));
+ for (i=0; i<NVS_MAX_TEMPS; i++)
+ rec->temps[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;
+}
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_span.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_span.c
new file mode 100644
index 000000000..74dec66af
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_span.c
@@ -0,0 +1,125 @@
+/**************************************************************************
+
+Copyright 2006 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_span.h"
+#include "nouveau_fifo.h"
+#include "nouveau_lock.h"
+
+#include "swrast/swrast.h"
+
+#define HAVE_HW_DEPTH_SPANS 0
+#define HAVE_HW_DEPTH_PIXELS 0
+#define HAVE_HW_STENCIL_SPANS 0
+#define HAVE_HW_STENCIL_PIXELS 0
+
+#define HW_CLIPLOOP() \
+ do { \
+ int _nc = nmesa->numClipRects; \
+ while ( _nc-- ) { \
+ int minx = nmesa->pClipRects[_nc].x1 - nmesa->drawX; \
+ int miny = nmesa->pClipRects[_nc].y1 - nmesa->drawY; \
+ int maxx = nmesa->pClipRects[_nc].x2 - nmesa->drawX; \
+ int maxy = nmesa->pClipRects[_nc].y2 - nmesa->drawY;
+
+#define LOCAL_VARS \
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); \
+ nouveau_renderbuffer *nrb = (nouveau_renderbuffer *)rb; \
+ GLuint height = nrb->mesa.Height; \
+ GLubyte *map = (GLubyte *)(nrb->map ? nrb->map : nrb->mem->map) + \
+ (nmesa->drawY * nrb->pitch) + (nmesa->drawX * nrb->cpp); \
+ GLuint p; \
+ (void) p;
+
+#define Y_FLIP( _y ) (height - _y - 1)
+
+#define HW_LOCK()
+
+#define HW_UNLOCK()
+
+
+
+/* ================================================================
+ * Color buffers
+ */
+
+/* RGB565 */
+#define SPANTMP_PIXEL_FMT GL_RGB
+#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
+
+#define TAG(x) nouveau##x##_RGB565
+#define TAG2(x,y) nouveau##x##_RGB565##y
+#define GET_PTR(X,Y) (map + (Y)*nrb->pitch + (X)*nrb->cpp)
+#include "spantmp2.h"
+
+
+/* ARGB8888 */
+#define SPANTMP_PIXEL_FMT GL_BGRA
+#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
+
+#define TAG(x) nouveau##x##_ARGB8888
+#define TAG2(x,y) nouveau##x##_ARGB8888##y
+#define GET_PTR(X,Y) (map + (Y)*nrb->pitch + (X)*nrb->cpp)
+#include "spantmp2.h"
+
+static void
+nouveauSpanRenderStart( GLcontext *ctx )
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ FIRE_RING();
+ LOCK_HARDWARE(nmesa);
+ nouveauWaitForIdleLocked( nmesa );
+}
+
+static void
+nouveauSpanRenderFinish( GLcontext *ctx )
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ _swrast_flush( ctx );
+ nouveauWaitForIdleLocked( nmesa );
+ UNLOCK_HARDWARE( nmesa );
+}
+
+void nouveauSpanInitFunctions( GLcontext *ctx )
+{
+ struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
+ swdd->SpanRenderStart = nouveauSpanRenderStart;
+ swdd->SpanRenderFinish = nouveauSpanRenderFinish;
+}
+
+
+/**
+ * Plug in the Get/Put routines for the given driRenderbuffer.
+ */
+void
+nouveauSpanSetFunctions(nouveau_renderbuffer *nrb, const GLvisual *vis)
+{
+ if (nrb->mesa._ActualFormat == GL_RGBA8)
+ nouveauInitPointers_ARGB8888(&nrb->mesa);
+ else if (nrb->mesa._ActualFormat == GL_RGB5)
+ nouveauInitPointers_RGB565(&nrb->mesa);
+}
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_span.h b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_span.h
new file mode 100644
index 000000000..bc39ecd17
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_span.h
@@ -0,0 +1,39 @@
+/**************************************************************************
+
+Copyright 2006 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.
+
+**************************************************************************/
+
+
+
+#ifndef __NOUVEAU_SPAN_H__
+#define __NOUVEAU_SPAN_H__
+
+#include "drirenderbuffer.h"
+#include "nouveau_buffers.h"
+
+extern void nouveauSpanInitFunctions( GLcontext *ctx );
+extern void nouveauSpanSetFunctions(nouveau_renderbuffer *nrb, const GLvisual *vis);
+
+#endif /* __NOUVEAU_SPAN_H__ */
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_state.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_state.c
new file mode 100644
index 000000000..e9fd188d7
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_state.c
@@ -0,0 +1,345 @@
+/**************************************************************************
+
+Copyright 2006 Jeremy Kolb
+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_state.h"
+#include "nouveau_swtcl.h"
+#include "nouveau_fifo.h"
+
+#include "swrast/swrast.h"
+#include "tnl/tnl.h"
+#include "swrast_setup/swrast_setup.h"
+
+#include "tnl/t_pipeline.h"
+
+#include "mtypes.h"
+#include "colormac.h"
+
+static __inline__ GLuint nouveauPackColor(GLuint format,
+ GLubyte r, GLubyte g,
+ GLubyte b, GLubyte a)
+{
+ switch (format) {
+ case 2:
+ return PACK_COLOR_565( r, g, b );
+ case 4:
+ return PACK_COLOR_8888( r, g, b, a);
+ default:
+ fprintf(stderr, "unknown format %d\n", (int)format);
+ return 0;
+ }
+}
+
+static void nouveauCalcViewport(GLcontext *ctx)
+{
+ /* Calculate the Viewport Matrix */
+
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ const GLfloat *v = ctx->Viewport._WindowMap.m;
+ GLfloat *m = nmesa->viewport.m;
+ GLfloat xoffset = nmesa->drawX, yoffset = nmesa->drawY;
+
+ nmesa->depth_scale = 1.0 / ctx->DrawBuffer->_DepthMaxF;
+
+ m[MAT_SX] = v[MAT_SX];
+ m[MAT_TX] = v[MAT_TX] + xoffset + SUBPIXEL_X;
+ m[MAT_SY] = - v[MAT_SY];
+ m[MAT_TY] = v[MAT_TY] + yoffset + SUBPIXEL_Y;
+ m[MAT_SZ] = v[MAT_SZ] * nmesa->depth_scale;
+ m[MAT_TZ] = v[MAT_TZ] * nmesa->depth_scale;
+
+ nmesa->hw_func.WindowMoved(nmesa);
+}
+
+static void nouveauViewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+{
+ /*
+ * Need to send (at least on an nv35 the following:
+ * cons = 4 (this may be bytes per pixel)
+ *
+ * The viewport:
+ * 445 0x0000bee0 {size: 0x0 channel: 0x1 cmd: 0x00009ee0} <-- VIEWPORT_SETUP/HEADER ?
+ * 446 0x00000000 {size: 0x0 channel: 0x0 cmd: 0x00000000} <-- x * cons
+ * 447 0x00000c80 {size: 0x0 channel: 0x0 cmd: 0x00000c80} <-- (height + x) * cons
+ * 448 0x00000000 {size: 0x0 channel: 0x0 cmd: 0x00000000} <-- y * cons
+ * 449 0x00000960 {size: 0x0 channel: 0x0 cmd: 0x00000960} <-- (width + y) * cons
+ * 44a 0x00082a00 {size: 0x2 channel: 0x1 cmd: 0x00000a00} <-- VIEWPORT_DIMS
+ * 44b 0x04000000 <-- (Width_from_glViewport << 16) | x
+ * 44c 0x03000000 <-- (Height_from_glViewport << 16) | (win_height - height - y)
+ *
+ */
+
+ nouveauCalcViewport(ctx);
+}
+
+static void nouveauDepthRange(GLcontext *ctx, GLclampd near, GLclampd far)
+{
+ nouveauCalcViewport(ctx);
+}
+
+static void nouveauDDUpdateHWState(GLcontext *ctx)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ int new_state = nmesa->new_state;
+
+ if ( new_state || nmesa->new_render_state & _NEW_TEXTURE )
+ {
+ nmesa->new_state = 0;
+
+ /* Update the various parts of the context's state.
+ */
+ /*
+ if ( new_state & NOUVEAU_NEW_ALPHA )
+ nouveauUpdateAlphaMode( ctx );
+
+ if ( new_state & NOUVEAU_NEW_DEPTH )
+ nouveauUpdateZMode( ctx );
+
+ if ( new_state & NOUVEAU_NEW_FOG )
+ nouveauUpdateFogAttrib( ctx );
+
+ if ( new_state & NOUVEAU_NEW_CLIP )
+ nouveauUpdateClipping( ctx );
+
+ if ( new_state & NOUVEAU_NEW_CULL )
+ nouveauUpdateCull( ctx );
+
+ if ( new_state & NOUVEAU_NEW_MASKS )
+ nouveauUpdateMasks( ctx );
+
+ if ( new_state & NOUVEAU_NEW_WINDOW )
+ nouveauUpdateWindow( ctx );
+
+ if ( nmesa->new_render_state & _NEW_TEXTURE ) {
+ nouveauUpdateTextureState( ctx );
+ }*/
+ }
+}
+
+static void nouveauDDInvalidateState(GLcontext *ctx, GLuint new_state)
+{
+ _swrast_InvalidateState( ctx, new_state );
+ _swsetup_InvalidateState( ctx, new_state );
+ _vbo_InvalidateState( ctx, new_state );
+ _tnl_InvalidateState( ctx, new_state );
+ NOUVEAU_CONTEXT(ctx)->new_render_state |= new_state;
+}
+
+/* Initialize the context's hardware state. */
+void nouveauDDInitState(nouveauContextPtr nmesa)
+{
+ uint32_t type = nmesa->screen->card->type;
+ switch(type)
+ {
+ case NV_03:
+ /* Unimplemented */
+ break;
+ case NV_04:
+ case NV_05:
+ nv04InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
+ break;
+ case NV_10:
+ nv10InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
+ break;
+ case NV_20:
+ nv20InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
+ break;
+ case NV_30:
+ case NV_40:
+ case NV_44:
+ nv30InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
+ break;
+ case NV_50:
+ nv50InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
+ break;
+ default:
+ break;
+ }
+ nouveau_state_cache_init(nmesa);
+}
+
+/* Initialize the driver's state functions */
+void nouveauDDInitStateFuncs(GLcontext *ctx)
+{
+ ctx->Driver.UpdateState = nouveauDDInvalidateState;
+
+ ctx->Driver.ClearIndex = NULL;
+ ctx->Driver.ClearColor = NULL; //nouveauDDClearColor;
+ ctx->Driver.ClearStencil = NULL; //nouveauDDClearStencil;
+ ctx->Driver.DrawBuffer = NULL; //nouveauDDDrawBuffer;
+ ctx->Driver.ReadBuffer = NULL; //nouveauDDReadBuffer;
+
+ ctx->Driver.IndexMask = NULL;
+ ctx->Driver.ColorMask = NULL; //nouveauDDColorMask;
+ ctx->Driver.AlphaFunc = NULL; //nouveauDDAlphaFunc;
+ ctx->Driver.BlendEquationSeparate = NULL; //nouveauDDBlendEquationSeparate;
+ ctx->Driver.BlendFuncSeparate = NULL; //nouveauDDBlendFuncSeparate;
+ ctx->Driver.ClearDepth = NULL; //nouveauDDClearDepth;
+ ctx->Driver.CullFace = NULL; //nouveauDDCullFace;
+ ctx->Driver.FrontFace = NULL; //nouveauDDFrontFace;
+ ctx->Driver.DepthFunc = NULL; //nouveauDDDepthFunc;
+ ctx->Driver.DepthMask = NULL; //nouveauDDDepthMask;
+ ctx->Driver.Enable = NULL; //nouveauDDEnable;
+ ctx->Driver.Fogfv = NULL; //nouveauDDFogfv;
+ ctx->Driver.Hint = NULL;
+ ctx->Driver.Lightfv = NULL;
+ ctx->Driver.LightModelfv = NULL; //nouveauDDLightModelfv;
+ ctx->Driver.LogicOpcode = NULL; //nouveauDDLogicOpCode;
+ ctx->Driver.PolygonMode = NULL;
+ ctx->Driver.PolygonStipple = NULL; //nouveauDDPolygonStipple;
+ ctx->Driver.RenderMode = NULL; //nouveauDDRenderMode;
+ ctx->Driver.Scissor = NULL; //nouveauDDScissor;
+ ctx->Driver.ShadeModel = NULL; //nouveauDDShadeModel;
+ ctx->Driver.StencilFuncSeparate = NULL; //nouveauDDStencilFuncSeparate;
+ ctx->Driver.StencilMaskSeparate = NULL; //nouveauDDStencilMaskSeparate;
+ ctx->Driver.StencilOpSeparate = NULL; //nouveauDDStencilOpSeparate;
+
+ ctx->Driver.DepthRange = nouveauDepthRange;
+ ctx->Driver.Viewport = nouveauViewport;
+
+ /* Pixel path fallbacks.
+ */
+ ctx->Driver.Accum = _swrast_Accum;
+ ctx->Driver.Bitmap = _swrast_Bitmap;
+ ctx->Driver.CopyPixels = _swrast_CopyPixels;
+ ctx->Driver.DrawPixels = _swrast_DrawPixels;
+ ctx->Driver.ReadPixels = _swrast_ReadPixels;
+
+ /* Swrast hooks for imaging extensions:
+ */
+ ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
+ ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
+ ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
+ ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
+}
+
+#define STATE_INIT(a) if (ctx->Driver.a) ctx->Driver.a
+
+void nouveauInitState(GLcontext *ctx)
+{
+ /*
+ * Mesa should do this for us:
+ */
+
+ STATE_INIT(AlphaFunc)( ctx,
+ ctx->Color.AlphaFunc,
+ ctx->Color.AlphaRef);
+
+ STATE_INIT(BlendColor)( ctx,
+ ctx->Color.BlendColor );
+
+ STATE_INIT(BlendEquationSeparate)( ctx,
+ ctx->Color.BlendEquationRGB,
+ ctx->Color.BlendEquationA);
+
+ STATE_INIT(BlendFuncSeparate)( ctx,
+ ctx->Color.BlendSrcRGB,
+ ctx->Color.BlendDstRGB,
+ ctx->Color.BlendSrcA,
+ ctx->Color.BlendDstA);
+
+ STATE_INIT(ClearColor)( ctx, ctx->Color.ClearColor);
+ STATE_INIT(ClearDepth)( ctx, ctx->Depth.Clear);
+ STATE_INIT(ClearStencil)( ctx, ctx->Stencil.Clear);
+
+ STATE_INIT(ColorMask)( ctx,
+ ctx->Color.ColorMask[RCOMP],
+ ctx->Color.ColorMask[GCOMP],
+ ctx->Color.ColorMask[BCOMP],
+ ctx->Color.ColorMask[ACOMP]);
+
+ STATE_INIT(CullFace)( ctx, ctx->Polygon.CullFaceMode );
+ STATE_INIT(DepthFunc)( ctx, ctx->Depth.Func );
+ STATE_INIT(DepthMask)( ctx, ctx->Depth.Mask );
+
+ STATE_INIT(Enable)( ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled );
+ STATE_INIT(Enable)( ctx, GL_BLEND, ctx->Color.BlendEnabled );
+ STATE_INIT(Enable)( ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled );
+ STATE_INIT(Enable)( ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled );
+ STATE_INIT(Enable)( ctx, GL_CULL_FACE, ctx->Polygon.CullFlag );
+ STATE_INIT(Enable)( ctx, GL_DEPTH_TEST, ctx->Depth.Test );
+ STATE_INIT(Enable)( ctx, GL_DITHER, ctx->Color.DitherFlag );
+ STATE_INIT(Enable)( ctx, GL_FOG, ctx->Fog.Enabled );
+ STATE_INIT(Enable)( ctx, GL_LIGHTING, ctx->Light.Enabled );
+ STATE_INIT(Enable)( ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag );
+ STATE_INIT(Enable)( ctx, GL_LINE_STIPPLE, ctx->Line.StippleFlag );
+ STATE_INIT(Enable)( ctx, GL_POINT_SMOOTH, ctx->Point.SmoothFlag );
+ STATE_INIT(Enable)( ctx, GL_POLYGON_OFFSET_FILL, ctx->Polygon.OffsetFill);
+ STATE_INIT(Enable)( ctx, GL_POLYGON_OFFSET_LINE, ctx->Polygon.OffsetLine);
+ STATE_INIT(Enable)( ctx, GL_POLYGON_OFFSET_POINT, ctx->Polygon.OffsetPoint);
+ STATE_INIT(Enable)( ctx, GL_POLYGON_SMOOTH, ctx->Polygon.SmoothFlag );
+ STATE_INIT(Enable)( ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag );
+ STATE_INIT(Enable)( ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled );
+ STATE_INIT(Enable)( ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled );
+ STATE_INIT(Enable)( ctx, GL_TEXTURE_1D, GL_FALSE );
+ STATE_INIT(Enable)( ctx, GL_TEXTURE_2D, GL_FALSE );
+ STATE_INIT(Enable)( ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE );
+ STATE_INIT(Enable)( ctx, GL_TEXTURE_3D, GL_FALSE );
+ STATE_INIT(Enable)( ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE );
+
+ STATE_INIT(Fogfv)( ctx, GL_FOG_COLOR, ctx->Fog.Color );
+ STATE_INIT(Fogfv)( ctx, GL_FOG_MODE, 0 );
+ STATE_INIT(Fogfv)( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
+ STATE_INIT(Fogfv)( ctx, GL_FOG_START, &ctx->Fog.Start );
+ STATE_INIT(Fogfv)( ctx, GL_FOG_END, &ctx->Fog.End );
+
+ STATE_INIT(FrontFace)( ctx, ctx->Polygon.FrontFace );
+
+ {
+ GLfloat f = (GLfloat)ctx->Light.Model.ColorControl;
+ STATE_INIT(LightModelfv)( ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f );
+ }
+
+ STATE_INIT(LineStipple)( ctx, ctx->Line.StippleFactor, ctx->Line.StipplePattern );
+ STATE_INIT(LineWidth)( ctx, ctx->Line.Width );
+ STATE_INIT(LogicOpcode)( ctx, ctx->Color.LogicOp );
+ STATE_INIT(PointSize)( ctx, ctx->Point.Size );
+ STATE_INIT(PolygonMode)( ctx, GL_FRONT, ctx->Polygon.FrontMode );
+ STATE_INIT(PolygonMode)( ctx, GL_BACK, ctx->Polygon.BackMode );
+ STATE_INIT(PolygonOffset)( ctx,
+ ctx->Polygon.OffsetFactor,
+ ctx->Polygon.OffsetUnits );
+ STATE_INIT(PolygonStipple)( ctx, (const GLubyte *)ctx->PolygonStipple );
+ STATE_INIT(ShadeModel)( ctx, ctx->Light.ShadeModel );
+ STATE_INIT(StencilFuncSeparate)( ctx, GL_FRONT,
+ ctx->Stencil.Function[0],
+ ctx->Stencil.Ref[0],
+ ctx->Stencil.ValueMask[0] );
+ STATE_INIT(StencilFuncSeparate)( ctx, GL_BACK,
+ ctx->Stencil.Function[1],
+ ctx->Stencil.Ref[1],
+ ctx->Stencil.ValueMask[1] );
+ STATE_INIT(StencilMaskSeparate)( ctx, GL_FRONT, ctx->Stencil.WriteMask[0] );
+ STATE_INIT(StencilMaskSeparate)( ctx, GL_BACK, ctx->Stencil.WriteMask[1] );
+ STATE_INIT(StencilOpSeparate)( ctx, GL_FRONT,
+ ctx->Stencil.FailFunc[0],
+ ctx->Stencil.ZFailFunc[0],
+ ctx->Stencil.ZPassFunc[0]);
+ STATE_INIT(StencilOpSeparate)( ctx, GL_BACK,
+ ctx->Stencil.FailFunc[1],
+ ctx->Stencil.ZFailFunc[1],
+ ctx->Stencil.ZPassFunc[1]);
+}
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_state.h b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_state.h
new file mode 100644
index 000000000..dbac71760
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_state.h
@@ -0,0 +1,50 @@
+/**************************************************************************
+
+Copyright 2006 Jeremy Kolb
+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.
+
+**************************************************************************/
+
+#ifndef __NOUVEAU_STATE_H__
+#define __NOUVEAU_STATE_H__
+
+#include "nouveau_context.h"
+
+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);
+extern void nv50InitStateFuncs(GLcontext *ctx, struct dd_function_table *func);
+
+extern void nouveauInitState(GLcontext *ctx);
+
+/*
+extern void nouveauDDUpdateState(GLcontext *ctx);
+extern void nouveauDDUpdateHWState(GLcontext *ctx);
+
+extern void nouveauEmitHwStateLocked(nouveauContextPtr nmesa);
+*/
+#endif
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_state_cache.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_state_cache.c
new file mode 100644
index 000000000..cb4b9d302
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_state_cache.c
@@ -0,0 +1,69 @@
+
+#include "nouveau_state_cache.h"
+#include "nouveau_context.h"
+#include "nouveau_object.h"
+#include "nouveau_fifo.h"
+
+#define BEGIN_RING_NOFLUSH(subchannel,tag,size) do { \
+ if (nmesa->fifo.free <= (size)) \
+ WAIT_RING(nmesa,(size)); \
+ OUT_RING( ((size)<<18) | ((subchannel) << 13) | (tag)); \
+ nmesa->fifo.free -= ((size) + 1); \
+}while(0)
+
+// flush all the dirty state
+void nouveau_state_cache_flush(nouveauContextPtr nmesa)
+{
+ int i=0;
+ int run=0;
+
+ // fast-path no state changes
+ if (!nmesa->state_cache.dirty)
+ return;
+ nmesa->state_cache.dirty=0;
+
+ do
+ {
+ // jump to a dirty state
+ while((nmesa->state_cache.hdirty[i/NOUVEAU_STATE_CACHE_HIER_SIZE]==0)&&(i<NOUVEAU_STATE_CACHE_ENTRIES))
+ i=(i&~(NOUVEAU_STATE_CACHE_HIER_SIZE-1))+NOUVEAU_STATE_CACHE_HIER_SIZE;
+ while((nmesa->state_cache.atoms[i].dirty==0)&&(i<NOUVEAU_STATE_CACHE_ENTRIES))
+ i++;
+
+ // figure out a run of dirty values
+ run=0;
+ while((nmesa->state_cache.atoms[i+run].dirty)&&(i+run<NOUVEAU_STATE_CACHE_ENTRIES))
+ run++;
+
+ // output everything as a single run
+ if (run>0) {
+ int j;
+
+ BEGIN_RING_NOFLUSH(NvSub3D, i*4, run);
+ for(j=0;j<run;j++)
+ {
+ OUT_RING(nmesa->state_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(i<NOUVEAU_STATE_CACHE_ENTRIES);
+ nmesa->state_cache.hdirty[NOUVEAU_STATE_CACHE_HIER_SIZE/NOUVEAU_STATE_CACHE_HIER_SIZE-1]=0;
+}
+
+
+// inits the state cache
+void nouveau_state_cache_init(nouveauContextPtr nmesa)
+{
+ int i;
+ for(i=0;i<NOUVEAU_STATE_CACHE_ENTRIES;i++)
+ {
+ nmesa->state_cache.atoms[i].dirty=0;
+ nmesa->state_cache.atoms[i].value=0xDEADBEEF; // nvidia cards like beef
+ }
+ nmesa->state_cache.dirty=0;
+}
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_state_cache.h b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_state_cache.h
new file mode 100644
index 000000000..5f9d42645
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_state_cache.h
@@ -0,0 +1,29 @@
+
+#ifndef __NOUVEAU_STATE_CACHE_H__
+#define __NOUVEAU_STATE_CACHE_H__
+
+#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;
+ uint32_t dirty;
+}nouveau_state_atom;
+
+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
+ uint8_t dirty;
+}nouveau_state_cache;
+
+
+#endif
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c
new file mode 100644
index 000000000..8a013bd99
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c
@@ -0,0 +1,127 @@
+/**************************************************************************
+
+Copyright 2006 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.
+
+**************************************************************************/
+
+/* Common software TCL code */
+
+#include "nouveau_context.h"
+#include "nouveau_swtcl.h"
+#include "nv10_swtcl.h"
+#include "nouveau_span.h"
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "tnl/tnl.h"
+#include "tnl/t_pipeline.h"
+
+/* Common tri functions */
+
+/* The fallbacks */
+void nouveau_fallback_tri(struct nouveau_context *nmesa,
+ nouveauVertex *v0,
+ nouveauVertex *v1,
+ nouveauVertex *v2)
+{
+ GLcontext *ctx = nmesa->glCtx;
+ SWvertex v[3];
+ _swsetup_Translate(ctx, v0, &v[0]);
+ _swsetup_Translate(ctx, v1, &v[1]);
+ _swsetup_Translate(ctx, v2, &v[2]);
+ _swrast_Triangle(ctx, &v[0], &v[1], &v[2]);
+}
+
+
+void nouveau_fallback_line(struct nouveau_context *nmesa,
+ nouveauVertex *v0,
+ nouveauVertex *v1)
+{
+ GLcontext *ctx = nmesa->glCtx;
+ SWvertex v[2];
+ _swsetup_Translate(ctx, v0, &v[0]);
+ _swsetup_Translate(ctx, v1, &v[1]);
+ _swrast_Line(ctx, &v[0], &v[1]);
+}
+
+
+void nouveau_fallback_point(struct nouveau_context *nmesa,
+ nouveauVertex *v0)
+{
+ GLcontext *ctx = nmesa->glCtx;
+ SWvertex v[1];
+ _swsetup_Translate(ctx, v0, &v[0]);
+ _swrast_Point(ctx, &v[0]);
+}
+
+void nouveauFallback(struct nouveau_context *nmesa, GLuint bit, GLboolean mode)
+{
+ GLcontext *ctx = nmesa->glCtx;
+ GLuint oldfallback = nmesa->Fallback;
+
+ if (mode) {
+ nmesa->Fallback |= bit;
+ if (oldfallback == 0) {
+ if (nmesa->screen->card->type<NV_10) {
+ //nv04FinishPrimitive(nmesa);
+ } else {
+ //nv10FinishPrimitive(nmesa);
+ }
+
+ _swsetup_Wakeup(ctx);
+ nmesa->render_index = ~0;
+ }
+ }
+ else {
+ nmesa->Fallback &= ~bit;
+ if (oldfallback == bit) {
+ _swrast_flush( ctx );
+
+ if (nmesa->screen->card->type<NV_10) {
+ nv04TriInitFunctions(ctx);
+ } else {
+ nv10TriInitFunctions(ctx);
+ }
+
+ _tnl_invalidate_vertex_state( ctx, ~0 );
+ _tnl_invalidate_vertices( ctx, ~0 );
+ _tnl_install_attrs( ctx,
+ nmesa->vertex_attrs,
+ nmesa->vertex_attr_count,
+ nmesa->viewport.m, 0 );
+ }
+ }
+}
+
+
+void nouveauRunPipeline( GLcontext *ctx )
+{
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+
+ if (nmesa->new_state) {
+ nmesa->new_render_state |= nmesa->new_state;
+ }
+
+ _tnl_run_pipeline( ctx );
+}
+
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_swtcl.h b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_swtcl.h
new file mode 100644
index 000000000..ba4d8725a
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_swtcl.h
@@ -0,0 +1,55 @@
+/**************************************************************************
+
+Copyright 2006 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.
+
+**************************************************************************/
+
+
+
+#ifndef __NOUVEAU_SWTCL_H__
+#define __NOUVEAU_SWTCL_H__
+
+#include "nouveau_context.h"
+
+extern void nouveau_fallback_tri(struct nouveau_context *nmesa,
+ nouveauVertex *v0,
+ nouveauVertex *v1,
+ nouveauVertex *v2);
+
+extern void nouveau_fallback_line(struct nouveau_context *nmesa,
+ nouveauVertex *v0,
+ nouveauVertex *v1);
+
+extern void nouveau_fallback_point(struct nouveau_context *nmesa,
+ nouveauVertex *v0);
+
+extern void nouveauFallback(struct nouveau_context *nmesa, GLuint bit, GLboolean mode);
+
+extern void nouveauRunPipeline( GLcontext *ctx );
+
+extern void nouveauTriInitFunctions( GLcontext *ctx );
+
+
+#endif /* __NOUVEAU_SWTCL_H__ */
+
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_sync.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_sync.c
new file mode 100644
index 000000000..30e669626
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_sync.c
@@ -0,0 +1,194 @@
+/*
+ * 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"
+#include "nouveau_buffers.h"
+#include "nouveau_object.h"
+#include "nouveau_fifo.h"
+#include "nouveau_reg.h"
+#include "nouveau_msg.h"
+#include "nouveau_sync.h"
+
+nouveau_notifier *
+nouveau_notifier_new(GLcontext *ctx, GLuint handle, GLuint count)
+{
+ 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;
+
+ notifier->mem = nouveau_mem_alloc(ctx,
+ NOUVEAU_MEM_FB | NOUVEAU_MEM_MAPPED,
+ count * NV_NOTIFIER_SIZE,
+ 0);
+ if (!notifier->mem) {
+ FREE(notifier);
+ return NULL;
+ }
+
+ if (!nouveauCreateDmaObjectFromMem(nmesa, handle, NV_DMA_IN_MEMORY,
+ notifier->mem,
+ NOUVEAU_MEM_ACCESS_RW)) {
+ nouveau_mem_free(ctx, notifier->mem);
+ FREE(notifier);
+ return NULL;
+ }
+
+ notifier->handle = handle;
+ return notifier;
+}
+
+void
+nouveau_notifier_destroy(GLcontext *ctx, nouveau_notifier *notifier)
+{
+ /*XXX: free DMA object.. */
+ nouveau_mem_free(ctx, notifier->mem);
+ FREE(notifier);
+}
+
+void
+nouveau_notifier_reset(nouveau_notifier *notifier, GLuint id)
+{
+ volatile GLuint *n = notifier->mem->map + (id * NV_NOTIFIER_SIZE);
+
+#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;
+ n[NV_NOTIFY_STATE /4] = (NV_NOTIFY_STATE_STATUS_IN_PROCESS <<
+ 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 id,
+ GLuint status, GLuint timeout)
+{
+ volatile GLuint *n = notifier->mem->map + (id * NV_NOTIFIER_SIZE);
+ 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",
+ n[NV_NOTIFY_STATE/4] &
+ NV_NOTIFY_STATE_ERROR_CODE_MASK);
+ return GL_FALSE;
+ }
+
+ if (((n[NV_NOTIFY_STATE/4] & NV_NOTIFY_STATE_STATUS_MASK) >>
+ NV_NOTIFY_STATE_STATUS_SHIFT) == status)
+ return GL_TRUE;
+
+ if (timeout) {
+ DO_USLEEP(1);
+ time++;
+ }
+ }
+
+ MESSAGE("Notifier timed out\n");
+ return GL_FALSE;
+}
+
+void
+nouveau_notifier_wait_nop(GLcontext *ctx, nouveau_notifier *notifier,
+ GLuint subc)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLboolean ret;
+
+ nouveau_notifier_reset(notifier, 0);
+
+ BEGIN_RING_SIZE(subc, NV_NOTIFY, 1);
+ OUT_RING (NV_NOTIFY_STYLE_WRITE_ONLY);
+ BEGIN_RING_SIZE(subc, NV_NOP, 1);
+ OUT_RING (0);
+ FIRE_RING();
+
+ 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");
+}
+
+GLboolean nouveauSyncInitFuncs(GLcontext *ctx)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+#ifdef NOUVEAU_RING_DEBUG
+ return GL_TRUE;
+#endif
+
+ nmesa->syncNotifier = nouveau_notifier_new(ctx, NvSyncNotify, 1);
+ if (!nmesa->syncNotifier) {
+ MESSAGE("Failed to create channel sync notifier\n");
+ return GL_FALSE;
+ }
+
+ /* 0x180 is SET_DMA_NOTIFY, should be correct for all supported 3D
+ * object classes
+ */
+ BEGIN_RING_CACHE(NvSub3D, 0x180, 1);
+ OUT_RING_CACHE (NvSyncNotify);
+#ifdef ALLOW_MULTI_SUBCHANNEL
+ BEGIN_RING_SIZE(NvSubMemFormat,
+ NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
+ OUT_RING (NvSyncNotify);
+#endif
+
+ return GL_TRUE;
+}
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_sync.h b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_sync.h
new file mode 100644
index 000000000..019d5f662
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_sync.h
@@ -0,0 +1,67 @@
+/*
+ * 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__
+
+#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
+#define NV_NOTIFY_STATE 0x0000000C
+#define NV_NOTIFY_STATE_STATUS_MASK 0xFF000000
+#define NV_NOTIFY_STATE_STATUS_SHIFT 24
+#define NV_NOTIFY_STATE_STATUS_COMPLETED 0x00
+#define NV_NOTIFY_STATE_STATUS_IN_PROCESS 0x01
+#define NV_NOTIFY_STATE_ERROR_CODE_MASK 0x0000FFFF
+#define NV_NOTIFY_STATE_ERROR_CODE_SHIFT 0
+
+/* Methods that (hopefully) all objects have */
+#define NV_NOP 0x00000100
+#define NV_NOTIFY 0x00000104
+#define NV_NOTIFY_STYLE_WRITE_ONLY 0
+
+typedef struct nouveau_notifier_t {
+ GLuint handle;
+ nouveau_mem *mem;
+} nouveau_notifier;
+
+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 *, 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);
+
+extern GLboolean nouveauSyncInitFuncs(GLcontext *ctx);
+#endif
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_tex.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_tex.c
new file mode 100644
index 000000000..0a8d27966
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_tex.c
@@ -0,0 +1,49 @@
+/**************************************************************************
+
+Copyright 2006 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_tex.h"
+
+// XXX needs some love
+void nouveauTexInitFunctions( struct dd_function_table *functions )
+{
+/*
+ functions->TexEnv = nouveauTexEnv;
+ functions->ChooseTextureFormat = nouveauChooseTextureFormat;
+ functions->TexImage1D = nouveauTexImage1D;
+ functions->TexSubImage1D = nouveauTexSubImage1D;
+ functions->TexImage2D = nouveauTexImage2D;
+ functions->TexSubImage2D = nouveauTexSubImage2D;
+ functions->TexParameter = nouveauTexParameter;
+ functions->BindTexture = nouveauBindTexture;
+ functions->NewTextureObject = nouveauNewTextureObject;
+ functions->DeleteTexture = nouveauDeleteTexture;
+ functions->IsTextureResident = driIsTextureResident;
+
+ driInitTextureFormats();
+*/
+}
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_tex.h b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_tex.h
new file mode 100644
index 000000000..7ac71f830
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nouveau_tex.h
@@ -0,0 +1,38 @@
+/**************************************************************************
+
+Copyright 2006 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.
+
+**************************************************************************/
+
+
+#ifndef __NOUVEAU_TEX_H__
+#define __NOUVEAU_TEX_H__
+
+#include <errno.h>
+#include "mtypes.h"
+#include "macros.h"
+#include "dd.h"
+
+extern void nouveauTexInitFunctions( struct dd_function_table *functions );
+
+#endif /* __NOUVEAU_TEX_H__ */
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nv04_state.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv04_state.c
new file mode 100644
index 000000000..25df3d2a6
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv04_state.c
@@ -0,0 +1,540 @@
+/**************************************************************************
+
+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(GLuint f)
+{
+ switch ( f ) {
+ 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(GLuint f)
+{
+ switch ( f ) {
+ 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 0x%x\n",f);
+ 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->Color.AlphaFunc)<<8);
+ control|=(ctx->Color.AlphaEnabled<<12);
+ control|=(1<<13);
+ control|=(ctx->Depth.Test<<14);
+ 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))
+ 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->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);
+}
+
+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);
+ nv04_emit_fog_color(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)
+{
+ 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)
+{
+ GLuint x, y, w, h;
+ uint32_t depth_pitch=(depth?depth->pitch:0+15)&~15+16;
+ if (depth_pitch<256) depth_pitch=256;
+
+ w = color[0]->mesa.Width;
+ h = color[0]->mesa.Height;
+ x = nmesa->drawX;
+ y = nmesa->drawY;
+
+ BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_FORMAT, 1);
+ if (color[0]->mesa._ActualFormat == GL_RGBA8)
+ OUT_RING(0x108/*A8R8G8B8*/);
+ else
+ OUT_RING(0x103/*R5G6B5*/);
+
+ /* 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);*/
+
+ 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;
+}
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nv04_swtcl.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv04_swtcl.c
new file mode 100644
index 000000000..cb072e0bd
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv04_swtcl.c
@@ -0,0 +1,619 @@
+/*
+ * 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
+ * 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
+ * VIA, S3 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.
+ */
+
+/* Software TCL for NV04, NV05, NV06 */
+
+#include <stdio.h>
+#include <math.h>
+
+#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);
+}
+
+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 */
+/**********************************************************************/
+
+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;i<count-5;i+=6)
+ nv04_2triangles(nmesa,
+ (nouveauVertex*)(vertptr+(i+0)*vertsize),
+ (nouveauVertex*)(vertptr+(i+1)*vertsize),
+ (nouveauVertex*)(vertptr+(i+2)*vertsize),
+ (nouveauVertex*)(vertptr+(i+3)*vertsize),
+ (nouveauVertex*)(vertptr+(i+4)*vertsize),
+ (nouveauVertex*)(vertptr+(i+5)*vertsize)
+ );
+ if (i!=count)
+ {
+ nv04_1triangle(nmesa,
+ (nouveauVertex*)(vertptr+(i+0)*vertsize),
+ (nouveauVertex*)(vertptr+(i+1)*vertsize),
+ (nouveauVertex*)(vertptr+(i+2)*vertsize)
+ );
+ i+=3;
+ }
+ if (i!=count)
+ printf("oops\n");
+}
+
+static void nv04_render_tri_strip_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;
+ uint32_t striptbl[]={0x321210,0x543432,0x765654,0x987876,0xBA9A98,0xDCBCBA,0xFEDEDC};
+ int i,j;
+
+ for(i=start;i<count;i+=14)
+ {
+ int numvert=MIN2(16,count-i);
+ int numtri=numvert-2;
+ if (numvert<3)
+ break;
+
+ BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0),numvert*8);
+ for(j=0;j<numvert;j++)
+ OUT_RINGp((nouveauVertex*)(vertptr+(i+j)*vertsize),8);
+
+ BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_DRAW|NONINC_METHOD,(numtri+1)/2);
+ for(j=0;j<numtri/2;j++)
+ OUT_RING(striptbl[j]);
+ if (numtri%2)
+ OUT_RING(striptbl[numtri/2]&0xFFF);
+ }
+}
+
+static void nv04_render_tri_fan_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;
+ 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;i<count;i+=14)
+ {
+ int numvert=MIN2(15,count-i);
+ int numtri=numvert-1;
+ if (numvert<3)
+ break;
+
+ BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x1),numvert*8);
+
+ for(j=0;j<numvert;j++)
+ OUT_RINGp((nouveauVertex*)(vertptr+(i+j)*vertsize),8);
+
+ BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_DRAW|NONINC_METHOD,(numtri+1)/2);
+ for(j=0;j<numtri/2;j++)
+ OUT_RING(fantbl[j]);
+ if (numtri%2)
+ OUT_RING(fantbl[numtri/2]&0xFFF);
+ }
+}
+
+static void nv04_render_quads_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;i<count;i+=4)
+ nv04_1quad(nmesa,
+ (nouveauVertex*)(vertptr+(i+0)*vertsize),
+ (nouveauVertex*)(vertptr+(i+1)*vertsize),
+ (nouveauVertex*)(vertptr+(i+2)*vertsize),
+ (nouveauVertex*)(vertptr+(i+3)*vertsize)
+ );
+}
+
+static void nv04_render_noop_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+}
+
+static void (*nv04_render_tab_verts[GL_POLYGON+2])(GLcontext *,
+ GLuint,
+ GLuint,
+ GLuint) =
+{
+ nv04_render_points_verts,
+ nv04_render_lines_verts,
+ nv04_render_line_loop_verts,
+ nv04_render_line_strip_verts,
+ nv04_render_triangles_verts,
+ nv04_render_tri_strip_verts,
+ nv04_render_tri_fan_verts,
+ nv04_render_quads_verts,
+ nv04_render_tri_strip_verts, //nv04_render_quad_strip_verts
+ nv04_render_tri_fan_verts, //nv04_render_poly_verts
+ nv04_render_noop_verts,
+};
+
+
+static void nv04_render_points_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ // erm
+}
+
+static void nv04_render_lines_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ // umm
+}
+
+static void nv04_render_line_strip_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ // yeah
+}
+
+static void nv04_render_line_loop_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ // right
+}
+
+static void nv04_render_triangles_elts(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;
+ const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts;
+ int i;
+
+ for(i=start;i<count-5;i+=6)
+ nv04_2triangles(nmesa,
+ (nouveauVertex*)(vertptr+elt[i+0]*vertsize),
+ (nouveauVertex*)(vertptr+elt[i+1]*vertsize),
+ (nouveauVertex*)(vertptr+elt[i+2]*vertsize),
+ (nouveauVertex*)(vertptr+elt[i+3]*vertsize),
+ (nouveauVertex*)(vertptr+elt[i+4]*vertsize),
+ (nouveauVertex*)(vertptr+elt[i+5]*vertsize)
+ );
+ if (i!=count)
+ {
+ nv04_1triangle(nmesa,
+ (nouveauVertex*)(vertptr+elt[i+0]*vertsize),
+ (nouveauVertex*)(vertptr+elt[i+1]*vertsize),
+ (nouveauVertex*)(vertptr+elt[i+2]*vertsize)
+ );
+ i+=3;
+ }
+ if (i!=count)
+ printf("oops\n");
+}
+
+static void nv04_render_tri_strip_elts(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;
+ 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;i<count;i+=14)
+ {
+ int numvert=MIN2(16,count-i);
+ int numtri=numvert-2;
+ if (numvert<3)
+ break;
+
+ BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0),numvert*8);
+ for(j=0;j<numvert;j++)
+ OUT_RINGp((nouveauVertex*)(vertptr+elt[i+j]*vertsize),8);
+
+ BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_DRAW|NONINC_METHOD,(numtri+1)/2);
+ for(j=0;j<numtri/2;j++)
+ OUT_RING(striptbl[j]);
+ if (numtri%2)
+ OUT_RING(striptbl[numtri/2]&0xFFF);
+ }
+}
+
+static void nv04_render_tri_fan_elts(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;
+ 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;i<count;i+=14)
+ {
+ int numvert=MIN2(15,count-i);
+ int numtri=numvert-2;
+ if (numvert<3)
+ break;
+
+ BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x1),numvert*8);
+
+ for(j=0;j<numvert;j++)
+ OUT_RINGp((nouveauVertex*)(vertptr+elt[i+j]*vertsize),8);
+
+ BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_DRAW|NONINC_METHOD,(numtri+1)/2);
+ for(j=0;j<numtri/2;j++)
+ OUT_RING(fantbl[j]);
+ if (numtri%2)
+ OUT_RING(fantbl[numtri/2]&0xFFF);
+ }
+}
+
+static void nv04_render_quads_elts(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;
+ const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts;
+ int i;
+
+ for(i=start;i<count;i+=4)
+ nv04_1quad(nmesa,
+ (nouveauVertex*)(vertptr+elt[i+0]*vertsize),
+ (nouveauVertex*)(vertptr+elt[i+1]*vertsize),
+ (nouveauVertex*)(vertptr+elt[i+2]*vertsize),
+ (nouveauVertex*)(vertptr+elt[i+3]*vertsize)
+ );
+}
+
+static void nv04_render_noop_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+}
+
+static void (*nv04_render_tab_elts[GL_POLYGON+2])(GLcontext *,
+ GLuint,
+ GLuint,
+ GLuint) =
+{
+ nv04_render_points_elts,
+ nv04_render_lines_elts,
+ nv04_render_line_loop_elts,
+ nv04_render_line_strip_elts,
+ nv04_render_triangles_elts,
+ nv04_render_tri_strip_elts,
+ nv04_render_tri_fan_elts,
+ nv04_render_quads_elts,
+ nv04_render_tri_strip_elts, // nv04_render_quad_strip_elts,
+ nv04_render_tri_fan_elts, // nv04_render_poly_elts,
+ nv04_render_noop_elts,
+};
+
+
+/**********************************************************************/
+/* Choose render functions */
+/**********************************************************************/
+
+
+#define EMIT_ATTR( ATTR, STYLE ) \
+do { \
+ nmesa->vertex_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 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)
+{
+ 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 = 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;
+}
+
+
+
+static inline void nv04OutputVertexFormat(struct nouveau_context* nmesa)
+{
+ GLcontext* ctx=nmesa->glCtx;
+ DECLARE_RENDERINPUTS(index);
+
+ /*
+ * Tell t_vertex about the vertex format
+ */
+ nmesa->vertex_attr_count = 0;
+ 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,
+ nmesa->viewport.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/dist/Mesa/src/mesa/drivers/dri/nouveau/nv04_swtcl.h b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv04_swtcl.h
new file mode 100644
index 000000000..42dde5383
--- /dev/null
+++ b/dist/Mesa/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__ */
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nv10_state.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv10_state.c
new file mode 100644
index 000000000..5f304ccab
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv10_state.c
@@ -0,0 +1,798 @@
+/**************************************************************************
+
+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 "tnl/t_pipeline.h"
+
+#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;
+/* 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);
+ 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);
+ GLubyte ubRef;
+ CLAMPED_FLOAT_TO_UBYTE(ubRef, ref);
+
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC, 2);
+ OUT_RING_CACHE(func);
+ OUT_RING_CACHE(ubRef);
+}
+
+static void nv10BlendColor(GLcontext *ctx, const GLfloat color[4])
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte cf[4];
+
+ CLAMPED_FLOAT_TO_UBYTE(cf[0], color[0]);
+ CLAMPED_FLOAT_TO_UBYTE(cf[1], color[1]);
+ CLAMPED_FLOAT_TO_UBYTE(cf[2], color[2]);
+ CLAMPED_FLOAT_TO_UBYTE(cf[3], color[3]);
+
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_COLOR, 1);
+ OUT_RING_CACHE(PACK_COLOR_8888(cf[3], cf[1], cf[2], cf[0]));
+}
+
+static void nv10BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA)
+{
+ 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)
+{
+ 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);
+}
+
+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)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+/* 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)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+/* 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)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4);
+ OUT_RING_CACHEf(equation[0]);
+ OUT_RING_CACHEf(equation[1]);
+ OUT_RING_CACHEf(equation[2]);
+ OUT_RING_CACHEf(equation[3]);
+}
+
+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));
+}
+
+static void nv10ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode)
+{
+ /* TODO I need love */
+}
+
+static void nv10CullFace(GLcontext *ctx, GLenum mode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CULL_FACE, 1);
+ OUT_RING_CACHE(mode);
+}
+
+static void nv10FrontFace(GLcontext *ctx, GLenum mode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FRONT_FACE, 1);
+ OUT_RING_CACHE(mode);
+}
+
+static void nv10DepthFunc(GLcontext *ctx, GLenum func)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1);
+ OUT_RING_CACHE(func);
+}
+
+static void nv10DepthMask(GLcontext *ctx, GLboolean flag)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1);
+ OUT_RING_CACHE(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 * depth_scale);
+ OUT_RING_CACHEf(farval * depth_scale);
+
+ nv10ViewportScale(nmesa);
+}
+
+/** 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 nv10Enable(GLcontext *ctx, GLenum cap, GLboolean state)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ switch(cap)
+ {
+ case GL_ALPHA_TEST:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_AUTO_NORMAL:
+ case GL_BLEND:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ 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:
+ BEGIN_RING_CACHE(NvSub3D, NV10_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, NV10_TCL_PRIMITIVE_3D_COLOR_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, NV10_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_DEPTH_TEST:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_DITHER:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DITHER_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_FOG:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FOG_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ 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:
+ {
+ uint32_t mask=1<<(2*(cap-GL_LIGHT0));
+ nmesa->enabled_lights=((nmesa->enabled_lights&mask)|(mask*state));
+ if (nmesa->lighting_enabled)
+ {
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1);
+ OUT_RING_CACHE(nmesa->enabled_lights);
+ }
+ break;
+ }
+ case GL_LIGHTING:
+ nmesa->lighting_enabled=state;
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1);
+ if (nmesa->lighting_enabled)
+ OUT_RING_CACHE(nmesa->enabled_lights);
+ else
+ OUT_RING_CACHE(0x0);
+ break;
+ case GL_LINE_SMOOTH:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// 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:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_POINT_SMOOTH:
+ case GL_POLYGON_OFFSET_POINT:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_POLYGON_OFFSET_LINE:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_POLYGON_OFFSET_FILL:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_POLYGON_SMOOTH:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// 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:
+ // TODO BACK and FRONT ?
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_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 nv10Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ switch(pname)
+ {
+ case GL_FOG_MODE:
+ //BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FOG_MODE, 1);
+ //OUT_RING_CACHE (params);
+ break;
+ /* TODO: unsure about the rest.*/
+ default:
+ break;
+ }
+
+}
+
+static void nv10Hint(GLcontext *ctx, GLenum target, GLenum mode)
+{
+ /* TODO I need love (fog and line_smooth hints) */
+}
+
+// void (*IndexMask)(GLcontext *ctx, GLuint mask);
+
+enum {
+ SPOTLIGHT_NO_UPDATE,
+ SPOTLIGHT_UPDATE_EXPONENT,
+ SPOTLIGHT_UPDATE_DIRECTION,
+ SPOTLIGHT_UPDATE_ALL
+};
+
+static void nv10Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params )
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLint p = light - GL_LIGHT0;
+ struct gl_light *l = &ctx->Light.Light[p];
+ int spotlight_update = SPOTLIGHT_NO_UPDATE;
+
+ switch(pname)
+ {
+ case GL_AMBIENT:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(p), 3);
+ OUT_RING_CACHEf(params[0]);
+ OUT_RING_CACHEf(params[1]);
+ OUT_RING_CACHEf(params[2]);
+ break;
+ case GL_DIFFUSE:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(p), 3);
+ OUT_RING_CACHEf(params[0]);
+ OUT_RING_CACHEf(params[1]);
+ OUT_RING_CACHEf(params[2]);
+ break;
+ case GL_SPECULAR:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(p), 3);
+ OUT_RING_CACHEf(params[0]);
+ OUT_RING_CACHEf(params[1]);
+ OUT_RING_CACHEf(params[2]);
+ break;
+ case GL_POSITION:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(p), 3);
+ OUT_RING_CACHEf(params[0]);
+ OUT_RING_CACHEf(params[1]);
+ OUT_RING_CACHEf(params[2]);
+ break;
+ case GL_SPOT_DIRECTION:
+ spotlight_update = SPOTLIGHT_UPDATE_DIRECTION;
+ break;
+ case GL_SPOT_EXPONENT:
+ spotlight_update = SPOTLIGHT_UPDATE_EXPONENT;
+ break;
+ case GL_SPOT_CUTOFF:
+ spotlight_update = SPOTLIGHT_UPDATE_ALL;
+ break;
+ case GL_CONSTANT_ATTENUATION:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(p), 1);
+ OUT_RING_CACHEf(*params);
+ break;
+ case GL_LINEAR_ATTENUATION:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(p), 1);
+ OUT_RING_CACHEf(*params);
+ break;
+ case GL_QUADRATIC_ATTENUATION:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(p), 1);
+ OUT_RING_CACHEf(*params);
+ break;
+ default:
+ break;
+ }
+
+ switch(spotlight_update) {
+ case SPOTLIGHT_UPDATE_DIRECTION:
+ {
+ GLfloat x,y,z;
+ GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0);
+ x = spot_light_coef_a * l->_NormDirection[0];
+ y = spot_light_coef_a * l->_NormDirection[1];
+ z = spot_light_coef_a * l->_NormDirection[2];
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p), 3);
+ OUT_RING_CACHEf(x);
+ OUT_RING_CACHEf(y);
+ OUT_RING_CACHEf(z);
+ }
+ break;
+ case SPOTLIGHT_UPDATE_EXPONENT:
+ {
+ GLfloat cc,lc,qc;
+ cc = 1.0; /* FIXME: These need to be correctly computed */
+ lc = 0.0;
+ qc = 2.0;
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 3);
+ OUT_RING_CACHEf(cc);
+ OUT_RING_CACHEf(lc);
+ OUT_RING_CACHEf(qc);
+ }
+ break;
+ case SPOTLIGHT_UPDATE_ALL:
+ {
+ GLfloat cc,lc,qc, x,y,z, c;
+ GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0);
+ cc = 1.0; /* FIXME: These need to be correctly computed */
+ lc = 0.0;
+ qc = 2.0;
+ x = spot_light_coef_a * l->_NormDirection[0];
+ y = spot_light_coef_a * l->_NormDirection[1];
+ z = spot_light_coef_a * l->_NormDirection[2];
+ c = spot_light_coef_a + 1.0;
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 7);
+ OUT_RING_CACHEf(cc);
+ OUT_RING_CACHEf(lc);
+ OUT_RING_CACHEf(qc);
+ OUT_RING_CACHEf(x);
+ OUT_RING_CACHEf(y);
+ OUT_RING_CACHEf(z);
+ OUT_RING_CACHEf(c);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/** Set the lighting model parameters */
+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)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LINE_WIDTH, 1);
+ OUT_RING_CACHE(((int) (width * 8.0)) & -4);
+}
+
+static void nv10LogicOpcode(GLcontext *ctx, GLenum opcode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP, 1);
+ OUT_RING_CACHE(opcode);
+}
+
+static void nv10PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
+{
+ /*TODO: not sure what goes here. */
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+}
+
+static void nv10PointSize(GLcontext *ctx, GLfloat size)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POINT_SIZE, 1);
+ OUT_RING_CACHE(((int) (size * 8.0)) & -4);
+}
+
+static void nv10PolygonMode(GLcontext *ctx, GLenum face, GLenum mode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 1);
+ OUT_RING_CACHE(mode);
+ }
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK, 1);
+ OUT_RING_CACHE(mode);
+ }
+}
+
+/** Set the scale and units used to calculate depth values */
+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 */
+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 */
+void (*RenderMode)(GLcontext *ctx, GLenum mode );
+
+/** Define the scissor box */
+static void nv10Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+{
+}
+
+/** Select flat or smooth shading */
+static void nv10ShadeModel(GLcontext *ctx, GLenum mode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_SHADE_MODEL, 1);
+ 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);
+
+ /* 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)
+{
+ 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)
+{
+ 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 */
+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 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);
+}
+
+/* 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_SIZE(NvSub3D, 0x02b4, 1);
+ OUT_RING(0);
+
+ BEGIN_RING_CACHE(NvSub3D,
+ 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,
+ 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);
+ }
+
+ nv10ViewportScale(nmesa);
+}
+
+/* Initialise any card-specific non-GL related state */
+static GLboolean nv10InitCard(nouveauContextPtr nmesa)
+{
+ 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, 0x0290, 1);
+ OUT_RING(0x00100001);
+ 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;
+}
+
+/* Update buffer offset/pitch/format */
+static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color,
+ nouveau_renderbuffer **color,
+ nouveau_renderbuffer *depth)
+{
+ 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, NV10_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 = 0x108;
+ if (color[0]->mesa._ActualFormat != GL_RGBA8) {
+ format = 0x103; /* 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);
+
+ /* 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;
+}
+
+void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ func->AlphaFunc = nv10AlphaFunc;
+ func->BlendColor = nv10BlendColor;
+ func->BlendEquationSeparate = nv10BlendEquationSeparate;
+ func->BlendFuncSeparate = nv10BlendFuncSeparate;
+ func->Clear = nv10Clear;
+ func->ClearColor = nv10ClearColor;
+ func->ClearDepth = nv10ClearDepth;
+ func->ClearStencil = nv10ClearStencil;
+ func->ClipPlane = nv10ClipPlane;
+ func->ColorMask = nv10ColorMask;
+ func->ColorMaterial = nv10ColorMaterial;
+ func->CullFace = nv10CullFace;
+ func->FrontFace = nv10FrontFace;
+ func->DepthFunc = nv10DepthFunc;
+ func->DepthMask = nv10DepthMask;
+ func->DepthRange = nv10DepthRange;
+ func->Enable = nv10Enable;
+ func->Fogfv = nv10Fogfv;
+ func->Hint = nv10Hint;
+ func->Lightfv = nv10Lightfv;
+/* func->LightModelfv = nv10LightModelfv; */
+ func->LineStipple = nv10LineStipple; /* Not for NV10 */
+ func->LineWidth = nv10LineWidth;
+ func->LogicOpcode = nv10LogicOpcode;
+ func->PointParameterfv = nv10PointParameterfv;
+ func->PointSize = nv10PointSize;
+ func->PolygonMode = nv10PolygonMode;
+ func->PolygonOffset = nv10PolygonOffset;
+ 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;
+/* func->TexGen = nv10TexGen;*/
+/* func->TexParameter = nv10TexParameter;*/
+ func->TextureMatrix = nv10TextureMatrix;
+
+ nmesa->hw_func.InitCard = nv10InitCard;
+ nmesa->hw_func.BindBuffers = nv10BindBuffers;
+ nmesa->hw_func.WindowMoved = nv10WindowMoved;
+}
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv10_swtcl.c
new file mode 100644
index 000000000..3bc84d862
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv10_swtcl.c
@@ -0,0 +1,656 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ * Copyright 2006 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
+ * 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
+ * VIA, S3 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.
+ */
+
+/* Software TCL for NV10, NV20, NV30, NV40, NV50 */
+
+#include <stdio.h>
+#include <math.h>
+
+#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 "nv10_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 nv10RasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim );
+static void nv10RenderPrimitive( GLcontext *ctx, GLenum prim );
+static void nv10ResetLineStipple( GLcontext *ctx );
+
+
+
+static inline void nv10StartPrimitive(struct nouveau_context* nmesa,uint32_t primitive,uint32_t size)
+{
+ if (nmesa->screen->card->type==NV_10)
+ BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_BEGIN_END,1);
+ else if (nmesa->screen->card->type==NV_20)
+ BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_BEGIN_END,1);
+ else
+ BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_BEGIN_END,1);
+ OUT_RING(primitive);
+
+ if (nmesa->screen->card->type==NV_10)
+ BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_DATA|NONINC_METHOD,size);
+ else if (nmesa->screen->card->type==NV_20)
+ BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_VERTEX_DATA|NONINC_METHOD,size);
+ else
+ BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_DATA|NONINC_METHOD,size);
+}
+
+inline void nv10FinishPrimitive(struct nouveau_context *nmesa)
+{
+ if (nmesa->screen->card->type==NV_10)
+ BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_BEGIN_END,1);
+ else if (nmesa->screen->card->type==NV_20)
+ BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_BEGIN_END,1);
+ else
+ BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_BEGIN_END,1);
+ OUT_RING(0x0);
+ FIRE_RING();
+}
+
+
+static inline void nv10ExtendPrimitive(struct nouveau_context* nmesa, int size)
+{
+ /* make sure there's enough room. if not, wait */
+ if (RING_AVAILABLE()<size)
+ {
+ WAIT_RING(nmesa,size);
+ }
+}
+
+/**********************************************************************/
+/* Render unclipped begin/end objects */
+/**********************************************************************/
+
+static inline void nv10_render_generic_primitive_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags,GLuint prim)
+{
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte *vertptr = (GLubyte *)nmesa->verts;
+ GLuint vertsize = nmesa->vertex_size;
+ GLuint size_dword = vertsize*(count-start)/4;
+
+ nv10ExtendPrimitive(nmesa, size_dword);
+ nv10StartPrimitive(nmesa,prim+1,size_dword);
+ OUT_RINGp((nouveauVertex*)(vertptr+(start*vertsize)),size_dword);
+ nv10FinishPrimitive(nmesa);
+}
+
+static void nv10_render_points_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_POINTS);
+}
+
+static void nv10_render_lines_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_LINES);
+}
+
+static void nv10_render_line_strip_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_LINE_STRIP);
+}
+
+static void nv10_render_line_loop_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_LINE_LOOP);
+}
+
+static void nv10_render_triangles_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_TRIANGLES);
+}
+
+static void nv10_render_tri_strip_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_TRIANGLE_STRIP);
+}
+
+static void nv10_render_tri_fan_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_TRIANGLE_FAN);
+}
+
+static void nv10_render_quads_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_QUADS);
+}
+
+static void nv10_render_quad_strip_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_QUAD_STRIP);
+}
+
+static void nv10_render_poly_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_POLYGON);
+}
+
+static void nv10_render_noop_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+}
+
+static void (*nv10_render_tab_verts[GL_POLYGON+2])(GLcontext *,
+ GLuint,
+ GLuint,
+ GLuint) =
+{
+ nv10_render_points_verts,
+ nv10_render_lines_verts,
+ nv10_render_line_loop_verts,
+ nv10_render_line_strip_verts,
+ nv10_render_triangles_verts,
+ nv10_render_tri_strip_verts,
+ nv10_render_tri_fan_verts,
+ nv10_render_quads_verts,
+ nv10_render_quad_strip_verts,
+ nv10_render_poly_verts,
+ nv10_render_noop_verts,
+};
+
+
+static inline void nv10_render_generic_primitive_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags,GLuint prim)
+{
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte *vertptr = (GLubyte *)nmesa->verts;
+ GLuint vertsize = nmesa->vertex_size;
+ GLuint size_dword = vertsize*(count-start)/4;
+ const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts;
+ GLuint j;
+
+ nv10ExtendPrimitive(nmesa, size_dword);
+ nv10StartPrimitive(nmesa,prim+1,size_dword);
+ for (j=start; j<count; j++ ) {
+ OUT_RINGp((nouveauVertex*)(vertptr+(elt[j]*vertsize)),vertsize/4);
+ }
+ nv10FinishPrimitive(nmesa);
+}
+
+static void nv10_render_points_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_POINTS);
+}
+
+static void nv10_render_lines_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_LINES);
+}
+
+static void nv10_render_line_strip_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_LINE_STRIP);
+}
+
+static void nv10_render_line_loop_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_LINE_LOOP);
+}
+
+static void nv10_render_triangles_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_TRIANGLES);
+}
+
+static void nv10_render_tri_strip_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_TRIANGLE_STRIP);
+}
+
+static void nv10_render_tri_fan_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_TRIANGLE_FAN);
+}
+
+static void nv10_render_quads_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_QUADS);
+}
+
+static void nv10_render_quad_strip_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_QUAD_STRIP);
+}
+
+static void nv10_render_poly_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_POLYGON);
+}
+
+static void nv10_render_noop_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+}
+
+static void (*nv10_render_tab_elts[GL_POLYGON+2])(GLcontext *,
+ GLuint,
+ GLuint,
+ GLuint) =
+{
+ nv10_render_points_elts,
+ nv10_render_lines_elts,
+ nv10_render_line_loop_elts,
+ nv10_render_line_strip_elts,
+ nv10_render_triangles_elts,
+ nv10_render_tri_strip_elts,
+ nv10_render_tri_fan_elts,
+ nv10_render_quads_elts,
+ nv10_render_quad_strip_elts,
+ nv10_render_poly_elts,
+ nv10_render_noop_elts,
+};
+
+
+/**********************************************************************/
+/* Choose render functions */
+/**********************************************************************/
+
+
+#define EMIT_ATTR( ATTR, STYLE ) \
+do { \
+ nmesa->vertex_attrs[nmesa->vertex_attr_count].attrib = (ATTR); \
+ nmesa->vertex_attrs[nmesa->vertex_attr_count].format = (STYLE); \
+ 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 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;
+
+ /* OUT_RINGp wants size in DWORDS */
+ vertsize >>= 2;
+
+ 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;
+
+ /* OUT_RINGp wants size in DWORDS */
+ vertsize >>= 2;
+
+ 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;
+
+ /* OUT_RINGp wants size in DWORDS */
+ vertsize >>= 2;
+
+ 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);
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+
+ tnl->Driver.Render.PrimTabVerts = nv10_render_tab_verts;
+ 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;
+}
+
+
+
+static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa)
+{
+ GLcontext* ctx=nmesa->glCtx;
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ DECLARE_RENDERINPUTS(index);
+ struct vertex_buffer *VB = &tnl->vb;
+ int attr_size[16];
+ int default_attr_size[8]={3,3,3,4,3,1,4,4};
+ int i;
+ int slots=0;
+ int total_size=0;
+ /* t_vertex_generic dereferences a NULL pointer if we
+ * pass NULL as the vp transform...
+ */
+ const GLfloat ident_vp[16] = {
+ 1.0, 0.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0, 0.0,
+ 0.0, 0.0, 1.0, 0.0,
+ 0.0, 0.0, 0.0, 1.0
+ };
+
+ nmesa->vertex_attr_count = 0;
+ RENDERINPUTS_COPY(index, nmesa->render_inputs_bitset);
+
+ /*
+ * Determine attribute sizes
+ */
+ for(i=0;i<8;i++)
+ {
+ if (RENDERINPUTS_TEST(index, i))
+ attr_size[i]=default_attr_size[i];
+ else
+ attr_size[i]=0;
+ }
+ for(i=8;i<16;i++)
+ {
+ if (RENDERINPUTS_TEST(index, i))
+ attr_size[i]=VB->TexCoordPtr[i-8]->size;
+ else
+ attr_size[i]=0;
+ }
+
+ /*
+ * Tell t_vertex about the vertex format
+ */
+ for(i=0;i<16;i++)
+ {
+ if (RENDERINPUTS_TEST(index, i))
+ {
+ slots=i+1;
+ if (i==_TNL_ATTRIB_POS)
+ {
+ /* special-case POS */
+ EMIT_ATTR(_TNL_ATTRIB_POS,EMIT_3F_VIEWPORT);
+ }
+ else
+ {
+ switch(attr_size[i])
+ {
+ case 1:
+ EMIT_ATTR(i,EMIT_1F);
+ break;
+ case 2:
+ EMIT_ATTR(i,EMIT_2F);
+ break;
+ case 3:
+ EMIT_ATTR(i,EMIT_3F);
+ break;
+ case 4:
+ EMIT_ATTR(i,EMIT_4F);
+ break;
+ }
+ }
+ if (i==_TNL_ATTRIB_COLOR0)
+ nmesa->color_offset=total_size;
+ if (i==_TNL_ATTRIB_COLOR1)
+ nmesa->specular_offset=total_size;
+ total_size+=attr_size[i];
+ }
+ }
+
+ nmesa->vertex_size=_tnl_install_attrs( ctx,
+ nmesa->vertex_attrs,
+ nmesa->vertex_attr_count,
+ ident_vp, 0 );
+ assert(nmesa->vertex_size==total_size*4);
+
+ /*
+ * Tell the hardware about the vertex format
+ */
+ if (nmesa->screen->card->type==NV_10) {
+ int size;
+
+#define NV_VERTEX_ATTRIBUTE_TYPE_FLOAT 2
+
+#define NV10_SET_VERTEX_ATTRIB(i,j) \
+ do { \
+ size = attr_size[j] << 4; \
+ size |= (attr_size[j]*4) << 8; \
+ size |= NV_VERTEX_ATTRIBUTE_TYPE_FLOAT; \
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_ATTR(i),1); \
+ OUT_RING_CACHE(size); \
+ } while (0)
+
+ NV10_SET_VERTEX_ATTRIB(0, _TNL_ATTRIB_POS);
+ NV10_SET_VERTEX_ATTRIB(1, _TNL_ATTRIB_COLOR0);
+ NV10_SET_VERTEX_ATTRIB(2, _TNL_ATTRIB_COLOR1);
+ NV10_SET_VERTEX_ATTRIB(3, _TNL_ATTRIB_TEX0);
+ NV10_SET_VERTEX_ATTRIB(4, _TNL_ATTRIB_TEX1);
+ NV10_SET_VERTEX_ATTRIB(5, _TNL_ATTRIB_NORMAL);
+ NV10_SET_VERTEX_ATTRIB(6, _TNL_ATTRIB_WEIGHT);
+ NV10_SET_VERTEX_ATTRIB(7, _TNL_ATTRIB_FOG);
+
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_VALIDATE,1);
+ OUT_RING_CACHE(0);
+ } else if (nmesa->screen->card->type==NV_20) {
+ for(i=0;i<16;i++)
+ {
+ int size=attr_size[i];
+ BEGIN_RING_CACHE(NvSub3D,NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR(i),1);
+ OUT_RING_CACHE(NV_VERTEX_ATTRIBUTE_TYPE_FLOAT|(size*0x10));
+ }
+ } else {
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DO_VERTICES, 1);
+ OUT_RING(0);
+ BEGIN_RING_CACHE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR0_POS,slots);
+ for(i=0;i<slots;i++)
+ {
+ int size=attr_size[i];
+ OUT_RING_CACHE(NV_VERTEX_ATTRIBUTE_TYPE_FLOAT|(size*0x10));
+ }
+ // FIXME this is probably not needed
+ BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_UNK_0,1);
+ OUT_RING(0);
+ BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_UNK_0,1);
+ OUT_RING(0);
+ BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_UNK_0,1);
+ OUT_RING(0);
+ }
+}
+
+
+static void nv10ChooseVertexState( 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);
+ 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
+ */
+ nvsUpdateShader(ctx, nmesa->passthrough_vp);
+
+ /* Update texenv shader / user fragprog */
+ nvsUpdateShader(ctx, (nouveauShader*)ctx->FragmentProgram._Current);
+ }
+}
+
+
+/**********************************************************************/
+/* High level hooks for t_vb_render.c */
+/**********************************************************************/
+
+
+static void nv10RenderStart(GLcontext *ctx)
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+
+ if (nmesa->new_state) {
+ nmesa->new_render_state |= nmesa->new_state;
+ }
+
+ if (nmesa->new_render_state) {
+ nv10ChooseVertexState(ctx);
+ nv10ChooseRenderState(ctx);
+ nmesa->new_render_state = 0;
+ }
+}
+
+static void nv10RenderFinish(GLcontext *ctx)
+{
+}
+
+
+/* System to flush dma and emit state changes based on the rasterized
+ * primitive.
+ */
+void nv10RasterPrimitive(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 nv10RenderPrimitive( GLcontext *ctx, GLuint prim )
+{
+ nv10RasterPrimitive( ctx, prim, hw_prim[prim] );
+}
+
+static void nv10ResetLineStipple( GLcontext *ctx )
+{
+ /* FIXME do something here */
+ WARN_ONCE("Unimplemented nv10ResetLineStipple\n");
+}
+
+
+/**********************************************************************/
+/* Initialization. */
+/**********************************************************************/
+
+void nv10TriInitFunctions(GLcontext *ctx)
+{
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+
+ tnl->Driver.RunPipeline = nouveauRunPipeline;
+ tnl->Driver.Render.Start = nv10RenderStart;
+ tnl->Driver.Render.Finish = nv10RenderFinish;
+ tnl->Driver.Render.PrimitiveNotify = nv10RenderPrimitive;
+ tnl->Driver.Render.ResetLineStipple = nv10ResetLineStipple;
+ 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,
+ 64 * sizeof(GLfloat) );
+
+ nmesa->verts = (GLubyte *)tnl->clipspace.vertex_buf;
+}
+
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nv10_swtcl.h b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv10_swtcl.h
new file mode 100644
index 000000000..7c854addd
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv10_swtcl.h
@@ -0,0 +1,40 @@
+/**************************************************************************
+
+Copyright 2006 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.
+
+**************************************************************************/
+
+
+
+#ifndef __NV10_SWTCL_H__
+#define __NV10_SWTCL_H__
+
+#include "mtypes.h"
+
+extern void nv10Fallback( GLcontext *ctx, GLuint bit, GLboolean mode );
+extern void nv10FinishPrimitive(struct nouveau_context *nmesa);
+extern void nv10TriInitFunctions(GLcontext *ctx);
+#define FALLBACK( nmesa, bit, mode ) nouveauFallback( nmesa->glCtx, bit, mode )
+
+#endif /* __NV10_SWTCL_H__ */
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nv20_shader.h b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv20_shader.h
new file mode 100644
index 000000000..7d2e29db6
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv20_shader.h
@@ -0,0 +1,121 @@
+/* NV20_TCL_PRIMITIVE_3D_0x0B00 */
+#define NV20_VP_INST_0B00 0x00000000 /* always 0? */
+#define NV20_VP_INST0_KNOWN 0
+
+/* NV20_TCL_PRIMITIVE_3D_0x0B04 */
+#define NV20_VP_INST_SCA_OPCODE_SHIFT 25
+#define NV20_VP_INST_SCA_OPCODE_MASK (0x0F << 25)
+#define NV20_VP_INST_OPCODE_RCP 0x2
+#define NV20_VP_INST_OPCODE_RCC 0x3
+#define NV20_VP_INST_OPCODE_RSQ 0x4
+#define NV20_VP_INST_OPCODE_EXP 0x5
+#define NV20_VP_INST_OPCODE_LOG 0x6
+#define NV20_VP_INST_OPCODE_LIT 0x7
+#define NV20_VP_INST_VEC_OPCODE_SHIFT 21
+#define NV20_VP_INST_VEC_OPCODE_MASK (0x0F << 21)
+#define NV20_VP_INST_OPCODE_NOP 0x0 /* guess */
+#define NV20_VP_INST_OPCODE_MOV 0x1
+#define NV20_VP_INST_OPCODE_MUL 0x2
+#define NV20_VP_INST_OPCODE_ADD 0x3
+#define NV20_VP_INST_OPCODE_MAD 0x4
+#define NV20_VP_INST_OPCODE_DP3 0x5
+#define NV20_VP_INST_OPCODE_DPH 0x6
+#define NV20_VP_INST_OPCODE_DP4 0x7
+#define NV20_VP_INST_OPCODE_DST 0x8
+#define NV20_VP_INST_OPCODE_MIN 0x9
+#define NV20_VP_INST_OPCODE_MAX 0xA
+#define NV20_VP_INST_OPCODE_SLT 0xB
+#define NV20_VP_INST_OPCODE_SGE 0xC
+#define NV20_VP_INST_OPCODE_ARL 0xD
+#define NV20_VP_INST_CONST_SRC_SHIFT 13
+#define NV20_VP_INST_CONST_SRC_MASK (0xFF << 13)
+#define NV20_VP_INST_INPUT_SRC_SHIFT 9
+#define NV20_VP_INST_INPUT_SRC_MASK (0xF << 9) /* guess */
+#define NV20_VP_INST_INPUT_SRC_POS 0
+#define NV20_VP_INST_INPUT_SRC_COL0 3
+#define NV20_VP_INST_INPUT_SRC_COL1 4
+#define NV20_VP_INST_INPUT_SRC_TC(n) (9+n)
+#define NV20_VP_INST_SRC0H_SHIFT 0
+#define NV20_VP_INST_SRC0H_MASK (0x1FF << 0)
+#define NV20_VP_INST1_KNOWN ( \
+ NV20_VP_INST_OPCODE_MASK | \
+ NV20_VP_INST_CONST_SRC_MASK | \
+ NV20_VP_INST_INPUT_SRC_MASK | \
+ NV20_VP_INST_SRC0H_MASK \
+ )
+
+/* NV20_TCL_PRIMITIVE_3D_0x0B08 */
+#define NV20_VP_INST_SRC0L_SHIFT 26
+#define NV20_VP_INST_SRC0L_MASK (0x3F <<26)
+#define NV20_VP_INST_SRC1_SHIFT 11
+#define NV20_VP_INST_SRC1_MASK (0x7FFF<<11)
+#define NV20_VP_INST_SRC2H_SHIFT 0
+#define NV20_VP_INST_SRC2H_MASK (0x7FF << 0)
+
+/* NV20_TCL_PRIMITIVE_3D_0x0B0C */
+#define NV20_VP_INST_SRC2L_SHIFT 28
+#define NV20_VP_INST_SRC2L_MASK (0x0F <<28)
+#define NV20_VP_INST_VTEMP_WRITEMASK_SHIFT 24
+#define NV20_VP_INST_VTEMP_WRITEMASK_MASK (0x0F <<24)
+# define NV20_VP_INST_TEMP_WRITEMASK_X (1<<27)
+# define NV20_VP_INST_TEMP_WRITEMASK_Y (1<<26)
+# define NV20_VP_INST_TEMP_WRITEMASK_Z (1<<25)
+# define NV20_VP_INST_TEMP_WRITEMASK_W (1<<24)
+#define NV20_VP_INST_DEST_TEMP_ID_SHIFT 20
+#define NV20_VP_INST_DEST_TEMP_ID_MASK (0x0F <<20)
+#define NV20_VP_INST_STEMP_WRITEMASK_SHIFT 16
+#define NV20_VP_INST_STEMP_WRITEMASK_MASK (0x0F <<16)
+# define NV20_VP_INST_STEMP_WRITEMASK_X (1<<19)
+# define NV20_VP_INST_STEMP_WRITEMASK_Y (1<<18)
+# define NV20_VP_INST_STEMP_WRITEMASK_Z (1<<17)
+# define NV20_VP_INST_STEMP_WRITEMASK_W (1<<16)
+#define NV20_VP_INST_DEST_WRITEMASK_SHIFT 12
+#define NV20_VP_INST_DEST_WRITEMASK_MASK (0x0F <<12)
+# define NV20_VP_INST_DEST_WRITEMASK_X (1<<15)
+# define NV20_VP_INST_DEST_WRITEMASK_Y (1<<14)
+# define NV20_VP_INST_DEST_WRITEMASK_Z (1<<13)
+# define NV20_VP_INST_DEST_WRITEMASK_W (1<<12)
+#define NV20_VP_INST_DEST_SHIFT 3
+#define NV20_VP_INST_DEST_MASK (0xF << 3) /* guess */
+#define NV20_VP_INST_DEST_POS 0
+#define NV20_VP_INST_DEST_COL0 3
+#define NV20_VP_INST_DEST_COL1 4
+#define NV20_VP_INST_DEST_TC(n) (9+n)
+#define NV20_VP_INST_INDEX_CONST (1<<1)
+#define NV20_VP_INST3_KNOWN ( \
+ NV20_VP_INST_SRC2L_MASK | \
+ NV20_VP_INST_TEMP_WRITEMASK_MASK | \
+ NV20_VP_INST_DEST_TEMP_ID_MASK | \
+ NV20_VP_INST_STEMP_WRITEMASK_MASK | \
+ NV20_VP_INST_DEST_WRITEMASK_MASK | \
+ NV20_VP_INST_DEST_MASK | \
+ NV20_VP_INST_INDEX_CONST \
+ )
+
+/* Useful to split the source selection regs into their pieces */
+#define NV20_VP_SRC0_HIGH_SHIFT 6
+#define NV20_VP_SRC0_HIGH_MASK 0x00007FC0
+#define NV20_VP_SRC0_LOW_MASK 0x0000003F
+#define NV20_VP_SRC2_HIGH_SHIFT 4
+#define NV20_VP_SRC2_HIGH_MASK 0x00007FF0
+#define NV20_VP_SRC2_LOW_MASK 0x0000000F
+
+#define NV20_VP_SRC_REG_NEGATE (1<<14)
+#define NV20_VP_SRC_REG_SWZ_X_SHIFT 12
+#define NV20_VP_SRC_REG_SWZ_X_MASK (0x03 <<12)
+#define NV20_VP_SRC_REG_SWZ_Y_SHIFT 10
+#define NV20_VP_SRC_REG_SWZ_Y_MASK (0x03 <<10)
+#define NV20_VP_SRC_REG_SWZ_Z_SHIFT 8
+#define NV20_VP_SRC_REG_SWZ_Z_MASK (0x03 << 8)
+#define NV20_VP_SRC_REG_SWZ_W_SHIFT 6
+#define NV20_VP_SRC_REG_SWZ_W_MASK (0x03 << 6)
+#define NV20_VP_SRC_REG_SWZ_ALL_SHIFT 6
+#define NV20_VP_SRC_REG_SWZ_ALL_MASK (0xFF << 6)
+#define NV20_VP_SRC_REG_TEMP_ID_SHIFT 2
+#define NV20_VP_SRC_REG_TEMP_ID_MASK (0x0F << 0)
+#define NV20_VP_SRC_REG_TYPE_SHIFT 0
+#define NV20_VP_SRC_REG_TYPE_MASK (0x03 << 0)
+#define NV20_VP_SRC_REG_TYPE_TEMP 1
+#define NV20_VP_SRC_REG_TYPE_INPUT 2
+#define NV20_VP_SRC_REG_TYPE_CONST 3 /* guess */
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nv20_state.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv20_state.c
new file mode 100644
index 000000000..3d8d83a86
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv20_state.c
@@ -0,0 +1,824 @@
+/**************************************************************************
+
+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 "tnl/t_pipeline.h"
+
+#include "mtypes.h"
+#include "colormac.h"
+
+static void nv20AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte ubRef;
+ CLAMPED_FLOAT_TO_UBYTE(ubRef, ref);
+
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC, 2);
+ OUT_RING_CACHE(func);
+ OUT_RING_CACHE(ubRef);
+}
+
+static void nv20BlendColor(GLcontext *ctx, const GLfloat color[4])
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte cf[4];
+
+ CLAMPED_FLOAT_TO_UBYTE(cf[0], color[0]);
+ CLAMPED_FLOAT_TO_UBYTE(cf[1], color[1]);
+ CLAMPED_FLOAT_TO_UBYTE(cf[2], color[2]);
+ CLAMPED_FLOAT_TO_UBYTE(cf[3], color[3]);
+
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_BLEND_COLOR, 1);
+ OUT_RING_CACHE(PACK_COLOR_8888(cf[3], cf[1], cf[2], cf[0]));
+}
+
+static void nv20BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_BLEND_EQUATION, 1);
+ OUT_RING_CACHE((modeA<<16) | modeRGB);
+}
+
+
+static void nv20BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB,
+ GLenum sfactorA, GLenum dfactorA)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2);
+ OUT_RING_CACHE((sfactorA<<16) | sfactorRGB);
+ OUT_RING_CACHE((dfactorA<<16) | dfactorRGB);
+}
+
+static void nv20Clear(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 |= 0xf0;
+ if (mask & (BUFFER_BIT_DEPTH))
+ hw_bufs |= 0x03;
+
+ if (hw_bufs) {
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_WHICH_BUFFERS, 1);
+ OUT_RING_CACHE(hw_bufs);
+ }
+}
+
+static void nv20ClearColor(GLcontext *ctx, const GLfloat color[4])
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte c[4];
+ UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,color);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB, 1);
+ OUT_RING_CACHE(PACK_COLOR_8888(c[3],c[0],c[1],c[2]));
+}
+
+static void nv20ClearDepth(GLcontext *ctx, GLclampd d)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nmesa->clear_value=((nmesa->clear_value&0x000000FF)|(((uint32_t)(d*0xFFFFFF))<<8));
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1);
+ OUT_RING_CACHE(nmesa->clear_value);
+}
+
+/* we're don't support indexed buffers
+ void (*ClearIndex)(GLcontext *ctx, GLuint index)
+ */
+
+static void nv20ClearStencil(GLcontext *ctx, GLint s)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nmesa->clear_value=((nmesa->clear_value&0xFFFFFF00)|(s&0x000000FF));
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1);
+ OUT_RING_CACHE(nmesa->clear_value);
+}
+
+static void nv20ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4);
+ OUT_RING_CACHEf(equation[0]);
+ OUT_RING_CACHEf(equation[1]);
+ OUT_RING_CACHEf(equation[2]);
+ OUT_RING_CACHEf(equation[3]);
+}
+
+static void nv20ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask,
+ GLboolean bmask, GLboolean amask )
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_COLOR_MASK, 1);
+ OUT_RING_CACHE(((amask && 0x01) << 24) | ((rmask && 0x01) << 16) | ((gmask && 0x01)<< 8) | ((bmask && 0x01) << 0));
+}
+
+static void nv20ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode)
+{
+ // TODO I need love
+}
+
+static void nv20CullFace(GLcontext *ctx, GLenum mode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CULL_FACE, 1);
+ OUT_RING_CACHE(mode);
+}
+
+static void nv20FrontFace(GLcontext *ctx, GLenum mode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_FRONT_FACE, 1);
+ OUT_RING_CACHE(mode);
+}
+
+static void nv20DepthFunc(GLcontext *ctx, GLenum func)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1);
+ OUT_RING_CACHE(func);
+}
+
+static void nv20DepthMask(GLcontext *ctx, GLboolean flag)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1);
+ OUT_RING_CACHE(flag);
+}
+
+static void nv20DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_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 nv20Enable(GLcontext *ctx, GLenum cap, GLboolean state)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ switch(cap)
+ {
+ case GL_ALPHA_TEST:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_AUTO_NORMAL:
+ case GL_BLEND:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ 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:
+ BEGIN_RING_CACHE(NvSub3D, NV20_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, NV20_TCL_PRIMITIVE_3D_COLOR_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, NV20_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_DEPTH_TEST:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_DITHER:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DITHER_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_FOG:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_FOG_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ 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:
+ {
+ uint32_t mask=0x11<<(2*(cap-GL_LIGHT0));
+ nmesa->enabled_lights=((nmesa->enabled_lights&mask)|(mask*state));
+ if (nmesa->lighting_enabled)
+ {
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1);
+ OUT_RING_CACHE(nmesa->enabled_lights);
+ }
+ break;
+ }
+ case GL_LIGHTING:
+ nmesa->lighting_enabled=state;
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1);
+ if (nmesa->lighting_enabled)
+ OUT_RING_CACHE(nmesa->enabled_lights);
+ else
+ OUT_RING_CACHE(0x0);
+ break;
+ case GL_LINE_SMOOTH:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// 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:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_POINT_SMOOTH:
+ case GL_POLYGON_OFFSET_POINT:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_POLYGON_OFFSET_LINE:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_POLYGON_OFFSET_FILL:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_POLYGON_SMOOTH:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_POLYGON_STIPPLE:
+ BEGIN_RING_CACHE(NvSub3D, NV20_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:
+ /* 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 ?
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_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 nv20Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ switch(pname)
+ {
+ case GL_FOG_MODE:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_FOG_MODE, 1);
+ //OUT_RING_CACHE (params);
+ break;
+ /* TODO: unsure about the rest.*/
+ default:
+ break;
+ }
+
+}
+
+static void nv20Hint(GLcontext *ctx, GLenum target, GLenum mode)
+{
+ // TODO I need love (fog and line_smooth hints)
+}
+
+// void (*IndexMask)(GLcontext *ctx, GLuint mask);
+
+enum {
+ SPOTLIGHT_NO_UPDATE,
+ SPOTLIGHT_UPDATE_EXPONENT,
+ SPOTLIGHT_UPDATE_DIRECTION,
+ SPOTLIGHT_UPDATE_ALL
+};
+
+static void nv20Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params )
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLint p = light - GL_LIGHT0;
+ struct gl_light *l = &ctx->Light.Light[p];
+ int spotlight_update = SPOTLIGHT_NO_UPDATE;
+
+ /* not sure where the fourth param value goes...*/
+ switch(pname)
+ {
+ case GL_AMBIENT:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(p), 3);
+ OUT_RING_CACHEf(params[0]);
+ OUT_RING_CACHEf(params[1]);
+ OUT_RING_CACHEf(params[2]);
+ break;
+ case GL_DIFFUSE:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(p), 3);
+ OUT_RING_CACHEf(params[0]);
+ OUT_RING_CACHEf(params[1]);
+ OUT_RING_CACHEf(params[2]);
+ break;
+ case GL_SPECULAR:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(p), 3);
+ OUT_RING_CACHEf(params[0]);
+ OUT_RING_CACHEf(params[1]);
+ OUT_RING_CACHEf(params[2]);
+ break;
+ case GL_POSITION:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(p), 3);
+ OUT_RING_CACHEf(params[0]);
+ OUT_RING_CACHEf(params[1]);
+ OUT_RING_CACHEf(params[2]);
+ break;
+ case GL_SPOT_DIRECTION:
+ spotlight_update = SPOTLIGHT_UPDATE_DIRECTION;
+ break;
+ case GL_SPOT_EXPONENT:
+ spotlight_update = SPOTLIGHT_UPDATE_EXPONENT;
+ break;
+ case GL_SPOT_CUTOFF:
+ spotlight_update = SPOTLIGHT_UPDATE_ALL;
+ break;
+ case GL_CONSTANT_ATTENUATION:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(p), 1);
+ OUT_RING_CACHEf(*params);
+ break;
+ case GL_LINEAR_ATTENUATION:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(p), 1);
+ OUT_RING_CACHEf(*params);
+ break;
+ case GL_QUADRATIC_ATTENUATION:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(p), 1);
+ OUT_RING_CACHEf(*params);
+ break;
+ default:
+ break;
+ }
+
+ switch(spotlight_update) {
+ case SPOTLIGHT_UPDATE_DIRECTION:
+ {
+ GLfloat x,y,z;
+ GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0);
+ x = spot_light_coef_a * l->_NormDirection[0];
+ y = spot_light_coef_a * l->_NormDirection[1];
+ z = spot_light_coef_a * l->_NormDirection[2];
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p), 3);
+ OUT_RING_CACHEf(x);
+ OUT_RING_CACHEf(y);
+ OUT_RING_CACHEf(z);
+ }
+ break;
+ case SPOTLIGHT_UPDATE_EXPONENT:
+ {
+ GLfloat cc,lc,qc;
+ cc = 1.0; /* FIXME: These need to be correctly computed */
+ lc = 0.0;
+ qc = 2.0;
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 3);
+ OUT_RING_CACHEf(cc);
+ OUT_RING_CACHEf(lc);
+ OUT_RING_CACHEf(qc);
+ }
+ break;
+ case SPOTLIGHT_UPDATE_ALL:
+ {
+ GLfloat cc,lc,qc, x,y,z, c;
+ GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0);
+ cc = 1.0; /* FIXME: These need to be correctly computed */
+ lc = 0.0;
+ qc = 2.0;
+ x = spot_light_coef_a * l->_NormDirection[0];
+ y = spot_light_coef_a * l->_NormDirection[1];
+ z = spot_light_coef_a * l->_NormDirection[2];
+ c = spot_light_coef_a + 1.0;
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 7);
+ OUT_RING_CACHEf(cc);
+ OUT_RING_CACHEf(lc);
+ OUT_RING_CACHEf(qc);
+ OUT_RING_CACHEf(x);
+ OUT_RING_CACHEf(y);
+ OUT_RING_CACHEf(z);
+ OUT_RING_CACHEf(c);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/** Set the lighting model parameters */
+static void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params);
+
+
+static void nv20LineStipple(GLcontext *ctx, GLint factor, GLushort pattern )
+{
+/* nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN, 1);
+ OUT_RING_CACHE((pattern << 16) | factor);*/
+}
+
+static void nv20LineWidth(GLcontext *ctx, GLfloat width)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LINE_WIDTH, 1);
+ OUT_RING_CACHEf(width);
+}
+
+static void nv20LogicOpcode(GLcontext *ctx, GLenum opcode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP, 1);
+ OUT_RING_CACHE(opcode);
+}
+
+static void nv20PointParameterfv(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 nv20PointSize(GLcontext *ctx, GLfloat size)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POINT_SIZE, 1);
+ OUT_RING_CACHEf(size);
+}
+
+/** Select a polygon rasterization mode */
+static void nv20PolygonMode(GLcontext *ctx, GLenum face, GLenum mode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 1);
+ OUT_RING_CACHE(mode);
+ }
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK, 1);
+ OUT_RING_CACHE(mode);
+ }
+}
+
+/** Set the scale and units used to calculate depth values */
+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 */
+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 */
+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, 1);
+ OUT_RING_CACHE((w << 16) | x );
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SCISSOR_Y2_Y1, 1);
+ OUT_RING_CACHE((h << 16) | y );
+
+}
+
+/** Select flat or smooth shading */
+static void nv20ShadeModel(GLcontext *ctx, GLenum mode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SHADE_MODEL, 1);
+ OUT_RING_CACHE(mode);
+}
+
+/** OpenGL 2.0 two-sided StencilFunc */
+static void nv20StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func,
+ GLint ref, GLuint mask)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ BEGIN_RING_CACHE(NvSub3D, NV20_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 nv20StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_MASK, 1);
+ OUT_RING_CACHE(mask);
+}
+
+/** OpenGL 2.0 two-sided StencilOp */
+static void nv20StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail,
+ GLenum zfail, GLenum zpass)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_OP_FAIL, 1);
+ 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 nv20TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat)
+{
+ 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 */
+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), 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,
+ 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)
+{
+ 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 */
+static GLboolean nv20BindBuffers(nouveauContextPtr nmesa, int num_color,
+ nouveau_renderbuffer **color,
+ nouveau_renderbuffer *depth)
+{
+ 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);
+ }
+
+ /* 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);
+
+ func->AlphaFunc = nv20AlphaFunc;
+ func->BlendColor = nv20BlendColor;
+ func->BlendEquationSeparate = nv20BlendEquationSeparate;
+ func->BlendFuncSeparate = nv20BlendFuncSeparate;
+ func->Clear = nv20Clear;
+ func->ClearColor = nv20ClearColor;
+ func->ClearDepth = nv20ClearDepth;
+ func->ClearStencil = nv20ClearStencil;
+ func->ClipPlane = nv20ClipPlane;
+ func->ColorMask = nv20ColorMask;
+ func->ColorMaterial = nv20ColorMaterial;
+ func->CullFace = nv20CullFace;
+ func->FrontFace = nv20FrontFace;
+ func->DepthFunc = nv20DepthFunc;
+ func->DepthMask = nv20DepthMask;
+ func->DepthRange = nv20DepthRange;
+ func->Enable = nv20Enable;
+ func->Fogfv = nv20Fogfv;
+ func->Hint = nv20Hint;
+ func->Lightfv = nv20Lightfv;
+/* func->LightModelfv = nv20LightModelfv; */
+ func->LineStipple = nv20LineStipple;
+ func->LineWidth = nv20LineWidth;
+ func->LogicOpcode = nv20LogicOpcode;
+ func->PointParameterfv = nv20PointParameterfv;
+ func->PointSize = nv20PointSize;
+ func->PolygonMode = nv20PolygonMode;
+ func->PolygonOffset = nv20PolygonOffset;
+ func->PolygonStipple = nv20PolygonStipple;
+/* func->ReadBuffer = nv20ReadBuffer;*/
+/* func->RenderMode = nv20RenderMode;*/
+ func->Scissor = nv20Scissor;
+ func->ShadeModel = nv20ShadeModel;
+ func->StencilFuncSeparate = nv20StencilFuncSeparate;
+ func->StencilMaskSeparate = nv20StencilMaskSeparate;
+ func->StencilOpSeparate = nv20StencilOpSeparate;
+/* func->TexGen = nv20TexGen;*/
+/* func->TexParameter = nv20TexParameter;*/
+ func->TextureMatrix = nv20TextureMatrix;
+
+ nmesa->hw_func.InitCard = nv20InitCard;
+ nmesa->hw_func.BindBuffers = nv20BindBuffers;
+ nmesa->hw_func.WindowMoved = nv20WindowMoved;
+}
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nv20_vertprog.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv20_vertprog.c
new file mode 100644
index 000000000..60cfcd705
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv20_vertprog.c
@@ -0,0 +1,447 @@
+#include "nouveau_context.h"
+#include "nouveau_object.h"
+#include "nouveau_fifo.h"
+#include "nouveau_reg.h"
+
+#include "nouveau_shader.h"
+#include "nv20_shader.h"
+
+unsigned int NVVP_TX_VOP_COUNT = 16;
+unsigned int NVVP_TX_NVS_OP_COUNT = 16;
+struct _op_xlat NVVP_TX_VOP[32];
+struct _op_xlat NVVP_TX_SOP[32];
+
+nvsSwzComp NV20VP_TX_SWIZZLE[4] = { NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W };
+
+/*****************************************************************************
+ * Support routines
+ */
+static void
+NV20VPUploadToHW(GLcontext *ctx, nouveauShader *nvs)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ int i;
+
+ /* XXX: missing a way to say what insn we're uploading from, and possible
+ * the program start position (if NV20 has one) */
+ for (i=0; i<nvs->program_size; i+=4) {
+ BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_INST0, 4);
+ OUT_RING(nvs->program[i + 0]);
+ OUT_RING(nvs->program[i + 1]);
+ OUT_RING(nvs->program[i + 2]);
+ OUT_RING(nvs->program[i + 3]);
+ }
+}
+
+static void
+NV20VPUpdateConst(GLcontext *ctx, nouveauShader *nvs, int id)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ /* Worth checking if the value *actually* changed? Mesa doesn't tell us this
+ * as far as I know..
+ */
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_ID, 1);
+ OUT_RING (id);
+ BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_X, 4);
+ OUT_RINGf(nvs->params[id].source_val[0]);
+ OUT_RINGf(nvs->params[id].source_val[1]);
+ OUT_RINGf(nvs->params[id].source_val[2]);
+ OUT_RINGf(nvs->params[id].source_val[3]);
+}
+
+/*****************************************************************************
+ * Assembly routines
+ */
+
+/*****************************************************************************
+ * Disassembly routines
+ */
+void
+NV20VPTXSwizzle(int hwswz, nvsSwzComp *swz)
+{
+ swz[NVS_SWZ_X] = NV20VP_TX_SWIZZLE[(hwswz & 0xC0) >> 6];
+ swz[NVS_SWZ_Y] = NV20VP_TX_SWIZZLE[(hwswz & 0x30) >> 4];
+ swz[NVS_SWZ_Z] = NV20VP_TX_SWIZZLE[(hwswz & 0x0C) >> 2];
+ swz[NVS_SWZ_W] = NV20VP_TX_SWIZZLE[(hwswz & 0x03) >> 0];
+}
+
+static int
+NV20VPHasMergedInst(nvsFunc * shader)
+{
+ if (shader->GetOpcodeHW(shader, 0) != NV20_VP_INST_OPCODE_NOP &&
+ shader->GetOpcodeHW(shader, 1) != NV20_VP_INST_OPCODE_NOP)
+ printf
+ ("\n\n*****both opcode fields have values - PLEASE REPORT*****\n");
+ return 0;
+}
+
+static int
+NV20VPIsLastInst(nvsFunc * shader)
+{
+ return ((shader->inst[3] & (1 << 0)) ? 1 : 0);
+}
+
+static int
+NV20VPGetOffsetNext(nvsFunc * shader)
+{
+ return 4;
+}
+
+static struct _op_xlat *
+NV20VPGetOPTXRec(nvsFunc * shader, int merged)
+{
+ struct _op_xlat *opr;
+ int op;
+
+ if (shader->GetOpcodeSlot(shader, merged)) {
+ opr = NVVP_TX_SOP;
+ op = shader->GetOpcodeHW(shader, 1);
+ if (op >= NVVP_TX_NVS_OP_COUNT)
+ return NULL;
+ }
+ else {
+ opr = NVVP_TX_VOP;
+ op = shader->GetOpcodeHW(shader, 0);
+ if (op >= NVVP_TX_VOP_COUNT)
+ return NULL;
+ }
+
+ if (opr[op].SOP == NVS_OP_UNKNOWN)
+ return NULL;
+ return &opr[op];
+}
+
+static struct _op_xlat *
+NV20VPGetOPTXFromSOP(nvsOpcode sop, int *id)
+{
+ int i;
+
+ for (i=0;i<NVVP_TX_VOP_COUNT;i++) {
+ if (NVVP_TX_VOP[i].SOP == sop) {
+ if (id) *id = 0;
+ return &NVVP_TX_VOP[i];
+ }
+ }
+
+ for (i=0;i<NVVP_TX_NVS_OP_COUNT;i++) {
+ if (NVVP_TX_SOP[i].SOP == sop) {
+ if (id) *id = 1;
+ return &NVVP_TX_SOP[i];
+ }
+ }
+
+ return NULL;
+}
+
+static int
+NV20VPGetOpcodeSlot(nvsFunc * shader, int merged)
+{
+ if (shader->HasMergedInst(shader))
+ return merged;
+ if (shader->GetOpcodeHW(shader, 0) == NV20_VP_INST_OPCODE_NOP)
+ return 1;
+ return 0;
+}
+
+static nvsOpcode
+NV20VPGetOpcode(nvsFunc * shader, int merged)
+{
+ struct _op_xlat *opr;
+
+ opr = shader->GetOPTXRec(shader, merged);
+ if (!opr)
+ return NVS_OP_UNKNOWN;
+
+ return opr->SOP;
+}
+
+static nvsOpcode
+NV20VPGetOpcodeHW(nvsFunc * shader, int slot)
+{
+ if (slot)
+ return (shader->inst[1] & NV20_VP_INST_SCA_OPCODE_MASK)
+ >> NV20_VP_INST_SCA_OPCODE_SHIFT;
+ return (shader->inst[1] & NV20_VP_INST_VEC_OPCODE_MASK)
+ >> NV20_VP_INST_VEC_OPCODE_SHIFT;
+}
+
+static nvsRegFile
+NV20VPGetDestFile(nvsFunc * shader, int merged)
+{
+ switch (shader->GetOpcode(shader, merged)) {
+ case NVS_OP_ARL:
+ return NVS_FILE_ADDRESS;
+ default:
+ /*FIXME: This probably isn't correct.. */
+ if ((shader->inst[3] & NV20_VP_INST_DEST_WRITEMASK_MASK) == 0)
+ return NVS_FILE_TEMP;
+ return NVS_FILE_RESULT;
+ }
+}
+
+static unsigned int
+NV20VPGetDestID(nvsFunc * shader, int merged)
+{
+ int id;
+
+ switch (shader->GetDestFile(shader, merged)) {
+ case NVS_FILE_RESULT:
+ id = ((shader->inst[3] & NV20_VP_INST_DEST_MASK)
+ >> NV20_VP_INST_DEST_SHIFT);
+ switch (id) {
+ case NV20_VP_INST_DEST_POS : return NVS_FR_POSITION;
+ case NV20_VP_INST_DEST_COL0 : return NVS_FR_COL0;
+ case NV20_VP_INST_DEST_COL1 : return NVS_FR_COL1;
+ case NV20_VP_INST_DEST_TC(0): return NVS_FR_TEXCOORD0;
+ case NV20_VP_INST_DEST_TC(1): return NVS_FR_TEXCOORD1;
+ case NV20_VP_INST_DEST_TC(2): return NVS_FR_TEXCOORD2;
+ case NV20_VP_INST_DEST_TC(3): return NVS_FR_TEXCOORD3;
+ default:
+ return -1;
+ }
+ case NVS_FILE_ADDRESS:
+ return 0;
+ case NVS_FILE_TEMP:
+ id = ((shader->inst[3] & NV20_VP_INST_DEST_TEMP_ID_MASK)
+ >> NV20_VP_INST_DEST_TEMP_ID_SHIFT);
+ return id;
+ default:
+ return -1;
+ }
+}
+
+static unsigned int
+NV20VPGetDestMask(nvsFunc * shader, int merged)
+{
+ int hwmask, mask = 0;
+
+ /* Special handling for ARL - hardware only supports a
+ * 1-component address reg
+ */
+ if (shader->GetOpcode(shader, merged) == NVS_OP_ARL)
+ return SMASK_X;
+
+ if (shader->GetDestFile(shader, merged) == NVS_FILE_RESULT)
+ hwmask = (shader->inst[3] & NV20_VP_INST_DEST_WRITEMASK_MASK)
+ >> NV20_VP_INST_DEST_WRITEMASK_SHIFT;
+ else if (shader->GetOpcodeSlot(shader, merged))
+ hwmask = (shader->inst[3] & NV20_VP_INST_STEMP_WRITEMASK_MASK)
+ >> NV20_VP_INST_STEMP_WRITEMASK_SHIFT;
+ else
+ hwmask = (shader->inst[3] & NV20_VP_INST_VTEMP_WRITEMASK_MASK)
+ >> NV20_VP_INST_VTEMP_WRITEMASK_SHIFT;
+
+ if (hwmask & (1 << 3)) mask |= SMASK_X;
+ if (hwmask & (1 << 2)) mask |= SMASK_Y;
+ if (hwmask & (1 << 1)) mask |= SMASK_Z;
+ if (hwmask & (1 << 0)) mask |= SMASK_W;
+
+ return mask;
+}
+
+static unsigned int
+NV20VPGetSourceHW(nvsFunc * shader, int merged, int pos)
+{
+ struct _op_xlat *opr;
+ unsigned int src;
+
+ opr = shader->GetOPTXRec(shader, merged);
+ if (!opr)
+ return -1;
+
+ switch (opr->srcpos[pos]) {
+ case 0:
+ src = ((shader->inst[1] & NV20_VP_INST_SRC0H_MASK)
+ >> NV20_VP_INST_SRC0H_SHIFT)
+ << NV20_VP_SRC0_HIGH_SHIFT;
+ src |= ((shader->inst[2] & NV20_VP_INST_SRC0L_MASK)
+ >> NV20_VP_INST_SRC0L_SHIFT);
+ break;
+ case 1:
+ src = ((shader->inst[2] & NV20_VP_INST_SRC1_MASK)
+ >> NV20_VP_INST_SRC1_SHIFT);
+ break;
+ case 2:
+ src = ((shader->inst[2] & NV20_VP_INST_SRC2H_MASK)
+ >> NV20_VP_INST_SRC2H_SHIFT)
+ << NV20_VP_SRC2_HIGH_SHIFT;
+ src |= ((shader->inst[3] & NV20_VP_INST_SRC2L_MASK)
+ >> NV20_VP_INST_SRC2L_SHIFT);
+ break;
+ default:
+ src = -1;
+ }
+
+ return src;
+}
+
+static nvsRegFile
+NV20VPGetSourceFile(nvsFunc * shader, int merged, int pos)
+{
+ unsigned int src;
+ struct _op_xlat *opr;
+ int file;
+
+ opr = shader->GetOPTXRec(shader, merged);
+ if (!opr || opr->srcpos[pos] == -1)
+ return -1;
+
+ switch (opr->srcpos[pos]) {
+ case SPOS_ADDRESS:
+ return NVS_FILE_ADDRESS;
+ default:
+ src = NV20VPGetSourceHW(shader, merged, pos);
+ file = (src & NV20_VP_SRC_REG_TYPE_MASK) >> NV20_VP_SRC_REG_TYPE_SHIFT;
+
+ switch (file) {
+ case NV20_VP_SRC_REG_TYPE_TEMP : return NVS_FILE_TEMP;
+ case NV20_VP_SRC_REG_TYPE_INPUT: return NVS_FILE_ATTRIB;
+ case NV20_VP_SRC_REG_TYPE_CONST: return NVS_FILE_CONST;
+ default:
+ return NVS_FILE_UNKNOWN;
+ }
+ }
+}
+
+static int
+NV20VPGetSourceID(nvsFunc * shader, int merged, int pos)
+{
+ unsigned int src;
+
+ switch (shader->GetSourceFile(shader, merged, pos)) {
+ case NVS_FILE_TEMP:
+ src = shader->GetSourceHW(shader, merged, pos);
+ return ((src & NV20_VP_SRC_REG_TEMP_ID_MASK) >>
+ NV20_VP_SRC_REG_TEMP_ID_SHIFT);
+ case NVS_FILE_CONST:
+ return ((shader->inst[1] & NV20_VP_INST_CONST_SRC_MASK)
+ >> NV20_VP_INST_CONST_SRC_SHIFT);
+ case NVS_FILE_ATTRIB:
+ src = ((shader->inst[1] & NV20_VP_INST_INPUT_SRC_MASK)
+ >> NV20_VP_INST_INPUT_SRC_SHIFT);
+ switch (src) {
+ case NV20_VP_INST_INPUT_SRC_POS : return NVS_FR_POSITION;
+ case NV20_VP_INST_INPUT_SRC_COL0 : return NVS_FR_COL0;
+ case NV20_VP_INST_INPUT_SRC_COL1 : return NVS_FR_COL1;
+ case NV20_VP_INST_INPUT_SRC_TC(0): return NVS_FR_TEXCOORD0;
+ case NV20_VP_INST_INPUT_SRC_TC(1): return NVS_FR_TEXCOORD1;
+ case NV20_VP_INST_INPUT_SRC_TC(2): return NVS_FR_TEXCOORD2;
+ case NV20_VP_INST_INPUT_SRC_TC(3): return NVS_FR_TEXCOORD3;
+ default:
+ return NVS_FR_UNKNOWN;
+ }
+ default:
+ return -1;
+ }
+}
+
+static int
+NV20VPGetSourceNegate(nvsFunc * shader, int merged, int pos)
+{
+ unsigned int src;
+
+ src = shader->GetSourceHW(shader, merged, pos);
+
+ return ((src & NV20_VP_SRC_REG_NEGATE) ? 1 : 0);
+}
+
+static int
+NV20VPGetSourceAbs(nvsFunc * shader, int merged, int pos)
+{
+ /* NV20 can't do ABS on sources? Appears to be emulated with
+ * MAX reg, reg, -reg
+ */
+ return 0;
+}
+
+static void
+NV20VPGetSourceSwizzle(nvsFunc * shader, int merged, int pos, nvsSwzComp *swz)
+{
+ unsigned int src;
+ int swzbits;
+
+ src = shader->GetSourceHW(shader, merged, pos);
+ swzbits =
+ (src & NV20_VP_SRC_REG_SWZ_ALL_MASK) >> NV20_VP_SRC_REG_SWZ_ALL_SHIFT;
+ return NV20VPTXSwizzle(swzbits, swz);
+}
+
+static int
+NV20VPGetSourceIndexed(nvsFunc * shader, int merged, int pos)
+{
+ /* I don't think NV20 can index into attribs, at least no GL
+ * extension is exposed that will allow it.
+ */
+ if (shader->GetSourceFile(shader, merged, pos) != NVS_FILE_CONST)
+ return 0;
+ if (shader->inst[3] & NV20_VP_INST_INDEX_CONST)
+ return 1;
+ return 0;
+}
+
+static int
+NV20VPGetAddressRegID(nvsFunc * shader)
+{
+ /* Only 1 address reg */
+ return 0;
+}
+
+static nvsSwzComp
+NV20VPGetAddressRegSwizzle(nvsFunc * shader)
+{
+ /* Only A0.x available */
+ return NVS_SWZ_X;
+}
+
+void
+NV20VPInitShaderFuncs(nvsFunc * shader)
+{
+ MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_NOP, NVS_OP_NOP, -1, -1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_MOV, NVS_OP_MOV, 0, -1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_MUL, NVS_OP_MUL, 0, 1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_ADD, NVS_OP_ADD, 0, 2, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_MAD, NVS_OP_MAD, 0, 1, 2);
+ MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_DP3, NVS_OP_DP3, 0, 1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_DPH, NVS_OP_DPH, 0, 1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_DP4, NVS_OP_DP4, 0, 1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_DST, NVS_OP_DST, 0, 1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_MIN, NVS_OP_MIN, 0, 1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_MAX, NVS_OP_MAX, 0, 1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_SLT, NVS_OP_SLT, 0, 1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_SGE, NVS_OP_SGE, 0, 1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_ARL, NVS_OP_ARL, 0, -1, -1);
+
+ MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_NOP, NVS_OP_NOP, -1, -1, -1);
+ MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_RCP, NVS_OP_RCP, 2, -1, -1);
+ MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_RCC, NVS_OP_RCC, 2, -1, -1);
+ MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_RSQ, NVS_OP_RSQ, 2, -1, -1);
+ MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_EXP, NVS_OP_EXP, 2, -1, -1);
+ MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_LOG, NVS_OP_LOG, 2, -1, -1);
+ MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_LIT, NVS_OP_LIT, 2, -1, -1);
+
+ shader->UploadToHW = NV20VPUploadToHW;
+ shader->UpdateConst = NV20VPUpdateConst;
+
+ shader->GetOPTXRec = NV20VPGetOPTXRec;
+ shader->GetOPTXFromSOP = NV20VPGetOPTXFromSOP;
+
+ shader->HasMergedInst = NV20VPHasMergedInst;
+ shader->IsLastInst = NV20VPIsLastInst;
+ shader->GetOffsetNext = NV20VPGetOffsetNext;
+ shader->GetOpcodeSlot = NV20VPGetOpcodeSlot;
+ shader->GetOpcode = NV20VPGetOpcode;
+ shader->GetOpcodeHW = NV20VPGetOpcodeHW;
+ shader->GetDestFile = NV20VPGetDestFile;
+ shader->GetDestID = NV20VPGetDestID;
+ shader->GetDestMask = NV20VPGetDestMask;
+ shader->GetSourceHW = NV20VPGetSourceHW;
+ shader->GetSourceFile = NV20VPGetSourceFile;
+ shader->GetSourceID = NV20VPGetSourceID;
+ shader->GetSourceNegate = NV20VPGetSourceNegate;
+ shader->GetSourceAbs = NV20VPGetSourceAbs;
+ shader->GetSourceSwizzle = NV20VPGetSourceSwizzle;
+ shader->GetSourceIndexed = NV20VPGetSourceIndexed;
+ shader->GetRelAddressRegID = NV20VPGetAddressRegID;
+ shader->GetRelAddressSwizzle = NV20VPGetAddressRegSwizzle;
+}
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nv30_fragprog.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv30_fragprog.c
new file mode 100644
index 000000000..e32452361
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv30_fragprog.c
@@ -0,0 +1,742 @@
+#include <stdint.h>
+
+#include "glheader.h"
+#include "macros.h"
+
+#include "nouveau_context.h"
+#include "nouveau_fifo.h"
+#include "nouveau_reg.h"
+#include "nouveau_drm.h"
+#include "nouveau_shader.h"
+#include "nouveau_object.h"
+#include "nouveau_msg.h"
+#include "nouveau_bufferobj.h"
+#include "nv30_shader.h"
+
+unsigned int NVFP_TX_AOP_COUNT = 64;
+struct _op_xlat NVFP_TX_AOP[64];
+
+/*******************************************************************************
+ * Support routines
+ */
+
+static void
+NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nvsCardPriv *priv = &nvs->card_priv;
+ uint32_t offset;
+
+ if (!nvs->program_buffer)
+ nvs->program_buffer = ctx->Driver.NewBufferObject(ctx, 0,
+ GL_ARRAY_BUFFER_ARB);
+
+ /* Should use STATIC_DRAW_ARB if shader doesn't use changable params */
+ 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_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.
+ * HW caches the program somewhere?
+ */
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM, 1);
+ OUT_RING (offset | 1);
+ 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
+NV30FPUpdateConst(GLcontext *ctx, nouveauShader *nvs, int id)
+{
+ uint32_t *new = nvs->params[id].source_val ?
+ (uint32_t*)nvs->params[id].source_val : (uint32_t*)nvs->params[id].val;
+ uint32_t *current;
+ int i;
+
+ for (i=0; i<nvs->params[id].hw_index_cnt; i++) {
+ current = nvs->program + nvs->params[id].hw_index[i];
+ COPY_4V(current, new);
+ }
+ nvs->on_hardware = 0;
+}
+
+/*******************************************************************************
+ * Assembly helpers
+ */
+static struct _op_xlat *
+NV30FPGetOPTXFromSOP(nvsOpcode op, int *id)
+{
+ int i;
+
+ for (i=0; i<NVFP_TX_AOP_COUNT; i++) {
+ if (NVFP_TX_AOP[i].SOP == op) {
+ if (id) *id = 0;
+ return &NVFP_TX_AOP[i];
+ }
+ }
+
+ return NULL;
+}
+
+static int
+NV30FPSupportsOpcode(nvsFunc *shader, nvsOpcode op)
+{
+ if (shader->GetOPTXFromSOP(op, NULL))
+ return 1;
+ return 0;
+}
+
+static void
+NV30FPSetOpcode(nvsFunc *shader, unsigned int opcode, int slot)
+{
+ if (opcode == NV30_FP_OP_OPCODE_KIL)
+ 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);
+}
+
+static void
+NV30FPSetCCUpdate(nvsFunc *shader)
+{
+ shader->inst[0] |= NV30_FP_OP_COND_WRITE_ENABLE;
+}
+
+static void
+NV30FPSetCondition(nvsFunc *shader, int on, nvsCond cond, int reg,
+ nvsSwzComp *swz)
+{
+ nvsSwzComp default_swz[4] = { NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W };
+ unsigned int hwcond;
+
+ /* cond masking is always enabled */
+ if (!on) {
+ cond = NVS_COND_TR;
+ reg = 0;
+ swz = default_swz;
+ }
+
+ switch (cond) {
+ case NVS_COND_TR: hwcond = NV30_FP_OP_COND_TR; break;
+ case NVS_COND_FL: hwcond = NV30_FP_OP_COND_FL; break;
+ case NVS_COND_LT: hwcond = NV30_FP_OP_COND_LT; break;
+ case NVS_COND_GT: hwcond = NV30_FP_OP_COND_GT; break;
+ case NVS_COND_LE: hwcond = NV30_FP_OP_COND_LE; break;
+ case NVS_COND_GE: hwcond = NV30_FP_OP_COND_GE; break;
+ case NVS_COND_EQ: hwcond = NV30_FP_OP_COND_EQ; break;
+ case NVS_COND_NE: hwcond = NV30_FP_OP_COND_NE; break;
+ default:
+ WARN_ONCE("unknown fp condmask=%d\n", cond);
+ hwcond = NV30_FP_OP_COND_TR;
+ break;
+ }
+
+ shader->inst[1] &= ~NV30_FP_OP_COND_MASK;
+ shader->inst[1] |= (hwcond << NV30_FP_OP_COND_SHIFT);
+
+ shader->inst[1] &= ~NV30_FP_OP_COND_SWZ_ALL_MASK;
+ shader->inst[1] |= (swz[NVS_SWZ_X] << NV30_FP_OP_COND_SWZ_X_SHIFT);
+ shader->inst[1] |= (swz[NVS_SWZ_Y] << NV30_FP_OP_COND_SWZ_Y_SHIFT);
+ shader->inst[1] |= (swz[NVS_SWZ_Z] << NV30_FP_OP_COND_SWZ_Z_SHIFT);
+ 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)
+{
+ unsigned int hwreg;
+
+ if (mask & SMASK_X) shader->inst[0] |= NV30_FP_OP_OUT_X;
+ if (mask & SMASK_Y) shader->inst[0] |= NV30_FP_OP_OUT_Y;
+ if (mask & SMASK_Z) shader->inst[0] |= NV30_FP_OP_OUT_Z;
+ if (mask & SMASK_W) shader->inst[0] |= NV30_FP_OP_OUT_W;
+
+ if (reg->file == NVS_FILE_RESULT) {
+ hwreg = 0; /* FIXME: this is only fragment.color */
+ /* This is *not* correct, I have no idea what it is either */
+ shader->inst[0] |= NV30_FP_OP_UNK0_7;
+ } else {
+ 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);
+}
+
+static void
+NV30FPSetSource(nvsFunc *shader, nvsRegister *reg, int pos)
+{
+ unsigned int hwsrc = 0;
+
+ switch (reg->file) {
+ 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:
+ {
+ unsigned int hwin;
+
+ switch (reg->index) {
+ case NVS_FR_POSITION : hwin = NV30_FP_OP_INPUT_SRC_POSITION; break;
+ case NVS_FR_COL0 : hwin = NV30_FP_OP_INPUT_SRC_COL0; break;
+ case NVS_FR_COL1 : hwin = NV30_FP_OP_INPUT_SRC_COL1; break;
+ case NVS_FR_FOGCOORD : hwin = NV30_FP_OP_INPUT_SRC_FOGC; break;
+ case NVS_FR_TEXCOORD0: hwin = NV30_FP_OP_INPUT_SRC_TC(0); break;
+ case NVS_FR_TEXCOORD1: hwin = NV30_FP_OP_INPUT_SRC_TC(1); break;
+ case NVS_FR_TEXCOORD2: hwin = NV30_FP_OP_INPUT_SRC_TC(2); break;
+ case NVS_FR_TEXCOORD3: hwin = NV30_FP_OP_INPUT_SRC_TC(3); break;
+ case NVS_FR_TEXCOORD4: hwin = NV30_FP_OP_INPUT_SRC_TC(4); break;
+ case NVS_FR_TEXCOORD5: hwin = NV30_FP_OP_INPUT_SRC_TC(5); break;
+ case NVS_FR_TEXCOORD6: hwin = NV30_FP_OP_INPUT_SRC_TC(6); break;
+ case NVS_FR_TEXCOORD7: hwin = NV30_FP_OP_INPUT_SRC_TC(7); break;
+ default:
+ WARN_ONCE("unknown fp input %d\n", reg->index);
+ hwin = NV30_FP_OP_INPUT_SRC_COL0;
+ break;
+ }
+ shader->inst[0] &= ~NV30_FP_OP_INPUT_SRC_MASK;
+ shader->inst[0] |= (hwin << NV30_FP_OP_INPUT_SRC_SHIFT);
+ hwsrc |= (hwin << NV30_FP_REG_SRC_SHIFT);
+ }
+ hwsrc |= (NV30_FP_REG_TYPE_INPUT << NV30_FP_REG_TYPE_SHIFT);
+ break;
+ case NVS_FILE_CONST:
+ /* consts are inlined after the inst */
+ hwsrc |= (NV30_FP_REG_TYPE_CONST << NV30_FP_REG_TYPE_SHIFT);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ if (reg->negate)
+ hwsrc |= NV30_FP_REG_NEGATE;
+ if (reg->abs)
+ shader->inst[1] |= (1 << (29+pos));
+ hwsrc |= (reg->swizzle[NVS_SWZ_X] << NV30_FP_REG_SWZ_X_SHIFT);
+ hwsrc |= (reg->swizzle[NVS_SWZ_Y] << NV30_FP_REG_SWZ_Y_SHIFT);
+ hwsrc |= (reg->swizzle[NVS_SWZ_Z] << NV30_FP_REG_SWZ_Z_SHIFT);
+ hwsrc |= (reg->swizzle[NVS_SWZ_W] << NV30_FP_REG_SWZ_W_SHIFT);
+
+ shader->inst[pos+1] &= ~NV30_FP_REG_ALL_MASK;
+ shader->inst[pos+1] |= hwsrc;
+}
+
+static void
+NV30FPSetTexImageUnit(nvsFunc *shader, int unit)
+{
+ shader->inst[0] &= ~NV30_FP_OP_TEX_UNIT_SHIFT;
+ shader->inst[0] |= (unit << NV30_FP_OP_TEX_UNIT_SHIFT);
+}
+
+static void
+NV30FPSetSaturate(nvsFunc *shader)
+{
+ shader->inst[0] |= NV30_FP_OP_OUT_SAT;
+}
+
+static void
+NV30FPInitInstruction(nvsFunc *shader)
+{
+ unsigned int hwsrc;
+
+ shader->inst[0] = 0;
+
+ hwsrc = (NV30_FP_REG_TYPE_INPUT << NV30_FP_REG_TYPE_SHIFT) |
+ (NVS_SWZ_X << NV30_FP_REG_SWZ_X_SHIFT) |
+ (NVS_SWZ_Y << NV30_FP_REG_SWZ_Y_SHIFT) |
+ (NVS_SWZ_Z << NV30_FP_REG_SWZ_Z_SHIFT) |
+ (NVS_SWZ_W << NV30_FP_REG_SWZ_W_SHIFT);
+ shader->inst[1] = hwsrc;
+ shader->inst[2] = hwsrc;
+ shader->inst[3] = hwsrc;
+}
+
+static void
+NV30FPSetLastInst(nvsFunc *shader)
+{
+ shader->inst[0] |= 1;
+}
+
+/*******************************************************************************
+ * Disassembly helpers
+ */
+static struct _op_xlat *
+NV30FPGetOPTXRec(nvsFunc * shader, int merged)
+{
+ int op;
+
+ op = shader->GetOpcodeHW(shader, 0);
+ if (op > NVFP_TX_AOP_COUNT)
+ return NULL;
+ if (NVFP_TX_AOP[op].SOP == NVS_OP_UNKNOWN)
+ return NULL;
+ return &NVFP_TX_AOP[op];
+}
+
+static int
+NV30FPHasMergedInst(nvsFunc * shader)
+{
+ return 0;
+}
+
+static int
+NV30FPIsLastInst(nvsFunc * shader)
+{
+ return ((shader->inst[0] & NV30_FP_OP_PROGRAM_END) ? 1 : 0);
+}
+
+static int
+NV30FPGetOffsetNext(nvsFunc * shader)
+{
+ int i;
+
+ for (i = 0; i < 3; i++)
+ if (shader->GetSourceFile(shader, 0, i) == NVS_FILE_CONST)
+ return 8;
+ return 4;
+}
+
+static nvsOpcode
+NV30FPGetOpcode(nvsFunc * shader, int merged)
+{
+ struct _op_xlat *opr;
+
+ opr = shader->GetOPTXRec(shader, merged);
+ if (!opr)
+ return NVS_OP_UNKNOWN;
+
+ return opr->SOP;
+}
+
+static unsigned int
+NV30FPGetOpcodeHW(nvsFunc * shader, int slot)
+{
+ int op;
+
+ op = (shader->inst[0] & NV30_FP_OP_OPCODE_MASK) >> NV30_FP_OP_OPCODE_SHIFT;
+
+ return op;
+}
+
+static nvsRegFile
+NV30FPGetDestFile(nvsFunc * shader, int merged)
+{
+ /* Result regs overlap temporary regs */
+ return NVS_FILE_TEMP;
+}
+
+static unsigned int
+NV30FPGetDestID(nvsFunc * shader, int merged)
+{
+ int id;
+
+ switch (shader->GetDestFile(shader, merged)) {
+ case NVS_FILE_TEMP:
+ id = ((shader->inst[0] & NV30_FP_OP_OUT_REG_MASK)
+ >> NV30_FP_OP_OUT_REG_SHIFT);
+ return id;
+ default:
+ return -1;
+ }
+}
+
+static unsigned int
+NV30FPGetDestMask(nvsFunc * shader, int merged)
+{
+ unsigned int mask = 0;
+
+ if (shader->inst[0] & NV30_FP_OP_OUT_X) mask |= SMASK_X;
+ if (shader->inst[0] & NV30_FP_OP_OUT_Y) mask |= SMASK_Y;
+ if (shader->inst[0] & NV30_FP_OP_OUT_Z) mask |= SMASK_Z;
+ if (shader->inst[0] & NV30_FP_OP_OUT_W) mask |= SMASK_W;
+
+ return mask;
+}
+
+static unsigned int
+NV30FPGetSourceHW(nvsFunc * shader, int merged, int pos)
+{
+ struct _op_xlat *opr;
+
+ opr = shader->GetOPTXRec(shader, merged);
+ if (!opr || opr->srcpos[pos] == -1)
+ return -1;
+
+ return shader->inst[opr->srcpos[pos] + 1];
+}
+
+static nvsRegFile
+NV30FPGetSourceFile(nvsFunc * shader, int merged, int pos)
+{
+ unsigned int src;
+ struct _op_xlat *opr;
+ int file;
+
+ opr = shader->GetOPTXRec(shader, merged);
+ if (!opr || opr->srcpos[pos] == -1)
+ return NVS_FILE_UNKNOWN;
+
+ switch (opr->srcpos[pos]) {
+ case SPOS_ADDRESS: return NVS_FILE_ADDRESS;
+ default:
+ src = shader->GetSourceHW(shader, merged, pos);
+ file = (src & NV30_FP_REG_TYPE_MASK) >> NV30_FP_REG_TYPE_SHIFT;
+
+ switch (file) {
+ case NV30_FP_REG_TYPE_TEMP : return NVS_FILE_TEMP;
+ case NV30_FP_REG_TYPE_INPUT: return NVS_FILE_ATTRIB;
+ case NV30_FP_REG_TYPE_CONST: return NVS_FILE_CONST;
+ default:
+ return NVS_FILE_UNKNOWN;
+ }
+ }
+}
+
+static int
+NV30FPGetSourceID(nvsFunc * shader, int merged, int pos)
+{
+ switch (shader->GetSourceFile(shader, merged, pos)) {
+ case NVS_FILE_ATTRIB:
+ switch ((shader->inst[0] & NV30_FP_OP_INPUT_SRC_MASK)
+ >> NV30_FP_OP_INPUT_SRC_SHIFT) {
+ case NV30_FP_OP_INPUT_SRC_POSITION: return NVS_FR_POSITION;
+ case NV30_FP_OP_INPUT_SRC_COL0 : return NVS_FR_COL0;
+ case NV30_FP_OP_INPUT_SRC_COL1 : return NVS_FR_COL1;
+ case NV30_FP_OP_INPUT_SRC_FOGC : return NVS_FR_FOGCOORD;
+ case NV30_FP_OP_INPUT_SRC_TC(0) : return NVS_FR_TEXCOORD0;
+ case NV30_FP_OP_INPUT_SRC_TC(1) : return NVS_FR_TEXCOORD1;
+ case NV30_FP_OP_INPUT_SRC_TC(2) : return NVS_FR_TEXCOORD2;
+ case NV30_FP_OP_INPUT_SRC_TC(3) : return NVS_FR_TEXCOORD3;
+ case NV30_FP_OP_INPUT_SRC_TC(4) : return NVS_FR_TEXCOORD4;
+ case NV30_FP_OP_INPUT_SRC_TC(5) : return NVS_FR_TEXCOORD5;
+ case NV30_FP_OP_INPUT_SRC_TC(6) : return NVS_FR_TEXCOORD6;
+ case NV30_FP_OP_INPUT_SRC_TC(7) : return NVS_FR_TEXCOORD7;
+ default:
+ return -1;
+ }
+ break;
+ case NVS_FILE_TEMP:
+ {
+ unsigned int src;
+
+ src = shader->GetSourceHW(shader, merged, pos);
+ return ((src & NV30_FP_REG_SRC_MASK) >> NV30_FP_REG_SRC_SHIFT);
+ }
+ case NVS_FILE_CONST: /* inlined into fragprog */
+ default:
+ return -1;
+ }
+}
+
+static int
+NV30FPGetTexImageUnit(nvsFunc *shader)
+{
+ return ((shader->inst[0] & NV30_FP_OP_TEX_UNIT_MASK)
+ >> NV30_FP_OP_TEX_UNIT_SHIFT);
+}
+
+static int
+NV30FPGetSourceNegate(nvsFunc * shader, int merged, int pos)
+{
+ unsigned int src;
+
+ src = shader->GetSourceHW(shader, merged, pos);
+
+ if (src == -1)
+ return -1;
+ return ((src & NV30_FP_REG_NEGATE) ? 1 : 0);
+}
+
+static int
+NV30FPGetSourceAbs(nvsFunc * shader, int merged, int pos)
+{
+ struct _op_xlat *opr;
+ static unsigned int abspos[3] = {
+ NV30_FP_OP_OUT_ABS,
+ (1 << 30), /* guess */
+ (1 << 31) /* guess */
+ };
+
+ opr = shader->GetOPTXRec(shader, merged);
+ if (!opr || opr->srcpos[pos] == -1)
+ return -1;
+
+ return ((shader->inst[1] & abspos[opr->srcpos[pos]]) ? 1 : 0);
+}
+
+nvsSwzComp NV30FP_TX_SWIZZLE[4] = {NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W };
+
+static void
+NV30FPTXSwizzle(int hwswz, nvsSwzComp *swz)
+{
+ swz[NVS_SWZ_W] = NV30FP_TX_SWIZZLE[(hwswz & 0xC0) >> 6];
+ swz[NVS_SWZ_Z] = NV30FP_TX_SWIZZLE[(hwswz & 0x30) >> 4];
+ swz[NVS_SWZ_Y] = NV30FP_TX_SWIZZLE[(hwswz & 0x0C) >> 2];
+ swz[NVS_SWZ_X] = NV30FP_TX_SWIZZLE[(hwswz & 0x03) >> 0];
+}
+
+static void
+NV30FPGetSourceSwizzle(nvsFunc * shader, int merged, int pos, nvsSwzComp *swz)
+{
+ unsigned int src;
+ int swzbits;
+
+ src = shader->GetSourceHW(shader, merged, pos);
+ swzbits = (src & NV30_FP_REG_SWZ_ALL_MASK) >> NV30_FP_REG_SWZ_ALL_SHIFT;
+ NV30FPTXSwizzle(swzbits, swz);
+}
+
+static int
+NV30FPGetSourceIndexed(nvsFunc * shader, int merged, int pos)
+{
+ switch (shader->GetSourceFile(shader, merged, pos)) {
+ case NVS_FILE_ATTRIB:
+ return ((shader->inst[3] & NV30_FP_OP_INDEX_INPUT) ? 1 : 0);
+ default:
+ return 0;
+ }
+}
+
+static void
+NV30FPGetSourceConstVal(nvsFunc * shader, int merged, int pos, float *val)
+{
+ val[0] = *(float *) &(shader->inst[4]);
+ val[1] = *(float *) &(shader->inst[5]);
+ val[2] = *(float *) &(shader->inst[6]);
+ val[3] = *(float *) &(shader->inst[7]);
+}
+
+static int
+NV30FPGetSourceScale(nvsFunc * shader, int merged, int pos)
+{
+/*FIXME: is this per-source, only for a specific source, or all sources??*/
+ return (1 << ((shader->inst[2] & NV30_FP_OP_SRC_SCALE_MASK)
+ >> NV30_FP_OP_SRC_SCALE_SHIFT));
+}
+
+static int
+NV30FPGetAddressRegID(nvsFunc * shader)
+{
+ return 0;
+}
+
+static nvsSwzComp
+NV30FPGetAddressRegSwizzle(nvsFunc * shader)
+{
+ return NVS_SWZ_X;
+}
+
+static int
+NV30FPSupportsConditional(nvsFunc * shader)
+{
+ /*FIXME: Is this true of all ops? */
+ return 1;
+}
+
+static int
+NV30FPGetConditionUpdate(nvsFunc * shader)
+{
+ return ((shader->inst[0] & NV30_FP_OP_COND_WRITE_ENABLE) ? 1 : 0);
+}
+
+static int
+NV30FPGetConditionTest(nvsFunc * shader)
+{
+ /*FIXME: always? */
+ return 1;
+}
+
+static nvsCond
+NV30FPGetCondition(nvsFunc * shader)
+{
+ int cond;
+
+ cond = ((shader->inst[1] & NV30_FP_OP_COND_MASK)
+ >> NV30_FP_OP_COND_SHIFT);
+
+ switch (cond) {
+ case NV30_FP_OP_COND_FL: return NVS_COND_FL;
+ case NV30_FP_OP_COND_LT: return NVS_COND_LT;
+ case NV30_FP_OP_COND_EQ: return NVS_COND_EQ;
+ case NV30_FP_OP_COND_LE: return NVS_COND_LE;
+ case NV30_FP_OP_COND_GT: return NVS_COND_GT;
+ case NV30_FP_OP_COND_NE: return NVS_COND_NE;
+ case NV30_FP_OP_COND_GE: return NVS_COND_GE;
+ case NV30_FP_OP_COND_TR: return NVS_COND_TR;
+ default:
+ return NVS_COND_UNKNOWN;
+ }
+}
+
+static void
+NV30FPGetCondRegSwizzle(nvsFunc * shader, nvsSwzComp *swz)
+{
+ int swzbits;
+
+ swzbits = (shader->inst[1] & NV30_FP_OP_COND_SWZ_ALL_MASK)
+ >> NV30_FP_OP_COND_SWZ_ALL_SHIFT;
+ NV30FPTXSwizzle(swzbits, swz);
+}
+
+static int
+NV30FPGetCondRegID(nvsFunc * shader)
+{
+ return 0;
+}
+
+static nvsPrecision
+NV30FPGetPrecision(nvsFunc * shader)
+{
+ int p;
+
+ p = (shader->inst[0] & NV30_FP_OP_PRECISION_MASK)
+ >> NV30_FP_OP_PRECISION_SHIFT;
+
+ switch (p) {
+ case NV30_FP_PRECISION_FP32: return NVS_PREC_FLOAT32;
+ case NV30_FP_PRECISION_FP16: return NVS_PREC_FLOAT16;
+ case NV30_FP_PRECISION_FX12: return NVS_PREC_FIXED12;
+ default:
+ return NVS_PREC_UNKNOWN;
+ }
+}
+
+static int
+NV30FPGetSaturate(nvsFunc * shader)
+{
+ return ((shader->inst[0] & NV30_FP_OP_OUT_SAT) ? 1 : 0);
+}
+
+/*******************************************************************************
+ * Init
+ */
+void
+NV30FPInitShaderFuncs(nvsFunc * shader)
+{
+ /* These are probably bogus, I made them up... */
+ shader->MaxInst = 1024;
+ shader->MaxAttrib = 16;
+ shader->MaxTemp = 32;
+ shader->MaxAddress = 1;
+ shader->MaxConst = 256;
+ shader->caps = SCAP_SRC_ABS;
+
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MOV, NVS_OP_MOV, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MUL, NVS_OP_MUL, 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_ADD, NVS_OP_ADD, 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MAD, NVS_OP_MAD, 0, 1, 2);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DP3, NVS_OP_DP3, 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DP4, NVS_OP_DP4, 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DST, NVS_OP_DST, 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MIN, NVS_OP_MIN, 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MAX, NVS_OP_MAX, 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SLT, NVS_OP_SLT, 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SGE, NVS_OP_SGE, 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_FRC, NVS_OP_FRC, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_FLR, NVS_OP_FLR, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_TEX, NVS_OP_TEX, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_TXD, NVS_OP_TXD, 0, 1, 2);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_TXP, NVS_OP_TXP, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_TXB, NVS_OP_TXB, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SEQ, NVS_OP_SEQ, 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SGT, NVS_OP_SGT, 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SLE, NVS_OP_SLE, 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SNE, NVS_OP_SNE, 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_RCP, NVS_OP_RCP, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_LG2, NVS_OP_LG2, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_EX2, NVS_OP_EX2, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_COS, NVS_OP_COS, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SIN, NVS_OP_SIN, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_NOP, NVS_OP_NOP, -1, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DDX, NVS_OP_DDX, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DDY, NVS_OP_DDY, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_KIL, NVS_OP_KIL, -1, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_PK4B, NVS_OP_PK4B, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_UP4B, NVS_OP_UP4B, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_PK2H, NVS_OP_PK2H, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_UP2H, NVS_OP_UP2H, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_PK4UB, NVS_OP_PK4UB, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_UP4UB, NVS_OP_UP4UB, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_PK2US, NVS_OP_PK2US, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_UP2US, NVS_OP_UP2US, 0, -1, -1);
+ /*FIXME: Haven't confirmed the source positions for the below opcodes */
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_LIT, NVS_OP_LIT, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_LRP, NVS_OP_LRP, 0, 1, 2);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_POW, NVS_OP_POW, 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_RSQ, NVS_OP_RSQ, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_RFL, NVS_OP_RFL, 0, 1, -1);
+
+ shader->GetOPTXRec = NV30FPGetOPTXRec;
+ shader->GetOPTXFromSOP = NV30FPGetOPTXFromSOP;
+
+ shader->UploadToHW = NV30FPUploadToHW;
+ shader->UpdateConst = NV30FPUpdateConst;
+
+ shader->InitInstruction = NV30FPInitInstruction;
+ shader->SupportsOpcode = NV30FPSupportsOpcode;
+ shader->SetOpcode = NV30FPSetOpcode;
+ shader->SetCCUpdate = NV30FPSetCCUpdate;
+ shader->SetCondition = NV30FPSetCondition;
+ shader->SetResult = NV30FPSetResult;
+ shader->SetSource = NV30FPSetSource;
+ shader->SetTexImageUnit = NV30FPSetTexImageUnit;
+ shader->SetSaturate = NV30FPSetSaturate;
+ shader->SetLastInst = NV30FPSetLastInst;
+
+ shader->HasMergedInst = NV30FPHasMergedInst;
+ shader->IsLastInst = NV30FPIsLastInst;
+ shader->GetOffsetNext = NV30FPGetOffsetNext;
+ shader->GetOpcode = NV30FPGetOpcode;
+ shader->GetOpcodeHW = NV30FPGetOpcodeHW;
+ shader->GetDestFile = NV30FPGetDestFile;
+ shader->GetDestID = NV30FPGetDestID;
+ shader->GetDestMask = NV30FPGetDestMask;
+ shader->GetSourceHW = NV30FPGetSourceHW;
+ shader->GetSourceFile = NV30FPGetSourceFile;
+ shader->GetSourceID = NV30FPGetSourceID;
+ shader->GetTexImageUnit = NV30FPGetTexImageUnit;
+ shader->GetSourceNegate = NV30FPGetSourceNegate;
+ shader->GetSourceAbs = NV30FPGetSourceAbs;
+ shader->GetSourceSwizzle = NV30FPGetSourceSwizzle;
+ shader->GetSourceIndexed = NV30FPGetSourceIndexed;
+ shader->GetSourceConstVal = NV30FPGetSourceConstVal;
+ shader->GetSourceScale = NV30FPGetSourceScale;
+ shader->GetRelAddressRegID = NV30FPGetAddressRegID;
+ shader->GetRelAddressSwizzle = NV30FPGetAddressRegSwizzle;
+ shader->GetPrecision = NV30FPGetPrecision;
+ shader->GetSaturate = NV30FPGetSaturate;
+ shader->SupportsConditional = NV30FPSupportsConditional;
+ shader->GetConditionUpdate = NV30FPGetConditionUpdate;
+ shader->GetConditionTest = NV30FPGetConditionTest;
+ shader->GetCondition = NV30FPGetCondition;
+ shader->GetCondRegSwizzle = NV30FPGetCondRegSwizzle;
+ shader->GetCondRegID = NV30FPGetCondRegID;
+}
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nv30_shader.h b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv30_shader.h
new file mode 100644
index 000000000..7a027dd42
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv30_shader.h
@@ -0,0 +1,379 @@
+#ifndef __NV30_SHADER_H__
+#define __NV30_SHADER_H__
+
+/* Vertex programs instruction set
+ *
+ * 128bit opcodes, split into 4 32-bit ones for ease of use.
+ *
+ * Non-native instructions
+ * ABS - MOV + NV40_VP_INST0_DEST_ABS
+ * POW - EX2 + MUL + LG2
+ * SUB - ADD, second source negated
+ * SWZ - MOV
+ * XPD -
+ *
+ * Register access
+ * - Only one INPUT can be accessed per-instruction (move extras into TEMPs)
+ * - Only one CONST can be accessed per-instruction (move extras into TEMPs)
+ *
+ * Relative Addressing
+ * According to the value returned for MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB
+ * there are only two address registers available. The destination in the ARL
+ * instruction is set to TEMP <n> (The temp isn't actually written).
+ *
+ * When using vanilla ARB_v_p, the proprietary driver will squish both the available
+ * ADDRESS regs into the first hardware reg in the X and Y components.
+ *
+ * To use an address reg as an index into consts, the CONST_SRC is set to
+ * (const_base + offset) and INDEX_CONST is set.
+ *
+ * To access the second address reg use ADDR_REG_SELECT_1. A particular component
+ * of the address regs is selected with ADDR_SWZ.
+ *
+ * Only one address register can be accessed per instruction.
+ *
+ * Conditional execution (see NV_vertex_program{2,3} for details)
+ * Conditional execution of an instruction is enabled by setting COND_TEST_ENABLE, and
+ * selecting the condition which will allow the test to pass with COND_{FL,LT,...}.
+ * It is possible to swizzle the values in the condition register, which allows for
+ * testing against an individual component.
+ *
+ * Branching
+ * The BRA/CAL instructions seem to follow a slightly different opcode layout. The
+ * destination instruction ID (IADDR) overlaps a source field. Instruction ID's seem to
+ * be numbered based on the UPLOAD_FROM_ID FIFO command, and is incremented automatically
+ * on each UPLOAD_INST FIFO command.
+ *
+ * Conditional branching is achieved by using the condition tests described above.
+ * There doesn't appear to be dedicated looping instructions, but this can be done
+ * using a temp reg + conditional branching.
+ *
+ * Subroutines may be uploaded before the main program itself, but the first executed
+ * instruction is determined by the PROGRAM_START_ID FIFO command.
+ *
+ */
+
+/* DWORD 0 */
+#define NV30_VP_INST_ADDR_REG_SELECT_1 (1 << 24)
+#define NV30_VP_INST_SRC2_ABS (1 << 23) /* guess */
+#define NV30_VP_INST_SRC1_ABS (1 << 22) /* guess */
+#define NV30_VP_INST_SRC0_ABS (1 << 21) /* guess */
+#define NV30_VP_INST_OUT_RESULT (1 << 20)
+#define NV30_VP_INST_DEST_TEMP_ID_SHIFT 16
+#define NV30_VP_INST_DEST_TEMP_ID_MASK (0x0F << 16)
+#define NV30_VP_INST_COND_UPDATE_ENABLE (1<<15)
+#define NV30_VP_INST_COND_TEST_ENABLE (1<<14)
+#define NV30_VP_INST_COND_SHIFT 11
+#define NV30_VP_INST_COND_MASK (0x07 << 11)
+# define NV30_VP_INST_COND_FL 0 /* guess */
+# define NV30_VP_INST_COND_LT 1
+# define NV30_VP_INST_COND_EQ 2
+# define NV30_VP_INST_COND_LE 3
+# define NV30_VP_INST_COND_GT 4
+# define NV30_VP_INST_COND_NE 5
+# define NV30_VP_INST_COND_GE 6
+# define NV30_VP_INST_COND_TR 7 /* guess */
+#define NV30_VP_INST_COND_SWZ_X_SHIFT 9
+#define NV30_VP_INST_COND_SWZ_X_MASK (0x03 << 9)
+#define NV30_VP_INST_COND_SWZ_Y_SHIFT 7
+#define NV30_VP_INST_COND_SWZ_Y_MASK (0x03 << 7)
+#define NV30_VP_INST_COND_SWZ_Z_SHIFT 5
+#define NV30_VP_INST_COND_SWZ_Z_MASK (0x03 << 5)
+#define NV30_VP_INST_COND_SWZ_W_SHIFT 3
+#define NV30_VP_INST_COND_SWZ_W_MASK (0x03 << 3)
+#define NV30_VP_INST_COND_SWZ_ALL_SHIFT 3
+#define NV30_VP_INST_COND_SWZ_ALL_MASK (0xFF << 3)
+#define NV30_VP_INST_ADDR_SWZ_SHIFT 1
+#define NV30_VP_INST_ADDR_SWZ_MASK (0x03 << 1)
+#define NV30_VP_INST_SCA_OPCODEH_SHIFT 0
+#define NV30_VP_INST_SCA_OPCODEH_MASK (0x01 << 0)
+
+/* DWORD 1 */
+#define NV30_VP_INST_SCA_OPCODEL_SHIFT 28
+#define NV30_VP_INST_SCA_OPCODEL_MASK (0x0F << 28)
+# define NV30_VP_INST_OP_NOP 0x00
+# define NV30_VP_INST_OP_RCP 0x02
+# define NV30_VP_INST_OP_RCC 0x03
+# define NV30_VP_INST_OP_RSQ 0x04
+# define NV30_VP_INST_OP_EXP 0x05
+# define NV30_VP_INST_OP_LOG 0x06
+# define NV30_VP_INST_OP_LIT 0x07
+# define NV30_VP_INST_OP_BRA 0x09
+# define NV30_VP_INST_OP_CAL 0x0B
+# define NV30_VP_INST_OP_RET 0x0C
+# define NV30_VP_INST_OP_LG2 0x0D
+# define NV30_VP_INST_OP_EX2 0x0E
+# define NV30_VP_INST_OP_SIN 0x0F
+# define NV30_VP_INST_OP_COS 0x10
+#define NV30_VP_INST_VEC_OPCODE_SHIFT 23
+#define NV30_VP_INST_VEC_OPCODE_MASK (0x1F << 23)
+# define NV30_VP_INST_OP_NOPV 0x00
+# define NV30_VP_INST_OP_MOV 0x01
+# define NV30_VP_INST_OP_MUL 0x02
+# define NV30_VP_INST_OP_ADD 0x03
+# define NV30_VP_INST_OP_MAD 0x04
+# define NV30_VP_INST_OP_DP3 0x05
+# define NV30_VP_INST_OP_DP4 0x07
+# define NV30_VP_INST_OP_DPH 0x06
+# define NV30_VP_INST_OP_DST 0x08
+# define NV30_VP_INST_OP_MIN 0x09
+# define NV30_VP_INST_OP_MAX 0x0A
+# define NV30_VP_INST_OP_SLT 0x0B
+# define NV30_VP_INST_OP_SGE 0x0C
+# define NV30_VP_INST_OP_ARL 0x0D
+# define NV30_VP_INST_OP_FRC 0x0E
+# define NV30_VP_INST_OP_FLR 0x0F
+# define NV30_VP_INST_OP_SEQ 0x10
+# define NV30_VP_INST_OP_SFL 0x11
+# define NV30_VP_INST_OP_SGT 0x12
+# define NV30_VP_INST_OP_SLE 0x13
+# define NV30_VP_INST_OP_SNE 0x14
+# define NV30_VP_INST_OP_STR 0x15
+# define NV30_VP_INST_OP_SSG 0x16
+# define NV30_VP_INST_OP_ARR 0x17
+# define NV30_VP_INST_OP_ARA 0x18
+#define NV30_VP_INST_CONST_SRC_SHIFT 14
+#define NV30_VP_INST_CONST_SRC_MASK (0xFF << 14)
+#define NV30_VP_INST_INPUT_SRC_SHIFT 9 /*NV20*/
+#define NV30_VP_INST_INPUT_SRC_MASK (0x0F << 9) /*NV20*/
+# define NV30_VP_INST_IN_POS 0 /* These seem to match the bindings specified in */
+# define NV30_VP_INST_IN_WEIGHT 1 /* the ARB_v_p spec (2.14.3.1) */
+# define NV30_VP_INST_IN_NORMAL 2
+# define NV30_VP_INST_IN_COL0 3 /* Should probably confirm them all though */
+# define NV30_VP_INST_IN_COL1 4
+# define NV30_VP_INST_IN_FOGC 5
+# define NV30_VP_INST_IN_TC0 8
+# define NV30_VP_INST_IN_TC(n) (8+n)
+#define NV30_VP_INST_SRC0H_SHIFT 0 /*NV20*/
+#define NV30_VP_INST_SRC0H_MASK (0x1FF << 0) /*NV20*/
+
+/* DWORD 2 */
+#define NV30_VP_INST_SRC0L_SHIFT 26 /*NV20*/
+#define NV30_VP_INST_SRC0L_MASK (0x3F <<26) /*NV20*/
+#define NV30_VP_INST_SRC1_SHIFT 11 /*NV20*/
+#define NV30_VP_INST_SRC1_MASK (0x7FFF<<11) /*NV20*/
+#define NV30_VP_INST_SRC2H_SHIFT 0 /*NV20*/
+#define NV30_VP_INST_SRC2H_MASK (0x7FF << 0) /*NV20*/
+#define NV30_VP_INST_IADDR_SHIFT 2
+#define NV30_VP_INST_IADDR_MASK (0xFF << 2) /* guess */
+
+/* DWORD 3 */
+#define NV30_VP_INST_SRC2L_SHIFT 28 /*NV20*/
+#define NV30_VP_INST_SRC2L_MASK (0x0F <<28) /*NV20*/
+#define NV30_VP_INST_STEMP_WRITEMASK_SHIFT 24
+#define NV30_VP_INST_STEMP_WRITEMASK_MASK (0x0F << 24)
+#define NV30_VP_INST_VTEMP_WRITEMASK_SHIFT 20
+#define NV30_VP_INST_VTEMP_WRITEMASK_MASK (0x0F << 20)
+#define NV30_VP_INST_SDEST_WRITEMASK_SHIFT 16
+#define NV30_VP_INST_SDEST_WRITEMASK_MASK (0x0F << 16)
+#define NV30_VP_INST_VDEST_WRITEMASK_SHIFT 12 /*NV20*/
+#define NV30_VP_INST_VDEST_WRITEMASK_MASK (0x0F << 12) /*NV20*/
+#define NV30_VP_INST_DEST_ID_SHIFT 2
+#define NV30_VP_INST_DEST_ID_MASK (0x0F << 2)
+# define NV30_VP_INST_DEST_POS 0
+# define NV30_VP_INST_DEST_COL0 3
+# define NV30_VP_INST_DEST_COL1 4
+# define NV30_VP_INST_DEST_TC(n) (8+n)
+
+/* Source-register definition - matches NV20 exactly */
+#define NV30_VP_SRC_REG_NEGATE (1<<14)
+#define NV30_VP_SRC_REG_SWZ_X_SHIFT 12
+#define NV30_VP_SRC_REG_SWZ_X_MASK (0x03 <<12)
+#define NV30_VP_SRC_REG_SWZ_Y_SHIFT 10
+#define NV30_VP_SRC_REG_SWZ_Y_MASK (0x03 <<10)
+#define NV30_VP_SRC_REG_SWZ_Z_SHIFT 8
+#define NV30_VP_SRC_REG_SWZ_Z_MASK (0x03 << 8)
+#define NV30_VP_SRC_REG_SWZ_W_SHIFT 6
+#define NV30_VP_SRC_REG_SWZ_W_MASK (0x03 << 6)
+#define NV30_VP_SRC_REG_SWZ_ALL_SHIFT 6
+#define NV30_VP_SRC_REG_SWZ_ALL_MASK (0xFF << 6)
+#define NV30_VP_SRC_REG_TEMP_ID_SHIFT 2
+#define NV30_VP_SRC_REG_TEMP_ID_MASK (0x0F << 0)
+#define NV30_VP_SRC_REG_TYPE_SHIFT 0
+#define NV30_VP_SRC_REG_TYPE_MASK (0x03 << 0)
+#define NV30_VP_SRC_REG_TYPE_TEMP 1
+#define NV30_VP_SRC_REG_TYPE_INPUT 2
+#define NV30_VP_SRC_REG_TYPE_CONST 3 /* guess */
+
+/*
+ * Each fragment program opcode appears to be comprised of 4 32-bit values.
+ *
+ * 0 - Opcode, output reg/mask, ATTRIB source
+ * 1 - Source 0
+ * 2 - Source 1
+ * 3 - Source 2
+ *
+ * There appears to be no special difference between result regs and temp regs.
+ * result.color == R0.xyzw
+ * result.depth == R1.z
+ * When the fragprog contains instructions to write depth, NV30_TCL_PRIMITIVE_3D_UNK1D78=0
+ * otherwise it is set to 1.
+ *
+ * Constants are inserted directly after the instruction that uses them.
+ *
+ * It appears that it's not possible to use two input registers in one
+ * instruction as the input sourcing is done in the instruction dword
+ * and not the source selection dwords. As such instructions such as:
+ *
+ * ADD result.color, fragment.color, fragment.texcoord[0];
+ *
+ * must be split into two MOV's and then an ADD (nvidia does this) but
+ * I'm not sure why it's not just one MOV and then source the second input
+ * in the ADD instruction..
+ *
+ * Negation of the full source is done with NV30_FP_REG_NEGATE, arbitrary
+ * negation requires multiplication with a const.
+ *
+ * Arbitrary swizzling is supported with the exception of SWIZZLE_ZERO/SWIZZLE_ONE
+ * The temp/result regs appear to be initialised to (0.0, 0.0, 0.0, 0.0) as SWIZZLE_ZERO
+ * is implemented simply by not writing to the relevant components of the destination.
+ *
+ * Conditional execution
+ * TODO
+ *
+ * Non-native instructions:
+ * LIT
+ * LRP - MAD+MAD
+ * SUB - ADD, negate second source
+ * RSQ - LG2 + EX2
+ * POW - LG2 + MUL + EX2
+ * SCS - COS + SIN
+ * XPD
+ */
+
+//== Opcode / Destination selection ==
+#define NV30_FP_OP_PROGRAM_END (1 << 0)
+#define NV30_FP_OP_OUT_REG_SHIFT 1
+#define NV30_FP_OP_OUT_REG_MASK (31 << 1) /* uncertain */
+/* Needs to be set when writing outputs to get expected result.. */
+#define NV30_FP_OP_UNK0_7 (1 << 7)
+#define NV30_FP_OP_COND_WRITE_ENABLE (1 << 8)
+#define NV30_FP_OP_OUTMASK_SHIFT 9
+#define NV30_FP_OP_OUTMASK_MASK (0xF << 9)
+# define NV30_FP_OP_OUT_X (1<<9)
+# define NV30_FP_OP_OUT_Y (1<<10)
+# define NV30_FP_OP_OUT_Z (1<<11)
+# define NV30_FP_OP_OUT_W (1<<12)
+/* Uncertain about these, especially the input_src values.. it's possible that
+ * they can be dynamically changed.
+ */
+#define NV30_FP_OP_INPUT_SRC_SHIFT 13
+#define NV30_FP_OP_INPUT_SRC_MASK (15 << 13)
+# define NV30_FP_OP_INPUT_SRC_POSITION 0x0
+# define NV30_FP_OP_INPUT_SRC_COL0 0x1
+# define NV30_FP_OP_INPUT_SRC_COL1 0x2
+# define NV30_FP_OP_INPUT_SRC_FOGC 0x3
+# define NV30_FP_OP_INPUT_SRC_TC0 0x4
+# define NV30_FP_OP_INPUT_SRC_TC(n) (0x4 + n)
+#define NV30_FP_OP_TEX_UNIT_SHIFT 17
+#define NV30_FP_OP_TEX_UNIT_MASK (0xF << 17) /* guess */
+#define NV30_FP_OP_PRECISION_SHIFT 22
+#define NV30_FP_OP_PRECISION_MASK (3 << 22)
+# define NV30_FP_PRECISION_FP32 0
+# define NV30_FP_PRECISION_FP16 1
+# define NV30_FP_PRECISION_FX12 2
+#define NV30_FP_OP_OPCODE_SHIFT 24
+#define NV30_FP_OP_OPCODE_MASK (0x3F << 24)
+# define NV30_FP_OP_OPCODE_NOP 0x00
+# define NV30_FP_OP_OPCODE_MOV 0x01
+# define NV30_FP_OP_OPCODE_MUL 0x02
+# define NV30_FP_OP_OPCODE_ADD 0x03
+# define NV30_FP_OP_OPCODE_MAD 0x04
+# define NV30_FP_OP_OPCODE_DP3 0x05
+# define NV30_FP_OP_OPCODE_DP4 0x06
+# define NV30_FP_OP_OPCODE_DST 0x07
+# define NV30_FP_OP_OPCODE_MIN 0x08
+# define NV30_FP_OP_OPCODE_MAX 0x09
+# define NV30_FP_OP_OPCODE_SLT 0x0A
+# define NV30_FP_OP_OPCODE_SGE 0x0B
+# define NV30_FP_OP_OPCODE_SLE 0x0C
+# define NV30_FP_OP_OPCODE_SGT 0x0D
+# define NV30_FP_OP_OPCODE_SNE 0x0E
+# define NV30_FP_OP_OPCODE_SEQ 0x0F
+# define NV30_FP_OP_OPCODE_FRC 0x10
+# define NV30_FP_OP_OPCODE_FLR 0x11
+# define NV30_FP_OP_OPCODE_KIL 0x12
+# define NV30_FP_OP_OPCODE_PK4B 0x13
+# define NV30_FP_OP_OPCODE_UP4B 0x14
+# define NV30_FP_OP_OPCODE_DDX 0x15 /* can only write XY */
+# define NV30_FP_OP_OPCODE_DDY 0x16 /* can only write XY */
+# define NV30_FP_OP_OPCODE_TEX 0x17
+# define NV30_FP_OP_OPCODE_TXP 0x18
+# define NV30_FP_OP_OPCODE_TXD 0x19
+# define NV30_FP_OP_OPCODE_RCP 0x1A
+# define NV30_FP_OP_OPCODE_RSQ 0x1B
+# define NV30_FP_OP_OPCODE_EX2 0x1C
+# define NV30_FP_OP_OPCODE_LG2 0x1D
+# define NV30_FP_OP_OPCODE_LIT 0x1E
+# define NV30_FP_OP_OPCODE_LRP 0x1F
+# define NV30_FP_OP_OPCODE_COS 0x22
+# define NV30_FP_OP_OPCODE_SIN 0x23
+# define NV30_FP_OP_OPCODE_PK2H 0x24
+# define NV30_FP_OP_OPCODE_UP2H 0x25
+# define NV30_FP_OP_OPCODE_POW 0x26
+# define NV30_FP_OP_OPCODE_PK4UB 0x27
+# define NV30_FP_OP_OPCODE_UP4UB 0x28
+# define NV30_FP_OP_OPCODE_PK2US 0x29
+# define NV30_FP_OP_OPCODE_UP2US 0x2A
+# define NV30_FP_OP_OPCODE_DP2A 0x2E
+# define NV30_FP_OP_OPCODE_TXB 0x31
+# define NV30_FP_OP_OPCODE_RFL 0x36
+#define NV30_FP_OP_OUT_SAT (1 << 31)
+
+/* high order bits of SRC0 */
+#define NV30_FP_OP_OUT_ABS (1 << 29)
+#define NV30_FP_OP_COND_SWZ_W_SHIFT 27
+#define NV30_FP_OP_COND_SWZ_W_MASK (3 << 27)
+#define NV30_FP_OP_COND_SWZ_Z_SHIFT 25
+#define NV30_FP_OP_COND_SWZ_Z_MASK (3 << 25)
+#define NV30_FP_OP_COND_SWZ_Y_SHIFT 23
+#define NV30_FP_OP_COND_SWZ_Y_MASK (3 << 23)
+#define NV30_FP_OP_COND_SWZ_X_SHIFT 21
+#define NV30_FP_OP_COND_SWZ_X_MASK (3 << 21)
+#define NV30_FP_OP_COND_SWZ_ALL_SHIFT 21
+#define NV30_FP_OP_COND_SWZ_ALL_MASK (0xFF << 21)
+#define NV30_FP_OP_COND_SHIFT 18
+#define NV30_FP_OP_COND_MASK (0x07 << 18)
+# define NV30_FP_OP_COND_FL 0
+# define NV30_FP_OP_COND_LT 1
+# define NV30_FP_OP_COND_EQ 2
+# define NV30_FP_OP_COND_LE 3
+# define NV30_FP_OP_COND_GT 4
+# define NV30_FP_OP_COND_NE 5
+# define NV30_FP_OP_COND_GE 6
+# define NV30_FP_OP_COND_TR 7
+
+/* high order bits of SRC1 */
+#define NV30_FP_OP_SRC_SCALE_SHIFT 28
+#define NV30_FP_OP_SRC_SCALE_MASK (3 << 28)
+
+/* high order bits of SRC2 */
+#define NV30_FP_OP_INDEX_INPUT (1 << 30)
+
+//== Register selection ==
+#define NV30_FP_REG_ALL_MASK (0x1FFFF<<0)
+#define NV30_FP_REG_TYPE_SHIFT 0
+#define NV30_FP_REG_TYPE_MASK (3 << 0)
+# define NV30_FP_REG_TYPE_TEMP 0
+# define NV30_FP_REG_TYPE_INPUT 1
+# define NV30_FP_REG_TYPE_CONST 2
+#define NV30_FP_REG_SRC_SHIFT 2 /* uncertain */
+#define NV30_FP_REG_SRC_MASK (31 << 2)
+#define NV30_FP_REG_UNK_0 (1 << 8)
+#define NV30_FP_REG_SWZ_ALL_SHIFT 9
+#define NV30_FP_REG_SWZ_ALL_MASK (255 << 9)
+#define NV30_FP_REG_SWZ_X_SHIFT 9
+#define NV30_FP_REG_SWZ_X_MASK (3 << 9)
+#define NV30_FP_REG_SWZ_Y_SHIFT 11
+#define NV30_FP_REG_SWZ_Y_MASK (3 << 11)
+#define NV30_FP_REG_SWZ_Z_SHIFT 13
+#define NV30_FP_REG_SWZ_Z_MASK (3 << 13)
+#define NV30_FP_REG_SWZ_W_SHIFT 15
+#define NV30_FP_REG_SWZ_W_MASK (3 << 15)
+# define NV30_FP_SWIZZLE_X 0
+# define NV30_FP_SWIZZLE_Y 1
+# define NV30_FP_SWIZZLE_Z 2
+# define NV30_FP_SWIZZLE_W 3
+#define NV30_FP_REG_NEGATE (1 << 17)
+
+#endif
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nv30_state.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv30_state.c
new file mode 100644
index 000000000..ad21fa273
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv30_state.c
@@ -0,0 +1,980 @@
+/**************************************************************************
+
+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"
+
+#define NOUVEAU_CARD_USING_SHADERS (nmesa->screen->card->type >= NV_40)
+
+static void nv30AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte ubRef;
+ CLAMPED_FLOAT_TO_UBYTE(ubRef, ref);
+
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC, 2);
+ OUT_RING_CACHE(func); /* NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC */
+ OUT_RING_CACHE(ubRef); /* NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF */
+}
+
+static void nv30BlendColor(GLcontext *ctx, const GLfloat color[4])
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte cf[4];
+
+ CLAMPED_FLOAT_TO_UBYTE(cf[0], color[0]);
+ CLAMPED_FLOAT_TO_UBYTE(cf[1], color[1]);
+ CLAMPED_FLOAT_TO_UBYTE(cf[2], color[2]);
+ CLAMPED_FLOAT_TO_UBYTE(cf[3], color[3]);
+
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_COLOR, 1);
+ OUT_RING_CACHE(PACK_COLOR_8888(cf[3], cf[1], cf[2], cf[0]));
+}
+
+static void nv30BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_EQUATION, 1);
+ OUT_RING_CACHE((modeA<<16) | modeRGB);
+}
+
+
+static void nv30BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB,
+ GLenum sfactorA, GLenum dfactorA)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2);
+ OUT_RING_CACHE((sfactorA<<16) | sfactorRGB);
+ OUT_RING_CACHE((dfactorA<<16) | dfactorRGB);
+}
+
+static void nv30Clear(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 |= 0xf0;
+ if (mask & (BUFFER_BIT_DEPTH))
+ hw_bufs |= 0x03;
+
+ if (hw_bufs) {
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_WHICH_BUFFERS, 1);
+ OUT_RING(hw_bufs);
+ }
+}
+
+static void nv30ClearColor(GLcontext *ctx, const GLfloat color[4])
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte c[4];
+ UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,color);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB, 1);
+ OUT_RING_CACHE(PACK_COLOR_8888(c[3],c[0],c[1],c[2]));
+}
+
+static void nv30ClearDepth(GLcontext *ctx, GLclampd d)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nmesa->clear_value=((nmesa->clear_value&0x000000FF)|(((uint32_t)(d*0xFFFFFF))<<8));
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1);
+ OUT_RING_CACHE(nmesa->clear_value);
+}
+
+/* we're don't support indexed buffers
+ void (*ClearIndex)(GLcontext *ctx, GLuint index)
+ */
+
+static void nv30ClearStencil(GLcontext *ctx, GLint s)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nmesa->clear_value=((nmesa->clear_value&0xFFFFFF00)|(s&0x000000FF));
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1);
+ OUT_RING_CACHE(nmesa->clear_value);
+}
+
+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]);
+ OUT_RING_CACHEf(equation[2]);
+ OUT_RING_CACHEf(equation[3]);
+}
+
+static void nv30ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask,
+ GLboolean bmask, GLboolean amask )
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_MASK, 1);
+ OUT_RING_CACHE(((amask && 0x01) << 24) | ((rmask && 0x01) << 16) | ((gmask && 0x01)<< 8) | ((bmask && 0x01) << 0));
+}
+
+static void nv30ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode)
+{
+ // TODO I need love
+}
+
+static void nv30CullFace(GLcontext *ctx, GLenum mode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CULL_FACE, 1);
+ OUT_RING_CACHE(mode);
+}
+
+static void nv30FrontFace(GLcontext *ctx, GLenum mode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FRONT_FACE, 1);
+ OUT_RING_CACHE(mode);
+}
+
+static void nv30DepthFunc(GLcontext *ctx, GLenum func)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1);
+ OUT_RING_CACHE(func);
+}
+
+static void nv30DepthMask(GLcontext *ctx, GLboolean flag)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1);
+ OUT_RING_CACHE(flag);
+}
+
+static void nv30DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV30_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 nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ switch(cap)
+ {
+ case GL_ALPHA_TEST:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_AUTO_NORMAL:
+ case GL_BLEND:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ 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:
+ 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);
+ 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, NV30_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_DEPTH_TEST:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_DITHER:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DITHER_ENABLE, 1);
+ 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;
+// 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:
+ {
+ uint32_t mask=0x11<<(2*(cap-GL_LIGHT0));
+
+ if (NOUVEAU_CARD_USING_SHADERS)
+ break;
+
+ nmesa->enabled_lights=((nmesa->enabled_lights&mask)|(mask*state));
+ if (nmesa->lighting_enabled)
+ {
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1);
+ OUT_RING_CACHE(nmesa->enabled_lights);
+ }
+ break;
+ }
+ case GL_LIGHTING:
+ if (NOUVEAU_CARD_USING_SHADERS)
+ break;
+
+ nmesa->lighting_enabled=state;
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1);
+ if (nmesa->lighting_enabled)
+ OUT_RING_CACHE(nmesa->enabled_lights);
+ else
+ OUT_RING_CACHE(0x0);
+ break;
+// 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:
+ if (nmesa->screen->card->type != NV_44) {
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ }
+ break;
+// case GL_POINT_SMOOTH:
+ case GL_POLYGON_OFFSET_POINT:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_POLYGON_OFFSET_LINE:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_POLYGON_OFFSET_FILL:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_POLYGON_SMOOTH:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_POLYGON_STIPPLE:
+ BEGIN_RING_CACHE(NvSub3D, NV30_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:
+ /* No enable bit, nv30Scissor 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 ?
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ BEGIN_RING_CACHE(NvSub3D, NV30_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 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:
+ {
+ int mode = 0;
+ /* The modes are different in GL and the card. */
+ switch(ctx->Fog.Mode)
+ {
+ case GL_LINEAR:
+ mode = 0x804;
+ break;
+ 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)
+{
+ // TODO I need love (fog and line_smooth hints)
+}
+
+// void (*IndexMask)(GLcontext *ctx, GLuint mask);
+
+enum {
+ SPOTLIGHT_NO_UPDATE,
+ SPOTLIGHT_UPDATE_EXPONENT,
+ SPOTLIGHT_UPDATE_DIRECTION,
+ SPOTLIGHT_UPDATE_ALL
+};
+
+static void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params )
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLint p = light - GL_LIGHT0;
+ struct gl_light *l = &ctx->Light.Light[p];
+ int spotlight_update = SPOTLIGHT_NO_UPDATE;
+
+ if (NOUVEAU_CARD_USING_SHADERS)
+ return;
+
+ /* not sure where the fourth param value goes...*/
+ switch(pname)
+ {
+ case GL_AMBIENT:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(p), 3);
+ OUT_RING_CACHEf(params[0]);
+ OUT_RING_CACHEf(params[1]);
+ OUT_RING_CACHEf(params[2]);
+ break;
+ case GL_DIFFUSE:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(p), 3);
+ OUT_RING_CACHEf(params[0]);
+ OUT_RING_CACHEf(params[1]);
+ OUT_RING_CACHEf(params[2]);
+ break;
+ case GL_SPECULAR:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(p), 3);
+ OUT_RING_CACHEf(params[0]);
+ OUT_RING_CACHEf(params[1]);
+ OUT_RING_CACHEf(params[2]);
+ break;
+ case GL_POSITION:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(p), 3);
+ OUT_RING_CACHEf(params[0]);
+ OUT_RING_CACHEf(params[1]);
+ OUT_RING_CACHEf(params[2]);
+ break;
+ case GL_SPOT_DIRECTION:
+ spotlight_update = SPOTLIGHT_UPDATE_DIRECTION;
+ break;
+ case GL_SPOT_EXPONENT:
+ spotlight_update = SPOTLIGHT_UPDATE_EXPONENT;
+ break;
+ case GL_SPOT_CUTOFF:
+ spotlight_update = SPOTLIGHT_UPDATE_ALL;
+ break;
+ case GL_CONSTANT_ATTENUATION:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(p), 1);
+ OUT_RING_CACHEf(*params);
+ break;
+ case GL_LINEAR_ATTENUATION:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(p), 1);
+ OUT_RING_CACHEf(*params);
+ break;
+ case GL_QUADRATIC_ATTENUATION:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(p), 1);
+ OUT_RING_CACHEf(*params);
+ break;
+ default:
+ break;
+ }
+
+ switch(spotlight_update) {
+ case SPOTLIGHT_UPDATE_DIRECTION:
+ {
+ GLfloat x,y,z;
+ GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0);
+ x = spot_light_coef_a * l->_NormDirection[0];
+ y = spot_light_coef_a * l->_NormDirection[1];
+ z = spot_light_coef_a * l->_NormDirection[2];
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p), 3);
+ OUT_RING_CACHEf(x);
+ OUT_RING_CACHEf(y);
+ OUT_RING_CACHEf(z);
+ }
+ break;
+ case SPOTLIGHT_UPDATE_EXPONENT:
+ {
+ GLfloat cc,lc,qc;
+ cc = 1.0; /* FIXME: These need to be correctly computed */
+ lc = 0.0;
+ qc = 2.0;
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 3);
+ OUT_RING_CACHEf(cc);
+ OUT_RING_CACHEf(lc);
+ OUT_RING_CACHEf(qc);
+ }
+ break;
+ case SPOTLIGHT_UPDATE_ALL:
+ {
+ GLfloat cc,lc,qc, x,y,z, c;
+ GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0);
+ cc = 1.0; /* FIXME: These need to be correctly computed */
+ lc = 0.0;
+ qc = 2.0;
+ x = spot_light_coef_a * l->_NormDirection[0];
+ y = spot_light_coef_a * l->_NormDirection[1];
+ z = spot_light_coef_a * l->_NormDirection[2];
+ c = spot_light_coef_a + 1.0;
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 7);
+ OUT_RING_CACHEf(cc);
+ OUT_RING_CACHEf(lc);
+ OUT_RING_CACHEf(qc);
+ OUT_RING_CACHEf(x);
+ OUT_RING_CACHEf(y);
+ OUT_RING_CACHEf(z);
+ OUT_RING_CACHEf(c);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/** Set the lighting model parameters */
+void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params);
+
+
+static void nv30LineStipple(GLcontext *ctx, GLint factor, GLushort pattern )
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN, 1);
+ OUT_RING_CACHE((pattern << 16) | factor);
+}
+
+static void nv30LineWidth(GLcontext *ctx, GLfloat width)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte ubWidth;
+
+ ubWidth = (GLubyte)(width * 8.0) & 0xFF;
+
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_WIDTH_SMOOTH, 1);
+ OUT_RING_CACHE(ubWidth);
+}
+
+static void nv30LogicOpcode(GLcontext *ctx, GLenum opcode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP, 1);
+ OUT_RING_CACHE(opcode);
+}
+
+static void nv30PointParameterfv(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 nv30PointSize(GLcontext *ctx, GLfloat size)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POINT_SIZE, 1);
+ OUT_RING_CACHEf(size);
+}
+
+/** Select a polygon rasterization mode */
+static void nv30PolygonMode(GLcontext *ctx, GLenum face, GLenum mode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 1);
+ OUT_RING_CACHE(mode);
+ }
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK, 1);
+ OUT_RING_CACHE(mode);
+ }
+}
+
+/** Set the scale and units used to calculate depth values */
+static void nv30PolygonOffset(GLcontext *ctx, GLfloat factor, GLfloat units)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR, 2);
+ OUT_RING_CACHEf(factor);
+
+ /* Looks like we always multiply units by 2.0... according to the dumps.*/
+ OUT_RING_CACHEf(units * 2.0);
+}
+
+/** Set the polygon stippling pattern */
+static void nv30PolygonStipple(GLcontext *ctx, const GLubyte *mask )
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV30_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 nv30Scissor(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, NV30_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS, 2);
+ OUT_RING_CACHE(((w) << 16) | x);
+ OUT_RING_CACHE(((h) << 16) | y);
+}
+
+/** Select flat or smooth shading */
+static void nv30ShadeModel(GLcontext *ctx, GLenum mode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SHADE_MODEL, 1);
+ OUT_RING_CACHE(mode);
+}
+
+/** OpenGL 2.0 two-sided StencilFunc */
+static void nv30StencilFuncSeparate(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, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_FUNC, 3);
+ OUT_RING_CACHE(func);
+ OUT_RING_CACHE(ref);
+ OUT_RING_CACHE(mask);
+ }
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_FUNC, 3);
+ OUT_RING_CACHE(func);
+ OUT_RING_CACHE(ref);
+ OUT_RING_CACHE(mask);
+ }
+}
+
+/** OpenGL 2.0 two-sided StencilMask */
+static void nv30StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_MASK, 1);
+ OUT_RING_CACHE(mask);
+ }
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_MASK, 1);
+ OUT_RING_CACHE(mask);
+ }
+}
+
+/** OpenGL 2.0 two-sided StencilOp */
+static void nv30StencilOpSeparate(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, NV30_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, NV30_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 nv30TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ 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)
+{
+ 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;
+
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_0, 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,
+ NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_OFS0, 2);
+ OUT_RING_CACHE(((w+x) << 16) | x);
+ OUT_RING_CACHE(((h+y) << 16) | y);
+ /* viewport transform */
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_OX, 8);
+ OUT_RING_CACHEf (v[MAT_TX]);
+ OUT_RING_CACHEf (v[MAT_TY]);
+ OUT_RING_CACHEf (v[MAT_TZ]);
+ OUT_RING_CACHEf (0.0);
+ OUT_RING_CACHEf (v[MAT_SX]);
+ OUT_RING_CACHEf (v[MAT_SY]);
+ OUT_RING_CACHEf (v[MAT_SZ]);
+ OUT_RING_CACHEf (0.0);
+
+ ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
+ ctx->Scissor.Width, ctx->Scissor.Height);
+}
+
+static GLboolean nv30InitCard(nouveauContextPtr nmesa)
+{
+ 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);
+
+ /* 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);
+
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_RC_ENABLE, 1);
+ OUT_RING (0);
+
+ return GL_TRUE;
+}
+
+static GLboolean nv40InitCard(nouveauContextPtr nmesa)
+{
+ nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D);
+
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT1, 2);
+ OUT_RING(NvDmaFB);
+ 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, 0x0220, 1);
+ OUT_RING(1);
+
+ BEGIN_RING_SIZE(NvSub3D, 0x1ea4, 3);
+ OUT_RING(0x00000010);
+ OUT_RING(0x01000100);
+ OUT_RING(0xff800006);
+ BEGIN_RING_SIZE(NvSub3D, 0x1fc4, 1);
+ OUT_RING(0x06144321);
+ BEGIN_RING_SIZE(NvSub3D, 0x1fc8, 2);
+ OUT_RING(0xedcba987);
+ OUT_RING(0x00000021);
+ BEGIN_RING_SIZE(NvSub3D, 0x1fd0, 1);
+ OUT_RING(0x00171615);
+ BEGIN_RING_SIZE(NvSub3D, 0x1fd4, 1);
+ OUT_RING(0x001b1a19);
+
+ BEGIN_RING_SIZE(NvSub3D, 0x1ef8, 1);
+ OUT_RING(0x0020ffff);
+ BEGIN_RING_SIZE(NvSub3D, 0x1d64, 1);
+ OUT_RING(0x00d30000);
+ BEGIN_RING_SIZE(NvSub3D, 0x1e94, 1);
+ OUT_RING(0x00000001);
+
+ return GL_TRUE;
+}
+
+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);
+ 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);
+ }
+ }
+
+ return GL_TRUE;
+}
+
+void nv30InitStateFuncs(GLcontext *ctx, struct dd_function_table *func)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ func->AlphaFunc = nv30AlphaFunc;
+ func->BlendColor = nv30BlendColor;
+ func->BlendEquationSeparate = nv30BlendEquationSeparate;
+ func->BlendFuncSeparate = nv30BlendFuncSeparate;
+ func->Clear = nv30Clear;
+ func->ClearColor = nv30ClearColor;
+ func->ClearDepth = nv30ClearDepth;
+ func->ClearStencil = nv30ClearStencil;
+ func->ClipPlane = nv30ClipPlane;
+ func->ColorMask = nv30ColorMask;
+ func->ColorMaterial = nv30ColorMaterial;
+ func->CullFace = nv30CullFace;
+ func->FrontFace = nv30FrontFace;
+ func->DepthFunc = nv30DepthFunc;
+ func->DepthMask = nv30DepthMask;
+ func->DepthRange = nv30DepthRange;
+ func->Enable = nv30Enable;
+ func->Fogfv = nv30Fogfv;
+ func->Hint = nv30Hint;
+ func->Lightfv = nv30Lightfv;
+/* func->LightModelfv = nv30LightModelfv; */
+ func->LineStipple = nv30LineStipple;
+ func->LineWidth = nv30LineWidth;
+ func->LogicOpcode = nv30LogicOpcode;
+ func->PointParameterfv = nv30PointParameterfv;
+ func->PointSize = nv30PointSize;
+ func->PolygonMode = nv30PolygonMode;
+ func->PolygonOffset = nv30PolygonOffset;
+ func->PolygonStipple = nv30PolygonStipple;
+#if 0
+ func->ReadBuffer = nv30ReadBuffer;
+ func->RenderMode = nv30RenderMode;
+#endif
+ func->Scissor = nv30Scissor;
+ func->ShadeModel = nv30ShadeModel;
+ func->StencilFuncSeparate = nv30StencilFuncSeparate;
+ func->StencilMaskSeparate = nv30StencilMaskSeparate;
+ func->StencilOpSeparate = nv30StencilOpSeparate;
+#if 0
+ func->TexGen = nv30TexGen;
+ func->TexParameter = nv30TexParameter;
+#endif
+ func->TextureMatrix = nv30TextureMatrix;
+
+
+ if (nmesa->screen->card->type >= NV_40)
+ nmesa->hw_func.InitCard = nv40InitCard;
+ else
+ nmesa->hw_func.InitCard = nv30InitCard;
+ nmesa->hw_func.BindBuffers = nv30BindBuffers;
+ nmesa->hw_func.WindowMoved = nv30WindowMoved;
+}
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nv30_vertprog.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv30_vertprog.c
new file mode 100644
index 000000000..d023e8439
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv30_vertprog.c
@@ -0,0 +1,367 @@
+#include "nouveau_context.h"
+#include "nouveau_object.h"
+#include "nouveau_fifo.h"
+#include "nouveau_reg.h"
+
+#include "nouveau_shader.h"
+#include "nv30_shader.h"
+
+/*****************************************************************************
+ * Support routines
+ */
+static void
+NV30VPUploadToHW(GLcontext *ctx, nouveauShader *nvs)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ int i;
+
+ /* We can do better here and keep more than one VP on the hardware, and
+ * switch between them with PROGRAM_START_ID..
+ */
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_FROM_ID, 1);
+ OUT_RING(0);
+ for (i=0; i<nvs->program_size; i+=4) {
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_INST0, 4);
+ OUT_RING(nvs->program[i + 0]);
+ OUT_RING(nvs->program[i + 1]);
+ OUT_RING(nvs->program[i + 2]);
+ OUT_RING(nvs->program[i + 3]);
+ }
+ 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);
+
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_CLIPPING_PLANES, 1);
+ OUT_RING_CACHE (nvs->card_priv.NV30VP.clip_enables);
+}
+
+static void
+NV30VPUpdateConst(GLcontext *ctx, nouveauShader *nvs, int id)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLfloat *val;
+
+ val = nvs->params[id].source_val ?
+ nvs->params[id].source_val : nvs->params[id].val;
+
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_ID, 5);
+ OUT_RING (id);
+ OUT_RINGp(val, 4);
+}
+
+/*****************************************************************************
+ * 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
+ */
+static unsigned int
+NV30VPGetOpcodeHW(nvsFunc * shader, int slot)
+{
+ int op;
+
+ if (slot) {
+ op = (shader->inst[1] & NV30_VP_INST_SCA_OPCODEL_MASK)
+ >> NV30_VP_INST_SCA_OPCODEL_SHIFT;
+ op |= ((shader->inst[0] & NV30_VP_INST_SCA_OPCODEH_MASK)
+ >> NV30_VP_INST_SCA_OPCODEH_SHIFT) << 4;
+ }
+ else {
+ op = (shader->inst[1] & NV30_VP_INST_VEC_OPCODE_MASK)
+ >> NV30_VP_INST_VEC_OPCODE_SHIFT;
+ }
+
+ return op;
+}
+
+static nvsRegFile
+NV30VPGetDestFile(nvsFunc * shader, int merged)
+{
+ switch (shader->GetOpcode(shader, merged)) {
+ case NVS_OP_ARL:
+ case NVS_OP_ARR:
+ case NVS_OP_ARA:
+ return NVS_FILE_ADDRESS;
+ default:
+ /*FIXME: This probably isn't correct.. */
+ if ((shader->inst[3] & NV30_VP_INST_VDEST_WRITEMASK_MASK) != 0)
+ return NVS_FILE_RESULT;
+ if ((shader->inst[3] & NV30_VP_INST_SDEST_WRITEMASK_MASK) != 0)
+ return NVS_FILE_RESULT;
+ return NVS_FILE_TEMP;
+ }
+}
+
+static unsigned int
+NV30VPGetDestID(nvsFunc * shader, int merged)
+{
+ int id;
+
+ switch (shader->GetDestFile(shader, merged)) {
+ case NVS_FILE_RESULT:
+ id = ((shader->inst[3] & NV30_VP_INST_DEST_ID_MASK)
+ >> NV30_VP_INST_DEST_ID_SHIFT);
+ switch (id) {
+ case NV30_VP_INST_DEST_POS : return NVS_FR_POSITION;
+ case NV30_VP_INST_DEST_COL0 : return NVS_FR_COL0;
+ case NV30_VP_INST_DEST_COL1 : return NVS_FR_COL1;
+ case NV30_VP_INST_DEST_TC(0): return NVS_FR_TEXCOORD0;
+ case NV30_VP_INST_DEST_TC(1): return NVS_FR_TEXCOORD1;
+ case NV30_VP_INST_DEST_TC(2): return NVS_FR_TEXCOORD2;
+ case NV30_VP_INST_DEST_TC(3): return NVS_FR_TEXCOORD3;
+ case NV30_VP_INST_DEST_TC(4): return NVS_FR_TEXCOORD4;
+ case NV30_VP_INST_DEST_TC(5): return NVS_FR_TEXCOORD5;
+ case NV30_VP_INST_DEST_TC(6): return NVS_FR_TEXCOORD6;
+ case NV30_VP_INST_DEST_TC(7): return NVS_FR_TEXCOORD7;
+ default:
+ return -1;
+ }
+ case NVS_FILE_ADDRESS:
+ case NVS_FILE_TEMP:
+ return (shader->inst[0] & NV30_VP_INST_DEST_TEMP_ID_MASK)
+ >> NV30_VP_INST_DEST_TEMP_ID_SHIFT;
+ default:
+ return -1;
+ }
+}
+
+static unsigned int
+NV30VPGetDestMask(nvsFunc * shader, int merged)
+{
+ int hwmask, mask = 0;
+
+ if (shader->GetDestFile(shader, merged) == NVS_FILE_RESULT)
+ if (shader->GetOpcodeSlot(shader, merged))
+ hwmask = (shader->inst[3] & NV30_VP_INST_SDEST_WRITEMASK_MASK)
+ >> NV30_VP_INST_SDEST_WRITEMASK_SHIFT;
+ else
+ hwmask = (shader->inst[3] & NV30_VP_INST_VDEST_WRITEMASK_MASK)
+ >> NV30_VP_INST_VDEST_WRITEMASK_SHIFT;
+ else if (shader->GetOpcodeSlot(shader, merged))
+ hwmask = (shader->inst[3] & NV30_VP_INST_STEMP_WRITEMASK_MASK)
+ >> NV30_VP_INST_STEMP_WRITEMASK_SHIFT;
+ else
+ hwmask = (shader->inst[3] & NV30_VP_INST_VTEMP_WRITEMASK_MASK)
+ >> NV30_VP_INST_VTEMP_WRITEMASK_SHIFT;
+
+ if (hwmask & (1 << 3)) mask |= SMASK_X;
+ if (hwmask & (1 << 2)) mask |= SMASK_Y;
+ if (hwmask & (1 << 1)) mask |= SMASK_Z;
+ if (hwmask & (1 << 0)) mask |= SMASK_W;
+
+ return mask;
+}
+
+static int
+NV30VPGetSourceID(nvsFunc * shader, int merged, int pos)
+{
+ unsigned int src;
+
+ switch (shader->GetSourceFile(shader, merged, pos)) {
+ case NVS_FILE_TEMP:
+ src = shader->GetSourceHW(shader, merged, pos);
+ return ((src & NV30_VP_SRC_REG_TEMP_ID_MASK) >>
+ NV30_VP_SRC_REG_TEMP_ID_SHIFT);
+ case NVS_FILE_CONST:
+ return ((shader->inst[1] & NV30_VP_INST_CONST_SRC_MASK)
+ >> NV30_VP_INST_CONST_SRC_SHIFT);
+ case NVS_FILE_ATTRIB:
+ src = ((shader->inst[1] & NV30_VP_INST_INPUT_SRC_MASK)
+ >> NV30_VP_INST_INPUT_SRC_SHIFT);
+ switch (src) {
+ case NV30_VP_INST_IN_POS : return NVS_FR_POSITION;
+ case NV30_VP_INST_IN_COL0 : return NVS_FR_COL0;
+ case NV30_VP_INST_IN_COL1 : return NVS_FR_COL1;
+ case NV30_VP_INST_IN_TC(0): return NVS_FR_TEXCOORD0;
+ case NV30_VP_INST_IN_TC(1): return NVS_FR_TEXCOORD1;
+ case NV30_VP_INST_IN_TC(2): return NVS_FR_TEXCOORD2;
+ case NV30_VP_INST_IN_TC(3): return NVS_FR_TEXCOORD3;
+ case NV30_VP_INST_IN_TC(4): return NVS_FR_TEXCOORD4;
+ case NV30_VP_INST_IN_TC(5): return NVS_FR_TEXCOORD5;
+ case NV30_VP_INST_IN_TC(6): return NVS_FR_TEXCOORD6;
+ case NV30_VP_INST_IN_TC(7): return NVS_FR_TEXCOORD7;
+ default:
+ return NVS_FR_UNKNOWN;
+ }
+ default:
+ return -1;
+ }
+}
+
+static int
+NV30VPGetSourceAbs(nvsFunc * shader, int merged, int pos)
+{
+ struct _op_xlat *opr;
+ static unsigned int abspos[3] = {
+ NV30_VP_INST_SRC0_ABS,
+ NV30_VP_INST_SRC1_ABS,
+ NV30_VP_INST_SRC2_ABS,
+ };
+
+ opr = shader->GetOPTXRec(shader, merged);
+ if (!opr || opr->srcpos[pos] == -1 || opr->srcpos[pos] > 2)
+ return 0;
+
+ return ((shader->inst[0] & abspos[opr->srcpos[pos]]) ? 1 : 0);
+}
+
+static int
+NV30VPGetRelAddressRegID(nvsFunc * shader)
+{
+ return ((shader->inst[0] & NV30_VP_INST_ADDR_REG_SELECT_1) ? 1 : 0);
+}
+
+static nvsSwzComp
+NV30VPGetRelAddressSwizzle(nvsFunc * shader)
+{
+ nvsSwzComp swz;
+
+ swz = NV20VP_TX_SWIZZLE[(shader->inst[0] & NV30_VP_INST_ADDR_SWZ_MASK)
+ >> NV30_VP_INST_ADDR_SWZ_SHIFT];
+ return swz;
+}
+
+static int
+NV30VPSupportsConditional(nvsFunc * shader)
+{
+ /*FIXME: Is this true of all ops? */
+ return 1;
+}
+
+static int
+NV30VPGetConditionUpdate(nvsFunc * shader)
+{
+ return ((shader->inst[0] & NV30_VP_INST_COND_UPDATE_ENABLE) ? 1 : 0);
+}
+
+static int
+NV30VPGetConditionTest(nvsFunc * shader)
+{
+ int op;
+
+ /* The condition test is unconditionally enabled on some
+ * instructions. ie: the condition test bit does *NOT* have
+ * to be set.
+ *
+ * FIXME: check other relevant ops for this situation.
+ */
+ op = shader->GetOpcodeHW(shader, 1);
+ switch (op) {
+ case NV30_VP_INST_OP_BRA:
+ return 1;
+ default:
+ return ((shader->inst[0] & NV30_VP_INST_COND_TEST_ENABLE) ? 1 : 0);
+ }
+}
+
+static nvsCond
+NV30VPGetCondition(nvsFunc * shader)
+{
+ int cond;
+
+ cond = ((shader->inst[0] & NV30_VP_INST_COND_MASK)
+ >> NV30_VP_INST_COND_SHIFT);
+
+ switch (cond) {
+ case NV30_VP_INST_COND_FL: return NVS_COND_FL;
+ case NV30_VP_INST_COND_LT: return NVS_COND_LT;
+ case NV30_VP_INST_COND_EQ: return NVS_COND_EQ;
+ case NV30_VP_INST_COND_LE: return NVS_COND_LE;
+ case NV30_VP_INST_COND_GT: return NVS_COND_GT;
+ case NV30_VP_INST_COND_NE: return NVS_COND_NE;
+ case NV30_VP_INST_COND_GE: return NVS_COND_GE;
+ case NV30_VP_INST_COND_TR: return NVS_COND_TR;
+ default:
+ return NVS_COND_UNKNOWN;
+ }
+}
+
+static void
+NV30VPGetCondRegSwizzle(nvsFunc * shader, nvsSwzComp *swz)
+{
+ int swzbits;
+
+ swzbits = (shader->inst[0] & NV30_VP_INST_COND_SWZ_ALL_MASK)
+ >> NV30_VP_INST_COND_SWZ_ALL_SHIFT;
+ NV20VPTXSwizzle(swzbits, swz);
+}
+
+static int
+NV30VPGetCondRegID(nvsFunc * shader)
+{
+ return 0;
+}
+
+
+static int
+NV30VPGetBranch(nvsFunc * shader)
+{
+ return ((shader->inst[2] & NV30_VP_INST_IADDR_MASK)
+ >> NV30_VP_INST_IADDR_SHIFT);
+}
+
+void
+NV30VPInitShaderFuncs(nvsFunc * shader)
+{
+ /* Inherit NV20 code, a lot of it is the same */
+ NV20VPInitShaderFuncs(shader);
+
+ /* Increase max valid opcode ID, and add new instructions */
+ NVVP_TX_VOP_COUNT = NVVP_TX_NVS_OP_COUNT = 32;
+
+ MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_FRC, NVS_OP_FRC, 0, -1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_FLR, NVS_OP_FLR, 0, -1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SEQ, NVS_OP_SEQ, 0, 1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SFL, NVS_OP_SFL, 0, 1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SGT, NVS_OP_SGT, 0, 1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SLE, NVS_OP_SLE, 0, 1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SNE, NVS_OP_SNE, 0, 1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_STR, NVS_OP_STR, 0, 1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SSG, NVS_OP_SSG, 0, -1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_ARR, NVS_OP_ARR, 0, -1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_ARA, NVS_OP_ARA, 3, -1, -1);
+
+ MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_BRA, NVS_OP_BRA, -1, -1, -1);
+ MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_CAL, NVS_OP_CAL, -1, -1, -1);
+ MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_RET, NVS_OP_RET, -1, -1, -1);
+ MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_LG2, NVS_OP_LG2, 2, -1, -1);
+ MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_EX2, NVS_OP_EX2, 2, -1, -1);
+ MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_SIN, NVS_OP_SIN, 2, -1, -1);
+ MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_COS, NVS_OP_COS, 2, -1, -1);
+
+ shader->UploadToHW = NV30VPUploadToHW;
+ shader->UpdateConst = NV30VPUpdateConst;
+
+ shader->GetOpcodeHW = NV30VPGetOpcodeHW;
+
+ shader->GetDestFile = NV30VPGetDestFile;
+ shader->GetDestID = NV30VPGetDestID;
+ shader->GetDestMask = NV30VPGetDestMask;
+
+ shader->GetSourceID = NV30VPGetSourceID;
+ shader->GetSourceAbs = NV30VPGetSourceAbs;
+
+ shader->GetRelAddressRegID = NV30VPGetRelAddressRegID;
+ shader->GetRelAddressSwizzle = NV30VPGetRelAddressSwizzle;
+
+ shader->SupportsConditional = NV30VPSupportsConditional;
+ shader->GetConditionUpdate = NV30VPGetConditionUpdate;
+ shader->GetConditionTest = NV30VPGetConditionTest;
+ shader->GetCondition = NV30VPGetCondition;
+ shader->GetCondRegSwizzle = NV30VPGetCondRegSwizzle;
+ shader->GetCondRegID = NV30VPGetCondRegID;
+
+ shader->GetBranch = NV30VPGetBranch;
+ shader->SetBranchTarget = NV30VPSetBranchTarget;
+}
+
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nv40_fragprog.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv40_fragprog.c
new file mode 100644
index 000000000..3e4ae0496
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv40_fragprog.c
@@ -0,0 +1,224 @@
+#include "nouveau_shader.h"
+#include "nv40_shader.h"
+
+/* branching ops */
+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 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)
+{
+ 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)
+{
+ struct _op_xlat *opr;
+ int op;
+
+ op = shader->GetOpcodeHW(shader, 0);
+ if (shader->inst[2] & NV40_FP_OP_OPCODE_IS_BRANCH) {
+ opr = NVFP_TX_BOP;
+ op &= ~NV40_FP_OP_OPCODE_IS_BRANCH;
+ if (op > NVFP_TX_BOP_COUNT)
+ return NULL;
+ }
+ else {
+ opr = NVFP_TX_AOP;
+ if (op > NVFP_TX_AOP_COUNT)
+ return NULL;
+ }
+
+ if (opr[op].SOP == NVS_OP_UNKNOWN)
+ return NULL;
+ return &opr[op];
+}
+
+static int
+NV40FPGetSourceID(nvsFunc * shader, int merged, int pos)
+{
+ switch (shader->GetSourceFile(shader, merged, pos)) {
+ case NVS_FILE_ATTRIB:
+ switch ((shader->inst[0] & NV40_FP_OP_INPUT_SRC_MASK)
+ >> NV40_FP_OP_INPUT_SRC_SHIFT) {
+ case NV40_FP_OP_INPUT_SRC_POSITION: return NVS_FR_POSITION;
+ case NV40_FP_OP_INPUT_SRC_COL0 : return NVS_FR_COL0;
+ case NV40_FP_OP_INPUT_SRC_COL1 : return NVS_FR_COL1;
+ case NV40_FP_OP_INPUT_SRC_FOGC : return NVS_FR_FOGCOORD;
+ case NV40_FP_OP_INPUT_SRC_TC(0) : return NVS_FR_TEXCOORD0;
+ case NV40_FP_OP_INPUT_SRC_TC(1) : return NVS_FR_TEXCOORD1;
+ case NV40_FP_OP_INPUT_SRC_TC(2) : return NVS_FR_TEXCOORD2;
+ case NV40_FP_OP_INPUT_SRC_TC(3) : return NVS_FR_TEXCOORD3;
+ case NV40_FP_OP_INPUT_SRC_TC(4) : return NVS_FR_TEXCOORD4;
+ case NV40_FP_OP_INPUT_SRC_TC(5) : return NVS_FR_TEXCOORD5;
+ case NV40_FP_OP_INPUT_SRC_TC(6) : return NVS_FR_TEXCOORD6;
+ case NV40_FP_OP_INPUT_SRC_TC(7) : return NVS_FR_TEXCOORD7;
+ case NV40_FP_OP_INPUT_SRC_FACING : return NVS_FR_FACING;
+ default:
+ return -1;
+ }
+ break;
+ case NVS_FILE_TEMP:
+ {
+ unsigned int src;
+
+ src = shader->GetSourceHW(shader, merged, pos);
+ return ((src & NV40_FP_REG_SRC_MASK) >> NV40_FP_REG_SRC_SHIFT);
+ }
+ case NVS_FILE_CONST: /* inlined into fragprog */
+ default:
+ return -1;
+ }
+}
+
+static int
+NV40FPGetBranch(nvsFunc * shader)
+{
+ return ((shader->inst[2] & NV40_FP_OP_IADDR_MASK)
+ >> NV40_FP_OP_IADDR_SHIFT);;
+}
+
+static int
+NV40FPGetBranchElse(nvsFunc * shader)
+{
+ return ((shader->inst[2] & NV40_FP_OP_ELSE_ID_MASK)
+ >> NV40_FP_OP_ELSE_ID_SHIFT);
+}
+
+static int
+NV40FPGetBranchEnd(nvsFunc * shader)
+{
+ return ((shader->inst[3] & NV40_FP_OP_END_ID_MASK)
+ >> NV40_FP_OP_END_ID_SHIFT);
+}
+
+static int
+NV40FPGetLoopCount(nvsFunc * shader)
+{
+ return ((shader->inst[2] & NV40_FP_OP_LOOP_COUNT_MASK)
+ >> NV40_FP_OP_LOOP_COUNT_SHIFT);
+}
+
+static int
+NV40FPGetLoopInitial(nvsFunc * shader)
+{
+ return ((shader->inst[2] & NV40_FP_OP_LOOP_INDEX_MASK)
+ >> NV40_FP_OP_LOOP_INDEX_SHIFT);
+}
+
+static int
+NV40FPGetLoopIncrement(nvsFunc * shader)
+{
+ return ((shader->inst[2] & NV40_FP_OP_LOOP_INCR_MASK)
+ >> NV40_FP_OP_LOOP_INCR_SHIFT);
+}
+
+void
+NV40FPInitShaderFuncs(nvsFunc * shader)
+{
+ /* Inherit NV30 FP code, it's mostly the same */
+ NV30FPInitShaderFuncs(shader);
+
+ /* Kill off opcodes seen on NV30, but not seen on NV40 - need to find
+ * out if these actually work or not.
+ *
+ * update: either LIT/RSQ don't work on nv40, or I generate bad code for
+ * them. haven't tested the others yet
+ */
+ MOD_OPCODE(NVFP_TX_AOP, 0x1B, NVS_OP_UNKNOWN, -1, -1, -1); /* NV30 RSQ */
+ MOD_OPCODE(NVFP_TX_AOP, 0x1E, NVS_OP_UNKNOWN, -1, -1, -1); /* NV30 LIT */
+ MOD_OPCODE(NVFP_TX_AOP, 0x1F, NVS_OP_UNKNOWN, -1, -1, -1); /* NV30 LRP */
+ MOD_OPCODE(NVFP_TX_AOP, 0x26, NVS_OP_UNKNOWN, -1, -1, -1); /* NV30 POW */
+ MOD_OPCODE(NVFP_TX_AOP, 0x36, NVS_OP_UNKNOWN, -1, -1, -1); /* NV30 RFL */
+
+ /* Extra opcodes supported on NV40 */
+ MOD_OPCODE(NVFP_TX_AOP, NV40_FP_OP_OPCODE_DIV , NVS_OP_DIV , 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV40_FP_OP_OPCODE_DP2A , NVS_OP_DP2A, 0, 1, 2);
+ MOD_OPCODE(NVFP_TX_AOP, NV40_FP_OP_OPCODE_TXL , NVS_OP_TXL , 0, -1, -1);
+
+ MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_BRK , NVS_OP_BRK , -1, -1, -1);
+ MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_CAL , NVS_OP_CAL , -1, -1, -1);
+ MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_IF , NVS_OP_IF , -1, -1, -1);
+ MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_LOOP, NVS_OP_LOOP, -1, -1, -1);
+ 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;
+
+ /* branching */
+ shader->GetOPTXRec = NV40FPGetOPTXRec;
+ shader->GetBranch = NV40FPGetBranch;
+ shader->GetBranchElse = NV40FPGetBranchElse;
+ shader->GetBranchEnd = NV40FPGetBranchEnd;
+ shader->GetLoopCount = NV40FPGetLoopCount;
+ shader->GetLoopInitial = NV40FPGetLoopInitial;
+ shader->GetLoopIncrement = NV40FPGetLoopIncrement;
+ shader->SetBranchTarget = NV40FPSetBranchTarget;
+ shader->SetBranchElse = NV40FPSetBranchElse;
+ shader->SetBranchEnd = NV40FPSetBranchEnd;
+ shader->SetLoopParams = NV40FPSetLoopParams;
+}
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nv40_shader.h b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv40_shader.h
new file mode 100644
index 000000000..584f4c23e
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv40_shader.h
@@ -0,0 +1,467 @@
+#ifndef __NV40_SHADER_H__
+#define __NV40_SHADER_H__
+
+/* Vertex programs instruction set
+ *
+ * The NV40 instruction set is very similar to NV30. Most fields are in
+ * a slightly different position in the instruction however.
+ *
+ * Merged instructions
+ * In some cases it is possible to put two instructions into one opcode
+ * slot. The rules for when this is OK is not entirely clear to me yet.
+ *
+ * There are separate writemasks and dest temp register fields for each
+ * grouping of instructions. There is however only one field with the
+ * ID of a result register. Writing to temp/result regs is selected by
+ * setting VEC_RESULT/SCA_RESULT.
+ *
+ * Temporary registers
+ * The source/dest temp register fields have been extended by 1 bit, to
+ * give a total of 32 temporary registers.
+ *
+ * Relative Addressing
+ * NV40 can use an address register to index into vertex attribute regs.
+ * This is done by putting the offset value into INPUT_SRC and setting
+ * the INDEX_INPUT flag.
+ *
+ * Conditional execution (see NV_vertex_program{2,3} for details)
+ * There is a second condition code register on NV40, it's use is enabled
+ * by setting the COND_REG_SELECT_1 flag.
+ *
+ * Texture lookup
+ * TODO
+ */
+
+/* ---- OPCODE BITS 127:96 / data DWORD 0 --- */
+#define NV40_VP_INST_VEC_RESULT (1 << 30)
+/* uncertain.. */
+#define NV40_VP_INST_COND_UPDATE_ENABLE ((1 << 14)|1<<29)
+/* use address reg as index into attribs */
+#define NV40_VP_INST_INDEX_INPUT (1 << 27)
+#define NV40_VP_INST_COND_REG_SELECT_1 (1 << 25)
+#define NV40_VP_INST_ADDR_REG_SELECT_1 (1 << 24)
+#define NV40_VP_INST_SRC2_ABS (1 << 23)
+#define NV40_VP_INST_SRC1_ABS (1 << 22)
+#define NV40_VP_INST_SRC0_ABS (1 << 21)
+#define NV40_VP_INST_VEC_DEST_TEMP_SHIFT 15
+#define NV40_VP_INST_VEC_DEST_TEMP_MASK (0x1F << 15)
+#define NV40_VP_INST_COND_TEST_ENABLE (1 << 13)
+#define NV40_VP_INST_COND_SHIFT 10
+#define NV40_VP_INST_COND_MASK (0x7 << 10)
+# define NV40_VP_INST_COND_FL 0
+# define NV40_VP_INST_COND_LT 1
+# define NV40_VP_INST_COND_EQ 2
+# define NV40_VP_INST_COND_LE 3
+# define NV40_VP_INST_COND_GT 4
+# define NV40_VP_INST_COND_NE 5
+# define NV40_VP_INST_COND_GE 6
+# define NV40_VP_INST_COND_TR 7
+#define NV40_VP_INST_COND_SWZ_X_SHIFT 8
+#define NV40_VP_INST_COND_SWZ_X_MASK (3 << 8)
+#define NV40_VP_INST_COND_SWZ_Y_SHIFT 6
+#define NV40_VP_INST_COND_SWZ_Y_MASK (3 << 6)
+#define NV40_VP_INST_COND_SWZ_Z_SHIFT 4
+#define NV40_VP_INST_COND_SWZ_Z_MASK (3 << 4)
+#define NV40_VP_INST_COND_SWZ_W_SHIFT 2
+#define NV40_VP_INST_COND_SWZ_W_MASK (3 << 2)
+#define NV40_VP_INST_COND_SWZ_ALL_SHIFT 2
+#define NV40_VP_INST_COND_SWZ_ALL_MASK (0xFF << 2)
+#define NV40_VP_INST_ADDR_SWZ_SHIFT 0
+#define NV40_VP_INST_ADDR_SWZ_MASK (0x03 << 0)
+#define NV40_VP_INST0_KNOWN ( \
+ NV40_VP_INST_INDEX_INPUT | \
+ NV40_VP_INST_COND_REG_SELECT_1 | \
+ NV40_VP_INST_ADDR_REG_SELECT_1 | \
+ NV40_VP_INST_SRC2_ABS | \
+ NV40_VP_INST_SRC1_ABS | \
+ NV40_VP_INST_SRC0_ABS | \
+ NV40_VP_INST_VEC_DEST_TEMP_MASK | \
+ NV40_VP_INST_COND_TEST_ENABLE | \
+ NV40_VP_INST_COND_MASK | \
+ NV40_VP_INST_COND_SWZ_ALL_MASK | \
+ NV40_VP_INST_ADDR_SWZ_MASK)
+
+/* ---- OPCODE BITS 95:64 / data DWORD 1 --- */
+#define NV40_VP_INST_VEC_OPCODE_SHIFT 22
+#define NV40_VP_INST_VEC_OPCODE_MASK (0x1F << 22)
+# define NV40_VP_INST_OP_NOP 0x00
+# define NV40_VP_INST_OP_MOV 0x01
+# define NV40_VP_INST_OP_MUL 0x02
+# define NV40_VP_INST_OP_ADD 0x03
+# define NV40_VP_INST_OP_MAD 0x04
+# define NV40_VP_INST_OP_DP3 0x05
+# define NV40_VP_INST_OP_DP4 0x07
+# define NV40_VP_INST_OP_DPH 0x06
+# define NV40_VP_INST_OP_DST 0x08
+# define NV40_VP_INST_OP_MIN 0x09
+# define NV40_VP_INST_OP_MAX 0x0A
+# define NV40_VP_INST_OP_SLT 0x0B
+# define NV40_VP_INST_OP_SGE 0x0C
+# define NV40_VP_INST_OP_ARL 0x0D
+# define NV40_VP_INST_OP_FRC 0x0E
+# define NV40_VP_INST_OP_FLR 0x0F
+# define NV40_VP_INST_OP_SEQ 0x10
+# define NV40_VP_INST_OP_SFL 0x11
+# define NV40_VP_INST_OP_SGT 0x12
+# define NV40_VP_INST_OP_SLE 0x13
+# define NV40_VP_INST_OP_SNE 0x14
+# define NV40_VP_INST_OP_STR 0x15
+# define NV40_VP_INST_OP_SSG 0x16
+# define NV40_VP_INST_OP_ARR 0x17
+# define NV40_VP_INST_OP_ARA 0x18
+# define NV40_VP_INST_OP_TXWHAT 0x19
+#define NV40_VP_INST_SCA_OPCODE_SHIFT 27
+#define NV40_VP_INST_SCA_OPCODE_MASK (0x1F << 27)
+# define NV40_VP_INST_OP_RCP 0x02
+# define NV40_VP_INST_OP_RCC 0x03
+# define NV40_VP_INST_OP_RSQ 0x04
+# define NV40_VP_INST_OP_EXP 0x05
+# define NV40_VP_INST_OP_LOG 0x06
+# define NV40_VP_INST_OP_LIT 0x07
+# define NV40_VP_INST_OP_BRA 0x09
+# define NV40_VP_INST_OP_CAL 0x0B
+# define NV40_VP_INST_OP_RET 0x0C
+# define NV40_VP_INST_OP_LG2 0x0D
+# define NV40_VP_INST_OP_EX2 0x0E
+# define NV40_VP_INST_OP_SIN 0x0F
+# define NV40_VP_INST_OP_COS 0x10
+# define NV40_VP_INST_OP_PUSHA 0x13
+# define NV40_VP_INST_OP_POPA 0x14
+#define NV40_VP_INST_CONST_SRC_SHIFT 12
+#define NV40_VP_INST_CONST_SRC_MASK (0xFF << 12)
+#define NV40_VP_INST_INPUT_SRC_SHIFT 8
+#define NV40_VP_INST_INPUT_SRC_MASK (0x0F << 8)
+# define NV40_VP_INST_IN_POS 0
+# define NV40_VP_INST_IN_WEIGHT 1
+# define NV40_VP_INST_IN_NORMAL 2
+# define NV40_VP_INST_IN_COL0 3
+# define NV40_VP_INST_IN_COL1 4
+# define NV40_VP_INST_IN_FOGC 5
+# define NV40_VP_INST_IN_TC0 8
+# define NV40_VP_INST_IN_TC(n) (8+n)
+#define NV40_VP_INST_SRC0H_SHIFT 0
+#define NV40_VP_INST_SRC0H_MASK (0xFF << 0)
+#define NV40_VP_INST1_KNOWN ( \
+ NV40_VP_INST_VEC_OPCODE_MASK | \
+ NV40_VP_INST_SCA_OPCODE_MASK | \
+ NV40_VP_INST_CONST_SRC_MASK | \
+ NV40_VP_INST_INPUT_SRC_MASK | \
+ NV40_VP_INST_SRC0H_MASK \
+ )
+
+/* ---- OPCODE BITS 63:32 / data DWORD 2 --- */
+#define NV40_VP_INST_SRC0L_SHIFT 23
+#define NV40_VP_INST_SRC0L_MASK (0x1FF << 23)
+#define NV40_VP_INST_SRC1_SHIFT 6
+#define NV40_VP_INST_SRC1_MASK (0x1FFFF << 6)
+#define NV40_VP_INST_SRC2H_SHIFT 0
+#define NV40_VP_INST_SRC2H_MASK (0x3F << 0)
+#define NV40_VP_INST_IADDRH_SHIFT 0
+#define NV40_VP_INST_IADDRH_MASK (0x1F << 0)
+
+/* ---- OPCODE BITS 31:0 / data DWORD 3 --- */
+#define NV40_VP_INST_IADDRL_SHIFT 29
+#define NV40_VP_INST_IADDRL_MASK (7 << 29)
+#define NV40_VP_INST_SRC2L_SHIFT 21
+#define NV40_VP_INST_SRC2L_MASK (0x7FF << 21)
+#define NV40_VP_INST_SCA_WRITEMASK_SHIFT 17
+#define NV40_VP_INST_SCA_WRITEMASK_MASK (0xF << 17)
+# define NV40_VP_INST_SCA_WRITEMASK_X (1 << 20)
+# define NV40_VP_INST_SCA_WRITEMASK_Y (1 << 19)
+# define NV40_VP_INST_SCA_WRITEMASK_Z (1 << 18)
+# define NV40_VP_INST_SCA_WRITEMASK_W (1 << 17)
+#define NV40_VP_INST_VEC_WRITEMASK_SHIFT 13
+#define NV40_VP_INST_VEC_WRITEMASK_MASK (0xF << 13)
+# define NV40_VP_INST_VEC_WRITEMASK_X (1 << 16)
+# define NV40_VP_INST_VEC_WRITEMASK_Y (1 << 15)
+# define NV40_VP_INST_VEC_WRITEMASK_Z (1 << 14)
+# define NV40_VP_INST_VEC_WRITEMASK_W (1 << 13)
+#define NV40_VP_INST_SCA_RESULT (1 << 12)
+#define NV40_VP_INST_SCA_DEST_TEMP_SHIFT 7
+#define NV40_VP_INST_SCA_DEST_TEMP_MASK (0x1F << 7)
+#define NV40_VP_INST_DEST_SHIFT 2
+#define NV40_VP_INST_DEST_MASK (31 << 2)
+# define NV40_VP_INST_DEST_POS 0
+# define NV40_VP_INST_DEST_COL0 1
+# define NV40_VP_INST_DEST_COL1 2
+# define NV40_VP_INST_DEST_BFC0 3
+# define NV40_VP_INST_DEST_BFC1 4
+# define NV40_VP_INST_DEST_FOGC 5
+# define NV40_VP_INST_DEST_PSZ 6
+# define NV40_VP_INST_DEST_TC0 7
+# define NV40_VP_INST_DEST_TC(n) (7+n)
+# define NV40_VP_INST_DEST_TEMP 0x1F
+#define NV40_VP_INST_INDEX_CONST (1 << 1)
+#define NV40_VP_INST_LAST (1 << 0)
+#define NV40_VP_INST3_KNOWN ( \
+ NV40_VP_INST_SRC2L_MASK |\
+ NV40_VP_INST_SCA_WRITEMASK_MASK |\
+ NV40_VP_INST_VEC_WRITEMASK_MASK |\
+ NV40_VP_INST_SCA_DEST_TEMP_MASK |\
+ NV40_VP_INST_DEST_MASK |\
+ NV40_VP_INST_INDEX_CONST)
+
+/* Useful to split the source selection regs into their pieces */
+#define NV40_VP_SRC0_HIGH_SHIFT 9
+#define NV40_VP_SRC0_HIGH_MASK 0x0001FE00
+#define NV40_VP_SRC0_LOW_MASK 0x000001FF
+#define NV40_VP_SRC2_HIGH_SHIFT 11
+#define NV40_VP_SRC2_HIGH_MASK 0x0001F800
+#define NV40_VP_SRC2_LOW_MASK 0x000007FF
+
+/* Source selection - these are the bits you fill NV40_VP_INST_SRCn with */
+#define NV40_VP_SRC_NEGATE (1 << 16)
+#define NV40_VP_SRC_SWZ_X_SHIFT 14
+#define NV40_VP_SRC_SWZ_X_MASK (3 << 14)
+#define NV40_VP_SRC_SWZ_Y_SHIFT 12
+#define NV40_VP_SRC_SWZ_Y_MASK (3 << 12)
+#define NV40_VP_SRC_SWZ_Z_SHIFT 10
+#define NV40_VP_SRC_SWZ_Z_MASK (3 << 10)
+#define NV40_VP_SRC_SWZ_W_SHIFT 8
+#define NV40_VP_SRC_SWZ_W_MASK (3 << 8)
+#define NV40_VP_SRC_SWZ_ALL_SHIFT 8
+#define NV40_VP_SRC_SWZ_ALL_MASK (0xFF << 8)
+#define NV40_VP_SRC_TEMP_SRC_SHIFT 2
+#define NV40_VP_SRC_TEMP_SRC_MASK (0x1F << 2)
+#define NV40_VP_SRC_REG_TYPE_SHIFT 0
+#define NV40_VP_SRC_REG_TYPE_MASK (3 << 0)
+# define NV40_VP_SRC_REG_TYPE_UNK0 0
+# define NV40_VP_SRC_REG_TYPE_TEMP 1
+# define NV40_VP_SRC_REG_TYPE_INPUT 2
+# define NV40_VP_SRC_REG_TYPE_CONST 3
+
+
+/*
+ * Each fragment program opcode appears to be comprised of 4 32-bit values.
+ *
+ * 0 - Opcode, output reg/mask, ATTRIB source
+ * 1 - Source 0
+ * 2 - Source 1
+ * 3 - Source 2
+ *
+ * There appears to be no special difference between result regs and temp regs.
+ * result.color == R0.xyzw
+ * result.depth == R1.z
+ * When the fragprog contains instructions to write depth,
+ * NV30_TCL_PRIMITIVE_3D_UNK1D78=0 otherwise it is set to 1.
+ *
+ * Constants are inserted directly after the instruction that uses them.
+ *
+ * It appears that it's not possible to use two input registers in one
+ * instruction as the input sourcing is done in the instruction dword
+ * and not the source selection dwords. As such instructions such as:
+ *
+ * ADD result.color, fragment.color, fragment.texcoord[0];
+ *
+ * must be split into two MOV's and then an ADD (nvidia does this) but
+ * I'm not sure why it's not just one MOV and then source the second input
+ * in the ADD instruction..
+ *
+ * Negation of the full source is done with NV30_FP_REG_NEGATE, arbitrary
+ * negation requires multiplication with a const.
+ *
+ * Arbitrary swizzling is supported with the exception of SWIZZLE_ZERO and
+ * SWIZZLE_ONE.
+ *
+ * The temp/result regs appear to be initialised to (0.0, 0.0, 0.0, 0.0) as
+ * SWIZZLE_ZERO is implemented simply by not writing to the relevant components
+ * of the destination.
+ *
+ * Looping
+ * Loops appear to be fairly expensive on NV40 at least, the proprietary
+ * driver goes to a lot of effort to avoid using the native looping
+ * instructions. If the total number of *executed* instructions between
+ * REP/ENDREP or LOOP/ENDLOOP is <=500, the driver will unroll the loop.
+ * The maximum loop count is 255.
+ *
+ * Conditional execution
+ * TODO
+ *
+ * Non-native instructions:
+ * LIT
+ * LRP - MAD+MAD
+ * SUB - ADD, negate second source
+ * RSQ - LG2 + EX2
+ * POW - LG2 + MUL + EX2
+ * SCS - COS + SIN
+ * XPD
+ * DP2 - MUL + ADD
+ * NRM
+ */
+
+//== Opcode / Destination selection ==
+#define NV40_FP_OP_PROGRAM_END (1 << 0)
+#define NV40_FP_OP_OUT_REG_SHIFT 1
+#define NV40_FP_OP_OUT_REG_MASK (31 << 1)
+/* Needs to be set when writing outputs to get expected result.. */
+#define NV40_FP_OP_UNK0_7 (1 << 7)
+#define NV40_FP_OP_COND_WRITE_ENABLE (1 << 8)
+#define NV40_FP_OP_OUTMASK_SHIFT 9
+#define NV40_FP_OP_OUTMASK_MASK (0xF << 9)
+# define NV40_FP_OP_OUT_X (1 << 9)
+# define NV40_FP_OP_OUT_Y (1 <<10)
+# define NV40_FP_OP_OUT_Z (1 <<11)
+# define NV40_FP_OP_OUT_W (1 <<12)
+/* Uncertain about these, especially the input_src values.. it's possible that
+ * they can be dynamically changed.
+ */
+#define NV40_FP_OP_INPUT_SRC_SHIFT 13
+#define NV40_FP_OP_INPUT_SRC_MASK (15 << 13)
+# define NV40_FP_OP_INPUT_SRC_POSITION 0x0
+# define NV40_FP_OP_INPUT_SRC_COL0 0x1
+# define NV40_FP_OP_INPUT_SRC_COL1 0x2
+# define NV40_FP_OP_INPUT_SRC_FOGC 0x3
+# define NV40_FP_OP_INPUT_SRC_TC0 0x4
+# define NV40_FP_OP_INPUT_SRC_TC(n) (0x4 + n)
+# define NV40_FP_OP_INPUT_SRC_FACING 0xE
+#define NV40_FP_OP_TEX_UNIT_SHIFT 17
+#define NV40_FP_OP_TEX_UNIT_MASK (0xF << 17)
+#define NV40_FP_OP_PRECISION_SHIFT 22
+#define NV40_FP_OP_PRECISION_MASK (3 << 22)
+# define NV40_FP_PRECISION_FP32 0
+# define NV40_FP_PRECISION_FP16 1
+# define NV40_FP_PRECISION_FX12 2
+#define NV40_FP_OP_OPCODE_SHIFT 24
+#define NV40_FP_OP_OPCODE_MASK (0x3F << 24)
+# define NV40_FP_OP_OPCODE_NOP 0x00
+# define NV40_FP_OP_OPCODE_MOV 0x01
+# define NV40_FP_OP_OPCODE_MUL 0x02
+# define NV40_FP_OP_OPCODE_ADD 0x03
+# define NV40_FP_OP_OPCODE_MAD 0x04
+# define NV40_FP_OP_OPCODE_DP3 0x05
+# define NV40_FP_OP_OPCODE_DP4 0x06
+# define NV40_FP_OP_OPCODE_DST 0x07
+# define NV40_FP_OP_OPCODE_MIN 0x08
+# define NV40_FP_OP_OPCODE_MAX 0x09
+# define NV40_FP_OP_OPCODE_SLT 0x0A
+# define NV40_FP_OP_OPCODE_SGE 0x0B
+# define NV40_FP_OP_OPCODE_SLE 0x0C
+# define NV40_FP_OP_OPCODE_SGT 0x0D
+# define NV40_FP_OP_OPCODE_SNE 0x0E
+# define NV40_FP_OP_OPCODE_SEQ 0x0F
+# define NV40_FP_OP_OPCODE_FRC 0x10
+# define NV40_FP_OP_OPCODE_FLR 0x11
+# define NV40_FP_OP_OPCODE_KIL 0x12
+# define NV40_FP_OP_OPCODE_PK4B 0x13
+# define NV40_FP_OP_OPCODE_UP4B 0x14
+/* DDX/DDY can only write to XY */
+# define NV40_FP_OP_OPCODE_DDX 0x15
+# define NV40_FP_OP_OPCODE_DDY 0x16
+# define NV40_FP_OP_OPCODE_TEX 0x17
+# define NV40_FP_OP_OPCODE_TXP 0x18
+# define NV40_FP_OP_OPCODE_TXD 0x19
+# define NV40_FP_OP_OPCODE_RCP 0x1A
+# define NV40_FP_OP_OPCODE_EX2 0x1C
+# define NV40_FP_OP_OPCODE_LG2 0x1D
+# define NV40_FP_OP_OPCODE_COS 0x22
+# define NV40_FP_OP_OPCODE_SIN 0x23
+# define NV40_FP_OP_OPCODE_PK2H 0x24
+# define NV40_FP_OP_OPCODE_UP2H 0x25
+# define NV40_FP_OP_OPCODE_PK4UB 0x27
+# define NV40_FP_OP_OPCODE_UP4UB 0x28
+# define NV40_FP_OP_OPCODE_PK2US 0x29
+# define NV40_FP_OP_OPCODE_UP2US 0x2A
+# define NV40_FP_OP_OPCODE_DP2A 0x2E
+# define NV40_FP_OP_OPCODE_TXL 0x2F
+# define NV40_FP_OP_OPCODE_TXB 0x31
+# define NV40_FP_OP_OPCODE_DIV 0x3A
+/* The use of these instructions appears to be indicated by bit 31 of DWORD 2.*/
+# define NV40_FP_OP_BRA_OPCODE_BRK 0x0
+# define NV40_FP_OP_BRA_OPCODE_CAL 0x1
+# define NV40_FP_OP_BRA_OPCODE_IF 0x2
+# define NV40_FP_OP_BRA_OPCODE_LOOP 0x3
+# define NV40_FP_OP_BRA_OPCODE_REP 0x4
+# define NV40_FP_OP_BRA_OPCODE_RET 0x5
+#define NV40_FP_OP_OUT_SAT (1 << 31)
+
+/* high order bits of SRC0 */
+#define NV40_FP_OP_OUT_ABS (1 << 29)
+#define NV40_FP_OP_COND_SWZ_W_SHIFT 27
+#define NV40_FP_OP_COND_SWZ_W_MASK (3 << 27)
+#define NV40_FP_OP_COND_SWZ_Z_SHIFT 25
+#define NV40_FP_OP_COND_SWZ_Z_MASK (3 << 25)
+#define NV40_FP_OP_COND_SWZ_Y_SHIFT 23
+#define NV40_FP_OP_COND_SWZ_Y_MASK (3 << 23)
+#define NV40_FP_OP_COND_SWZ_X_SHIFT 21
+#define NV40_FP_OP_COND_SWZ_X_MASK (3 << 21)
+#define NV40_FP_OP_COND_SWZ_ALL_SHIFT 21
+#define NV40_FP_OP_COND_SWZ_ALL_MASK (0xFF << 21)
+#define NV40_FP_OP_COND_SHIFT 18
+#define NV40_FP_OP_COND_MASK (0x07 << 18)
+# define NV40_FP_OP_COND_FL 0
+# define NV40_FP_OP_COND_LT 1
+# define NV40_FP_OP_COND_EQ 2
+# define NV40_FP_OP_COND_LE 3
+# define NV40_FP_OP_COND_GT 4
+# define NV40_FP_OP_COND_NE 5
+# define NV40_FP_OP_COND_GE 6
+# define NV40_FP_OP_COND_TR 7
+
+/* high order bits of SRC1 */
+#define NV40_FP_OP_OPCODE_IS_BRANCH (1<<31)
+#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
+#define NV40_FP_OP_LOOP_INCR_MASK (0xFF << 19)
+#define NV40_FP_OP_LOOP_INDEX_SHIFT 10
+#define NV40_FP_OP_LOOP_INDEX_MASK (0xFF << 10)
+#define NV40_FP_OP_LOOP_COUNT_SHIFT 2
+#define NV40_FP_OP_LOOP_COUNT_MASK (0xFF << 2)
+
+/* SRC1 IF */
+#define NV40_FP_OP_ELSE_ID_SHIFT 2
+#define NV40_FP_OP_ELSE_ID_MASK (0xFF << 2)
+
+/* SRC1 CAL */
+#define NV40_FP_OP_IADDR_SHIFT 2
+#define NV40_FP_OP_IADDR_MASK (0xFF << 2)
+
+/* SRC1 REP
+ * I have no idea why there are 3 count values here.. but they
+ * have always been filled with the same value in my tests so
+ * far..
+ */
+#define NV40_FP_OP_REP_COUNT1_SHIFT 2
+#define NV40_FP_OP_REP_COUNT1_MASK (0xFF << 2)
+#define NV40_FP_OP_REP_COUNT2_SHIFT 10
+#define NV40_FP_OP_REP_COUNT2_MASK (0xFF << 10)
+#define NV40_FP_OP_REP_COUNT3_SHIFT 19
+#define NV40_FP_OP_REP_COUNT3_MASK (0xFF << 19)
+
+/* SRC2 REP/IF */
+#define NV40_FP_OP_END_ID_SHIFT 2
+#define NV40_FP_OP_END_ID_MASK (0xFF << 2)
+
+// SRC2 high-order
+#define NV40_FP_OP_INDEX_INPUT (1 << 30)
+#define NV40_FP_OP_ADDR_INDEX_SHIFT 19
+#define NV40_FP_OP_ADDR_INDEX_MASK (0xF << 19)
+
+//== Register selection ==
+#define NV40_FP_REG_TYPE_SHIFT 0
+#define NV40_FP_REG_TYPE_MASK (3 << 0)
+# define NV40_FP_REG_TYPE_TEMP 0
+# define NV40_FP_REG_TYPE_INPUT 1
+# define NV40_FP_REG_TYPE_CONST 2
+#define NV40_FP_REG_SRC_SHIFT 2
+#define NV40_FP_REG_SRC_MASK (31 << 2)
+#define NV40_FP_REG_UNK_0 (1 << 8)
+#define NV40_FP_REG_SWZ_ALL_SHIFT 9
+#define NV40_FP_REG_SWZ_ALL_MASK (255 << 9)
+#define NV40_FP_REG_SWZ_X_SHIFT 9
+#define NV40_FP_REG_SWZ_X_MASK (3 << 9)
+#define NV40_FP_REG_SWZ_Y_SHIFT 11
+#define NV40_FP_REG_SWZ_Y_MASK (3 << 11)
+#define NV40_FP_REG_SWZ_Z_SHIFT 13
+#define NV40_FP_REG_SWZ_Z_MASK (3 << 13)
+#define NV40_FP_REG_SWZ_W_SHIFT 15
+#define NV40_FP_REG_SWZ_W_MASK (3 << 15)
+# define NV40_FP_SWIZZLE_X 0
+# define NV40_FP_SWIZZLE_Y 1
+# define NV40_FP_SWIZZLE_Z 2
+# define NV40_FP_SWIZZLE_W 3
+#define NV40_FP_REG_NEGATE (1 << 17)
+
+#endif
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nv40_vertprog.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv40_vertprog.c
new file mode 100644
index 000000000..d054140bc
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv40_vertprog.c
@@ -0,0 +1,778 @@
+#include "nouveau_shader.h"
+#include "nouveau_msg.h"
+#include "nv40_shader.h"
+
+/*****************************************************************************
+ * Assembly routines
+ */
+static int
+NV40VPSupportsOpcode(nvsFunc * shader, nvsOpcode op)
+{
+ if (shader->GetOPTXFromSOP(op, NULL))
+ return 1;
+ return 0;
+}
+
+static void
+NV40VPSetOpcode(nvsFunc *shader, unsigned int opcode, int slot)
+{
+ if (slot) {
+ shader->inst[1] &= ~NV40_VP_INST_SCA_OPCODE_MASK;
+ shader->inst[1] |= (opcode << NV40_VP_INST_SCA_OPCODE_SHIFT);
+ } else {
+ shader->inst[1] &= ~NV40_VP_INST_VEC_OPCODE_MASK;
+ shader->inst[1] |= (opcode << NV40_VP_INST_VEC_OPCODE_SHIFT);
+ }
+}
+
+static void
+NV40VPSetCCUpdate(nvsFunc *shader)
+{
+ shader->inst[0] |= NV40_VP_INST_COND_UPDATE_ENABLE;
+}
+
+static void
+NV40VPSetCondition(nvsFunc *shader, int on, nvsCond cond, int reg,
+ nvsSwzComp *swizzle)
+{
+ unsigned int hwcond;
+
+ if (on ) shader->inst[0] |= NV40_VP_INST_COND_TEST_ENABLE;
+ else shader->inst[0] &= ~NV40_VP_INST_COND_TEST_ENABLE;
+ if (reg) shader->inst[0] |= NV40_VP_INST_COND_REG_SELECT_1;
+ else shader->inst[0] &= ~NV40_VP_INST_COND_REG_SELECT_1;
+
+ switch (cond) {
+ case NVS_COND_TR: hwcond = NV40_VP_INST_COND_TR; break;
+ case NVS_COND_FL: hwcond = NV40_VP_INST_COND_FL; break;
+ case NVS_COND_LT: hwcond = NV40_VP_INST_COND_LT; break;
+ case NVS_COND_GT: hwcond = NV40_VP_INST_COND_GT; break;
+ case NVS_COND_NE: hwcond = NV40_VP_INST_COND_NE; break;
+ case NVS_COND_EQ: hwcond = NV40_VP_INST_COND_EQ; break;
+ case NVS_COND_GE: hwcond = NV40_VP_INST_COND_GE; break;
+ case NVS_COND_LE: hwcond = NV40_VP_INST_COND_LE; break;
+ default:
+ WARN_ONCE("unknown vp cond %d\n", cond);
+ hwcond = NV40_VP_INST_COND_TR;
+ break;
+ }
+ shader->inst[0] &= ~NV40_VP_INST_COND_MASK;
+ shader->inst[0] |= (hwcond << NV40_VP_INST_COND_SHIFT);
+
+ shader->inst[0] &= ~NV40_VP_INST_COND_SWZ_ALL_MASK;
+ shader->inst[0] |= (swizzle[NVS_SWZ_X] << NV40_VP_INST_COND_SWZ_X_SHIFT);
+ shader->inst[0] |= (swizzle[NVS_SWZ_Y] << NV40_VP_INST_COND_SWZ_Y_SHIFT);
+ shader->inst[0] |= (swizzle[NVS_SWZ_Z] << NV40_VP_INST_COND_SWZ_Z_SHIFT);
+ 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;
+ unsigned int *clip_en = &shader->card_priv->NV30VP.clip_enables;
+
+ *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;
+ (*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:
+ (*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;
+ (*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;
+ 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)
+{
+ unsigned int hwmask = 0;
+
+ if (mask & SMASK_X) hwmask |= (1 << 3);
+ if (mask & SMASK_Y) hwmask |= (1 << 2);
+ if (mask & SMASK_Z) hwmask |= (1 << 1);
+ if (mask & SMASK_W) hwmask |= (1 << 0);
+
+ if (dest->file == NVS_FILE_RESULT) {
+ unsigned int valid_mask;
+ int hwidx;
+
+ 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);
+
+ if (slot) shader->inst[3] |= NV40_VP_INST_SCA_RESULT;
+ else shader->inst[0] |= NV40_VP_INST_VEC_RESULT;
+ } else {
+ /* NVS_FILE_TEMP || NVS_FILE_ADDRESS */
+ if (slot) {
+ shader->inst[3] &= ~NV40_VP_INST_SCA_RESULT;
+ shader->inst[3] &= ~NV40_VP_INST_SCA_DEST_TEMP_MASK;
+ shader->inst[3] |= (dest->index << NV40_VP_INST_SCA_DEST_TEMP_SHIFT);
+ } else {
+ shader->inst[0] &= ~NV40_VP_INST_VEC_RESULT;
+ shader->inst[0] &= ~(NV40_VP_INST_VEC_DEST_TEMP_MASK | (1<<20));
+ shader->inst[0] |= (dest->index << NV40_VP_INST_VEC_DEST_TEMP_SHIFT);
+ }
+ }
+
+ if (slot) {
+ shader->inst[3] &= ~NV40_VP_INST_SCA_WRITEMASK_MASK;
+ shader->inst[3] |= (hwmask << NV40_VP_INST_SCA_WRITEMASK_SHIFT);
+ } else {
+ shader->inst[3] &= ~NV40_VP_INST_VEC_WRITEMASK_MASK;
+ shader->inst[3] |= (hwmask << NV40_VP_INST_VEC_WRITEMASK_SHIFT);
+ }
+}
+
+static void
+NV40VPInsertSource(nvsFunc *shader, unsigned int hw, int pos)
+{
+ switch (pos) {
+ case 0:
+ shader->inst[1] &= ~NV40_VP_INST_SRC0H_MASK;
+ shader->inst[2] &= ~NV40_VP_INST_SRC0L_MASK;
+ shader->inst[1] |= ((hw & NV40_VP_SRC0_HIGH_MASK) >>
+ NV40_VP_SRC0_HIGH_SHIFT)
+ << NV40_VP_INST_SRC0H_SHIFT;
+ shader->inst[2] |= (hw & NV40_VP_SRC0_LOW_MASK)
+ << NV40_VP_INST_SRC0L_SHIFT;
+ break;
+ case 1:
+ shader->inst[2] &= ~NV40_VP_INST_SRC1_MASK;
+ shader->inst[2] |= hw
+ << NV40_VP_INST_SRC1_SHIFT;
+ break;
+ case 2:
+ shader->inst[2] &= ~NV40_VP_INST_SRC2H_MASK;
+ shader->inst[3] &= ~NV40_VP_INST_SRC2L_MASK;
+ shader->inst[2] |= ((hw & NV40_VP_SRC2_HIGH_MASK) >>
+ NV40_VP_SRC2_HIGH_SHIFT)
+ << NV40_VP_INST_SRC2H_SHIFT;
+ shader->inst[3] |= (hw & NV40_VP_SRC2_LOW_MASK)
+ << NV40_VP_INST_SRC2L_SHIFT;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+}
+
+static void
+NV40VPSetSource(nvsFunc *shader, nvsRegister * src, int pos)
+{
+ unsigned int hw = 0;
+
+ switch (src->file) {
+ case NVS_FILE_ADDRESS:
+ break;
+ case NVS_FILE_ATTRIB:
+ hw |= (NV40_VP_SRC_REG_TYPE_INPUT << NV40_VP_SRC_REG_TYPE_SHIFT);
+
+ 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)
+ shader->inst[0] |= NV40_VP_INST_ADDR_REG_SELECT_1;
+ else
+ shader->inst[0] &= ~NV40_VP_INST_ADDR_REG_SELECT_1;
+ shader->inst[0] &= ~NV40_VP_INST_ADDR_SWZ_SHIFT;
+ shader->inst[0] |= (src->addr_comp << NV40_VP_INST_ADDR_SWZ_SHIFT);
+ } else
+ shader->inst[0] &= ~NV40_VP_INST_INDEX_INPUT;
+ break;
+ case NVS_FILE_CONST:
+ hw |= (NV40_VP_SRC_REG_TYPE_CONST << NV40_VP_SRC_REG_TYPE_SHIFT);
+
+ shader->inst[1] &= ~NV40_VP_INST_CONST_SRC_MASK;
+ shader->inst[1] |= (src->index << NV40_VP_INST_CONST_SRC_SHIFT);
+ if (src->indexed) {
+ shader->inst[3] |= NV40_VP_INST_INDEX_CONST;
+ if (src->addr_reg)
+ shader->inst[0] |= NV40_VP_INST_ADDR_REG_SELECT_1;
+ else
+ shader->inst[0] &= ~NV40_VP_INST_ADDR_REG_SELECT_1;
+ shader->inst[0] &= ~NV40_VP_INST_ADDR_SWZ_MASK;
+ shader->inst[0] |= (src->addr_comp << NV40_VP_INST_ADDR_SWZ_SHIFT);
+ } else
+ shader->inst[3] &= ~NV40_VP_INST_INDEX_CONST;
+ break;
+ case NVS_FILE_TEMP:
+ hw |= (NV40_VP_SRC_REG_TYPE_TEMP << NV40_VP_SRC_REG_TYPE_SHIFT);
+ hw |= (src->index << NV40_VP_SRC_TEMP_SRC_SHIFT);
+ break;
+ default:
+ fprintf(stderr, "unknown source file %d\n", src->file);
+ assert(0);
+ break;
+ }
+
+ if (src->file != NVS_FILE_ADDRESS) {
+ if (src->negate)
+ hw |= NV40_VP_SRC_NEGATE;
+ if (src->abs)
+ shader->inst[0] |= (1 << (21 + pos));
+ else
+ shader->inst[0] &= ~(1 << (21 + pos));
+ hw |= (src->swizzle[0] << NV40_VP_SRC_SWZ_X_SHIFT);
+ hw |= (src->swizzle[1] << NV40_VP_SRC_SWZ_Y_SHIFT);
+ hw |= (src->swizzle[2] << NV40_VP_SRC_SWZ_Z_SHIFT);
+ hw |= (src->swizzle[3] << NV40_VP_SRC_SWZ_W_SHIFT);
+
+ NV40VPInsertSource(shader, hw, 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)
+{
+ unsigned int hwsrc = 0;
+
+ shader->inst[0] = /*NV40_VP_INST_VEC_RESULT | */
+ NV40_VP_INST_VEC_DEST_TEMP_MASK | (1<<20);
+ shader->inst[1] = 0;
+ shader->inst[2] = 0;
+ shader->inst[3] = NV40_VP_INST_SCA_RESULT |
+ NV40_VP_INST_SCA_DEST_TEMP_MASK |
+ NV40_VP_INST_DEST_MASK;
+
+ hwsrc = (NV40_VP_SRC_REG_TYPE_INPUT << NV40_VP_SRC_REG_TYPE_SHIFT) |
+ (NVS_SWZ_X << NV40_VP_SRC_SWZ_X_SHIFT) |
+ (NVS_SWZ_Y << NV40_VP_SRC_SWZ_Y_SHIFT) |
+ (NVS_SWZ_Z << NV40_VP_SRC_SWZ_Z_SHIFT) |
+ (NVS_SWZ_W << NV40_VP_SRC_SWZ_W_SHIFT);
+ NV40VPInsertSource(shader, hwsrc, 0);
+ NV40VPInsertSource(shader, hwsrc, 1);
+ NV40VPInsertSource(shader, hwsrc, 2);
+}
+
+static void
+NV40VPSetLastInst(nvsFunc *shader)
+{
+ shader->inst[3] |= 1;
+}
+
+/*****************************************************************************
+ * Disassembly routines
+ */
+static int
+NV40VPHasMergedInst(nvsFunc * shader)
+{
+ if (shader->GetOpcodeHW(shader, 0) != NV40_VP_INST_OP_NOP &&
+ shader->GetOpcodeHW(shader, 1) != NV40_VP_INST_OP_NOP)
+ return 1;
+ return 0;
+}
+
+static unsigned int
+NV40VPGetOpcodeHW(nvsFunc * shader, int slot)
+{
+ int op;
+
+ if (slot)
+ op = (shader->inst[1] & NV40_VP_INST_SCA_OPCODE_MASK)
+ >> NV40_VP_INST_SCA_OPCODE_SHIFT;
+ else
+ op = (shader->inst[1] & NV40_VP_INST_VEC_OPCODE_MASK)
+ >> NV40_VP_INST_VEC_OPCODE_SHIFT;
+
+ return op;
+}
+
+static nvsRegFile
+NV40VPGetDestFile(nvsFunc * shader, int merged)
+{
+ nvsOpcode op;
+
+ op = shader->GetOpcode(shader, merged);
+ switch (op) {
+ case NVS_OP_ARL:
+ case NVS_OP_ARR:
+ case NVS_OP_ARA:
+ case NVS_OP_POPA:
+ return NVS_FILE_ADDRESS;
+ default:
+ if (shader->GetOpcodeSlot(shader, merged)) {
+ if (shader->inst[3] & NV40_VP_INST_SCA_RESULT)
+ return NVS_FILE_RESULT;
+ }
+ else {
+ if (shader->inst[0] & NV40_VP_INST_VEC_RESULT)
+ return NVS_FILE_RESULT;
+ }
+ return NVS_FILE_TEMP;
+ }
+
+}
+
+static unsigned int
+NV40VPGetDestID(nvsFunc * shader, int merged)
+{
+ int id;
+
+ switch (shader->GetDestFile(shader, merged)) {
+ case NVS_FILE_RESULT:
+ id = ((shader->inst[3] & NV40_VP_INST_DEST_MASK)
+ >> NV40_VP_INST_DEST_SHIFT);
+ switch (id) {
+ case NV40_VP_INST_DEST_POS : return NVS_FR_POSITION;
+ case NV40_VP_INST_DEST_COL0: return NVS_FR_COL0;
+ case NV40_VP_INST_DEST_COL1: return NVS_FR_COL1;
+ case NV40_VP_INST_DEST_BFC0: return NVS_FR_BFC0;
+ case NV40_VP_INST_DEST_BFC1: return NVS_FR_BFC1;
+ case NV40_VP_INST_DEST_FOGC: {
+ int mask = shader->GetDestMask(shader, merged);
+ switch (mask) {
+ case SMASK_X: return NVS_FR_FOGCOORD;
+ case SMASK_Y: return NVS_FR_CLIP0;
+ case SMASK_Z: return NVS_FR_CLIP1;
+ case SMASK_W: return NVS_FR_CLIP2;
+ default:
+ printf("more than 1 mask component set in FOGC writemask!\n");
+ return NVS_FR_UNKNOWN;
+ }
+ }
+ case NV40_VP_INST_DEST_PSZ:
+ {
+ int mask = shader->GetDestMask(shader, merged);
+ switch (mask) {
+ case SMASK_X: return NVS_FR_POINTSZ;
+ case SMASK_Y: return NVS_FR_CLIP3;
+ case SMASK_Z: return NVS_FR_CLIP4;
+ case SMASK_W: return NVS_FR_CLIP5;
+ default:
+ printf("more than 1 mask component set in PSZ writemask!\n");
+ return NVS_FR_UNKNOWN;
+ }
+ }
+ case NV40_VP_INST_DEST_TC(0): return NVS_FR_TEXCOORD0;
+ case NV40_VP_INST_DEST_TC(1): return NVS_FR_TEXCOORD1;
+ case NV40_VP_INST_DEST_TC(2): return NVS_FR_TEXCOORD2;
+ case NV40_VP_INST_DEST_TC(3): return NVS_FR_TEXCOORD3;
+ case NV40_VP_INST_DEST_TC(4): return NVS_FR_TEXCOORD4;
+ case NV40_VP_INST_DEST_TC(5): return NVS_FR_TEXCOORD5;
+ case NV40_VP_INST_DEST_TC(6): return NVS_FR_TEXCOORD6;
+ case NV40_VP_INST_DEST_TC(7): return NVS_FR_TEXCOORD7;
+ default:
+ return -1;
+ }
+ case NVS_FILE_ADDRESS:
+ /* Instructions that write address regs are encoded as if
+ * they would write temps.
+ */
+ case NVS_FILE_TEMP:
+ if (shader->GetOpcodeSlot(shader, merged))
+ id = ((shader->inst[3] & NV40_VP_INST_SCA_DEST_TEMP_MASK)
+ >> NV40_VP_INST_SCA_DEST_TEMP_SHIFT);
+ else
+ id = ((shader->inst[0] & NV40_VP_INST_VEC_DEST_TEMP_MASK)
+ >> NV40_VP_INST_VEC_DEST_TEMP_SHIFT);
+ return id;
+ default:
+ return -1;
+ }
+}
+
+static unsigned int
+NV40VPGetDestMask(nvsFunc * shader, int merged)
+{
+ unsigned int mask = 0;
+
+ if (shader->GetOpcodeSlot(shader, merged)) {
+ if (shader->inst[3] & NV40_VP_INST_SCA_WRITEMASK_X) mask |= SMASK_X;
+ if (shader->inst[3] & NV40_VP_INST_SCA_WRITEMASK_Y) mask |= SMASK_Y;
+ if (shader->inst[3] & NV40_VP_INST_SCA_WRITEMASK_Z) mask |= SMASK_Z;
+ if (shader->inst[3] & NV40_VP_INST_SCA_WRITEMASK_W) mask |= SMASK_W;
+ } else {
+ if (shader->inst[3] & NV40_VP_INST_VEC_WRITEMASK_X) mask |= SMASK_X;
+ if (shader->inst[3] & NV40_VP_INST_VEC_WRITEMASK_Y) mask |= SMASK_Y;
+ if (shader->inst[3] & NV40_VP_INST_VEC_WRITEMASK_Z) mask |= SMASK_Z;
+ if (shader->inst[3] & NV40_VP_INST_VEC_WRITEMASK_W) mask |= SMASK_W;
+ }
+
+ return mask;
+}
+
+static unsigned int
+NV40VPGetSourceHW(nvsFunc * shader, int merged, int pos)
+{
+ struct _op_xlat *opr;
+ unsigned int src;
+
+ opr = shader->GetOPTXRec(shader, merged);
+ if (!opr)
+ return -1;
+
+ switch (opr->srcpos[pos]) {
+ case 0:
+ src = ((shader->inst[1] & NV40_VP_INST_SRC0H_MASK)
+ >> NV40_VP_INST_SRC0H_SHIFT)
+ << NV40_VP_SRC0_HIGH_SHIFT;
+ src |= ((shader->inst[2] & NV40_VP_INST_SRC0L_MASK)
+ >> NV40_VP_INST_SRC0L_SHIFT);
+ break;
+ case 1:
+ src = ((shader->inst[2] & NV40_VP_INST_SRC1_MASK)
+ >> NV40_VP_INST_SRC1_SHIFT);
+ break;
+ case 2:
+ src = ((shader->inst[2] & NV40_VP_INST_SRC2H_MASK)
+ >> NV40_VP_INST_SRC2H_SHIFT)
+ << NV40_VP_SRC2_HIGH_SHIFT;
+ src |= ((shader->inst[3] & NV40_VP_INST_SRC2L_MASK)
+ >> NV40_VP_INST_SRC2L_SHIFT);
+ break;
+ default:
+ src = -1;
+ }
+
+ return src;
+}
+
+static nvsRegFile
+NV40VPGetSourceFile(nvsFunc * shader, int merged, int pos)
+{
+ unsigned int src;
+ struct _op_xlat *opr;
+ int file;
+
+ opr = shader->GetOPTXRec(shader, merged);
+ if (!opr || opr->srcpos[pos] == -1)
+ return -1;
+
+ switch (opr->srcpos[pos]) {
+ case SPOS_ADDRESS: return NVS_FILE_ADDRESS;
+ default:
+ src = shader->GetSourceHW(shader, merged, pos);
+ file = (src & NV40_VP_SRC_REG_TYPE_MASK) >> NV40_VP_SRC_REG_TYPE_SHIFT;
+
+ switch (file) {
+ case NV40_VP_SRC_REG_TYPE_TEMP : return NVS_FILE_TEMP;
+ case NV40_VP_SRC_REG_TYPE_INPUT: return NVS_FILE_ATTRIB;
+ case NV40_VP_SRC_REG_TYPE_CONST: return NVS_FILE_CONST;
+ default:
+ return NVS_FILE_UNKNOWN;
+ }
+ }
+}
+
+static int
+NV40VPGetSourceID(nvsFunc * shader, int merged, int pos)
+{
+ switch (shader->GetSourceFile(shader, merged, pos)) {
+ case NVS_FILE_ATTRIB:
+ switch ((shader->inst[1] & NV40_VP_INST_INPUT_SRC_MASK)
+ >> NV40_VP_INST_INPUT_SRC_SHIFT) {
+ case NV40_VP_INST_IN_POS: return NVS_FR_POSITION;
+ case NV40_VP_INST_IN_WEIGHT: return NVS_FR_WEIGHT;
+ case NV40_VP_INST_IN_NORMAL: return NVS_FR_NORMAL;
+ case NV40_VP_INST_IN_COL0: return NVS_FR_COL0;
+ case NV40_VP_INST_IN_COL1: return NVS_FR_COL1;
+ case NV40_VP_INST_IN_FOGC: return NVS_FR_FOGCOORD;
+ case NV40_VP_INST_IN_TC(0): return NVS_FR_TEXCOORD0;
+ case NV40_VP_INST_IN_TC(1): return NVS_FR_TEXCOORD1;
+ case NV40_VP_INST_IN_TC(2): return NVS_FR_TEXCOORD2;
+ case NV40_VP_INST_IN_TC(3): return NVS_FR_TEXCOORD3;
+ case NV40_VP_INST_IN_TC(4): return NVS_FR_TEXCOORD4;
+ case NV40_VP_INST_IN_TC(5): return NVS_FR_TEXCOORD5;
+ case NV40_VP_INST_IN_TC(6): return NVS_FR_TEXCOORD6;
+ case NV40_VP_INST_IN_TC(7): return NVS_FR_TEXCOORD7;
+ default:
+ return -1;
+ }
+ break;
+ case NVS_FILE_CONST:
+ return ((shader->inst[1] & NV40_VP_INST_CONST_SRC_MASK)
+ >> NV40_VP_INST_CONST_SRC_SHIFT);
+ case NVS_FILE_TEMP:
+ {
+ unsigned int src;
+
+ src = shader->GetSourceHW(shader, merged, pos);
+ return ((src & NV40_VP_SRC_TEMP_SRC_MASK) >>
+ NV40_VP_SRC_TEMP_SRC_SHIFT);
+ }
+ default:
+ return -1;
+ }
+}
+
+static int
+NV40VPGetSourceNegate(nvsFunc * shader, int merged, int pos)
+{
+ unsigned int src;
+
+ src = shader->GetSourceHW(shader, merged, pos);
+
+ if (src == -1)
+ return -1;
+ return ((src & NV40_VP_SRC_NEGATE) ? 1 : 0);
+}
+
+static void
+NV40VPGetSourceSwizzle(nvsFunc * shader, int merged, int pos, nvsSwzComp *swz)
+{
+ unsigned int src;
+ int swzbits;
+
+ src = shader->GetSourceHW(shader, merged, pos);
+ swzbits = (src & NV40_VP_SRC_SWZ_ALL_MASK) >> NV40_VP_SRC_SWZ_ALL_SHIFT;
+ NV20VPTXSwizzle(swzbits, swz);
+}
+
+static int
+NV40VPGetSourceIndexed(nvsFunc * shader, int merged, int pos)
+{
+ switch (shader->GetSourceFile(shader, merged, pos)) {
+ case NVS_FILE_ATTRIB:
+ return ((shader->inst[0] & NV40_VP_INST_INDEX_INPUT) ? 1 : 0);
+ case NVS_FILE_CONST:
+ return ((shader->inst[3] & NV40_VP_INST_INDEX_CONST) ? 1 : 0);
+ default:
+ return 0;
+ }
+}
+
+static nvsSwzComp
+NV40VPGetAddressRegSwizzle(nvsFunc * shader)
+{
+ nvsSwzComp swz;
+
+ swz = NV20VP_TX_SWIZZLE[(shader->inst[0] & NV40_VP_INST_ADDR_SWZ_MASK)
+ >> NV40_VP_INST_ADDR_SWZ_SHIFT];
+ return swz;
+}
+
+static int
+NV40VPSupportsConditional(nvsFunc * shader)
+{
+ /*FIXME: Is this true of all ops? */
+ return 1;
+}
+
+static int
+NV40VPGetConditionUpdate(nvsFunc * shader)
+{
+ return ((shader->inst[0] & NV40_VP_INST_COND_UPDATE_ENABLE) ? 1 : 0);
+}
+
+static int
+NV40VPGetConditionTest(nvsFunc * shader)
+{
+ int op;
+
+ /* The condition test is unconditionally enabled on some
+ * instructions. ie: the condition test bit does *NOT* have
+ * to be set.
+ *
+ * FIXME: check other relevant ops for this situation.
+ */
+ op = shader->GetOpcodeHW(shader, 1);
+ switch (op) {
+ case NV40_VP_INST_OP_BRA:
+ return 1;
+ default:
+ return ((shader->inst[0] & NV40_VP_INST_COND_TEST_ENABLE) ? 1 : 0);
+ }
+}
+
+static nvsCond
+NV40VPGetCondition(nvsFunc * shader)
+{
+ int cond;
+
+ cond = ((shader->inst[0] & NV40_VP_INST_COND_MASK)
+ >> NV40_VP_INST_COND_SHIFT);
+
+ switch (cond) {
+ case NV40_VP_INST_COND_FL: return NVS_COND_FL;
+ case NV40_VP_INST_COND_LT: return NVS_COND_LT;
+ case NV40_VP_INST_COND_EQ: return NVS_COND_EQ;
+ case NV40_VP_INST_COND_LE: return NVS_COND_LE;
+ case NV40_VP_INST_COND_GT: return NVS_COND_GT;
+ case NV40_VP_INST_COND_NE: return NVS_COND_NE;
+ case NV40_VP_INST_COND_GE: return NVS_COND_GE;
+ case NV40_VP_INST_COND_TR: return NVS_COND_TR;
+ default:
+ return NVS_COND_UNKNOWN;
+ }
+}
+
+static void
+NV40VPGetCondRegSwizzle(nvsFunc * shader, nvsSwzComp *swz)
+{
+ int swzbits;
+
+ swzbits = (shader->inst[0] & NV40_VP_INST_COND_SWZ_ALL_MASK)
+ >> NV40_VP_INST_COND_SWZ_ALL_SHIFT;
+ NV20VPTXSwizzle(swzbits, swz);
+}
+
+static int
+NV40VPGetCondRegID(nvsFunc * shader)
+{
+ return ((shader->inst[0] & NV40_VP_INST_COND_REG_SELECT_1) ? 1 : 0);
+}
+
+static int
+NV40VPGetBranch(nvsFunc * shader)
+{
+ int addr;
+
+ addr = ((shader->inst[2] & NV40_VP_INST_IADDRH_MASK)
+ >> NV40_VP_INST_IADDRH_SHIFT) << 3;
+ addr |= ((shader->inst[3] & NV40_VP_INST_IADDRL_MASK)
+ >> NV40_VP_INST_IADDRL_SHIFT);
+ return addr;
+}
+
+void
+NV40VPInitShaderFuncs(nvsFunc * shader)
+{
+ /* Inherit NV30 VP code, we share some of it */
+ NV30VPInitShaderFuncs(shader);
+
+ /* Limits */
+ shader->MaxInst = 4096;
+ shader->MaxAttrib = 16;
+ shader->MaxTemp = 32;
+ shader->MaxAddress = 2;
+ shader->MaxConst = 256;
+ shader->caps = SCAP_SRC_ABS;
+
+ /* Add extra opcodes for NV40+ */
+// MOD_OPCODE(NVVP_TX_VOP, NV40_VP_INST_OP_TXWHAT, NVS_OP_TEX , 0, 4, -1);
+ MOD_OPCODE(NVVP_TX_SOP, NV40_VP_INST_OP_PUSHA, NVS_OP_PUSHA, 3, -1, -1);
+ MOD_OPCODE(NVVP_TX_SOP, NV40_VP_INST_OP_POPA , NVS_OP_POPA , -1, -1, -1);
+
+ shader->InitInstruction = NV40VPInitInstruction;
+ shader->SupportsOpcode = NV40VPSupportsOpcode;
+ shader->SetOpcode = NV40VPSetOpcode;
+ shader->SetCCUpdate = NV40VPSetCCUpdate;
+ shader->SetCondition = NV40VPSetCondition;
+ shader->SetResult = NV40VPSetResult;
+ shader->SetSource = NV40VPSetSource;
+ shader->SetLastInst = NV40VPSetLastInst;
+ shader->SetBranchTarget = NV40VPSetBranchTarget;
+
+ shader->HasMergedInst = NV40VPHasMergedInst;
+ shader->GetOpcodeHW = NV40VPGetOpcodeHW;
+
+ shader->GetDestFile = NV40VPGetDestFile;
+ shader->GetDestID = NV40VPGetDestID;
+ shader->GetDestMask = NV40VPGetDestMask;
+
+ shader->GetSourceHW = NV40VPGetSourceHW;
+ shader->GetSourceFile = NV40VPGetSourceFile;
+ shader->GetSourceID = NV40VPGetSourceID;
+ shader->GetSourceNegate = NV40VPGetSourceNegate;
+ shader->GetSourceSwizzle = NV40VPGetSourceSwizzle;
+ shader->GetSourceIndexed = NV40VPGetSourceIndexed;
+
+ shader->GetRelAddressSwizzle = NV40VPGetAddressRegSwizzle;
+
+ shader->SupportsConditional = NV40VPSupportsConditional;
+ shader->GetConditionUpdate = NV40VPGetConditionUpdate;
+ shader->GetConditionTest = NV40VPGetConditionTest;
+ shader->GetCondition = NV40VPGetCondition;
+ shader->GetCondRegSwizzle = NV40VPGetCondRegSwizzle;
+ shader->GetCondRegID = NV40VPGetCondRegID;
+
+ shader->GetBranch = NV40VPGetBranch;
+}
diff --git a/dist/Mesa/src/mesa/drivers/dri/nouveau/nv50_state.c b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv50_state.c
new file mode 100644
index 000000000..818e26861
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/nouveau/nv50_state.c
@@ -0,0 +1,641 @@
+/**************************************************************************
+
+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:
+ /* 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 ?
+ 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);
+
+ /* 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 */
+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)
+{
+ 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;
+}
+
+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;
+}
diff --git a/dist/Mesa/src/mesa/drivers/dri/r300/r300_emit.c b/dist/Mesa/src/mesa/drivers/dri/r300/r300_emit.c
new file mode 100644
index 000000000..2c26069f9
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/r300/r300_emit.c
@@ -0,0 +1,627 @@
+/*
+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.
+
+**************************************************************************/
+
+/**
+ * \file
+ *
+ * \author Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "glheader.h"
+#include "mtypes.h"
+#include "colormac.h"
+#include "imports.h"
+#include "macros.h"
+#include "image.h"
+
+#include "swrast_setup/swrast_setup.h"
+#include "math/m_translate.h"
+#include "tnl/tnl.h"
+#include "tnl/t_context.h"
+
+#include "r300_context.h"
+#include "radeon_ioctl.h"
+#include "r300_state.h"
+#include "r300_emit.h"
+#include "r300_ioctl.h"
+
+#ifdef USER_BUFFERS
+#include "r300_mem.h"
+#endif
+
+#if SWIZZLE_X != R300_INPUT_ROUTE_SELECT_X || \
+ SWIZZLE_Y != R300_INPUT_ROUTE_SELECT_Y || \
+ SWIZZLE_Z != R300_INPUT_ROUTE_SELECT_Z || \
+ SWIZZLE_W != R300_INPUT_ROUTE_SELECT_W || \
+ SWIZZLE_ZERO != R300_INPUT_ROUTE_SELECT_ZERO || \
+ SWIZZLE_ONE != R300_INPUT_ROUTE_SELECT_ONE
+#error Cannot change these!
+#endif
+
+#define DEBUG_ALL DEBUG_VERTS
+
+#if defined(USE_X86_ASM)
+#define COPY_DWORDS( dst, src, nr ) \
+do { \
+ int __tmp; \
+ __asm__ __volatile__( "rep ; movsl" \
+ : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \
+ : "0" (nr), \
+ "D" ((long)dst), \
+ "S" ((long)src) ); \
+} while (0)
+#else
+#define COPY_DWORDS( dst, src, nr ) \
+do { \
+ int j; \
+ for ( j = 0 ; j < nr ; j++ ) \
+ dst[j] = ((int *)src)[j]; \
+ dst += nr; \
+} while (0)
+#endif
+
+static void r300EmitVec4(GLcontext * ctx,
+ struct r300_dma_region *rvb,
+ GLvoid * data, int stride, int count)
+{
+ int i;
+ int *out = (int *)(rvb->address + rvb->start);
+
+ if (RADEON_DEBUG & DEBUG_VERTS)
+ fprintf(stderr, "%s count %d stride %d\n",
+ __FUNCTION__, count, stride);
+
+ if (stride == 4)
+ COPY_DWORDS(out, data, count);
+ else
+ for (i = 0; i < count; i++) {
+ out[0] = *(int *)data;
+ out++;
+ data += stride;
+ }
+}
+
+static void r300EmitVec8(GLcontext * ctx,
+ struct r300_dma_region *rvb,
+ GLvoid * data, int stride, int count)
+{
+ int i;
+ int *out = (int *)(rvb->address + rvb->start);
+
+ if (RADEON_DEBUG & DEBUG_VERTS)
+ fprintf(stderr, "%s count %d stride %d\n",
+ __FUNCTION__, count, stride);
+
+ if (stride == 8)
+ COPY_DWORDS(out, data, count * 2);
+ else
+ for (i = 0; i < count; i++) {
+ out[0] = *(int *)data;
+ out[1] = *(int *)(data + 4);
+ out += 2;
+ data += stride;
+ }
+}
+
+static void r300EmitVec12(GLcontext * ctx,
+ struct r300_dma_region *rvb,
+ GLvoid * data, int stride, int count)
+{
+ int i;
+ int *out = (int *)(rvb->address + rvb->start);
+
+ if (RADEON_DEBUG & DEBUG_VERTS)
+ fprintf(stderr, "%s count %d stride %d out %p data %p\n",
+ __FUNCTION__, count, stride, (void *)out, (void *)data);
+
+ if (stride == 12)
+ COPY_DWORDS(out, data, count * 3);
+ else
+ for (i = 0; i < count; i++) {
+ out[0] = *(int *)data;
+ out[1] = *(int *)(data + 4);
+ out[2] = *(int *)(data + 8);
+ out += 3;
+ data += stride;
+ }
+}
+
+static void r300EmitVec16(GLcontext * ctx,
+ struct r300_dma_region *rvb,
+ GLvoid * data, int stride, int count)
+{
+ int i;
+ int *out = (int *)(rvb->address + rvb->start);
+
+ if (RADEON_DEBUG & DEBUG_VERTS)
+ fprintf(stderr, "%s count %d stride %d\n",
+ __FUNCTION__, count, stride);
+
+ if (stride == 16)
+ COPY_DWORDS(out, data, count * 4);
+ else
+ for (i = 0; i < count; i++) {
+ out[0] = *(int *)data;
+ out[1] = *(int *)(data + 4);
+ out[2] = *(int *)(data + 8);
+ out[3] = *(int *)(data + 12);
+ out += 4;
+ data += stride;
+ }
+}
+
+static void r300EmitVec(GLcontext * ctx,
+ struct r300_dma_region *rvb,
+ GLvoid * data, int size, int stride, int count)
+{
+ r300ContextPtr rmesa = R300_CONTEXT(ctx);
+
+ if (RADEON_DEBUG & DEBUG_VERTS)
+ fprintf(stderr, "%s count %d size %d stride %d\n",
+ __FUNCTION__, count, size, stride);
+
+ /* Gets triggered when playing with future_hw_tcl_on ... */
+ //assert(!rvb->buf);
+
+ if (stride == 0) {
+ r300AllocDmaRegion(rmesa, rvb, size * 4, 4);
+ count = 1;
+ rvb->aos_offset = GET_START(rvb);
+ rvb->aos_stride = 0;
+ } else {
+ r300AllocDmaRegion(rmesa, rvb, size * count * 4, 4); /* alignment? */
+ rvb->aos_offset = GET_START(rvb);
+ rvb->aos_stride = size;
+ }
+
+ /* Emit the data
+ */
+ switch (size) {
+ case 1:
+ r300EmitVec4(ctx, rvb, data, stride, count);
+ break;
+ case 2:
+ r300EmitVec8(ctx, rvb, data, stride, count);
+ break;
+ case 3:
+ r300EmitVec12(ctx, rvb, data, stride, count);
+ break;
+ case 4:
+ r300EmitVec16(ctx, rvb, data, stride, count);
+ break;
+ default:
+ assert(0);
+ _mesa_exit(-1);
+ break;
+ }
+
+}
+
+static GLuint t_type(struct dt *dt)
+{
+ switch (dt->type) {
+ case GL_UNSIGNED_BYTE:
+ return AOS_FORMAT_UBYTE;
+ case GL_SHORT:
+ return AOS_FORMAT_USHORT;
+ case GL_FLOAT:
+ return AOS_FORMAT_FLOAT;
+ default:
+ assert(0);
+ break;
+ }
+
+ return AOS_FORMAT_FLOAT;
+}
+
+static GLuint t_vir0_size(struct dt *dt)
+{
+ switch (dt->type) {
+ case GL_UNSIGNED_BYTE:
+ return 4;
+ case GL_SHORT:
+ return 7;
+ case GL_FLOAT:
+ return dt->size - 1;
+ default:
+ assert(0);
+ break;
+ }
+
+ return 0;
+}
+
+static GLuint t_aos_size(struct dt *dt)
+{
+ switch (dt->type) {
+ case GL_UNSIGNED_BYTE:
+ return 1;
+ case GL_SHORT:
+ return 2;
+ case GL_FLOAT:
+ return dt->size;
+ default:
+ assert(0);
+ break;
+ }
+
+ return 0;
+}
+
+static GLuint t_vir0(uint32_t * dst, struct dt *dt, int *inputs,
+ GLint * tab, GLuint nr)
+{
+ GLuint i, dw;
+
+ for (i = 0; i + 1 < nr; i += 2) {
+ dw = t_vir0_size(&dt[tab[i]]) | (inputs[tab[i]] << 8) |
+ (t_type(&dt[tab[i]]) << 14);
+ dw |=
+ (t_vir0_size(&dt[tab[i + 1]]) |
+ (inputs[tab[i + 1]] << 8) | (t_type(&dt[tab[i + 1]])
+ << 14)) << 16;
+
+ if (i + 2 == nr) {
+ dw |= (1 << (13 + 16));
+ }
+ dst[i >> 1] = dw;
+ }
+
+ if (nr & 1) {
+ dw = t_vir0_size(&dt[tab[nr - 1]]) | (inputs[tab[nr - 1]]
+ << 8) |
+ (t_type(&dt[tab[nr - 1]]) << 14);
+ dw |= 1 << 13;
+
+ dst[nr >> 1] = dw;
+ }
+
+ return (nr + 1) >> 1;
+}
+
+static GLuint t_swizzle(int swizzle[4])
+{
+ return (swizzle[0] << R300_INPUT_ROUTE_X_SHIFT) |
+ (swizzle[1] << R300_INPUT_ROUTE_Y_SHIFT) |
+ (swizzle[2] << R300_INPUT_ROUTE_Z_SHIFT) |
+ (swizzle[3] << R300_INPUT_ROUTE_W_SHIFT);
+}
+
+static GLuint t_vir1(uint32_t * dst, int swizzle[][4], GLuint nr)
+{
+ GLuint i;
+
+ for (i = 0; i + 1 < nr; i += 2) {
+ dst[i >> 1] = t_swizzle(swizzle[i]) | R300_INPUT_ROUTE_ENABLE;
+ dst[i >> 1] |=
+ (t_swizzle(swizzle[i + 1]) | R300_INPUT_ROUTE_ENABLE)
+ << 16;
+ }
+
+ if (nr & 1)
+ dst[nr >> 1] =
+ t_swizzle(swizzle[nr - 1]) | R300_INPUT_ROUTE_ENABLE;
+
+ return (nr + 1) >> 1;
+}
+
+static GLuint t_emit_size(struct dt *dt)
+{
+ return dt->size;
+}
+
+static GLuint t_vic(GLcontext * ctx, GLuint InputsRead)
+{
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
+ GLuint i, vic_1 = 0;
+
+ if (InputsRead & (1 << VERT_ATTRIB_POS))
+ vic_1 |= R300_INPUT_CNTL_POS;
+
+ if (InputsRead & (1 << VERT_ATTRIB_NORMAL))
+ vic_1 |= R300_INPUT_CNTL_NORMAL;
+
+ if (InputsRead & (1 << VERT_ATTRIB_COLOR0))
+ vic_1 |= R300_INPUT_CNTL_COLOR;
+
+ r300->state.texture.tc_count = 0;
+ for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
+ if (InputsRead & (1 << (VERT_ATTRIB_TEX0 + i))) {
+ r300->state.texture.tc_count++;
+ vic_1 |= R300_INPUT_CNTL_TC0 << i;
+ }
+
+ return vic_1;
+}
+
+/* Emit vertex data to GART memory
+ * Route inputs to the vertex processor
+ * This function should never return R300_FALLBACK_TCL when using software tcl.
+ */
+
+int r300EmitArrays(GLcontext * ctx)
+{
+ r300ContextPtr rmesa = R300_CONTEXT(ctx);
+ r300ContextPtr r300 = rmesa;
+ struct radeon_vertex_buffer *VB = &rmesa->state.VB;
+ GLuint nr;
+ GLuint count = VB->Count;
+ GLuint i;
+ GLuint InputsRead = 0, OutputsWritten = 0;
+ int *inputs = NULL;
+ int vir_inputs[VERT_ATTRIB_MAX];
+ GLint tab[VERT_ATTRIB_MAX];
+ int swizzle[VERT_ATTRIB_MAX][4];
+
+ if (hw_tcl_on) {
+ struct r300_vertex_program *prog =
+ (struct r300_vertex_program *)
+ CURRENT_VERTEX_SHADER(ctx);
+ inputs = prog->inputs;
+ InputsRead = CURRENT_VERTEX_SHADER(ctx)->key.InputsRead;
+ OutputsWritten = CURRENT_VERTEX_SHADER(ctx)->key.OutputsWritten;
+ } else {
+ DECLARE_RENDERINPUTS(inputs_bitset);
+ inputs = r300->state.sw_tcl_inputs;
+
+ RENDERINPUTS_COPY(inputs_bitset,
+ TNL_CONTEXT(ctx)->render_inputs_bitset);
+
+ assert(RENDERINPUTS_TEST(inputs_bitset, _TNL_ATTRIB_POS));
+ InputsRead |= 1 << VERT_ATTRIB_POS;
+ OutputsWritten |= 1 << VERT_RESULT_HPOS;
+
+ assert(RENDERINPUTS_TEST(inputs_bitset, _TNL_ATTRIB_NORMAL)
+ == 0);
+
+ assert(RENDERINPUTS_TEST(inputs_bitset, _TNL_ATTRIB_COLOR0));
+ InputsRead |= 1 << VERT_ATTRIB_COLOR0;
+ OutputsWritten |= 1 << VERT_RESULT_COL0;
+
+ if (RENDERINPUTS_TEST(inputs_bitset, _TNL_ATTRIB_COLOR1)) {
+ InputsRead |= 1 << VERT_ATTRIB_COLOR1;
+ OutputsWritten |= 1 << VERT_RESULT_COL1;
+ }
+
+ for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
+ if (RENDERINPUTS_TEST
+ (inputs_bitset, _TNL_ATTRIB_TEX(i))) {
+ InputsRead |= 1 << (VERT_ATTRIB_TEX0 + i);
+ OutputsWritten |= 1 << (VERT_RESULT_TEX0 + i);
+ }
+
+ for (i = 0, nr = 0; i < VERT_ATTRIB_MAX; i++)
+ if (InputsRead & (1 << i))
+ inputs[i] = nr++;
+ else
+ inputs[i] = -1;
+
+ if (!
+ (r300->radeon.radeonScreen->
+ chip_flags & RADEON_CHIPSET_TCL)) {
+ /* Fixed, apply to vir0 only */
+ memcpy(vir_inputs, inputs,
+ VERT_ATTRIB_MAX * sizeof(int));
+ inputs = vir_inputs;
+
+ if (InputsRead & VERT_ATTRIB_POS)
+ inputs[VERT_ATTRIB_POS] = 0;
+
+ if (InputsRead & (1 << VERT_ATTRIB_COLOR0))
+ inputs[VERT_ATTRIB_COLOR0] = 2;
+
+ if (InputsRead & (1 << VERT_ATTRIB_COLOR1))
+ inputs[VERT_ATTRIB_COLOR1] = 3;
+
+ for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX7; i++)
+ if (InputsRead & (1 << i))
+ inputs[i] = 6 + (i - VERT_ATTRIB_TEX0);
+ }
+
+ RENDERINPUTS_COPY(rmesa->state.render_inputs_bitset,
+ inputs_bitset);
+ }
+ assert(InputsRead);
+ assert(OutputsWritten);
+
+ for (i = 0, nr = 0; i < VERT_ATTRIB_MAX; i++)
+ if (InputsRead & (1 << i))
+ tab[nr++] = i;
+
+ if (nr > R300_MAX_AOS_ARRAYS)
+ return R300_FALLBACK_TCL;
+
+ for (i = 0; i < nr; i++) {
+ int ci;
+ int comp_size, fix, found = 0;
+
+ swizzle[i][0] = SWIZZLE_ZERO;
+ swizzle[i][1] = SWIZZLE_ZERO;
+ swizzle[i][2] = SWIZZLE_ZERO;
+ swizzle[i][3] = SWIZZLE_ONE;
+
+ for (ci = 0; ci < VB->AttribPtr[tab[i]].size; ci++)
+ swizzle[i][ci] = ci;
+
+#if MESA_BIG_ENDIAN
+#define SWAP_INT(a, b) do { \
+ int __temp; \
+ __temp = a;\
+ a = b; \
+ b = __temp; \
+} while (0)
+
+ if (VB->AttribPtr[tab[i]].type == GL_UNSIGNED_BYTE) {
+ SWAP_INT(swizzle[i][0], swizzle[i][3]);
+ SWAP_INT(swizzle[i][1], swizzle[i][2]);
+ }
+#endif /* MESA_BIG_ENDIAN */
+
+ if (r300IsGartMemory(rmesa, VB->AttribPtr[tab[i]].data,
+ /*(count-1)*stride */ 4)) {
+ if (VB->AttribPtr[tab[i]].stride % 4)
+ return R300_FALLBACK_TCL;
+
+ rmesa->state.aos[i].address =
+ VB->AttribPtr[tab[i]].data;
+ rmesa->state.aos[i].start = 0;
+ rmesa->state.aos[i].aos_offset =
+ r300GartOffsetFromVirtual(rmesa,
+ VB->
+ AttribPtr[tab[i]].data);
+ rmesa->state.aos[i].aos_stride =
+ VB->AttribPtr[tab[i]].stride / 4;
+
+ rmesa->state.aos[i].aos_size =
+ t_emit_size(&VB->AttribPtr[tab[i]]);
+ } else {
+ /* TODO: r300EmitVec can only handle 4 byte vectors */
+ if (VB->AttribPtr[tab[i]].type != GL_FLOAT)
+ return R300_FALLBACK_TCL;
+
+ r300EmitVec(ctx, &rmesa->state.aos[i],
+ VB->AttribPtr[tab[i]].data,
+ t_emit_size(&VB->AttribPtr[tab[i]]),
+ VB->AttribPtr[tab[i]].stride, count);
+ }
+
+ rmesa->state.aos[i].aos_size =
+ t_aos_size(&VB->AttribPtr[tab[i]]);
+
+ comp_size = _mesa_sizeof_type(VB->AttribPtr[tab[i]].type);
+
+ for (fix = 0; fix <= 4 - VB->AttribPtr[tab[i]].size; fix++) {
+ if ((rmesa->state.aos[i].aos_offset -
+ comp_size * fix) % 4)
+ continue;
+
+ found = 1;
+ break;
+ }
+
+ if (found) {
+ if (fix > 0) {
+ WARN_ONCE("Feeling lucky?\n");
+ }
+
+ rmesa->state.aos[i].aos_offset -= comp_size * fix;
+
+ for (ci = 0; ci < VB->AttribPtr[tab[i]].size; ci++)
+ swizzle[i][ci] += fix;
+ } else {
+ WARN_ONCE
+ ("Cannot handle offset %x with stride %d, comp %d\n",
+ rmesa->state.aos[i].aos_offset,
+ rmesa->state.aos[i].aos_stride,
+ VB->AttribPtr[tab[i]].size);
+ return R300_FALLBACK_TCL;
+ }
+ }
+
+ /* setup INPUT_ROUTE */
+ R300_STATECHANGE(r300, vir[0]);
+ ((drm_r300_cmd_header_t *) r300->hw.vir[0].cmd)->packet0.count =
+ t_vir0(&r300->hw.vir[0].cmd[R300_VIR_CNTL_0], VB->AttribPtr,
+ inputs, tab, nr);
+
+ R300_STATECHANGE(r300, vir[1]);
+ ((drm_r300_cmd_header_t *) r300->hw.vir[1].cmd)->packet0.count =
+ t_vir1(&r300->hw.vir[1].cmd[R300_VIR_CNTL_0], swizzle, nr);
+
+ /* Set up input_cntl */
+ /* I don't think this is needed for vertex buffers, but it doesn't hurt anything */
+ R300_STATECHANGE(r300, vic);
+ r300->hw.vic.cmd[R300_VIC_CNTL_0] = 0x5555; /* Hard coded value, no idea what it means */
+ r300->hw.vic.cmd[R300_VIC_CNTL_1] = t_vic(ctx, InputsRead);
+
+ /* Stage 3: VAP output */
+
+ R300_STATECHANGE(r300, vof);
+
+ r300->hw.vof.cmd[R300_VOF_CNTL_0] = 0;
+ r300->hw.vof.cmd[R300_VOF_CNTL_1] = 0;
+
+ if (OutputsWritten & (1 << VERT_RESULT_HPOS))
+ r300->hw.vof.cmd[R300_VOF_CNTL_0] |=
+ R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
+
+ if (OutputsWritten & (1 << VERT_RESULT_COL0))
+ r300->hw.vof.cmd[R300_VOF_CNTL_0] |=
+ R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
+
+ if (OutputsWritten & (1 << VERT_RESULT_COL1))
+ r300->hw.vof.cmd[R300_VOF_CNTL_0] |=
+ R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT;
+
+ /*if(OutputsWritten & (1 << VERT_RESULT_BFC0))
+ r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT;
+
+ if(OutputsWritten & (1 << VERT_RESULT_BFC1))
+ r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT; */
+ //if(OutputsWritten & (1 << VERT_RESULT_FOGC))
+
+ if (OutputsWritten & (1 << VERT_RESULT_PSIZ))
+ r300->hw.vof.cmd[R300_VOF_CNTL_0] |=
+ R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
+
+ for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
+ if (OutputsWritten & (1 << (VERT_RESULT_TEX0 + i)))
+ r300->hw.vof.cmd[R300_VOF_CNTL_1] |= (4 << (3 * i));
+
+ rmesa->state.aos_count = nr;
+
+ return R300_FALLBACK_NONE;
+}
+
+#ifdef USER_BUFFERS
+void r300UseArrays(GLcontext * ctx)
+{
+ r300ContextPtr rmesa = R300_CONTEXT(ctx);
+ int i;
+
+ if (rmesa->state.elt_dma.buf)
+ r300_mem_use(rmesa, rmesa->state.elt_dma.buf->id);
+
+ for (i = 0; i < rmesa->state.aos_count; i++) {
+ if (rmesa->state.aos[i].buf)
+ r300_mem_use(rmesa, rmesa->state.aos[i].buf->id);
+ }
+}
+#endif
+
+void r300ReleaseArrays(GLcontext * ctx)
+{
+ r300ContextPtr rmesa = R300_CONTEXT(ctx);
+ int i;
+
+ r300ReleaseDmaRegion(rmesa, &rmesa->state.elt_dma, __FUNCTION__);
+ for (i = 0; i < rmesa->state.aos_count; i++) {
+ r300ReleaseDmaRegion(rmesa, &rmesa->state.aos[i], __FUNCTION__);
+ }
+}
diff --git a/dist/Mesa/src/mesa/drivers/dri/r300/r300_mem.c b/dist/Mesa/src/mesa/drivers/dri/r300/r300_mem.c
new file mode 100644
index 000000000..f8f9d4fcd
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/r300/r300_mem.c
@@ -0,0 +1,385 @@
+/*
+ * Copyright (C) 2005 Aapo Tahkola.
+ *
+ * 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.
+ *
+ */
+
+/**
+ * \file
+ *
+ * \author Aapo Tahkola <aet@rasterburn.org>
+ */
+
+#include <unistd.h>
+
+#include "r300_context.h"
+#include "r300_cmdbuf.h"
+#include "r300_ioctl.h"
+#include "r300_mem.h"
+#include "radeon_ioctl.h"
+
+#ifdef USER_BUFFERS
+
+static void resize_u_list(r300ContextPtr rmesa)
+{
+ void *temp;
+ int nsize;
+
+ temp = rmesa->rmm->u_list;
+ nsize = rmesa->rmm->u_size * 2;
+
+ rmesa->rmm->u_list = _mesa_malloc(nsize * sizeof(*rmesa->rmm->u_list));
+ _mesa_memset(rmesa->rmm->u_list, 0,
+ nsize * sizeof(*rmesa->rmm->u_list));
+
+ if (temp) {
+ r300FlushCmdBuf(rmesa, __FUNCTION__);
+
+ _mesa_memcpy(rmesa->rmm->u_list, temp,
+ rmesa->rmm->u_size * sizeof(*rmesa->rmm->u_list));
+ _mesa_free(temp);
+ }
+
+ rmesa->rmm->u_size = nsize;
+}
+
+void r300_mem_init(r300ContextPtr rmesa)
+{
+ rmesa->rmm = malloc(sizeof(struct r300_memory_manager));
+ memset(rmesa->rmm, 0, sizeof(struct r300_memory_manager));
+
+ rmesa->rmm->u_size = 128;
+ resize_u_list(rmesa);
+}
+
+void r300_mem_destroy(r300ContextPtr rmesa)
+{
+ _mesa_free(rmesa->rmm->u_list);
+ rmesa->rmm->u_list = NULL;
+
+ _mesa_free(rmesa->rmm);
+ rmesa->rmm = NULL;
+}
+
+void *r300_mem_ptr(r300ContextPtr rmesa, int id)
+{
+ assert(id <= rmesa->rmm->u_last);
+ return rmesa->rmm->u_list[id].ptr;
+}
+
+int r300_mem_find(r300ContextPtr rmesa, void *ptr)
+{
+ int i;
+
+ for (i = 1; i < rmesa->rmm->u_size + 1; i++)
+ if (rmesa->rmm->u_list[i].ptr &&
+ ptr >= rmesa->rmm->u_list[i].ptr &&
+ ptr <
+ rmesa->rmm->u_list[i].ptr + rmesa->rmm->u_list[i].size)
+ break;
+
+ if (i < rmesa->rmm->u_size + 1)
+ return i;
+
+ fprintf(stderr, "%p failed\n", ptr);
+ return 0;
+}
+
+//#define MM_DEBUG
+int r300_mem_alloc(r300ContextPtr rmesa, int alignment, int size)
+{
+ drm_radeon_mem_alloc_t alloc;
+ int offset = 0, ret;
+ int i, free = -1;
+ int done_age;
+ drm_radeon_mem_free_t memfree;
+ int tries = 0;
+ static int bytes_wasted = 0, allocated = 0;
+
+ if (size < 4096)
+ bytes_wasted += 4096 - size;
+
+ allocated += size;
+
+#if 0
+ static int t = 0;
+ if (t != time(NULL)) {
+ t = time(NULL);
+ fprintf(stderr, "slots used %d, wasted %d kb, allocated %d\n",
+ rmesa->rmm->u_last, bytes_wasted / 1024,
+ allocated / 1024);
+ }
+#endif
+
+ memfree.region = RADEON_MEM_REGION_GART;
+
+ again:
+
+ done_age = radeonGetAge((radeonContextPtr) rmesa);
+
+ if (rmesa->rmm->u_last + 1 >= rmesa->rmm->u_size)
+ resize_u_list(rmesa);
+
+ for (i = rmesa->rmm->u_last + 1; i > 0; i--) {
+ if (rmesa->rmm->u_list[i].ptr == NULL) {
+ free = i;
+ continue;
+ }
+
+ if (rmesa->rmm->u_list[i].h_pending == 0 &&
+ rmesa->rmm->u_list[i].pending
+ && rmesa->rmm->u_list[i].age <= done_age) {
+ memfree.region_offset =
+ (char *)rmesa->rmm->u_list[i].ptr -
+ (char *)rmesa->radeon.radeonScreen->gartTextures.
+ map;
+
+ ret =
+ drmCommandWrite(rmesa->radeon.radeonScreen->
+ driScreen->fd, DRM_RADEON_FREE,
+ &memfree, sizeof(memfree));
+
+ if (ret) {
+ fprintf(stderr, "Failed to free at %p\n",
+ rmesa->rmm->u_list[i].ptr);
+ fprintf(stderr, "ret = %s\n", strerror(-ret));
+ exit(1);
+ } else {
+#ifdef MM_DEBUG
+ fprintf(stderr, "really freed %d at age %x\n",
+ i,
+ radeonGetAge((radeonContextPtr) rmesa));
+#endif
+ if (i == rmesa->rmm->u_last)
+ rmesa->rmm->u_last--;
+
+ if (rmesa->rmm->u_list[i].size < 4096)
+ bytes_wasted -=
+ 4096 - rmesa->rmm->u_list[i].size;
+
+ allocated -= rmesa->rmm->u_list[i].size;
+ rmesa->rmm->u_list[i].pending = 0;
+ rmesa->rmm->u_list[i].ptr = NULL;
+ free = i;
+ }
+ }
+ }
+ rmesa->rmm->u_head = i;
+
+ if (free == -1) {
+ WARN_ONCE("Ran out of slots!\n");
+ //usleep(100);
+ r300FlushCmdBuf(rmesa, __FUNCTION__);
+ tries++;
+ if (tries > 100) {
+ WARN_ONCE("Ran out of slots!\n");
+ exit(1);
+ }
+ goto again;
+ }
+
+ alloc.region = RADEON_MEM_REGION_GART;
+ alloc.alignment = alignment;
+ alloc.size = size;
+ alloc.region_offset = &offset;
+
+ ret =
+ drmCommandWriteRead(rmesa->radeon.dri.fd, DRM_RADEON_ALLOC, &alloc,
+ sizeof(alloc));
+ if (ret) {
+#if 0
+ WARN_ONCE("Ran out of mem!\n");
+ r300FlushCmdBuf(rmesa, __FUNCTION__);
+ //usleep(100);
+ tries2++;
+ tries = 0;
+ if (tries2 > 100) {
+ WARN_ONCE("Ran out of GART memory!\n");
+ exit(1);
+ }
+ goto again;
+#else
+ WARN_ONCE
+ ("Ran out of GART memory (for %d)!\nPlease consider adjusting GARTSize option.\n",
+ size);
+ return 0;
+#endif
+ }
+
+ i = free;
+
+ if (i > rmesa->rmm->u_last)
+ rmesa->rmm->u_last = i;
+
+ rmesa->rmm->u_list[i].ptr =
+ ((GLubyte *) rmesa->radeon.radeonScreen->gartTextures.map) + offset;
+ rmesa->rmm->u_list[i].size = size;
+ rmesa->rmm->u_list[i].age = 0;
+ //fprintf(stderr, "alloc %p at id %d\n", rmesa->rmm->u_list[i].ptr, i);
+
+#ifdef MM_DEBUG
+ fprintf(stderr, "allocated %d at age %x\n", i,
+ radeonGetAge((radeonContextPtr) rmesa));
+#endif
+
+ return i;
+}
+
+void r300_mem_use(r300ContextPtr rmesa, int id)
+{
+ uint64_t ull;
+#ifdef MM_DEBUG
+ fprintf(stderr, "%s: %d at age %x\n", __FUNCTION__, id,
+ radeonGetAge((radeonContextPtr) rmesa));
+#endif
+ drm_r300_cmd_header_t *cmd;
+
+ assert(id <= rmesa->rmm->u_last);
+
+ if (id == 0)
+ return;
+
+ cmd =
+ (drm_r300_cmd_header_t *) r300AllocCmdBuf(rmesa,
+ 2 + sizeof(ull) / 4,
+ __FUNCTION__);
+ cmd[0].scratch.cmd_type = R300_CMD_SCRATCH;
+ cmd[0].scratch.reg = R300_MEM_SCRATCH;
+ cmd[0].scratch.n_bufs = 1;
+ cmd[0].scratch.flags = 0;
+ cmd++;
+
+ ull = (uint64_t) (intptr_t) & rmesa->rmm->u_list[id].age;
+ _mesa_memcpy(cmd, &ull, sizeof(ull));
+ cmd += sizeof(ull) / 4;
+
+ cmd[0].u = /*id */ 0;
+
+ LOCK_HARDWARE(&rmesa->radeon); /* Protect from DRM. */
+ rmesa->rmm->u_list[id].h_pending++;
+ UNLOCK_HARDWARE(&rmesa->radeon);
+}
+
+unsigned long r300_mem_offset(r300ContextPtr rmesa, int id)
+{
+ unsigned long offset;
+
+ assert(id <= rmesa->rmm->u_last);
+
+ offset = (char *)rmesa->rmm->u_list[id].ptr -
+ (char *)rmesa->radeon.radeonScreen->gartTextures.map;
+ offset += rmesa->radeon.radeonScreen->gart_texture_offset;
+
+ return offset;
+}
+
+void *r300_mem_map(r300ContextPtr rmesa, int id, int access)
+{
+#ifdef MM_DEBUG
+ fprintf(stderr, "%s: %d at age %x\n", __FUNCTION__, id,
+ radeonGetAge((radeonContextPtr) rmesa));
+#endif
+ void *ptr;
+ int tries = 0;
+
+ assert(id <= rmesa->rmm->u_last);
+
+ if (access == R300_MEM_R) {
+
+ if (rmesa->rmm->u_list[id].mapped == 1)
+ WARN_ONCE("buffer %d already mapped\n", id);
+
+ rmesa->rmm->u_list[id].mapped = 1;
+ ptr = r300_mem_ptr(rmesa, id);
+
+ return ptr;
+ }
+
+ if (rmesa->rmm->u_list[id].h_pending)
+ r300FlushCmdBuf(rmesa, __FUNCTION__);
+
+ if (rmesa->rmm->u_list[id].h_pending) {
+ return NULL;
+ }
+
+ while (rmesa->rmm->u_list[id].age >
+ radeonGetAge((radeonContextPtr) rmesa) && tries++ < 1000)
+ usleep(10);
+
+ if (tries >= 1000) {
+ fprintf(stderr, "Idling failed (%x vs %x)\n",
+ rmesa->rmm->u_list[id].age,
+ radeonGetAge((radeonContextPtr) rmesa));
+ return NULL;
+ }
+
+ if (rmesa->rmm->u_list[id].mapped == 1)
+ WARN_ONCE("buffer %d already mapped\n", id);
+
+ rmesa->rmm->u_list[id].mapped = 1;
+ ptr = r300_mem_ptr(rmesa, id);
+
+ return ptr;
+}
+
+void r300_mem_unmap(r300ContextPtr rmesa, int id)
+{
+#ifdef MM_DEBUG
+ fprintf(stderr, "%s: %d at age %x\n", __FUNCTION__, id,
+ radeonGetAge((radeonContextPtr) rmesa));
+#endif
+
+ assert(id <= rmesa->rmm->u_last);
+
+ if (rmesa->rmm->u_list[id].mapped == 0)
+ WARN_ONCE("buffer %d not mapped\n", id);
+
+ rmesa->rmm->u_list[id].mapped = 0;
+}
+
+void r300_mem_free(r300ContextPtr rmesa, int id)
+{
+#ifdef MM_DEBUG
+ fprintf(stderr, "%s: %d at age %x\n", __FUNCTION__, id,
+ radeonGetAge((radeonContextPtr) rmesa));
+#endif
+
+ assert(id <= rmesa->rmm->u_last);
+
+ if (id == 0)
+ return;
+
+ if (rmesa->rmm->u_list[id].ptr == NULL) {
+ WARN_ONCE("Not allocated!\n");
+ return;
+ }
+
+ if (rmesa->rmm->u_list[id].pending) {
+ WARN_ONCE("%p already pended!\n", rmesa->rmm->u_list[id].ptr);
+ return;
+ }
+
+ rmesa->rmm->u_list[id].pending = 1;
+}
+#endif
diff --git a/dist/Mesa/src/mesa/drivers/dri/r300/r300_mem.h b/dist/Mesa/src/mesa/drivers/dri/r300/r300_mem.h
new file mode 100644
index 000000000..625a7f6d8
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/r300/r300_mem.h
@@ -0,0 +1,37 @@
+#ifndef __R300_MEM_H__
+#define __R300_MEM_H__
+
+//#define R300_MEM_PDL 0
+#define R300_MEM_UL 1
+
+#define R300_MEM_R 1
+#define R300_MEM_W 2
+#define R300_MEM_RW (R300_MEM_R | R300_MEM_W)
+
+#define R300_MEM_SCRATCH 2
+
+struct r300_memory_manager {
+ struct {
+ void *ptr;
+ uint32_t size;
+ uint32_t age;
+ uint32_t h_pending;
+ int pending;
+ int mapped;
+ } *u_list;
+ int u_head, u_size, u_last;
+
+};
+
+extern void r300_mem_init(r300ContextPtr rmesa);
+extern void r300_mem_destroy(r300ContextPtr rmesa);
+extern void *r300_mem_ptr(r300ContextPtr rmesa, int id);
+extern int r300_mem_find(r300ContextPtr rmesa, void *ptr);
+extern int r300_mem_alloc(r300ContextPtr rmesa, int alignment, int size);
+extern void r300_mem_use(r300ContextPtr rmesa, int id);
+extern unsigned long r300_mem_offset(r300ContextPtr rmesa, int id);
+extern void *r300_mem_map(r300ContextPtr rmesa, int id, int access);
+extern void r300_mem_unmap(r300ContextPtr rmesa, int id);
+extern void r300_mem_free(r300ContextPtr rmesa, int id);
+
+#endif
diff --git a/dist/Mesa/src/mesa/drivers/dri/r300/r300_vertprog.c b/dist/Mesa/src/mesa/drivers/dri/r300/r300_vertprog.c
new file mode 100644
index 000000000..1d90ade2e
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/r300/r300_vertprog.c
@@ -0,0 +1,1305 @@
+/**************************************************************************
+
+Copyright (C) 2005 Aapo Tahkola.
+
+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
+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.
+
+**************************************************************************/
+
+/**
+ * \file
+ *
+ * \author Aapo Tahkola <aet@rasterburn.org>
+ */
+
+#include "glheader.h"
+#include "macros.h"
+#include "enums.h"
+#include "program.h"
+#include "shader/prog_instruction.h"
+#include "shader/prog_parameter.h"
+#include "shader/prog_statevars.h"
+#include "tnl/tnl.h"
+
+#include "r300_context.h"
+
+#if SWIZZLE_X != VSF_IN_COMPONENT_X || \
+ SWIZZLE_Y != VSF_IN_COMPONENT_Y || \
+ SWIZZLE_Z != VSF_IN_COMPONENT_Z || \
+ SWIZZLE_W != VSF_IN_COMPONENT_W || \
+ SWIZZLE_ZERO != VSF_IN_COMPONENT_ZERO || \
+ SWIZZLE_ONE != VSF_IN_COMPONENT_ONE || \
+ WRITEMASK_X != VSF_FLAG_X || \
+ WRITEMASK_Y != VSF_FLAG_Y || \
+ WRITEMASK_Z != VSF_FLAG_Z || \
+ WRITEMASK_W != VSF_FLAG_W
+#error Cannot change these!
+#endif
+
+#define SCALAR_FLAG (1<<31)
+#define FLAG_MASK (1<<31)
+#define OP_MASK (0xf) /* we are unlikely to have more than 15 */
+#define OPN(operator, ip) {#operator, OPCODE_##operator, ip}
+
+static struct {
+ char *name;
+ int opcode;
+ unsigned long ip; /* number of input operands and flags */
+} op_names[] = {
+ /* *INDENT-OFF* */
+ OPN(ABS, 1),
+ OPN(ADD, 2),
+ OPN(ARL, 1 | SCALAR_FLAG),
+ OPN(DP3, 2),
+ OPN(DP4, 2),
+ OPN(DPH, 2),
+ OPN(DST, 2),
+ OPN(EX2, 1 | SCALAR_FLAG),
+ OPN(EXP, 1 | SCALAR_FLAG),
+ OPN(FLR, 1),
+ OPN(FRC, 1),
+ OPN(LG2, 1 | SCALAR_FLAG),
+ OPN(LIT, 1),
+ OPN(LOG, 1 | SCALAR_FLAG),
+ OPN(MAD, 3),
+ OPN(MAX, 2),
+ OPN(MIN, 2),
+ OPN(MOV, 1),
+ OPN(MUL, 2),
+ OPN(POW, 2 | SCALAR_FLAG),
+ OPN(RCP, 1 | SCALAR_FLAG),
+ OPN(RSQ, 1 | SCALAR_FLAG),
+ OPN(SGE, 2),
+ OPN(SLT, 2),
+ OPN(SUB, 2),
+ OPN(SWZ, 1),
+ OPN(XPD, 2),
+ OPN(RCC, 0), //extra
+ OPN(PRINT, 0),
+ OPN(END, 0)
+ /* *INDENT-ON* */
+};
+
+#undef OPN
+
+int r300VertexProgUpdateParams(GLcontext * ctx,
+ struct r300_vertex_program_cont *vp, float *dst)
+{
+ int pi;
+ struct gl_vertex_program *mesa_vp = &vp->mesa_program;
+ float *dst_o = dst;
+ struct gl_program_parameter_list *paramList;
+
+ if (mesa_vp->IsNVProgram) {
+ _mesa_load_tracked_matrices(ctx);
+
+ for (pi = 0; pi < MAX_NV_VERTEX_PROGRAM_PARAMS; pi++) {
+ *dst++ = ctx->VertexProgram.Parameters[pi][0];
+ *dst++ = ctx->VertexProgram.Parameters[pi][1];
+ *dst++ = ctx->VertexProgram.Parameters[pi][2];
+ *dst++ = ctx->VertexProgram.Parameters[pi][3];
+ }
+ return dst - dst_o;
+ }
+
+ assert(mesa_vp->Base.Parameters);
+ _mesa_load_state_parameters(ctx, mesa_vp->Base.Parameters);
+
+ if (mesa_vp->Base.Parameters->NumParameters * 4 >
+ VSF_MAX_FRAGMENT_LENGTH) {
+ fprintf(stderr, "%s:Params exhausted\n", __FUNCTION__);
+ _mesa_exit(-1);
+ }
+
+ paramList = mesa_vp->Base.Parameters;
+ for (pi = 0; pi < paramList->NumParameters; pi++) {
+ switch (paramList->Parameters[pi].Type) {
+
+ case PROGRAM_STATE_VAR:
+ case PROGRAM_NAMED_PARAM:
+ //fprintf(stderr, "%s", vp->Parameters->Parameters[pi].Name);
+ case PROGRAM_CONSTANT:
+ *dst++ = paramList->ParameterValues[pi][0];
+ *dst++ = paramList->ParameterValues[pi][1];
+ *dst++ = paramList->ParameterValues[pi][2];
+ *dst++ = paramList->ParameterValues[pi][3];
+ break;
+
+ default:
+ _mesa_problem(NULL, "Bad param type in %s",
+ __FUNCTION__);
+ }
+
+ }
+
+ return dst - dst_o;
+}
+
+static unsigned long t_dst_mask(GLuint mask)
+{
+ /* WRITEMASK_* is equivalent to VSF_FLAG_* */
+ return mask & VSF_FLAG_ALL;
+}
+
+static unsigned long t_dst_class(enum register_file file)
+{
+
+ switch (file) {
+ case PROGRAM_TEMPORARY:
+ return VSF_OUT_CLASS_TMP;
+ case PROGRAM_OUTPUT:
+ return VSF_OUT_CLASS_RESULT;
+ case PROGRAM_ADDRESS:
+ return VSF_OUT_CLASS_ADDR;
+ /*
+ case PROGRAM_INPUT:
+ case PROGRAM_LOCAL_PARAM:
+ case PROGRAM_ENV_PARAM:
+ case PROGRAM_NAMED_PARAM:
+ case PROGRAM_STATE_VAR:
+ case PROGRAM_WRITE_ONLY:
+ case PROGRAM_ADDRESS:
+ */
+ default:
+ fprintf(stderr, "problem in %s", __FUNCTION__);
+ _mesa_exit(-1);
+ return -1;
+ }
+}
+
+static unsigned long t_dst_index(struct r300_vertex_program *vp,
+ struct prog_dst_register *dst)
+{
+ if (dst->File == PROGRAM_OUTPUT)
+ return vp->outputs[dst->Index];
+
+ return dst->Index;
+}
+
+static unsigned long t_src_class(enum register_file file)
+{
+
+ switch (file) {
+ case PROGRAM_TEMPORARY:
+ return VSF_IN_CLASS_TMP;
+
+ case PROGRAM_INPUT:
+ return VSF_IN_CLASS_ATTR;
+
+ case PROGRAM_LOCAL_PARAM:
+ case PROGRAM_ENV_PARAM:
+ case PROGRAM_NAMED_PARAM:
+ case PROGRAM_STATE_VAR:
+ return VSF_IN_CLASS_PARAM;
+ /*
+ case PROGRAM_OUTPUT:
+ case PROGRAM_WRITE_ONLY:
+ case PROGRAM_ADDRESS:
+ */
+ default:
+ fprintf(stderr, "problem in %s", __FUNCTION__);
+ _mesa_exit(-1);
+ return -1;
+ }
+}
+
+static __inline unsigned long t_swizzle(GLubyte swizzle)
+{
+/* this is in fact a NOP as the Mesa SWIZZLE_* are all identical to VSF_IN_COMPONENT_* */
+ return swizzle;
+}
+
+#if 0
+static void vp_dump_inputs(struct r300_vertex_program *vp, char *caller)
+{
+ int i;
+
+ if (vp == NULL) {
+ fprintf(stderr, "vp null in call to %s from %s\n", __FUNCTION__,
+ caller);
+ return;
+ }
+
+ fprintf(stderr, "%s:<", caller);
+ for (i = 0; i < VERT_ATTRIB_MAX; i++)
+ fprintf(stderr, "%d ", vp->inputs[i]);
+ fprintf(stderr, ">\n");
+
+}
+#endif
+
+static unsigned long t_src_index(struct r300_vertex_program *vp,
+ struct prog_src_register *src)
+{
+ int i;
+ int max_reg = -1;
+
+ if (src->File == PROGRAM_INPUT) {
+ if (vp->inputs[src->Index] != -1)
+ return vp->inputs[src->Index];
+
+ for (i = 0; i < VERT_ATTRIB_MAX; i++)
+ if (vp->inputs[i] > max_reg)
+ max_reg = vp->inputs[i];
+
+ vp->inputs[src->Index] = max_reg + 1;
+
+ //vp_dump_inputs(vp, __FUNCTION__);
+
+ return vp->inputs[src->Index];
+ } else {
+ if (src->Index < 0) {
+ fprintf(stderr,
+ "negative offsets for indirect addressing do not work.\n");
+ return 0;
+ }
+ return src->Index;
+ }
+}
+
+static unsigned long t_src(struct r300_vertex_program *vp,
+ struct prog_src_register *src)
+{
+ /* src->NegateBase uses the NEGATE_ flags from program_instruction.h,
+ * which equal our VSF_FLAGS_ values, so it's safe to just pass it here.
+ */
+ return MAKE_VSF_SOURCE(t_src_index(vp, src),
+ t_swizzle(GET_SWZ(src->Swizzle, 0)),
+ t_swizzle(GET_SWZ(src->Swizzle, 1)),
+ t_swizzle(GET_SWZ(src->Swizzle, 2)),
+ t_swizzle(GET_SWZ(src->Swizzle, 3)),
+ t_src_class(src->File),
+ src->NegateBase) | (src->RelAddr << 4);
+}
+
+static unsigned long t_src_scalar(struct r300_vertex_program *vp,
+ struct prog_src_register *src)
+{
+
+ return MAKE_VSF_SOURCE(t_src_index(vp, src),
+ t_swizzle(GET_SWZ(src->Swizzle, 0)),
+ t_swizzle(GET_SWZ(src->Swizzle, 0)),
+ t_swizzle(GET_SWZ(src->Swizzle, 0)),
+ t_swizzle(GET_SWZ(src->Swizzle, 0)),
+ t_src_class(src->File),
+ src->
+ NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) |
+ (src->RelAddr << 4);
+}
+
+static unsigned long t_opcode(enum prog_opcode opcode)
+{
+
+ switch (opcode) {
+ /* *INDENT-OFF* */
+ case OPCODE_ARL: return R300_VPI_OUT_OP_ARL;
+ case OPCODE_DST: return R300_VPI_OUT_OP_DST;
+ case OPCODE_EX2: return R300_VPI_OUT_OP_EX2;
+ case OPCODE_EXP: return R300_VPI_OUT_OP_EXP;
+ case OPCODE_FRC: return R300_VPI_OUT_OP_FRC;
+ case OPCODE_LG2: return R300_VPI_OUT_OP_LG2;
+ case OPCODE_LOG: return R300_VPI_OUT_OP_LOG;
+ case OPCODE_MAX: return R300_VPI_OUT_OP_MAX;
+ case OPCODE_MIN: return R300_VPI_OUT_OP_MIN;
+ case OPCODE_MUL: return R300_VPI_OUT_OP_MUL;
+ case OPCODE_RCP: return R300_VPI_OUT_OP_RCP;
+ case OPCODE_RSQ: return R300_VPI_OUT_OP_RSQ;
+ case OPCODE_SGE: return R300_VPI_OUT_OP_SGE;
+ case OPCODE_SLT: return R300_VPI_OUT_OP_SLT;
+ case OPCODE_DP4: return R300_VPI_OUT_OP_DOT;
+ /* *INDENT-ON* */
+
+ default:
+ fprintf(stderr, "%s: Should not be called with opcode %d!",
+ __FUNCTION__, opcode);
+ }
+ _mesa_exit(-1);
+ return 0;
+}
+
+static unsigned long op_operands(enum prog_opcode opcode)
+{
+ int i;
+
+ /* Can we trust mesas opcodes to be in order ? */
+ for (i = 0; i < sizeof(op_names) / sizeof(*op_names); i++)
+ if (op_names[i].opcode == opcode)
+ return op_names[i].ip;
+
+ fprintf(stderr, "op %d not found in op_names\n", opcode);
+ _mesa_exit(-1);
+ return 0;
+}
+
+static GLboolean valid_dst(struct r300_vertex_program *vp,
+ struct prog_dst_register *dst)
+{
+ if (dst->File == PROGRAM_OUTPUT && vp->outputs[dst->Index] == -1) {
+ return GL_FALSE;
+ } else if (dst->File == PROGRAM_ADDRESS) {
+ assert(dst->Index == 0);
+ }
+
+ return GL_TRUE;
+}
+
+/* TODO: Get rid of t_src_class call */
+#define CMP_SRCS(a, b) ((a.RelAddr != b.RelAddr) || (a.Index != b.Index && \
+ ((t_src_class(a.File) == VSF_IN_CLASS_PARAM && \
+ t_src_class(b.File) == VSF_IN_CLASS_PARAM) || \
+ (t_src_class(a.File) == VSF_IN_CLASS_ATTR && \
+ t_src_class(b.File) == VSF_IN_CLASS_ATTR)))) \
+
+#define ZERO_SRC_0 (MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), \
+ SWIZZLE_ZERO, SWIZZLE_ZERO, \
+ SWIZZLE_ZERO, SWIZZLE_ZERO, \
+ t_src_class(src[0].File), VSF_FLAG_NONE) | (src[0].RelAddr << 4))
+
+#define ZERO_SRC_1 (MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), \
+ SWIZZLE_ZERO, SWIZZLE_ZERO, \
+ SWIZZLE_ZERO, SWIZZLE_ZERO, \
+ t_src_class(src[1].File), VSF_FLAG_NONE) | (src[1].RelAddr << 4))
+
+#define ZERO_SRC_2 (MAKE_VSF_SOURCE(t_src_index(vp, &src[2]), \
+ SWIZZLE_ZERO, SWIZZLE_ZERO, \
+ SWIZZLE_ZERO, SWIZZLE_ZERO, \
+ t_src_class(src[2].File), VSF_FLAG_NONE) | (src[2].RelAddr << 4))
+
+#define ONE_SRC_0 (MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), \
+ SWIZZLE_ONE, SWIZZLE_ONE, \
+ SWIZZLE_ONE, SWIZZLE_ONE, \
+ t_src_class(src[0].File), VSF_FLAG_NONE) | (src[0].RelAddr << 4))
+
+#define ONE_SRC_1 (MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), \
+ SWIZZLE_ONE, SWIZZLE_ONE, \
+ SWIZZLE_ONE, SWIZZLE_ONE, \
+ t_src_class(src[1].File), VSF_FLAG_NONE) | (src[1].RelAddr << 4))
+
+#define ONE_SRC_2 (MAKE_VSF_SOURCE(t_src_index(vp, &src[2]), \
+ SWIZZLE_ONE, SWIZZLE_ONE, \
+ SWIZZLE_ONE, SWIZZLE_ONE, \
+ t_src_class(src[2].File), VSF_FLAG_NONE) | (src[2].RelAddr << 4))
+
+/* DP4 version seems to trigger some hw peculiarity */
+//#define PREFER_DP4
+
+#define FREE_TEMPS() \
+ do { \
+ if(u_temp_i < vp->num_temporaries) { \
+ WARN_ONCE("Ran out of temps, num temps %d, us %d\n", vp->num_temporaries, u_temp_i); \
+ vp->native = GL_FALSE; \
+ } \
+ u_temp_i=VSF_MAX_FRAGMENT_TEMPS-1; \
+ } while (0)
+
+static void r300TranslateVertexShader(struct r300_vertex_program *vp,
+ struct prog_instruction *vpi)
+{
+ int i, cur_reg = 0;
+ VERTEX_SHADER_INSTRUCTION *o_inst;
+ unsigned long operands;
+ int are_srcs_scalar;
+ unsigned long hw_op;
+ /* Initial value should be last tmp reg that hw supports.
+ Strangely enough r300 doesnt mind even though these would be out of range.
+ Smart enough to realize that it doesnt need it? */
+ int u_temp_i = VSF_MAX_FRAGMENT_TEMPS - 1;
+ struct prog_src_register src[3];
+
+ vp->pos_end = 0; /* Not supported yet */
+ vp->program.length = 0;
+ /*vp->num_temporaries=mesa_vp->Base.NumTemporaries; */
+
+ for (i = 0; i < VERT_ATTRIB_MAX; i++)
+ vp->inputs[i] = -1;
+
+ for (i = 0; i < VERT_RESULT_MAX; i++)
+ vp->outputs[i] = -1;
+
+ assert(vp->key.OutputsWritten & (1 << VERT_RESULT_HPOS));
+
+ /* Assign outputs */
+ if (vp->key.OutputsWritten & (1 << VERT_RESULT_HPOS))
+ vp->outputs[VERT_RESULT_HPOS] = cur_reg++;
+
+ if (vp->key.OutputsWritten & (1 << VERT_RESULT_PSIZ))
+ vp->outputs[VERT_RESULT_PSIZ] = cur_reg++;
+
+ if (vp->key.OutputsWritten & (1 << VERT_RESULT_COL0))
+ vp->outputs[VERT_RESULT_COL0] = cur_reg++;
+
+ if (vp->key.OutputsWritten & (1 << VERT_RESULT_COL1))
+ vp->outputs[VERT_RESULT_COL1] = cur_reg++;
+
+#if 0 /* Not supported yet */
+ if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC0))
+ vp->outputs[VERT_RESULT_BFC0] = cur_reg++;
+
+ if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC1))
+ vp->outputs[VERT_RESULT_BFC1] = cur_reg++;
+
+ if (vp->key.OutputsWritten & (1 << VERT_RESULT_FOGC))
+ vp->outputs[VERT_RESULT_FOGC] = cur_reg++;
+#endif
+
+ for (i = VERT_RESULT_TEX0; i <= VERT_RESULT_TEX7; i++)
+ if (vp->key.OutputsWritten & (1 << i))
+ vp->outputs[i] = cur_reg++;
+
+ vp->translated = GL_TRUE;
+ vp->native = GL_TRUE;
+
+ o_inst = vp->program.body.i;
+ for (; vpi->Opcode != OPCODE_END; vpi++, o_inst++) {
+ FREE_TEMPS();
+
+ if (!valid_dst(vp, &vpi->DstReg)) {
+ /* redirect result to unused temp */
+ vpi->DstReg.File = PROGRAM_TEMPORARY;
+ vpi->DstReg.Index = u_temp_i;
+ }
+
+ operands = op_operands(vpi->Opcode);
+ are_srcs_scalar = operands & SCALAR_FLAG;
+ operands &= OP_MASK;
+
+ for (i = 0; i < operands; i++)
+ src[i] = vpi->SrcReg[i];
+
+ if (operands == 3) { /* TODO: scalars */
+ if (CMP_SRCS(src[1], src[2])
+ || CMP_SRCS(src[0], src[2])) {
+ o_inst->op =
+ MAKE_VSF_OP(R300_VPI_OUT_OP_ADD, u_temp_i,
+ VSF_FLAG_ALL,
+ VSF_OUT_CLASS_TMP);
+
+ o_inst->src[0] =
+ MAKE_VSF_SOURCE(t_src_index(vp, &src[2]),
+ SWIZZLE_X, SWIZZLE_Y,
+ SWIZZLE_Z, SWIZZLE_W,
+ t_src_class(src[2].File),
+ VSF_FLAG_NONE) | (src[2].
+ RelAddr <<
+ 4);
+
+ o_inst->src[1] = ZERO_SRC_2;
+ o_inst->src[2] = ZERO_SRC_2;
+ o_inst++;
+
+ src[2].File = PROGRAM_TEMPORARY;
+ src[2].Index = u_temp_i;
+ src[2].RelAddr = 0;
+ u_temp_i--;
+ }
+
+ }
+
+ if (operands >= 2) {
+ if (CMP_SRCS(src[1], src[0])) {
+ o_inst->op =
+ MAKE_VSF_OP(R300_VPI_OUT_OP_ADD, u_temp_i,
+ VSF_FLAG_ALL,
+ VSF_OUT_CLASS_TMP);
+
+ o_inst->src[0] =
+ MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
+ SWIZZLE_X, SWIZZLE_Y,
+ SWIZZLE_Z, SWIZZLE_W,
+ t_src_class(src[0].File),
+ VSF_FLAG_NONE) | (src[0].
+ RelAddr <<
+ 4);
+
+ o_inst->src[1] = ZERO_SRC_0;
+ o_inst->src[2] = ZERO_SRC_0;
+ o_inst++;
+
+ src[0].File = PROGRAM_TEMPORARY;
+ src[0].Index = u_temp_i;
+ src[0].RelAddr = 0;
+ u_temp_i--;
+ }
+ }
+
+ /* These ops need special handling. */
+ switch (vpi->Opcode) {
+ case OPCODE_POW:
+ o_inst->op =
+ MAKE_VSF_OP(R300_VPI_OUT_OP_POW,
+ t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+ o_inst->src[0] = t_src_scalar(vp, &src[0]);
+ o_inst->src[1] = ZERO_SRC_0;
+ o_inst->src[2] = t_src_scalar(vp, &src[1]);
+ goto next;
+
+ case OPCODE_MOV: //ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{} {ZERO ZERO ZERO ZERO}
+ case OPCODE_SWZ:
+#if 1
+ o_inst->op =
+ MAKE_VSF_OP(R300_VPI_OUT_OP_ADD,
+ t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+ o_inst->src[0] = t_src(vp, &src[0]);
+ o_inst->src[1] = ZERO_SRC_0;
+ o_inst->src[2] = ZERO_SRC_0;
+#else
+ hw_op =
+ (src[0].File ==
+ PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 :
+ R300_VPI_OUT_OP_MAD;
+
+ o_inst->op =
+ MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+ o_inst->src[0] = t_src(vp, &src[0]);
+ o_inst->src[1] = ONE_SRC_0;
+ o_inst->src[2] = ZERO_SRC_0;
+#endif
+
+ goto next;
+
+ case OPCODE_ADD:
+#if 1
+ hw_op = (src[0].File == PROGRAM_TEMPORARY &&
+ src[1].File ==
+ PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 :
+ R300_VPI_OUT_OP_MAD;
+
+ o_inst->op =
+ MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+ o_inst->src[0] = ONE_SRC_0;
+ o_inst->src[1] = t_src(vp, &src[0]);
+ o_inst->src[2] = t_src(vp, &src[1]);
+#else
+ o_inst->op =
+ MAKE_VSF_OP(R300_VPI_OUT_OP_ADD,
+ t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+ o_inst->src[0] = t_src(vp, &src[0]);
+ o_inst->src[1] = t_src(vp, &src[1]);
+ o_inst->src[2] = ZERO_SRC_1;
+
+#endif
+ goto next;
+
+ case OPCODE_MAD:
+ hw_op = (src[0].File == PROGRAM_TEMPORARY &&
+ src[1].File == PROGRAM_TEMPORARY &&
+ src[2].File ==
+ PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 :
+ R300_VPI_OUT_OP_MAD;
+
+ o_inst->op =
+ MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+ o_inst->src[0] = t_src(vp, &src[0]);
+ o_inst->src[1] = t_src(vp, &src[1]);
+ o_inst->src[2] = t_src(vp, &src[2]);
+ goto next;
+
+ case OPCODE_MUL: /* HW mul can take third arg but appears to have some other limitations. */
+ hw_op = (src[0].File == PROGRAM_TEMPORARY &&
+ src[1].File ==
+ PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 :
+ R300_VPI_OUT_OP_MAD;
+
+ o_inst->op =
+ MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+ o_inst->src[0] = t_src(vp, &src[0]);
+ o_inst->src[1] = t_src(vp, &src[1]);
+
+ o_inst->src[2] = ZERO_SRC_1;
+ goto next;
+
+ case OPCODE_DP3: //DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ZERO} PARAM 0{} {X Y Z ZERO}
+ o_inst->op =
+ MAKE_VSF_OP(R300_VPI_OUT_OP_DOT,
+ t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+
+ o_inst->src[0] =
+ MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
+ t_swizzle(GET_SWZ
+ (src[0].Swizzle, 0)),
+ t_swizzle(GET_SWZ
+ (src[0].Swizzle, 1)),
+ t_swizzle(GET_SWZ
+ (src[0].Swizzle, 2)),
+ SWIZZLE_ZERO,
+ t_src_class(src[0].File),
+ src[0].
+ NegateBase ? VSF_FLAG_XYZ :
+ VSF_FLAG_NONE) | (src[0].
+ RelAddr << 4);
+
+ o_inst->src[1] =
+ MAKE_VSF_SOURCE(t_src_index(vp, &src[1]),
+ t_swizzle(GET_SWZ
+ (src[1].Swizzle, 0)),
+ t_swizzle(GET_SWZ
+ (src[1].Swizzle, 1)),
+ t_swizzle(GET_SWZ
+ (src[1].Swizzle, 2)),
+ SWIZZLE_ZERO,
+ t_src_class(src[1].File),
+ src[1].
+ NegateBase ? VSF_FLAG_XYZ :
+ VSF_FLAG_NONE) | (src[1].
+ RelAddr << 4);
+
+ o_inst->src[2] = ZERO_SRC_1;
+ goto next;
+
+ case OPCODE_SUB: //ADD RESULT 1.X Y Z W TMP 0{} {X Y Z W} PARAM 1{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W
+#if 1
+ hw_op = (src[0].File == PROGRAM_TEMPORARY &&
+ src[1].File ==
+ PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 :
+ R300_VPI_OUT_OP_MAD;
+
+ o_inst->op =
+ MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+ o_inst->src[0] = t_src(vp, &src[0]);
+ o_inst->src[1] = ONE_SRC_0;
+ o_inst->src[2] =
+ MAKE_VSF_SOURCE(t_src_index(vp, &src[1]),
+ t_swizzle(GET_SWZ
+ (src[1].Swizzle, 0)),
+ t_swizzle(GET_SWZ
+ (src[1].Swizzle, 1)),
+ t_swizzle(GET_SWZ
+ (src[1].Swizzle, 2)),
+ t_swizzle(GET_SWZ
+ (src[1].Swizzle, 3)),
+ t_src_class(src[1].File),
+ (!src[1].
+ NegateBase) ? VSF_FLAG_ALL :
+ VSF_FLAG_NONE) | (src[1].
+ RelAddr << 4);
+#else
+ o_inst->op =
+ MAKE_VSF_OP(R300_VPI_OUT_OP_ADD,
+ t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+
+ o_inst->src[0] = t_src(vp, &src[0]);
+ o_inst->src[1] =
+ MAKE_VSF_SOURCE(t_src_index(vp, &src[1]),
+ t_swizzle(GET_SWZ
+ (src[1].Swizzle, 0)),
+ t_swizzle(GET_SWZ
+ (src[1].Swizzle, 1)),
+ t_swizzle(GET_SWZ
+ (src[1].Swizzle, 2)),
+ t_swizzle(GET_SWZ
+ (src[1].Swizzle, 3)),
+ t_src_class(src[1].File),
+ (!src[1].
+ NegateBase) ? VSF_FLAG_ALL :
+ VSF_FLAG_NONE) | (src[1].
+ RelAddr << 4);
+ o_inst->src[2] = 0;
+#endif
+ goto next;
+
+ case OPCODE_ABS: //MAX RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W
+ o_inst->op =
+ MAKE_VSF_OP(R300_VPI_OUT_OP_MAX,
+ t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+
+ o_inst->src[0] = t_src(vp, &src[0]);
+ o_inst->src[1] =
+ MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
+ t_swizzle(GET_SWZ
+ (src[0].Swizzle, 0)),
+ t_swizzle(GET_SWZ
+ (src[0].Swizzle, 1)),
+ t_swizzle(GET_SWZ
+ (src[0].Swizzle, 2)),
+ t_swizzle(GET_SWZ
+ (src[0].Swizzle, 3)),
+ t_src_class(src[0].File),
+ (!src[0].
+ NegateBase) ? VSF_FLAG_ALL :
+ VSF_FLAG_NONE) | (src[0].
+ RelAddr << 4);
+ o_inst->src[2] = 0;
+ goto next;
+
+ case OPCODE_FLR:
+ /* FRC TMP 0.X Y Z W PARAM 0{} {X Y Z W}
+ ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} TMP 0{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W */
+
+ o_inst->op = MAKE_VSF_OP(R300_VPI_OUT_OP_FRC, u_temp_i,
+ t_dst_mask(vpi->DstReg.
+ WriteMask),
+ VSF_OUT_CLASS_TMP);
+
+ o_inst->src[0] = t_src(vp, &src[0]);
+ o_inst->src[1] = ZERO_SRC_0;
+ o_inst->src[2] = ZERO_SRC_0;
+ o_inst++;
+
+ o_inst->op =
+ MAKE_VSF_OP(R300_VPI_OUT_OP_ADD,
+ t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+
+ o_inst->src[0] = t_src(vp, &src[0]);
+ o_inst->src[1] = MAKE_VSF_SOURCE(u_temp_i,
+ VSF_IN_COMPONENT_X,
+ VSF_IN_COMPONENT_Y,
+ VSF_IN_COMPONENT_Z,
+ VSF_IN_COMPONENT_W,
+ VSF_IN_CLASS_TMP,
+ /* Not 100% sure about this */
+ (!src[0].
+ NegateBase) ?
+ VSF_FLAG_ALL :
+ VSF_FLAG_NONE
+ /*VSF_FLAG_ALL */ );
+
+ o_inst->src[2] = ZERO_SRC_0;
+ u_temp_i--;
+ goto next;
+
+ case OPCODE_LG2: // LG2 RESULT 1.X Y Z W PARAM 0{} {X X X X}
+ o_inst->op =
+ MAKE_VSF_OP(R300_VPI_OUT_OP_LG2,
+ t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+
+ o_inst->src[0] =
+ MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
+ t_swizzle(GET_SWZ
+ (src[0].Swizzle, 0)),
+ t_swizzle(GET_SWZ
+ (src[0].Swizzle, 0)),
+ t_swizzle(GET_SWZ
+ (src[0].Swizzle, 0)),
+ t_swizzle(GET_SWZ
+ (src[0].Swizzle, 0)),
+ t_src_class(src[0].File),
+ src[0].
+ NegateBase ? VSF_FLAG_ALL :
+ VSF_FLAG_NONE) | (src[0].
+ RelAddr << 4);
+ o_inst->src[1] = ZERO_SRC_0;
+ o_inst->src[2] = ZERO_SRC_0;
+ goto next;
+
+ case OPCODE_LIT: //LIT TMP 1.Y Z TMP 1{} {X W Z Y} TMP 1{} {Y W Z X} TMP 1{} {Y X Z W}
+ o_inst->op =
+ MAKE_VSF_OP(R300_VPI_OUT_OP_LIT,
+ t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+ /* NOTE: Users swizzling might not work. */
+ o_inst->src[0] = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // x
+ t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // w
+ VSF_IN_COMPONENT_ZERO, // z
+ t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // y
+ t_src_class(src[0].
+ File),
+ src[0].
+ NegateBase ?
+ VSF_FLAG_ALL :
+ VSF_FLAG_NONE) |
+ (src[0].RelAddr << 4);
+ o_inst->src[1] = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // y
+ t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // w
+ VSF_IN_COMPONENT_ZERO, // z
+ t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // x
+ t_src_class(src[0].
+ File),
+ src[0].
+ NegateBase ?
+ VSF_FLAG_ALL :
+ VSF_FLAG_NONE) |
+ (src[0].RelAddr << 4);
+ o_inst->src[2] = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // y
+ t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // x
+ VSF_IN_COMPONENT_ZERO, // z
+ t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // w
+ t_src_class(src[0].
+ File),
+ src[0].
+ NegateBase ?
+ VSF_FLAG_ALL :
+ VSF_FLAG_NONE) |
+ (src[0].RelAddr << 4);
+ goto next;
+
+ case OPCODE_DPH: //DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ONE} PARAM 0{} {X Y Z W}
+ o_inst->op =
+ MAKE_VSF_OP(R300_VPI_OUT_OP_DOT,
+ t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+
+ o_inst->src[0] =
+ MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
+ t_swizzle(GET_SWZ
+ (src[0].Swizzle, 0)),
+ t_swizzle(GET_SWZ
+ (src[0].Swizzle, 1)),
+ t_swizzle(GET_SWZ
+ (src[0].Swizzle, 2)),
+ VSF_IN_COMPONENT_ONE,
+ t_src_class(src[0].File),
+ src[0].
+ NegateBase ? VSF_FLAG_XYZ :
+ VSF_FLAG_NONE) | (src[0].
+ RelAddr << 4);
+ o_inst->src[1] = t_src(vp, &src[1]);
+ o_inst->src[2] = ZERO_SRC_1;
+ goto next;
+
+ case OPCODE_XPD:
+ /* mul r0, r1.yzxw, r2.zxyw
+ mad r0, -r2.yzxw, r1.zxyw, r0
+ NOTE: might need MAD_2
+ */
+
+ o_inst->op = MAKE_VSF_OP(R300_VPI_OUT_OP_MAD, u_temp_i,
+ t_dst_mask(vpi->DstReg.
+ WriteMask),
+ VSF_OUT_CLASS_TMP);
+
+ o_inst->src[0] = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // y
+ t_swizzle(GET_SWZ(src[0].Swizzle, 2)), // z
+ t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // x
+ t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // w
+ t_src_class(src[0].
+ File),
+ src[0].
+ NegateBase ?
+ VSF_FLAG_ALL :
+ VSF_FLAG_NONE) |
+ (src[0].RelAddr << 4);
+
+ o_inst->src[1] = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), t_swizzle(GET_SWZ(src[1].Swizzle, 2)), // z
+ t_swizzle(GET_SWZ(src[1].Swizzle, 0)), // x
+ t_swizzle(GET_SWZ(src[1].Swizzle, 1)), // y
+ t_swizzle(GET_SWZ(src[1].Swizzle, 3)), // w
+ t_src_class(src[1].
+ File),
+ src[1].
+ NegateBase ?
+ VSF_FLAG_ALL :
+ VSF_FLAG_NONE) |
+ (src[1].RelAddr << 4);
+
+ o_inst->src[2] = ZERO_SRC_1;
+ o_inst++;
+ u_temp_i--;
+
+ o_inst->op =
+ MAKE_VSF_OP(R300_VPI_OUT_OP_MAD,
+ t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+
+ o_inst->src[0] = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), t_swizzle(GET_SWZ(src[1].Swizzle, 1)), // y
+ t_swizzle(GET_SWZ(src[1].Swizzle, 2)), // z
+ t_swizzle(GET_SWZ(src[1].Swizzle, 0)), // x
+ t_swizzle(GET_SWZ(src[1].Swizzle, 3)), // w
+ t_src_class(src[1].
+ File),
+ (!src[1].
+ NegateBase) ?
+ VSF_FLAG_ALL :
+ VSF_FLAG_NONE) |
+ (src[1].RelAddr << 4);
+
+ o_inst->src[1] = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 2)), // z
+ t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // x
+ t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // y
+ t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // w
+ t_src_class(src[0].
+ File),
+ src[0].
+ NegateBase ?
+ VSF_FLAG_ALL :
+ VSF_FLAG_NONE) |
+ (src[0].RelAddr << 4);
+
+ o_inst->src[2] = MAKE_VSF_SOURCE(u_temp_i + 1,
+ VSF_IN_COMPONENT_X,
+ VSF_IN_COMPONENT_Y,
+ VSF_IN_COMPONENT_Z,
+ VSF_IN_COMPONENT_W,
+ VSF_IN_CLASS_TMP,
+ VSF_FLAG_NONE);
+
+ goto next;
+
+ case OPCODE_RCC:
+ fprintf(stderr, "Dont know how to handle op %d yet\n",
+ vpi->Opcode);
+ _mesa_exit(-1);
+ break;
+ case OPCODE_END:
+ break;
+ default:
+ break;
+ }
+
+ o_inst->op =
+ MAKE_VSF_OP(t_opcode(vpi->Opcode),
+ t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+
+ if (are_srcs_scalar) {
+ switch (operands) {
+ case 1:
+ o_inst->src[0] = t_src_scalar(vp, &src[0]);
+ o_inst->src[1] = ZERO_SRC_0;
+ o_inst->src[2] = ZERO_SRC_0;
+ break;
+
+ case 2:
+ o_inst->src[0] = t_src_scalar(vp, &src[0]);
+ o_inst->src[1] = t_src_scalar(vp, &src[1]);
+ o_inst->src[2] = ZERO_SRC_1;
+ break;
+
+ case 3:
+ o_inst->src[0] = t_src_scalar(vp, &src[0]);
+ o_inst->src[1] = t_src_scalar(vp, &src[1]);
+ o_inst->src[2] = t_src_scalar(vp, &src[2]);
+ break;
+
+ default:
+ fprintf(stderr,
+ "scalars and op RCC not handled yet");
+ _mesa_exit(-1);
+ break;
+ }
+ } else {
+ switch (operands) {
+ case 1:
+ o_inst->src[0] = t_src(vp, &src[0]);
+ o_inst->src[1] = ZERO_SRC_0;
+ o_inst->src[2] = ZERO_SRC_0;
+ break;
+
+ case 2:
+ o_inst->src[0] = t_src(vp, &src[0]);
+ o_inst->src[1] = t_src(vp, &src[1]);
+ o_inst->src[2] = ZERO_SRC_1;
+ break;
+
+ case 3:
+ o_inst->src[0] = t_src(vp, &src[0]);
+ o_inst->src[1] = t_src(vp, &src[1]);
+ o_inst->src[2] = t_src(vp, &src[2]);
+ break;
+
+ default:
+ fprintf(stderr,
+ "scalars and op RCC not handled yet");
+ _mesa_exit(-1);
+ break;
+ }
+ }
+ next:;
+ }
+
+ /* Will most likely segfault before we get here... fix later. */
+ if (o_inst - vp->program.body.i >= VSF_MAX_FRAGMENT_LENGTH / 4) {
+ vp->program.length = 0;
+ vp->native = GL_FALSE;
+ return;
+ }
+ vp->program.length = (o_inst - vp->program.body.i) * 4;
+#if 0
+ fprintf(stderr, "hw program:\n");
+ for (i = 0; i < vp->program.length; i++)
+ fprintf(stderr, "%08x\n", vp->program.body.d[i]);
+#endif
+}
+
+static void position_invariant(struct gl_program *prog)
+{
+ struct prog_instruction *vpi;
+ struct gl_program_parameter_list *paramList;
+ int i;
+
+ gl_state_index tokens[STATE_LENGTH] = { STATE_MVP_MATRIX, 0, 0, 0, 0 };
+
+ /* tokens[4] = matrix modifier */
+#ifdef PREFER_DP4
+ tokens[4] = 0; /* not transposed or inverted */
+#else
+ tokens[4] = STATE_MATRIX_TRANSPOSE;
+#endif
+ paramList = prog->Parameters;
+
+ vpi = _mesa_alloc_instructions(prog->NumInstructions + 4);
+ _mesa_init_instructions(vpi, prog->NumInstructions + 4);
+
+ for (i = 0; i < 4; i++) {
+ GLint idx;
+ tokens[2] = tokens[3] = i; /* matrix row[i]..row[i] */
+ idx = _mesa_add_state_reference(paramList, tokens);
+#ifdef PREFER_DP4
+ vpi[i].Opcode = OPCODE_DP4;
+ vpi[i].StringPos = 0;
+ vpi[i].Data = 0;
+
+ vpi[i].DstReg.File = PROGRAM_OUTPUT;
+ vpi[i].DstReg.Index = VERT_RESULT_HPOS;
+ vpi[i].DstReg.WriteMask = 1 << i;
+ vpi[i].DstReg.CondMask = COND_TR;
+
+ vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR;
+ vpi[i].SrcReg[0].Index = idx;
+ vpi[i].SrcReg[0].Swizzle = SWIZZLE_XYZW;
+
+ vpi[i].SrcReg[1].File = PROGRAM_INPUT;
+ vpi[i].SrcReg[1].Index = VERT_ATTRIB_POS;
+ vpi[i].SrcReg[1].Swizzle = SWIZZLE_XYZW;
+#else
+ if (i == 0)
+ vpi[i].Opcode = OPCODE_MUL;
+ else
+ vpi[i].Opcode = OPCODE_MAD;
+
+ vpi[i].StringPos = 0;
+ vpi[i].Data = 0;
+
+ if (i == 3)
+ vpi[i].DstReg.File = PROGRAM_OUTPUT;
+ else
+ vpi[i].DstReg.File = PROGRAM_TEMPORARY;
+ vpi[i].DstReg.Index = 0;
+ vpi[i].DstReg.WriteMask = 0xf;
+ vpi[i].DstReg.CondMask = COND_TR;
+
+ vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR;
+ vpi[i].SrcReg[0].Index = idx;
+ vpi[i].SrcReg[0].Swizzle = SWIZZLE_XYZW;
+
+ vpi[i].SrcReg[1].File = PROGRAM_INPUT;
+ vpi[i].SrcReg[1].Index = VERT_ATTRIB_POS;
+ vpi[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(i, i, i, i);
+
+ if (i > 0) {
+ vpi[i].SrcReg[2].File = PROGRAM_TEMPORARY;
+ vpi[i].SrcReg[2].Index = 0;
+ vpi[i].SrcReg[2].Swizzle = SWIZZLE_XYZW;
+ }
+#endif
+ }
+
+ _mesa_copy_instructions(&vpi[i], prog->Instructions,
+ prog->NumInstructions);
+
+ free(prog->Instructions);
+
+ prog->Instructions = vpi;
+
+ prog->NumInstructions += 4;
+ vpi = &prog->Instructions[prog->NumInstructions - 1];
+
+ assert(vpi->Opcode == OPCODE_END);
+}
+
+static void insert_wpos(struct r300_vertex_program *vp,
+ struct gl_program *prog, GLuint temp_index)
+{
+ struct prog_instruction *vpi;
+ struct prog_instruction *vpi_insert;
+ int i = 0;
+
+ vpi = _mesa_alloc_instructions(prog->NumInstructions + 2);
+ _mesa_init_instructions(vpi, prog->NumInstructions + 2);
+ /* all but END */
+ _mesa_copy_instructions(vpi, prog->Instructions,
+ prog->NumInstructions - 1);
+ /* END */
+ _mesa_copy_instructions(&vpi[prog->NumInstructions + 1],
+ &prog->Instructions[prog->NumInstructions - 1],
+ 1);
+ vpi_insert = &vpi[prog->NumInstructions - 1];
+
+ vpi_insert[i].Opcode = OPCODE_MOV;
+
+ vpi_insert[i].DstReg.File = PROGRAM_OUTPUT;
+ vpi_insert[i].DstReg.Index = VERT_RESULT_HPOS;
+ vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZW;
+ vpi_insert[i].DstReg.CondMask = COND_TR;
+
+ vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY;
+ vpi_insert[i].SrcReg[0].Index = temp_index;
+ vpi_insert[i].SrcReg[0].Swizzle = SWIZZLE_XYZW;
+ i++;
+
+ vpi_insert[i].Opcode = OPCODE_MOV;
+
+ vpi_insert[i].DstReg.File = PROGRAM_OUTPUT;
+ vpi_insert[i].DstReg.Index = VERT_RESULT_TEX0 + vp->wpos_idx;
+ vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZW;
+ vpi_insert[i].DstReg.CondMask = COND_TR;
+
+ vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY;
+ vpi_insert[i].SrcReg[0].Index = temp_index;
+ vpi_insert[i].SrcReg[0].Swizzle = SWIZZLE_XYZW;
+ i++;
+
+ free(prog->Instructions);
+
+ prog->Instructions = vpi;
+
+ prog->NumInstructions += i;
+ vpi = &prog->Instructions[prog->NumInstructions - 1];
+
+ assert(vpi->Opcode == OPCODE_END);
+}
+
+static void pos_as_texcoord(struct r300_vertex_program *vp,
+ struct gl_program *prog)
+{
+ struct prog_instruction *vpi;
+ 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) {
+ 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, struct gl_vertex_program
+ *mesa_vp, GLint wpos_idx)
+{
+ struct r300_vertex_program *vp;
+
+ vp = _mesa_calloc(sizeof(*vp));
+ _mesa_memcpy(&vp->key, wanted_key, sizeof(vp->key));
+
+ vp->wpos_idx = wpos_idx;
+
+ if (mesa_vp->IsPositionInvariant) {
+ position_invariant(&mesa_vp->Base);
+ }
+
+ if (wpos_idx > -1)
+ pos_as_texcoord(vp, &mesa_vp->Base);
+
+ assert(mesa_vp->Base.NumInstructions);
+
+ vp->num_temporaries = mesa_vp->Base.NumTemporaries;
+
+ r300TranslateVertexShader(vp, mesa_vp->Base.Instructions);
+
+ return vp;
+}
+
+void r300SelectVertexShader(r300ContextPtr r300)
+{
+ GLcontext *ctx = ctx = r300->radeon.glCtx;
+ GLuint InputsRead;
+ struct r300_vertex_program_key wanted_key = { 0 };
+ GLint i;
+ struct r300_vertex_program_cont *vpc;
+ struct r300_vertex_program *vp;
+ GLint wpos_idx;
+
+ vpc = (struct r300_vertex_program_cont *)ctx->VertexProgram._Current;
+ InputsRead = ctx->FragmentProgram._Current->Base.InputsRead;
+
+ wanted_key.OutputsWritten |= 1 << VERT_RESULT_HPOS;
+
+ wpos_idx = -1;
+ if (InputsRead & FRAG_BIT_WPOS) {
+ for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
+ if (!(InputsRead & (FRAG_BIT_TEX0 << i)))
+ break;
+
+ if (i == ctx->Const.MaxTextureUnits) {
+ fprintf(stderr, "\tno free texcoord found\n");
+ _mesa_exit(-1);
+ }
+
+ InputsRead |= (FRAG_BIT_TEX0 << i);
+ wpos_idx = i;
+ }
+
+ if (InputsRead & FRAG_BIT_COL0)
+ wanted_key.OutputsWritten |= 1 << VERT_RESULT_COL0;
+
+ if ((InputsRead & FRAG_BIT_COL1) /*||
+ (InputsRead & FRAG_BIT_FOGC) */ )
+ wanted_key.OutputsWritten |= 1 << VERT_RESULT_COL1;
+
+ for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
+ if (InputsRead & (FRAG_BIT_TEX0 << i))
+ 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) {
+ r300->selected_vp = vp;
+ return;
+ }
+ //_mesa_print_program(&vpc->mesa_program.Base);
+
+ vp = build_program(&wanted_key, &vpc->mesa_program, wpos_idx);
+ vp->next = vpc->progs;
+ vpc->progs = vp;
+ r300->selected_vp = vp;
+}
diff --git a/dist/Mesa/src/mesa/drivers/dri/r300/r300_vertprog.h b/dist/Mesa/src/mesa/drivers/dri/r300/r300_vertprog.h
new file mode 100644
index 000000000..252d5a901
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/dri/r300/r300_vertprog.h
@@ -0,0 +1,89 @@
+#ifndef __R300_VERTPROG_H_
+#define __R300_VERTPROG_H_
+
+#include "r300_reg.h"
+
+typedef struct {
+ GLuint op;
+ GLuint src[3];
+} VERTEX_SHADER_INSTRUCTION;
+
+#define VSF_FLAG_X 1
+#define VSF_FLAG_Y 2
+#define VSF_FLAG_Z 4
+#define VSF_FLAG_W 8
+#define VSF_FLAG_XYZ (VSF_FLAG_X | VSF_FLAG_Y | VSF_FLAG_Z)
+#define VSF_FLAG_ALL 0xf
+#define VSF_FLAG_NONE 0
+
+#define VSF_OUT_CLASS_TMP 0
+#define VSF_OUT_CLASS_ADDR 1
+#define VSF_OUT_CLASS_RESULT 2
+
+/* first DWORD of an instruction */
+
+/* possible operations:
+ DOT, MUL, ADD, MAD, FRC, MAX, MIN, SGE, SLT, EXP, LOG, LIT, POW, RCP, RSQ, EX2,
+ LG2, MAD_2 */
+
+#define MAKE_VSF_OP(op, out_reg_index, out_reg_fields, class) \
+ ((op) \
+ | ((out_reg_index) << R300_VPI_OUT_REG_INDEX_SHIFT) \
+ | ((out_reg_fields) << 20) \
+ | ( (class) << 8 ) )
+
+#define EASY_VSF_OP(op, out_reg_index, out_reg_fields, class) \
+ MAKE_VSF_OP(R300_VPI_OUT_OP_##op, out_reg_index, VSF_FLAG_##out_reg_fields, VSF_OUT_CLASS_##class) \
+
+/* according to Nikolai, the subsequent 3 DWORDs are sources, use same define for each */
+
+#define VSF_IN_CLASS_TMP 0
+#define VSF_IN_CLASS_ATTR 1
+#define VSF_IN_CLASS_PARAM 2
+#define VSF_IN_CLASS_NONE 9
+
+#define VSF_IN_COMPONENT_X 0
+#define VSF_IN_COMPONENT_Y 1
+#define VSF_IN_COMPONENT_Z 2
+#define VSF_IN_COMPONENT_W 3
+#define VSF_IN_COMPONENT_ZERO 4
+#define VSF_IN_COMPONENT_ONE 5
+
+#define MAKE_VSF_SOURCE(in_reg_index, comp_x, comp_y, comp_z, comp_w, class, negate) \
+ ( ((in_reg_index)<<R300_VPI_IN_REG_INDEX_SHIFT) \
+ | ((comp_x)<<R300_VPI_IN_X_SHIFT) \
+ | ((comp_y)<<R300_VPI_IN_Y_SHIFT) \
+ | ((comp_z)<<R300_VPI_IN_Z_SHIFT) \
+ | ((comp_w)<<R300_VPI_IN_W_SHIFT) \
+ | ((negate)<<25) | ((class)))
+
+#define EASY_VSF_SOURCE(in_reg_index, comp_x, comp_y, comp_z, comp_w, class, negate) \
+ MAKE_VSF_SOURCE(in_reg_index, \
+ VSF_IN_COMPONENT_##comp_x, \
+ VSF_IN_COMPONENT_##comp_y, \
+ VSF_IN_COMPONENT_##comp_z, \
+ VSF_IN_COMPONENT_##comp_w, \
+ VSF_IN_CLASS_##class, VSF_FLAG_##negate)
+
+/* special sources: */
+
+/* (1.0,1.0,1.0,1.0) vector (ATTR, plain ) */
+#define VSF_ATTR_UNITY(reg) EASY_VSF_SOURCE(reg, ONE, ONE, ONE, ONE, ATTR, NONE)
+#define VSF_UNITY(reg) EASY_VSF_SOURCE(reg, ONE, ONE, ONE, ONE, NONE, NONE)
+
+/* contents of unmodified register */
+#define VSF_REG(reg) EASY_VSF_SOURCE(reg, X, Y, Z, W, ATTR, NONE)
+
+/* contents of unmodified parameter */
+#define VSF_PARAM(reg) EASY_VSF_SOURCE(reg, X, Y, Z, W, PARAM, NONE)
+
+/* contents of unmodified temporary register */
+#define VSF_TMP(reg) EASY_VSF_SOURCE(reg, X, Y, Z, W, TMP, NONE)
+
+/* components of ATTR register */
+#define VSF_ATTR_X(reg) EASY_VSF_SOURCE(reg, X, X, X, X, ATTR, NONE)
+#define VSF_ATTR_Y(reg) EASY_VSF_SOURCE(reg, Y, Y, Y, Y, ATTR, NONE)
+#define VSF_ATTR_Z(reg) EASY_VSF_SOURCE(reg, Z, Z, Z, Z, ATTR, NONE)
+#define VSF_ATTR_W(reg) EASY_VSF_SOURCE(reg, W, W, W, W, ATTR, NONE)
+
+#endif
diff --git a/dist/Mesa/src/mesa/drivers/dri/unichrome/server/via_regs.h b/dist/Mesa/src/mesa/drivers/dri/unichrome/server/via_regs.h
index 5c5eecbe8..87e1e9daa 100644
--- a/dist/Mesa/src/mesa/drivers/dri/unichrome/server/via_regs.h
+++ b/dist/Mesa/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
diff --git a/dist/Mesa/src/mesa/drivers/x11/xm_glide.c b/dist/Mesa/src/mesa/drivers/x11/xm_glide.c
new file mode 100644
index 000000000..ae4f4282d
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/x11/xm_glide.c
@@ -0,0 +1,276 @@
+/*
+ * 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.
+ */
+
+
+#include "glxheader.h"
+#include "xmesaP.h"
+
+#ifdef FX
+#include "../glide/fxdrv.h"
+
+void
+FXcreateContext(XMesaVisual v, XMesaWindow w, XMesaContext c, XMesaBuffer b)
+{
+ char *fxEnvVar = _mesa_getenv("MESA_GLX_FX");
+ if (fxEnvVar) {
+ if (fxEnvVar[0]!='d') {
+ int attribs[100];
+ int numAttribs = 0;
+ int hw;
+ if (v->mesa_visual.depthBits > 0) {
+ attribs[numAttribs++] = FXMESA_DEPTH_SIZE;
+ attribs[numAttribs++] = v->mesa_visual.depthBits;
+ }
+ if (v->mesa_visual.doubleBufferMode) {
+ attribs[numAttribs++] = FXMESA_DOUBLEBUFFER;
+ }
+ if (v->mesa_visual.accumRedBits > 0) {
+ attribs[numAttribs++] = FXMESA_ACCUM_SIZE;
+ attribs[numAttribs++] = v->mesa_visual.accumRedBits;
+ }
+ if (v->mesa_visual.stencilBits > 0) {
+ attribs[numAttribs++] = FXMESA_STENCIL_SIZE;
+ attribs[numAttribs++] = v->mesa_visual.stencilBits;
+ }
+ if (v->mesa_visual.alphaBits > 0) {
+ attribs[numAttribs++] = FXMESA_ALPHA_SIZE;
+ attribs[numAttribs++] = v->mesa_visual.alphaBits;
+ }
+ if (1) {
+ attribs[numAttribs++] = FXMESA_SHARE_CONTEXT;
+ attribs[numAttribs++] = (int) &(c->mesa);
+ }
+ attribs[numAttribs++] = FXMESA_NONE;
+
+ /* [dBorca] we should take an envvar for `fxMesaSelectCurrentBoard'!!! */
+ hw = fxMesaSelectCurrentBoard(0);
+
+ /* if these fail, there's a new bug somewhere */
+ ASSERT(b->mesa_buffer.Width > 0);
+ ASSERT(b->mesa_buffer.Height > 0);
+
+ if ((hw == GR_SSTTYPE_VOODOO) || (hw == GR_SSTTYPE_Voodoo2)) {
+ b->FXctx = fxMesaCreateBestContext(0, b->mesa_buffer.Width,
+ b->mesa_buffer.Height, attribs);
+ if ((v->undithered_pf!=PF_Index) && (b->backxrb->ximage)) {
+ b->FXisHackUsable = b->FXctx ? GL_TRUE : GL_FALSE;
+ if (b->FXctx && (fxEnvVar[0]=='w' || fxEnvVar[0]=='W')) {
+ b->FXwindowHack = GL_TRUE;
+ FX_grSstControl(GR_CONTROL_DEACTIVATE);
+ }
+ else {
+ b->FXwindowHack = GL_FALSE;
+ }
+ }
+ }
+ else {
+ if (fxEnvVar[0]=='w' || fxEnvVar[0]=='W')
+ b->FXctx = fxMesaCreateContext(w, GR_RESOLUTION_NONE,
+ GR_REFRESH_75Hz, attribs);
+ else
+ b->FXctx = fxMesaCreateBestContext(0, b->mesa_buffer.Width,
+ b->mesa_buffer.Height, attribs);
+ b->FXisHackUsable = GL_FALSE;
+ b->FXwindowHack = GL_FALSE;
+ }
+ /*
+ fprintf(stderr,
+ "voodoo %d, wid %d height %d hack: usable %d active %d\n",
+ hw, b->mesa_buffer.Width, b->mesa_buffer.Height,
+ b->FXisHackUsable, b->FXwindowHack);
+ */
+ }
+ }
+ else {
+ _mesa_warning(NULL, "WARNING: This Mesa Library includes the Glide driver but\n");
+ _mesa_warning(NULL, " you have not defined the MESA_GLX_FX env. var.\n");
+ _mesa_warning(NULL, " (check the README.3DFX file for more information).\n\n");
+ _mesa_warning(NULL, " you can disable this message with a 'export MESA_GLX_FX=disable'.\n");
+ }
+}
+
+
+void FXdestroyContext( XMesaBuffer b )
+{
+ if (b && b->FXctx)
+ fxMesaDestroyContext(b->FXctx);
+}
+
+
+GLboolean FXmakeCurrent( XMesaBuffer b )
+{
+ if (b->FXctx) {
+ fxMesaMakeCurrent(b->FXctx);
+
+ return GL_TRUE;
+ }
+ return GL_FALSE;
+}
+
+
+/*
+ * Read image from VooDoo frame buffer into X/Mesa's back XImage.
+ */
+static void FXgetImage( XMesaBuffer b )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ static unsigned short pixbuf[MAX_WIDTH];
+ GLuint x, y;
+ GLuint width, height;
+
+#ifdef XFree86Server
+ x = b->frontxrb->pixmap->x;
+ y = b->frontxrb->pixmap->y;
+ width = b->frontxrb->pixmap->width;
+ height = b->frontxrb->pixmap->height;
+ depth = b->frontxrb->pixmap->depth;
+#else
+ xmesa_get_window_size(b->display, b, &width, &height);
+ x = y = 0;
+#endif
+ if (b->mesa_buffer.Width != width || b->mesa_buffer.Height != height) {
+ b->mesa_buffer.Width = MIN2((int)width, b->FXctx->width);
+ b->mesa_buffer.Height = MIN2((int)height, b->FXctx->height);
+ if (b->mesa_buffer.Width & 1)
+ b->mesa_buffer.Width--; /* prevent odd width */
+ }
+
+ /* [dBorca] we're always in the right GR_COLORFORMAT... aren't we? */
+ /* grLfbWriteColorFormat(GR_COLORFORMAT_ARGB); */
+ if (b->xm_visual->undithered_pf==PF_5R6G5B) {
+ /* Special case: 16bpp RGB */
+ grLfbReadRegion( GR_BUFFER_FRONTBUFFER, /* src buffer */
+ 0, b->FXctx->height - b->mesa_buffer.Height, /*pos*/
+ b->mesa_buffer.Width, b->mesa_buffer.Height, /* size */
+ b->mesa_buffer.Width * sizeof(GLushort), /* stride */
+ b->backxrb->ximage->data); /* dest buffer */
+ }
+ else if (b->xm_visual->dithered_pf==PF_Dither
+ && GET_VISUAL_DEPTH(b->xm_visual)==8) {
+ /* Special case: 8bpp RGB */
+ for (y=0;y<b->mesa_buffer.Height;y++) {
+ GLubyte *ptr = (GLubyte*) b->backxrb->ximage->data
+ + b->backxrb->ximage->bytes_per_line * y;
+ XDITHER_SETUP(y);
+
+ /* read row from 3Dfx frame buffer */
+ grLfbReadRegion( GR_BUFFER_FRONTBUFFER,
+ 0, b->FXctx->height-(b->mesa_buffer.Height-y),
+ b->mesa_buffer.Width, 1,
+ 0,
+ pixbuf );
+
+ /* write to XImage back buffer */
+ for (x=0;x<b->mesa_buffer.Width;x++) {
+ GLubyte r = (pixbuf[x] & 0xf800) >> 8;
+ GLubyte g = (pixbuf[x] & 0x07e0) >> 3;
+ GLubyte b = (pixbuf[x] & 0x001f) << 3;
+ *ptr++ = XDITHER( x, r, g, b);
+ }
+ }
+ }
+ else {
+ /* General case: slow! */
+ for (y=0;y<b->mesa_buffer.Height;y++) {
+ /* read row from 3Dfx frame buffer */
+ grLfbReadRegion( GR_BUFFER_FRONTBUFFER,
+ 0, b->FXctx->height-(b->mesa_buffer.Height-y),
+ b->mesa_buffer.Width, 1,
+ 0,
+ pixbuf );
+
+ /* write to XImage back buffer */
+ for (x=0;x<b->mesa_buffer.Width;x++) {
+ XMesaPutPixel(b->backxrb->ximage,x,y,
+ xmesa_color_to_pixel(ctx,
+ (pixbuf[x] & 0xf800) >> 8,
+ (pixbuf[x] & 0x07e0) >> 3,
+ (pixbuf[x] & 0x001f) << 3,
+ 0xff,
+ b->xm_visual->undithered_pf));
+ }
+ }
+ }
+ /* grLfbWriteColorFormat(GR_COLORFORMAT_ABGR); */
+}
+
+
+GLboolean FXswapBuffers( XMesaBuffer b )
+{
+ if (b->FXctx) {
+ fxMesaSwapBuffers();
+
+ if (!b->FXwindowHack)
+ return GL_TRUE;
+
+ FXgetImage(b);
+ }
+ return GL_FALSE;
+}
+
+
+/*
+ * Switch 3Dfx support hack between window and full-screen mode.
+ */
+GLboolean XMesaSetFXmode( GLint mode )
+{
+ const char *fx = _mesa_getenv("MESA_GLX_FX");
+ if (fx && fx[0] != 'd') {
+ GET_CURRENT_CONTEXT(ctx);
+ GrHwConfiguration hw;
+ if (!FX_grSstQueryHardware(&hw)) {
+ /*fprintf(stderr, "!grSstQueryHardware\n");*/
+ return GL_FALSE;
+ }
+ if (hw.num_sst < 1) {
+ /*fprintf(stderr, "hw.num_sst < 1\n");*/
+ return GL_FALSE;
+ }
+ if (ctx) {
+ /* [dBorca] Hack alert:
+ * oh, this is sooo wrong: ctx above is
+ * really an fxMesaContext, not an XMesaContext
+ */
+ XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer);
+ if (mode == XMESA_FX_WINDOW) {
+ if (xmbuf->FXisHackUsable) {
+ FX_grSstControl(GR_CONTROL_DEACTIVATE);
+ xmbuf->FXwindowHack = GL_TRUE;
+ return GL_TRUE;
+ }
+ }
+ else if (mode == XMESA_FX_FULLSCREEN) {
+ FX_grSstControl(GR_CONTROL_ACTIVATE);
+ xmbuf->FXwindowHack = GL_FALSE;
+ return GL_TRUE;
+ }
+ else {
+ /* Error: Bad mode value */
+ }
+ }
+ }
+ /*fprintf(stderr, "fallthrough\n");*/
+ return GL_FALSE;
+}
+#endif
diff --git a/dist/Mesa/src/mesa/drivers/x11/xm_glide.h b/dist/Mesa/src/mesa/drivers/x11/xm_glide.h
new file mode 100644
index 000000000..f7d031652
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/x11/xm_glide.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.
+ */
+
+
+#ifndef _XM_GLIDE_H_
+#define _XM_GLIDE_H_
+
+extern void FXcreateContext( XMesaVisual v,
+ XMesaWindow w,
+ XMesaContext c,
+ XMesaBuffer b );
+
+extern void FXdestroyContext( XMesaBuffer b );
+
+extern GLboolean FXmakeCurrent( XMesaBuffer b );
+
+extern GLboolean FXswapBuffers( XMesaBuffer b );
+
+#endif /* _XM_GLIDE_H_ */
diff --git a/dist/Mesa/src/mesa/drivers/x11/xm_image.c b/dist/Mesa/src/mesa/drivers/x11/xm_image.c
new file mode 100644
index 000000000..087b4e4c3
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/x11/xm_image.c
@@ -0,0 +1,133 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, 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 PRECISION INSIGHT 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:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ * Brian Paul <brian@precisioninsight.com>
+ */
+
+#include <stdlib.h>
+#include <X11/Xmd.h>
+
+#include "glxheader.h"
+#include "xmesaP.h"
+
+#ifdef XFree86Server
+
+#ifdef ROUNDUP
+#undef ROUNDUP
+#endif
+
+#define ROUNDUP(nbytes, pad) ((((nbytes) + ((pad)-1)) / (pad)) * ((pad)>>3))
+
+XMesaImage *XMesaCreateImage(int bitsPerPixel, int width, int height, char *data)
+{
+ XMesaImage *image;
+
+ image = (XMesaImage *)xalloc(sizeof(XMesaImage));
+
+ if (image) {
+ image->width = width;
+ image->height = height;
+ image->data = data;
+ /* Always pad to 32 bits */
+ image->bytes_per_line = ROUNDUP((bitsPerPixel * width), 32);
+ image->bits_per_pixel = bitsPerPixel;
+ }
+
+ return image;
+}
+
+void XMesaDestroyImage(XMesaImage *image)
+{
+ if (image->data)
+ free(image->data);
+ xfree(image);
+}
+
+unsigned long XMesaGetPixel(XMesaImage *image, int x, int y)
+{
+ CARD8 *row = (CARD8 *)(image->data + y*image->bytes_per_line);
+ CARD8 *i8;
+ CARD16 *i16;
+ CARD32 *i32;
+ switch (image->bits_per_pixel) {
+ case 8:
+ i8 = (CARD8 *)row;
+ return i8[x];
+ break;
+ case 15:
+ case 16:
+ i16 = (CARD16 *)row;
+ return i16[x];
+ break;
+ case 24: /* WARNING: architecture specific code */
+ i8 = (CARD8 *)row;
+ return (((CARD32)i8[x*3]) |
+ (((CARD32)i8[x*3+1])<<8) |
+ (((CARD32)i8[x*3+2])<<16));
+ break;
+ case 32:
+ i32 = (CARD32 *)row;
+ return i32[x];
+ break;
+ }
+ return 0;
+}
+
+#ifndef XMESA_USE_PUTPIXEL_MACRO
+void XMesaPutPixel(XMesaImage *image, int x, int y, unsigned long pixel)
+{
+ CARD8 *row = (CARD8 *)(image->data + y*image->bytes_per_line);
+ CARD8 *i8;
+ CARD16 *i16;
+ CARD32 *i32;
+ switch (image->bits_per_pixel) {
+ case 8:
+ i8 = (CARD8 *)row;
+ i8[x] = (CARD8)pixel;
+ break;
+ case 15:
+ case 16:
+ i16 = (CARD16 *)row;
+ i16[x] = (CARD16)pixel;
+ break;
+ case 24: /* WARNING: architecture specific code */
+ i8 = (CARD8 *)__row;
+ i8[x*3] = (CARD8)(p);
+ i8[x*3+1] = (CARD8)(p>>8);
+ i8[x*3+2] = (CARD8)(p>>16);
+ case 32:
+ i32 = (CARD32 *)row;
+ i32[x] = (CARD32)pixel;
+ break;
+ }
+}
+#endif
+
+#endif /* XFree86Server */
diff --git a/dist/Mesa/src/mesa/drivers/x11/xm_image.h b/dist/Mesa/src/mesa/drivers/x11/xm_image.h
new file mode 100644
index 000000000..240ccee1a
--- /dev/null
+++ b/dist/Mesa/src/mesa/drivers/x11/xm_image.h
@@ -0,0 +1,84 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, 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 PRECISION INSIGHT 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:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ * Brian Paul <brian@precisioninsight.com>
+ */
+
+#ifndef _XM_IMAGE_H_
+#define _XM_IMAGE_H_
+
+#define XMESA_USE_PUTPIXEL_MACRO
+
+struct _XMesaImageRec {
+ int width, height;
+ char *data;
+ int bytes_per_line; /* Padded to 32 bits */
+ int bits_per_pixel;
+};
+
+extern XMesaImage *XMesaCreateImage(int bitsPerPixel, int width, int height,
+ char *data);
+extern void XMesaDestroyImage(XMesaImage *image);
+extern unsigned long XMesaGetPixel(XMesaImage *image, int x, int y);
+#ifdef XMESA_USE_PUTPIXEL_MACRO
+#define XMesaPutPixel(__i,__x,__y,__p) \
+{ \
+ CARD8 *__row = (CARD8 *)(__i->data + __y*__i->bytes_per_line); \
+ CARD8 *__i8; \
+ CARD16 *__i16; \
+ CARD32 *__i32; \
+ switch (__i->bits_per_pixel) { \
+ case 8: \
+ __i8 = (CARD8 *)__row; \
+ __i8[__x] = (CARD8)__p; \
+ break; \
+ case 15: \
+ case 16: \
+ __i16 = (CARD16 *)__row; \
+ __i16[__x] = (CARD16)__p; \
+ break; \
+ case 24: /* WARNING: architecture specific code */ \
+ __i8 = (CARD8 *)__row; \
+ __i8[__x*3] = (CARD8)(__p); \
+ __i8[__x*3+1] = (CARD8)(__p>>8); \
+ __i8[__x*3+2] = (CARD8)(__p>>16); \
+ break; \
+ case 32: \
+ __i32 = (CARD32 *)__row; \
+ __i32[__x] = (CARD32)__p; \
+ break; \
+ } \
+}
+#else
+extern void XMesaPutPixel(XMesaImage *image, int x, int y,
+ unsigned long pixel);
+#endif
+
+#endif /* _XM_IMAGE_H_ */