summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri')
-rw-r--r--src/mesa/drivers/dri/common/dri_util.c30
-rw-r--r--src/mesa/drivers/dri/common/drirenderbuffer.h7
-rw-r--r--src/mesa/drivers/dri/common/extension_helper.h600
-rw-r--r--src/mesa/drivers/dri/common/xmlpool/.gitignore5
-rw-r--r--src/mesa/drivers/dri/common/xmlpool/Makefile2
-rw-r--r--src/mesa/drivers/dri/common/xmlpool/options.h69
-rw-r--r--src/mesa/drivers/dri/common/xmlpool/sv.po226
-rw-r--r--src/mesa/drivers/dri/i915/i830_metaops.c2
-rw-r--r--src/mesa/drivers/dri/i915/i830_state.c2
-rw-r--r--src/mesa/drivers/dri/i915/i915_fragprog.c13
-rw-r--r--src/mesa/drivers/dri/i915/i915_program.c5
-rw-r--r--src/mesa/drivers/dri/i915/i915_state.c2
-rw-r--r--src/mesa/drivers/dri/i915/intel_context.c1
-rw-r--r--src/mesa/drivers/dri/i915tex/Makefile5
-rw-r--r--src/mesa/drivers/dri/i915tex/i830_context.h5
-rw-r--r--src/mesa/drivers/dri/i915tex/i830_metaops.c32
-rw-r--r--src/mesa/drivers/dri/i915tex/i830_state.c5
-rw-r--r--src/mesa/drivers/dri/i915tex/i830_texstate.c32
-rw-r--r--src/mesa/drivers/dri/i915tex/i830_vtbl.c91
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_context.c3
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_context.h1
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_fragprog.c13
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_program.c7
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_state.c3
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_tex.c35
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_tex_layout.c56
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_vtbl.c1
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_batchbuffer.c16
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_blit.c35
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_blit.h3
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_buffers.c49
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_context.c22
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_context.h2
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c14
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_mipmap_tree.h2
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_pixel.c5
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_pixel_copy.c11
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_pixel_draw.c14
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_pixel_read.c8
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_regions.c11
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_screen.c3
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_tex.c56
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_tex.h14
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_tex_copy.c3
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_tex_format.c26
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_tex_image.c132
l---------src/mesa/drivers/dri/i915tex/intel_tex_layout.c1
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_tex_subimage.c3
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_tex_validate.c25
-rw-r--r--src/mesa/drivers/dri/i915tex/server/i830_common.h8
-rw-r--r--src/mesa/drivers/dri/i915tex/server/i830_dri.h42
-rw-r--r--src/mesa/drivers/dri/i915tex/server/intel.h5
-rw-r--r--src/mesa/drivers/dri/i915tex/server/intel_dri.c81
-rw-r--r--src/mesa/drivers/dri/i965/Makefile5
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.c1
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.h11
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw_upload.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_eu.h1
-rw-r--r--src/mesa/drivers/dri/i965/brw_eu_emit.c155
-rw-r--r--src/mesa/drivers/dri/i965/brw_gs.c4
-rw-r--r--src/mesa/drivers/dri/i965/brw_metaops.c97
-rw-r--r--src/mesa/drivers/dri/i965/brw_misc_state.c8
-rw-r--r--src/mesa/drivers/dri/i965/brw_structs.h22
-rw-r--r--src/mesa/drivers/dri/i965/brw_tex.c32
-rw-r--r--src/mesa/drivers/dri/i965/brw_tex_layout.c55
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_tnl.c6
-rw-r--r--src/mesa/drivers/dri/i965/brw_vtbl.c1
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.c49
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_fp.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_state.c4
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_surface_state.c6
-rw-r--r--src/mesa/drivers/dri/i965/bufmgr.h2
-rw-r--r--src/mesa/drivers/dri/i965/bufmgr_fake.c18
-rw-r--r--src/mesa/drivers/dri/i965/intel_blit.c42
-rw-r--r--src/mesa/drivers/dri/i965/intel_blit.h3
-rw-r--r--src/mesa/drivers/dri/i965/intel_context.c51
-rw-r--r--src/mesa/drivers/dri/i965/intel_context.h8
-rw-r--r--src/mesa/drivers/dri/i965/intel_ioctl.c37
-rw-r--r--src/mesa/drivers/dri/i965/intel_pixel_copy.c113
-rw-r--r--src/mesa/drivers/dri/i965/intel_regions.c3
-rw-r--r--src/mesa/drivers/dri/i965/intel_screen.c6
-rw-r--r--src/mesa/drivers/dri/i965/intel_screen.h1
l---------src/mesa/drivers/dri/i965/intel_tex_layout.c1
-rw-r--r--src/mesa/drivers/dri/i965/intel_tex_validate.c3
-rw-r--r--src/mesa/drivers/dri/i965/server/i830_common.h19
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_layout.c102
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_layout.h41
-rw-r--r--src/mesa/drivers/dri/mach64/mach64_context.c76
-rw-r--r--src/mesa/drivers/dri/mach64/mach64_context.h57
-rw-r--r--src/mesa/drivers/dri/mach64/mach64_lock.c7
-rw-r--r--src/mesa/drivers/dri/mach64/mach64_screen.c2
-rw-r--r--src/mesa/drivers/dri/mach64/mach64_tex.c131
-rw-r--r--src/mesa/drivers/dri/mach64/mach64_tex.h10
-rw-r--r--src/mesa/drivers/dri/mach64/mach64_texmem.c655
-rw-r--r--src/mesa/drivers/dri/mach64/mach64_texstate.c135
-rw-r--r--src/mesa/drivers/dri/mach64/mach64_tris.c17
-rw-r--r--src/mesa/drivers/dri/mga/mgastate.c12
-rw-r--r--src/mesa/drivers/dri/mga/mgatex.c3
-rw-r--r--src/mesa/drivers/dri/nouveau/Makefile50
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c272
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h27
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_buffers.c434
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_buffers.h48
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_card.c17
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_card.h49
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_card_list.h230
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_context.c366
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_context.h227
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_ctrlreg.h44
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_dri.h28
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_driver.c146
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_driver.h42
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_fifo.c137
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_fifo.h156
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_lock.c81
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_lock.h69
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_msg.h67
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_object.c92
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_object.h41
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_reg.h1505
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_screen.c376
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_screen.h61
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_shader.c798
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_shader.h374
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_shader_0_arb.c710
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_shader_1.c318
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_shader_2.c243
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_span.c125
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_span.h39
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_state.c341
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_state.h48
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_state_cache.c69
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_state_cache.h29
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_swtcl.c127
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_swtcl.h55
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_sync.c136
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_sync.h36
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_tex.c49
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_tex.h38
-rw-r--r--src/mesa/drivers/dri/nouveau/nv04_swtcl.c570
-rw-r--r--src/mesa/drivers/dri/nouveau/nv04_swtcl.h12
-rw-r--r--src/mesa/drivers/dri/nouveau/nv10_state.c746
-rw-r--r--src/mesa/drivers/dri/nouveau/nv10_swtcl.c569
-rw-r--r--src/mesa/drivers/dri/nouveau/nv10_swtcl.h40
-rw-r--r--src/mesa/drivers/dri/nouveau/nv20_shader.h121
-rw-r--r--src/mesa/drivers/dri/nouveau/nv20_state.c662
-rw-r--r--src/mesa/drivers/dri/nouveau/nv20_vertprog.c447
-rw-r--r--src/mesa/drivers/dri/nouveau/nv30_fragprog.c716
-rw-r--r--src/mesa/drivers/dri/nouveau/nv30_shader.h379
-rw-r--r--src/mesa/drivers/dri/nouveau/nv30_state.c901
-rw-r--r--src/mesa/drivers/dri/nouveau/nv30_vertprog.c353
-rw-r--r--src/mesa/drivers/dri/nouveau/nv40_fragprog.c152
-rw-r--r--src/mesa/drivers/dri/nouveau/nv40_shader.h467
-rw-r--r--src/mesa/drivers/dri/nouveau/nv40_vertprog.c685
-rw-r--r--src/mesa/drivers/dri/r128/r128_span.c8
-rw-r--r--src/mesa/drivers/dri/r200/.gitignore3
-rw-r--r--src/mesa/drivers/dri/r200/r200_context.c27
-rw-r--r--src/mesa/drivers/dri/r200/r200_context.h9
-rw-r--r--src/mesa/drivers/dri/r200/r200_fragshader.c43
-rw-r--r--src/mesa/drivers/dri/r200/r200_lock.c14
-rw-r--r--src/mesa/drivers/dri/r200/r200_maos_arrays.c191
-rw-r--r--src/mesa/drivers/dri/r200/r200_sanity.c2
-rw-r--r--src/mesa/drivers/dri/r200/r200_state.c35
-rw-r--r--src/mesa/drivers/dri/r200/r200_tcl.c7
-rw-r--r--src/mesa/drivers/dri/r200/r200_texstate.c4
-rw-r--r--src/mesa/drivers/dri/r200/r200_vertprog.c104
-rw-r--r--src/mesa/drivers/dri/r300/.gitignore3
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.h26
-rw-r--r--src/mesa/drivers/dri/r300/r300_fragprog.c928
-rw-r--r--src/mesa/drivers/dri/r300/r300_fragprog.h3
-rw-r--r--src/mesa/drivers/dri/r300/r300_fragprog_swz.c1328
-rw-r--r--src/mesa/drivers/dri/r300/r300_ioctl.c14
-rw-r--r--src/mesa/drivers/dri/r300/r300_ioctl.h1
-rw-r--r--src/mesa/drivers/dri/r300/r300_maos.c4
-rw-r--r--src/mesa/drivers/dri/r300/r300_shader.c17
-rw-r--r--src/mesa/drivers/dri/r300/r300_state.c82
-rw-r--r--src/mesa/drivers/dri/r300/r300_vertexprog.c488
-rw-r--r--src/mesa/drivers/dri/r300/radeon_context.c9
-rw-r--r--src/mesa/drivers/dri/r300/radeon_mm.c2
-rw-r--r--src/mesa/drivers/dri/r300/radeon_state.c4
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_context.c1
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_texstate.c4
-rw-r--r--src/mesa/drivers/dri/savage/savage_init.h13
-rw-r--r--src/mesa/drivers/dri/savage/savage_xmesa.c63
-rw-r--r--src/mesa/drivers/dri/savage/savagedd.c19
-rw-r--r--src/mesa/drivers/dri/savage/savagespan.c6
-rw-r--r--src/mesa/drivers/dri/savage/savagestate.c11
-rw-r--r--src/mesa/drivers/dri/tdfx/tdfx_context.c28
-rw-r--r--src/mesa/drivers/dri/tdfx/tdfx_context.h12
-rw-r--r--src/mesa/drivers/dri/tdfx/tdfx_dd.c134
-rw-r--r--src/mesa/drivers/dri/tdfx/tdfx_lock.c23
-rw-r--r--src/mesa/drivers/dri/tdfx/tdfx_pixels.c12
-rw-r--r--src/mesa/drivers/dri/tdfx/tdfx_screen.c14
-rw-r--r--src/mesa/drivers/dri/tdfx/tdfx_span.c29
-rw-r--r--src/mesa/drivers/dri/tdfx/tdfx_tex.c2
-rw-r--r--src/mesa/drivers/dri/tdfx/tdfx_texstate.c5
-rw-r--r--src/mesa/drivers/dri/trident/trident_context.c1
-rw-r--r--src/mesa/drivers/dri/unichrome/via_context.c146
-rw-r--r--src/mesa/drivers/dri/unichrome/via_context.h33
-rw-r--r--src/mesa/drivers/dri/unichrome/via_ioctl.c34
-rw-r--r--src/mesa/drivers/dri/unichrome/via_screen.c1
-rw-r--r--src/mesa/drivers/dri/unichrome/via_span.c10
-rw-r--r--src/mesa/drivers/dri/unichrome/via_state.c14
204 files changed, 19075 insertions, 3678 deletions
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index e7f07569f4..cc3dcf9d8d 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -411,13 +411,18 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
if (!pcp
|| ((pdp != pcp->driDrawablePriv) && (pdp != pcp->driReadablePriv))) {
- /* ERROR!!! */
- return;
+ /* ERROR!!!
+ * ...but we must ignore it. There can be many contexts bound to a
+ * drawable.
+ */
}
psp = pdp->driScreenPriv;
if (!psp) {
/* ERROR!!! */
+ _mesa_problem("Warning! Possible infinite loop due to bug "
+ "in file %s, line %d\n",
+ __FILE__, __LINE__);
return;
}
@@ -477,8 +482,27 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
static void driSwapBuffers( __DRInativeDisplay *dpy, void *drawablePrivate )
{
__DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
+ drm_clip_rect_t rect;
+
dPriv->swapBuffers(dPriv);
- (void) dpy;
+
+ /* Check that we actually have the new damage report method */
+ if (api_ver < 20070105 || dri_interface->reportDamage == NULL)
+ return;
+
+ /* Assume it's affecting the whole drawable for now */
+ rect.x1 = 0;
+ rect.y1 = 0;
+ rect.x2 = rect.x1 + dPriv->w;
+ rect.y2 = rect.y1 + dPriv->h;
+
+ /* Report the damage. Currently, all our drivers draw directly to the
+ * front buffer, so we report the damage there rather than to the backing
+ * store (if any).
+ */
+ (*dri_interface->reportDamage)(dpy, dPriv->screen, dPriv->draw,
+ dPriv->x, dPriv->y,
+ &rect, 1, GL_TRUE);
}
/**
diff --git a/src/mesa/drivers/dri/common/drirenderbuffer.h b/src/mesa/drivers/dri/common/drirenderbuffer.h
index cd73b78174..747f92fcdb 100644
--- a/src/mesa/drivers/dri/common/drirenderbuffer.h
+++ b/src/mesa/drivers/dri/common/drirenderbuffer.h
@@ -52,8 +52,11 @@ typedef struct {
*/
GLboolean depthHasSurface;
- /* XXX this is for s3v only. A handy flag to know if this is the back
- * color buffer.
+ /**
+ * A handy flag to know if this is the back color buffer.
+ *
+ * \note
+ * This is currently only used by s3v and tdfx.
*/
GLboolean backBuffer;
} driRenderbuffer;
diff --git a/src/mesa/drivers/dri/common/extension_helper.h b/src/mesa/drivers/dri/common/extension_helper.h
index 618f1794c1..d6d51cdd16 100644
--- a/src/mesa/drivers/dri/common/extension_helper.h
+++ b/src/mesa/drivers/dri/common/extension_helper.h
@@ -32,9 +32,10 @@
# define NULL 0
#endif
-#if defined(need_GL_ARB_shader_objects)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
static const char UniformMatrix3fvARB_names[] =
"iiip\0" /* Parameter signature */
+ "glUniformMatrix3fv\0"
"glUniformMatrix3fvARB\0"
"";
#endif
@@ -78,6 +79,13 @@ static const char PointParameteriNV_names[] =
"";
#endif
+#if defined(need_GL_VERSION_2_0)
+static const char GetProgramiv_names[] =
+ "iip\0" /* Parameter signature */
+ "glGetProgramiv\0"
+ "";
+#endif
+
#if defined(need_GL_VERSION_1_3)
static const char MultiTexCoord3sARB_names[] =
"iiii\0" /* Parameter signature */
@@ -231,16 +239,17 @@ static const char TexCoord2fColor4ubVertex3fvSUN_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
-static const char ProgramEnvParameter4dvARB_names[] =
- "iip\0" /* Parameter signature */
- "glProgramEnvParameter4dvARB\0"
+#if defined(need_GL_VERSION_2_0)
+static const char AttachShader_names[] =
+ "ii\0" /* Parameter signature */
+ "glAttachShader\0"
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib2fARB_names[] =
"iff\0" /* Parameter signature */
+ "glVertexAttrib2f\0"
"glVertexAttrib2fARB\0"
"";
#endif
@@ -252,9 +261,10 @@ static const char GetDebugLogLengthMESA_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib3fARB_names[] =
"ifff\0" /* Parameter signature */
+ "glVertexAttrib3f\0"
"glVertexAttrib3fARB\0"
"";
#endif
@@ -305,16 +315,25 @@ static const char CompressedTexSubImage2DARB_names[] =
"";
#endif
-#if defined(need_GL_ARB_shader_objects)
+#if defined(need_GL_NV_register_combiners)
+static const char CombinerOutputNV_names[] =
+ "iiiiiiiiii\0" /* Parameter signature */
+ "glCombinerOutputNV\0"
+ "";
+#endif
+
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
static const char Uniform2fARB_names[] =
"iff\0" /* Parameter signature */
+ "glUniform2f\0"
"glUniform2fARB\0"
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib1svARB_names[] =
"ip\0" /* Parameter signature */
+ "glVertexAttrib1sv\0"
"glVertexAttrib1svARB\0"
"";
#endif
@@ -326,9 +345,10 @@ static const char VertexAttribs1dvNV_names[] =
"";
#endif
-#if defined(need_GL_ARB_shader_objects)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
static const char Uniform2ivARB_names[] =
"iip\0" /* Parameter signature */
+ "glUniform2iv\0"
"glUniform2ivARB\0"
"";
#endif
@@ -347,6 +367,13 @@ static const char WeightubvARB_names[] =
"";
#endif
+#if defined(need_GL_NV_vertex_program)
+static const char VertexAttrib1fvNV_names[] =
+ "ip\0" /* Parameter signature */
+ "glVertexAttrib1fvNV\0"
+ "";
+#endif
+
#if defined(need_GL_EXT_convolution)
static const char CopyConvolutionFilter1D_names[] =
"iiiii\0" /* Parameter signature */
@@ -377,9 +404,10 @@ static const char BlendColor_names[] =
"";
#endif
-#if defined(need_GL_ARB_shader_objects)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
static const char UniformMatrix4fvARB_names[] =
"iiip\0" /* Parameter signature */
+ "glUniformMatrix4fv\0"
"glUniformMatrix4fvARB\0"
"";
#endif
@@ -398,6 +426,13 @@ static const char ReadInstrumentsSGIX_names[] =
"";
#endif
+#if defined(need_GL_VERSION_2_1)
+static const char UniformMatrix2x4fv_names[] =
+ "iiip\0" /* Parameter signature */
+ "glUniformMatrix2x4fv\0"
+ "";
+#endif
+
#if defined(need_GL_SUN_vertex)
static const char Color4ubVertex3fvSUN_names[] =
"pp\0" /* Parameter signature */
@@ -412,9 +447,10 @@ static const char GetListParameterivSGIX_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib4NusvARB_names[] =
"ip\0" /* Parameter signature */
+ "glVertexAttrib4Nusv\0"
"glVertexAttrib4NusvARB\0"
"";
#endif
@@ -440,10 +476,10 @@ static const char FragmentLightModelivSGIX_names[] =
"";
#endif
-#if defined(need_GL_ATI_fragment_shader)
-static const char ColorFragmentOp3ATI_names[] =
- "iiiiiiiiiiiii\0" /* Parameter signature */
- "glColorFragmentOp3ATI\0"
+#if defined(need_GL_VERSION_2_1)
+static const char UniformMatrix4x3fv_names[] =
+ "iiip\0" /* Parameter signature */
+ "glUniformMatrix4x3fv\0"
"";
#endif
@@ -536,9 +572,10 @@ static const char ProgramParameter4dvNV_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char DisableVertexAttribArrayARB_names[] =
"i\0" /* Parameter signature */
+ "glDisableVertexAttribArray\0"
"glDisableVertexAttribArrayARB\0"
"";
#endif
@@ -573,9 +610,10 @@ static const char GetConvolutionParameteriv_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib1fARB_names[] =
"if\0" /* Parameter signature */
+ "glVertexAttrib1f\0"
"glVertexAttrib1fARB\0"
"";
#endif
@@ -688,16 +726,25 @@ static const char VertexAttrib2dNV_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0)
+static const char GetProgramInfoLog_names[] =
+ "iipp\0" /* Parameter signature */
+ "glGetProgramInfoLog\0"
+ "";
+#endif
+
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib4NbvARB_names[] =
"ip\0" /* Parameter signature */
+ "glVertexAttrib4Nbv\0"
"glVertexAttrib4NbvARB\0"
"";
#endif
-#if defined(need_GL_ARB_vertex_shader)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_shader)
static const char GetActiveAttribARB_names[] =
"iiipppp\0" /* Parameter signature */
+ "glGetActiveAttrib\0"
"glGetActiveAttribARB\0"
"";
#endif
@@ -863,9 +910,10 @@ static const char ReplacementCodeubvSUN_names[] =
"";
#endif
-#if defined(need_GL_ARB_shader_objects)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
static const char Uniform3iARB_names[] =
"iiii\0" /* Parameter signature */
+ "glUniform3i\0"
"glUniform3iARB\0"
"";
#endif
@@ -877,10 +925,10 @@ static const char GetFragmentMaterialfvSGIX_names[] =
"";
#endif
-#if defined(need_GL_EXT_coordinate_frame)
-static const char Binormal3fEXT_names[] =
- "fff\0" /* Parameter signature */
- "glBinormal3fEXT\0"
+#if defined(need_GL_VERSION_2_0)
+static const char GetShaderInfoLog_names[] =
+ "iipp\0" /* Parameter signature */
+ "glGetShaderInfoLog\0"
"";
#endif
@@ -998,9 +1046,10 @@ static const char TexSubImage1D_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib1sARB_names[] =
"ii\0" /* Parameter signature */
+ "glVertexAttrib1s\0"
"glVertexAttrib1sARB\0"
"";
#endif
@@ -1026,9 +1075,10 @@ static const char ReplacementCodeuiTexCoord2fVertex3fSUN_names[] =
"";
#endif
-#if defined(need_GL_ARB_shader_objects)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
static const char Uniform1fARB_names[] =
"if\0" /* Parameter signature */
+ "glUniform1f\0"
"glUniform1fARB\0"
"";
#endif
@@ -1162,9 +1212,10 @@ static const char GetFragmentLightivSGIX_names[] =
"";
#endif
-#if defined(need_GL_ARB_shader_objects)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
static const char UniformMatrix2fvARB_names[] =
"iiip\0" /* Parameter signature */
+ "glUniformMatrix2fv\0"
"glUniformMatrix2fvARB\0"
"";
#endif
@@ -1208,9 +1259,10 @@ static const char MapParameterfvNV_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib3dvARB_names[] =
"ip\0" /* Parameter signature */
+ "glVertexAttrib3dv\0"
"glVertexAttrib3dvARB\0"
"";
#endif
@@ -1301,9 +1353,10 @@ static const char GetAttachedObjectsARB_names[] =
"";
#endif
-#if defined(need_GL_ARB_shader_objects)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
static const char Uniform3fvARB_names[] =
"iip\0" /* Parameter signature */
+ "glUniform3fv\0"
"glUniform3fvARB\0"
"";
#endif
@@ -1344,9 +1397,10 @@ static const char GetHandleARB_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char GetVertexAttribivARB_names[] =
"iip\0" /* Parameter signature */
+ "glGetVertexAttribiv\0"
"glGetVertexAttribivARB\0"
"";
#endif
@@ -1358,10 +1412,10 @@ static const char GetCombinerInputParameterfvNV_names[] =
"";
#endif
-#if defined(need_GL_SUN_vertex)
-static const char ReplacementCodeuiNormal3fVertex3fvSUN_names[] =
- "ppp\0" /* Parameter signature */
- "glReplacementCodeuiNormal3fVertex3fvSUN\0"
+#if defined(need_GL_VERSION_2_0)
+static const char CreateProgram_names[] =
+ "\0" /* Parameter signature */
+ "glCreateProgram\0"
"";
#endif
@@ -1599,9 +1653,10 @@ static const char VertexAttrib3dNV_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib3dARB_names[] =
"iddd\0" /* Parameter signature */
+ "glVertexAttrib3d\0"
"glVertexAttrib3dARB\0"
"";
#endif
@@ -1613,9 +1668,10 @@ static const char ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN_names[]
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib4fARB_names[] =
"iffff\0" /* Parameter signature */
+ "glVertexAttrib4f\0"
"glVertexAttrib4fARB\0"
"";
#endif
@@ -1664,9 +1720,10 @@ static const char SecondaryColorPointerEXT_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib4fvARB_names[] =
"ip\0" /* Parameter signature */
+ "glVertexAttrib4fv\0"
"glVertexAttrib4fvARB\0"
"";
#endif
@@ -1678,9 +1735,10 @@ static const char ColorPointerListIBM_names[] =
"";
#endif
-#if defined(need_GL_ARB_shader_objects)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
static const char GetActiveUniformARB_names[] =
"iiipppp\0" /* Parameter signature */
+ "glGetActiveUniform\0"
"glGetActiveUniformARB\0"
"";
#endif
@@ -1722,6 +1780,13 @@ static const char DeformationMap3dSGIX_names[] =
"";
#endif
+#if defined(need_GL_VERSION_2_0)
+static const char IsShader_names[] =
+ "i\0" /* Parameter signature */
+ "glIsShader\0"
+ "";
+#endif
+
#if defined(need_GL_HP_image_transform)
static const char GetImageTransformParameterivHP_names[] =
"iip\0" /* Parameter signature */
@@ -1766,9 +1831,10 @@ static const char ResizeBuffersMESA_names[] =
"";
#endif
-#if defined(need_GL_ARB_shader_objects)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
static const char GetUniformivARB_names[] =
"iip\0" /* Parameter signature */
+ "glGetUniformiv\0"
"glGetUniformivARB\0"
"";
#endif
@@ -1860,6 +1926,13 @@ static const char MultiTexCoord3iARB_names[] =
"";
#endif
+#if defined(need_GL_VERSION_2_0)
+static const char IsProgram_names[] =
+ "i\0" /* Parameter signature */
+ "glIsProgram\0"
+ "";
+#endif
+
#if defined(need_GL_IBM_vertex_array_lists)
static const char TexCoordPointerListIBM_names[] =
"iiipi\0" /* Parameter signature */
@@ -1998,9 +2071,10 @@ static const char PointParameterivNV_names[] =
"";
#endif
-#if defined(need_GL_ARB_shader_objects)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
static const char Uniform2fvARB_names[] =
"iip\0" /* Parameter signature */
+ "glUniform2fv\0"
"glUniform2fvARB\0"
"";
#endif
@@ -2027,10 +2101,10 @@ static const char DeleteObjectARB_names[] =
"";
#endif
-#if defined(need_GL_ARB_shader_objects)
-static const char UseProgramObjectARB_names[] =
- "i\0" /* Parameter signature */
- "glUseProgramObjectARB\0"
+#if defined(need_GL_ARB_matrix_palette)
+static const char MatrixIndexPointerARB_names[] =
+ "iiip\0" /* Parameter signature */
+ "glMatrixIndexPointerARB\0"
"";
#endif
@@ -2055,10 +2129,18 @@ static const char BindFramebufferEXT_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib4usvARB_names[] =
- "ip\0" /* Parameter signature */
- "glVertexAttrib4usvARB\0"
+#if defined(need_GL_SGIX_reference_plane)
+static const char ReferencePlaneSGIX_names[] =
+ "p\0" /* Parameter signature */
+ "glReferencePlaneSGIX\0"
+ "";
+#endif
+
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
+static const char ValidateProgramARB_names[] =
+ "i\0" /* Parameter signature */
+ "glValidateProgram\0"
+ "glValidateProgramARB\0"
"";
#endif
@@ -2100,9 +2182,10 @@ static const char CopyTexSubImage3D_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib2dARB_names[] =
"idd\0" /* Parameter signature */
+ "glVertexAttrib2d\0"
"glVertexAttrib2dARB\0"
"";
#endif
@@ -2169,9 +2252,10 @@ static const char MultiTexCoord2sARB_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib1dvARB_names[] =
"ip\0" /* Parameter signature */
+ "glVertexAttrib1dv\0"
"glVertexAttrib1dvARB\0"
"";
#endif
@@ -2226,9 +2310,10 @@ static const char DeformSGIX_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char GetVertexAttribfvARB_names[] =
"iip\0" /* Parameter signature */
+ "glGetVertexAttribfv\0"
"glGetVertexAttribfvARB\0"
"";
#endif
@@ -2241,6 +2326,13 @@ static const char SecondaryColor3ivEXT_names[] =
"";
#endif
+#if defined(need_GL_VERSION_2_1)
+static const char UniformMatrix4x2fv_names[] =
+ "iiip\0" /* Parameter signature */
+ "glUniformMatrix4x2fv\0"
+ "";
+#endif
+
#if defined(need_GL_SGIS_detail_texture)
static const char GetDetailTexFuncSGIS_names[] =
"ip\0" /* Parameter signature */
@@ -2255,6 +2347,13 @@ static const char GetCombinerStageParameterfvNV_names[] =
"";
#endif
+#if defined(need_GL_EXT_coordinate_frame)
+static const char Binormal3fEXT_names[] =
+ "fff\0" /* Parameter signature */
+ "glBinormal3fEXT\0"
+ "";
+#endif
+
#if defined(need_GL_SUN_vertex)
static const char Color4ubVertex2fvSUN_names[] =
"pp\0" /* Parameter signature */
@@ -2277,9 +2376,10 @@ static const char SampleMaskSGIS_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_shader)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_shader)
static const char GetAttribLocationARB_names[] =
"ip\0" /* Parameter signature */
+ "glGetAttribLocation\0"
"glGetAttribLocationARB\0"
"";
#endif
@@ -2328,9 +2428,10 @@ static const char ProgramEnvParameter4fARB_names[] =
"";
#endif
-#if defined(need_GL_ARB_shader_objects)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
static const char Uniform3ivARB_names[] =
"iip\0" /* Parameter signature */
+ "glUniform3iv\0"
"glUniform3ivARB\0"
"";
#endif
@@ -2365,10 +2466,10 @@ static const char MultiTexCoord4ivARB_names[] =
"";
#endif
-#if defined(need_GL_EXT_gpu_program_parameters)
-static const char ProgramLocalParameters4fvEXT_names[] =
- "iiip\0" /* Parameter signature */
- "glProgramLocalParameters4fvEXT\0"
+#if defined(need_GL_VERSION_2_0)
+static const char GetVertexAttribPointervARB_names[] =
+ "iip\0" /* Parameter signature */
+ "glGetVertexAttribPointerv\0"
"";
#endif
@@ -2379,9 +2480,10 @@ static const char GetMapAttribParameterfvNV_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib4sARB_names[] =
"iiiii\0" /* Parameter signature */
+ "glVertexAttrib4s\0"
"glVertexAttrib4sARB\0"
"";
#endif
@@ -2408,9 +2510,10 @@ static const char GenRenderbuffersEXT_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib2dvARB_names[] =
"ip\0" /* Parameter signature */
+ "glVertexAttrib2dv\0"
"glVertexAttrib2dvARB\0"
"";
#endif
@@ -2436,9 +2539,10 @@ static const char WeightbvARB_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib2fvARB_names[] =
"ip\0" /* Parameter signature */
+ "glVertexAttrib2fv\0"
"glVertexAttrib2fvARB\0"
"";
#endif
@@ -2472,17 +2576,18 @@ static const char InstrumentsBufferSGIX_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib4NivARB_names[] =
"ip\0" /* Parameter signature */
+ "glVertexAttrib4Niv\0"
"glVertexAttrib4NivARB\0"
"";
#endif
-#if defined(need_GL_SUN_triangle_list)
-static const char ReplacementCodeuivSUN_names[] =
- "p\0" /* Parameter signature */
- "glReplacementCodeuivSUN\0"
+#if defined(need_GL_VERSION_2_0)
+static const char GetAttachedShaders_names[] =
+ "iipp\0" /* Parameter signature */
+ "glGetAttachedShaders\0"
"";
#endif
@@ -2500,6 +2605,13 @@ static const char ProgramEnvParameters4fvEXT_names[] =
"";
#endif
+#if defined(need_GL_SUN_vertex)
+static const char TexCoord2fColor4fNormal3fVertex3fvSUN_names[] =
+ "pppp\0" /* Parameter signature */
+ "glTexCoord2fColor4fNormal3fVertex3fvSUN\0"
+ "";
+#endif
+
#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos)
static const char WindowPos2iMESA_names[] =
"ii\0" /* Parameter signature */
@@ -2539,17 +2651,26 @@ static const char GetProgramStringARB_names[] =
"";
#endif
-#if defined(need_GL_ARB_shader_objects)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
static const char CompileShaderARB_names[] =
"i\0" /* Parameter signature */
+ "glCompileShader\0"
"glCompileShaderARB\0"
"";
#endif
-#if defined(need_GL_NV_register_combiners)
-static const char CombinerOutputNV_names[] =
- "iiiiiiiiii\0" /* Parameter signature */
- "glCombinerOutputNV\0"
+#if defined(need_GL_VERSION_2_0)
+static const char DeleteShader_names[] =
+ "i\0" /* Parameter signature */
+ "glDeleteShader\0"
+ "";
+#endif
+
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
+static const char Uniform3fARB_names[] =
+ "ifff\0" /* Parameter signature */
+ "glUniform3f\0"
+ "glUniform3fARB\0"
"";
#endif
@@ -2611,9 +2732,10 @@ static const char WindowPos4sMESA_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib4NuivARB_names[] =
"ip\0" /* Parameter signature */
+ "glVertexAttrib4Nuiv\0"
"glVertexAttrib4NuivARB\0"
"";
#endif
@@ -2640,9 +2762,10 @@ static const char ReplacementCodeusvSUN_names[] =
"";
#endif
-#if defined(need_GL_ARB_shader_objects)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
static const char Uniform4fARB_names[] =
"iffff\0" /* Parameter signature */
+ "glUniform4f\0"
"glUniform4fARB\0"
"";
#endif
@@ -2713,9 +2836,10 @@ static const char VertexWeightfvEXT_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib1dARB_names[] =
"id\0" /* Parameter signature */
+ "glVertexAttrib1d\0"
"glVertexAttrib1dARB\0"
"";
#endif
@@ -2779,9 +2903,17 @@ static const char ReplacementCodeuiColor4ubVertex3fSUN_names[] =
"";
#endif
-#if defined(need_GL_ARB_shader_objects)
+#if defined(need_GL_ARB_vertex_program)
+static const char VertexAttrib4usvARB_names[] =
+ "ip\0" /* Parameter signature */
+ "glVertexAttrib4usvARB\0"
+ "";
+#endif
+
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
static const char LinkProgramARB_names[] =
"i\0" /* Parameter signature */
+ "glLinkProgram\0"
"glLinkProgramARB\0"
"";
#endif
@@ -2793,9 +2925,10 @@ static const char VertexAttrib2fNV_names[] =
"";
#endif
-#if defined(need_GL_ARB_shader_objects)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
static const char ShaderSourceARB_names[] =
"iipp\0" /* Parameter signature */
+ "glShaderSource\0"
"glShaderSourceARB\0"
"";
#endif
@@ -2807,9 +2940,10 @@ static const char FragmentMaterialiSGIX_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib3svARB_names[] =
"ip\0" /* Parameter signature */
+ "glVertexAttrib3sv\0"
"glVertexAttrib3svARB\0"
"";
#endif
@@ -2838,16 +2972,18 @@ static const char IsFramebufferEXT_names[] =
"";
#endif
-#if defined(need_GL_ARB_shader_objects)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
static const char Uniform4ivARB_names[] =
"iip\0" /* Parameter signature */
+ "glUniform4iv\0"
"glUniform4ivARB\0"
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char GetVertexAttribdvARB_names[] =
"iip\0" /* Parameter signature */
+ "glGetVertexAttribdv\0"
"glGetVertexAttribdvARB\0"
"";
#endif
@@ -2910,9 +3046,10 @@ static const char MultiDrawElementsEXT_names[] =
"";
#endif
-#if defined(need_GL_ARB_shader_objects)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
static const char Uniform1ivARB_names[] =
"iip\0" /* Parameter signature */
+ "glUniform1iv\0"
"glUniform1ivARB\0"
"";
#endif
@@ -2956,16 +3093,18 @@ static const char SecondaryColor3ubvEXT_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib4dvARB_names[] =
"ip\0" /* Parameter signature */
+ "glVertexAttrib4dv\0"
"glVertexAttrib4dvARB\0"
"";
#endif
-#if defined(need_GL_ARB_vertex_shader)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_shader)
static const char BindAttribLocationARB_names[] =
"iip\0" /* Parameter signature */
+ "glBindAttribLocation\0"
"glBindAttribLocationARB\0"
"";
#endif
@@ -3013,6 +3152,13 @@ static const char VertexAttribPointerNV_names[] =
"";
#endif
+#if defined(need_GL_EXT_gpu_program_parameters)
+static const char ProgramLocalParameters4fvEXT_names[] =
+ "iiip\0" /* Parameter signature */
+ "glProgramLocalParameters4fvEXT\0"
+ "";
+#endif
+
#if defined(need_GL_EXT_framebuffer_object)
static const char GetFramebufferAttachmentParameterivEXT_names[] =
"iiip\0" /* Parameter signature */
@@ -3035,13 +3181,6 @@ static const char PixelTransformParameteriEXT_names[] =
"";
#endif
-#if defined(need_GL_ARB_shader_objects)
-static const char ValidateProgramARB_names[] =
- "i\0" /* Parameter signature */
- "glValidateProgramARB\0"
- "";
-#endif
-
#if defined(need_GL_SUN_vertex)
static const char TexCoord2fColor4ubVertex3fSUN_names[] =
"ffiiiifff\0" /* Parameter signature */
@@ -3049,16 +3188,18 @@ static const char TexCoord2fColor4ubVertex3fSUN_names[] =
"";
#endif
-#if defined(need_GL_ARB_shader_objects)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
static const char Uniform1iARB_names[] =
"ii\0" /* Parameter signature */
+ "glUniform1i\0"
"glUniform1iARB\0"
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttribPointerARB_names[] =
"iiiiip\0" /* Parameter signature */
+ "glVertexAttribPointer\0"
"glVertexAttribPointerARB\0"
"";
#endif
@@ -3078,6 +3219,13 @@ static const char MultiTexCoord4fvARB_names[] =
"";
#endif
+#if defined(need_GL_VERSION_2_1)
+static const char UniformMatrix2x3fv_names[] =
+ "iiip\0" /* Parameter signature */
+ "glUniformMatrix2x3fv\0"
+ "";
+#endif
+
#if defined(need_GL_NV_vertex_program)
static const char TrackMatrixNV_names[] =
"iiii\0" /* Parameter signature */
@@ -3120,16 +3268,18 @@ static const char Normal3fVertex3fvSUN_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib4NsvARB_names[] =
"ip\0" /* Parameter signature */
+ "glVertexAttrib4Nsv\0"
"glVertexAttrib4NsvARB\0"
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib3fvARB_names[] =
"ip\0" /* Parameter signature */
+ "glVertexAttrib3fv\0"
"glVertexAttrib3fvARB\0"
"";
#endif
@@ -3192,10 +3342,10 @@ static const char PixelTexGenParameterfSGIS_names[] =
"";
#endif
-#if defined(need_GL_SUN_vertex)
-static const char TexCoord2fColor4fNormal3fVertex3fvSUN_names[] =
- "pppp\0" /* Parameter signature */
- "glTexCoord2fColor4fNormal3fVertex3fvSUN\0"
+#if defined(need_GL_VERSION_2_0)
+static const char CreateShader_names[] =
+ "i\0" /* Parameter signature */
+ "glCreateShader\0"
"";
#endif
@@ -3258,16 +3408,17 @@ static const char FragmentLightfvSGIX_names[] =
"";
#endif
-#if defined(need_GL_NV_vertex_program)
-static const char VertexAttrib3sNV_names[] =
- "iiii\0" /* Parameter signature */
- "glVertexAttrib3sNV\0"
+#if defined(need_GL_VERSION_2_0)
+static const char DetachShader_names[] =
+ "ii\0" /* Parameter signature */
+ "glDetachShader\0"
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib4NubARB_names[] =
"iiiii\0" /* Parameter signature */
+ "glVertexAttrib4Nub\0"
"glVertexAttrib4NubARB\0"
"";
#endif
@@ -3293,9 +3444,10 @@ static const char VertexAttrib3svNV_names[] =
"";
#endif
-#if defined(need_GL_ARB_shader_objects)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
static const char Uniform4fvARB_names[] =
"iip\0" /* Parameter signature */
+ "glUniform4fv\0"
"glUniform4fvARB\0"
"";
#endif
@@ -3315,9 +3467,10 @@ static const char ColorFragmentOp1ATI_names[] =
"";
#endif
-#if defined(need_GL_ARB_shader_objects)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
static const char GetUniformfvARB_names[] =
"iip\0" /* Parameter signature */
+ "glGetUniformfv\0"
"glGetUniformfvARB\0"
"";
#endif
@@ -3462,9 +3615,10 @@ static const char GetMapParameterivNV_names[] =
"";
#endif
-#if defined(need_GL_ARB_shader_objects)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
static const char Uniform4iARB_names[] =
"iiiii\0" /* Parameter signature */
+ "glUniform4i\0"
"glUniform4iARB\0"
"";
#endif
@@ -3501,6 +3655,13 @@ static const char GetColorTableParameteriv_names[] =
"";
#endif
+#if defined(need_GL_ARB_vertex_program)
+static const char ProgramEnvParameter4dvARB_names[] =
+ "iip\0" /* Parameter signature */
+ "glProgramEnvParameter4dvARB\0"
+ "";
+#endif
+
#if defined(need_GL_NV_vertex_program)
static const char VertexAttribs2fvNV_names[] =
"iip\0" /* Parameter signature */
@@ -3508,10 +3669,11 @@ static const char VertexAttribs2fvNV_names[] =
"";
#endif
-#if defined(need_GL_ARB_matrix_palette)
-static const char MatrixIndexPointerARB_names[] =
- "iiip\0" /* Parameter signature */
- "glMatrixIndexPointerARB\0"
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
+static const char UseProgramObjectARB_names[] =
+ "i\0" /* Parameter signature */
+ "glUseProgram\0"
+ "glUseProgramObjectARB\0"
"";
#endif
@@ -3529,10 +3691,10 @@ static const char PassTexCoordATI_names[] =
"";
#endif
-#if defined(need_GL_NV_vertex_program)
-static const char VertexAttrib1fvNV_names[] =
- "ip\0" /* Parameter signature */
- "glVertexAttrib1fvNV\0"
+#if defined(need_GL_VERSION_2_0)
+static const char DeleteProgram_names[] =
+ "i\0" /* Parameter signature */
+ "glDeleteProgram\0"
"";
#endif
@@ -3635,9 +3797,10 @@ static const char MultiTexCoord1dvARB_names[] =
"";
#endif
-#if defined(need_GL_ARB_shader_objects)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
static const char Uniform2iARB_names[] =
"iii\0" /* Parameter signature */
+ "glUniform2i\0"
"glUniform2iARB\0"
"";
#endif
@@ -3729,9 +3892,10 @@ static const char VertexAttribs4dvNV_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib4dARB_names[] =
"idddd\0" /* Parameter signature */
+ "glVertexAttrib4d\0"
"glVertexAttrib4dARB\0"
"";
#endif
@@ -3907,9 +4071,10 @@ static const char GetFogFuncSGIS_names[] =
"";
#endif
-#if defined(need_GL_ARB_shader_objects)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
static const char GetUniformLocationARB_names[] =
"ip\0" /* Parameter signature */
+ "glGetUniformLocation\0"
"glGetUniformLocationARB\0"
"";
#endif
@@ -3929,13 +4094,21 @@ static const char CombinerInputNV_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib3sARB_names[] =
"iiii\0" /* Parameter signature */
+ "glVertexAttrib3s\0"
"glVertexAttrib3sARB\0"
"";
#endif
+#if defined(need_GL_SUN_vertex)
+static const char ReplacementCodeuiNormal3fVertex3fvSUN_names[] =
+ "ppp\0" /* Parameter signature */
+ "glReplacementCodeuiNormal3fVertex3fvSUN\0"
+ "";
+#endif
+
#if defined(need_GL_ARB_vertex_program)
static const char ProgramStringARB_names[] =
"iiip\0" /* Parameter signature */
@@ -3951,6 +4124,13 @@ static const char TexCoord4fVertex4fvSUN_names[] =
#endif
#if defined(need_GL_NV_vertex_program)
+static const char VertexAttrib3sNV_names[] =
+ "iiii\0" /* Parameter signature */
+ "glVertexAttrib3sNV\0"
+ "";
+#endif
+
+#if defined(need_GL_NV_vertex_program)
static const char VertexAttrib1fNV_names[] =
"if\0" /* Parameter signature */
"glVertexAttrib1fNV\0"
@@ -3994,9 +4174,10 @@ static const char ActiveStencilFaceEXT_names[] =
"";
#endif
-#if defined(need_GL_ARB_shader_objects)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
static const char GetShaderSourceARB_names[] =
"iipp\0" /* Parameter signature */
+ "glGetShaderSource\0"
"glGetShaderSourceARB\0"
"";
#endif
@@ -4111,9 +4292,10 @@ static const char WeightsvARB_names[] =
"";
#endif
-#if defined(need_GL_ARB_shader_objects)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
static const char Uniform1fvARB_names[] =
"iip\0" /* Parameter signature */
+ "glUniform1fv\0"
"glUniform1fvARB\0"
"";
#endif
@@ -4156,9 +4338,17 @@ static const char VertexAttribs3svNV_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_SUN_triangle_list)
+static const char ReplacementCodeuivSUN_names[] =
+ "p\0" /* Parameter signature */
+ "glReplacementCodeuivSUN\0"
+ "";
+#endif
+
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char EnableVertexAttribArrayARB_names[] =
"i\0" /* Parameter signature */
+ "glEnableVertexAttribArray\0"
"glEnableVertexAttribArrayARB\0"
"";
#endif
@@ -4216,10 +4406,10 @@ static const char Tangent3bvEXT_names[] =
"";
#endif
-#if defined(need_GL_SGIX_reference_plane)
-static const char ReferencePlaneSGIX_names[] =
- "p\0" /* Parameter signature */
- "glReferencePlaneSGIX\0"
+#if defined(need_GL_VERSION_2_1)
+static const char UniformMatrix3x4fv_names[] =
+ "iiip\0" /* Parameter signature */
+ "glUniformMatrix3x4fv\0"
"";
#endif
@@ -4305,9 +4495,10 @@ static const char BindProgramNV_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib4svARB_names[] =
"ip\0" /* Parameter signature */
+ "glVertexAttrib4sv\0"
"glVertexAttrib4svARB\0"
"";
#endif
@@ -4319,10 +4510,10 @@ static const char CreateDebugObjectMESA_names[] =
"";
#endif
-#if defined(need_GL_ARB_shader_objects)
-static const char Uniform3fARB_names[] =
- "ifff\0" /* Parameter signature */
- "glUniform3fARB\0"
+#if defined(need_GL_VERSION_2_0)
+static const char GetShaderiv_names[] =
+ "iip\0" /* Parameter signature */
+ "glGetShaderiv\0"
"";
#endif
@@ -4378,9 +4569,17 @@ static const char GetFinalCombinerInputParameterfvNV_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_ATI_fragment_shader)
+static const char ColorFragmentOp3ATI_names[] =
+ "iiiiiiiiiiiii\0" /* Parameter signature */
+ "glColorFragmentOp3ATI\0"
+ "";
+#endif
+
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib2svARB_names[] =
"ip\0" /* Parameter signature */
+ "glVertexAttrib2sv\0"
"glVertexAttrib2svARB\0"
"";
#endif
@@ -4423,9 +4622,10 @@ static const char PollInstrumentsSGIX_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib4NubvARB_names[] =
"ip\0" /* Parameter signature */
+ "glVertexAttrib4Nubv\0"
"glVertexAttrib4NubvARB\0"
"";
#endif
@@ -4530,9 +4730,10 @@ static const char WeightuivARB_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib2sARB_names[] =
"iii\0" /* Parameter signature */
+ "glVertexAttrib2s\0"
"glVertexAttrib2sARB\0"
"";
#endif
@@ -4580,6 +4781,13 @@ static const char EdgeFlagPointerListIBM_names[] =
"";
#endif
+#if defined(need_GL_VERSION_2_1)
+static const char UniformMatrix3x2fv_names[] =
+ "iiip\0" /* Parameter signature */
+ "glUniformMatrix3x2fv\0"
+ "";
+#endif
+
#if defined(need_GL_EXT_histogram)
static const char GetMinmaxParameterfv_names[] =
"iip\0" /* Parameter signature */
@@ -4588,9 +4796,10 @@ static const char GetMinmaxParameterfv_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib1fvARB_names[] =
"ip\0" /* Parameter signature */
+ "glVertexAttrib1fv\0"
"glVertexAttrib1fvARB\0"
"";
#endif
@@ -4697,9 +4906,9 @@ static const struct dri_extension_function GL_ARB_draw_buffers_functions[] = {
static const struct dri_extension_function GL_ARB_matrix_palette_functions[] = {
{ MatrixIndexusvARB_names, MatrixIndexusvARB_remap_index, -1 },
{ MatrixIndexuivARB_names, MatrixIndexuivARB_remap_index, -1 },
+ { MatrixIndexPointerARB_names, MatrixIndexPointerARB_remap_index, -1 },
{ CurrentPaletteMatrixARB_names, CurrentPaletteMatrixARB_remap_index, -1 },
{ MatrixIndexubvARB_names, MatrixIndexubvARB_remap_index, -1 },
- { MatrixIndexPointerARB_names, MatrixIndexPointerARB_remap_index, -1 },
{ NULL, 0, 0 }
};
#endif
@@ -4752,26 +4961,26 @@ static const struct dri_extension_function GL_ARB_shader_objects_functions[] = {
{ GetUniformivARB_names, GetUniformivARB_remap_index, -1 },
{ Uniform2fvARB_names, Uniform2fvARB_remap_index, -1 },
{ DeleteObjectARB_names, DeleteObjectARB_remap_index, -1 },
- { UseProgramObjectARB_names, UseProgramObjectARB_remap_index, -1 },
+ { ValidateProgramARB_names, ValidateProgramARB_remap_index, -1 },
{ Uniform3ivARB_names, Uniform3ivARB_remap_index, -1 },
{ CompileShaderARB_names, CompileShaderARB_remap_index, -1 },
+ { Uniform3fARB_names, Uniform3fARB_remap_index, -1 },
{ Uniform4fARB_names, Uniform4fARB_remap_index, -1 },
{ LinkProgramARB_names, LinkProgramARB_remap_index, -1 },
{ ShaderSourceARB_names, ShaderSourceARB_remap_index, -1 },
{ Uniform4ivARB_names, Uniform4ivARB_remap_index, -1 },
{ Uniform1ivARB_names, Uniform1ivARB_remap_index, -1 },
- { ValidateProgramARB_names, ValidateProgramARB_remap_index, -1 },
{ Uniform1iARB_names, Uniform1iARB_remap_index, -1 },
{ Uniform4fvARB_names, Uniform4fvARB_remap_index, -1 },
{ GetUniformfvARB_names, GetUniformfvARB_remap_index, -1 },
{ DetachObjectARB_names, DetachObjectARB_remap_index, -1 },
{ Uniform4iARB_names, Uniform4iARB_remap_index, -1 },
+ { UseProgramObjectARB_names, UseProgramObjectARB_remap_index, -1 },
{ Uniform2iARB_names, Uniform2iARB_remap_index, -1 },
{ GetObjectParameterivARB_names, GetObjectParameterivARB_remap_index, -1 },
{ GetUniformLocationARB_names, GetUniformLocationARB_remap_index, -1 },
{ GetShaderSourceARB_names, GetShaderSourceARB_remap_index, -1 },
{ Uniform1fvARB_names, Uniform1fvARB_remap_index, -1 },
- { Uniform3fARB_names, Uniform3fARB_remap_index, -1 },
{ GetObjectParameterfvARB_names, GetObjectParameterfvARB_remap_index, -1 },
{ GetInfoLogARB_names, GetInfoLogARB_remap_index, -1 },
{ NULL, 0, 0 }
@@ -4836,7 +5045,6 @@ static const struct dri_extension_function GL_ARB_vertex_buffer_object_functions
#if defined(need_GL_ARB_vertex_program)
static const struct dri_extension_function GL_ARB_vertex_program_functions[] = {
- { ProgramEnvParameter4dvARB_names, ProgramEnvParameter4dvARB_remap_index, -1 },
{ VertexAttrib2fARB_names, VertexAttrib2fARB_remap_index, -1 },
{ VertexAttrib3fARB_names, VertexAttrib3fARB_remap_index, -1 },
{ VertexAttrib1svARB_names, VertexAttrib1svARB_remap_index, -1 },
@@ -4856,7 +5064,6 @@ static const struct dri_extension_function GL_ARB_vertex_program_functions[] = {
{ VertexAttrib4fARB_names, VertexAttrib4fARB_remap_index, -1 },
{ VertexAttrib4fvARB_names, VertexAttrib4fvARB_remap_index, -1 },
{ ProgramLocalParameter4dvARB_names, ProgramLocalParameter4dvARB_remap_index, -1 },
- { VertexAttrib4usvARB_names, VertexAttrib4usvARB_remap_index, -1 },
{ VertexAttrib2dARB_names, VertexAttrib2dARB_remap_index, -1 },
{ VertexAttrib1dvARB_names, VertexAttrib1dvARB_remap_index, -1 },
{ GetVertexAttribfvARB_names, GetVertexAttribfvARB_remap_index, -1 },
@@ -4871,6 +5078,7 @@ static const struct dri_extension_function GL_ARB_vertex_program_functions[] = {
{ IsProgramNV_names, IsProgramNV_remap_index, -1 },
{ ProgramEnvParameter4dARB_names, ProgramEnvParameter4dARB_remap_index, -1 },
{ VertexAttrib1dARB_names, VertexAttrib1dARB_remap_index, -1 },
+ { VertexAttrib4usvARB_names, VertexAttrib4usvARB_remap_index, -1 },
{ VertexAttrib3svARB_names, VertexAttrib3svARB_remap_index, -1 },
{ GetVertexAttribdvARB_names, GetVertexAttribdvARB_remap_index, -1 },
{ VertexAttrib4dvARB_names, VertexAttrib4dvARB_remap_index, -1 },
@@ -4879,6 +5087,7 @@ static const struct dri_extension_function GL_ARB_vertex_program_functions[] = {
{ VertexAttrib3fvARB_names, VertexAttrib3fvARB_remap_index, -1 },
{ VertexAttrib4NubARB_names, VertexAttrib4NubARB_remap_index, -1 },
{ GetProgramEnvParameterfvARB_names, GetProgramEnvParameterfvARB_remap_index, -1 },
+ { ProgramEnvParameter4dvARB_names, ProgramEnvParameter4dvARB_remap_index, -1 },
{ ProgramLocalParameter4fvARB_names, ProgramLocalParameter4fvARB_remap_index, -1 },
{ DeleteProgramsNV_names, DeleteProgramsNV_remap_index, -1 },
{ GetVertexAttribPointervNV_names, GetVertexAttribPointervNV_remap_index, -1 },
@@ -4949,7 +5158,6 @@ static const struct dri_extension_function GL_ATI_draw_buffers_functions[] = {
#if defined(need_GL_ATI_fragment_shader)
static const struct dri_extension_function GL_ATI_fragment_shader_functions[] = {
- { ColorFragmentOp3ATI_names, ColorFragmentOp3ATI_remap_index, -1 },
{ ColorFragmentOp2ATI_names, ColorFragmentOp2ATI_remap_index, -1 },
{ DeleteFragmentShaderATI_names, DeleteFragmentShaderATI_remap_index, -1 },
{ SetFragmentShaderConstantATI_names, SetFragmentShaderConstantATI_remap_index, -1 },
@@ -4961,6 +5169,7 @@ static const struct dri_extension_function GL_ATI_fragment_shader_functions[] =
{ PassTexCoordATI_names, PassTexCoordATI_remap_index, -1 },
{ BeginFragmentShaderATI_names, BeginFragmentShaderATI_remap_index, -1 },
{ BindFragmentShaderATI_names, BindFragmentShaderATI_remap_index, -1 },
+ { ColorFragmentOp3ATI_names, ColorFragmentOp3ATI_remap_index, -1 },
{ GenFragmentShadersATI_names, GenFragmentShadersATI_remap_index, -1 },
{ EndFragmentShaderATI_names, EndFragmentShaderATI_remap_index, -1 },
{ NULL, 0, 0 }
@@ -5032,11 +5241,11 @@ static const struct dri_extension_function GL_EXT_convolution_functions[] = {
#if defined(need_GL_EXT_coordinate_frame)
static const struct dri_extension_function GL_EXT_coordinate_frame_functions[] = {
- { Binormal3fEXT_names, Binormal3fEXT_remap_index, -1 },
{ TangentPointerEXT_names, TangentPointerEXT_remap_index, -1 },
{ Binormal3ivEXT_names, Binormal3ivEXT_remap_index, -1 },
{ Tangent3sEXT_names, Tangent3sEXT_remap_index, -1 },
{ Tangent3fvEXT_names, Tangent3fvEXT_remap_index, -1 },
+ { Binormal3fEXT_names, Binormal3fEXT_remap_index, -1 },
{ Tangent3dvEXT_names, Tangent3dvEXT_remap_index, -1 },
{ Binormal3bvEXT_names, Binormal3bvEXT_remap_index, -1 },
{ Binormal3dEXT_names, Binormal3dEXT_remap_index, -1 },
@@ -5134,8 +5343,8 @@ static const struct dri_extension_function GL_EXT_framebuffer_object_functions[]
#if defined(need_GL_EXT_gpu_program_parameters)
static const struct dri_extension_function GL_EXT_gpu_program_parameters_functions[] = {
- { ProgramLocalParameters4fvEXT_names, ProgramLocalParameters4fvEXT_remap_index, -1 },
{ ProgramEnvParameters4fvEXT_names, ProgramEnvParameters4fvEXT_remap_index, -1 },
+ { ProgramLocalParameters4fvEXT_names, ProgramLocalParameters4fvEXT_remap_index, -1 },
{ NULL, 0, 0 }
};
#endif
@@ -5475,12 +5684,12 @@ static const struct dri_extension_function GL_NV_point_sprite_functions[] = {
#if defined(need_GL_NV_register_combiners)
static const struct dri_extension_function GL_NV_register_combiners_functions[] = {
+ { CombinerOutputNV_names, CombinerOutputNV_remap_index, -1 },
{ CombinerParameterfvNV_names, CombinerParameterfvNV_remap_index, -1 },
{ GetCombinerOutputParameterfvNV_names, GetCombinerOutputParameterfvNV_remap_index, -1 },
{ FinalCombinerInputNV_names, FinalCombinerInputNV_remap_index, -1 },
{ GetCombinerInputParameterfvNV_names, GetCombinerInputParameterfvNV_remap_index, -1 },
{ GetCombinerOutputParameterivNV_names, GetCombinerOutputParameterivNV_remap_index, -1 },
- { CombinerOutputNV_names, CombinerOutputNV_remap_index, -1 },
{ CombinerParameteriNV_names, CombinerParameteriNV_remap_index, -1 },
{ GetFinalCombinerInputParameterivNV_names, GetFinalCombinerInputParameterivNV_remap_index, -1 },
{ CombinerInputNV_names, CombinerInputNV_remap_index, -1 },
@@ -5514,6 +5723,7 @@ static const struct dri_extension_function GL_NV_vertex_program_functions[] = {
{ VertexAttrib4ubvNV_names, VertexAttrib4ubvNV_remap_index, -1 },
{ VertexAttrib4svNV_names, VertexAttrib4svNV_remap_index, -1 },
{ VertexAttribs1dvNV_names, VertexAttribs1dvNV_remap_index, -1 },
+ { VertexAttrib1fvNV_names, VertexAttrib1fvNV_remap_index, -1 },
{ ProgramParameter4dvNV_names, ProgramParameter4dvNV_remap_index, -1 },
{ VertexAttrib4fNV_names, VertexAttrib4fNV_remap_index, -1 },
{ VertexAttrib2dNV_names, VertexAttrib2dNV_remap_index, -1 },
@@ -5546,7 +5756,6 @@ static const struct dri_extension_function GL_NV_vertex_program_functions[] = {
{ VertexAttribPointerNV_names, VertexAttribPointerNV_remap_index, -1 },
{ TrackMatrixNV_names, TrackMatrixNV_remap_index, -1 },
{ GetProgramParameterdvNV_names, GetProgramParameterdvNV_remap_index, -1 },
- { VertexAttrib3sNV_names, VertexAttrib3sNV_remap_index, -1 },
{ GetTrackMatrixivNV_names, GetTrackMatrixivNV_remap_index, -1 },
{ VertexAttrib3svNV_names, VertexAttrib3svNV_remap_index, -1 },
{ ProgramParameters4fvNV_names, ProgramParameters4fvNV_remap_index, -1 },
@@ -5554,13 +5763,13 @@ static const struct dri_extension_function GL_NV_vertex_program_functions[] = {
{ GetVertexAttribdvNV_names, GetVertexAttribdvNV_remap_index, -1 },
{ VertexAttrib3fvNV_names, VertexAttrib3fvNV_remap_index, -1 },
{ VertexAttribs2fvNV_names, VertexAttribs2fvNV_remap_index, -1 },
- { VertexAttrib1fvNV_names, VertexAttrib1fvNV_remap_index, -1 },
{ DeleteProgramsNV_names, DeleteProgramsNV_remap_index, -1 },
{ GetVertexAttribPointervNV_names, GetVertexAttribPointervNV_remap_index, -1 },
{ GetProgramStringNV_names, GetProgramStringNV_remap_index, -1 },
{ VertexAttrib4sNV_names, VertexAttrib4sNV_remap_index, -1 },
{ VertexAttribs4dvNV_names, VertexAttribs4dvNV_remap_index, -1 },
{ ProgramParameters4dvNV_names, ProgramParameters4dvNV_remap_index, -1 },
+ { VertexAttrib3sNV_names, VertexAttrib3sNV_remap_index, -1 },
{ VertexAttrib1fNV_names, VertexAttrib1fNV_remap_index, -1 },
{ VertexAttrib4dNV_names, VertexAttrib4dNV_remap_index, -1 },
{ VertexAttribs4ubvNV_names, VertexAttribs4ubvNV_remap_index, -1 },
@@ -5827,11 +6036,11 @@ static const struct dri_extension_function GL_SUN_mesh_array_functions[] = {
static const struct dri_extension_function GL_SUN_triangle_list_functions[] = {
{ ReplacementCodeubSUN_names, ReplacementCodeubSUN_remap_index, -1 },
{ ReplacementCodeubvSUN_names, ReplacementCodeubvSUN_remap_index, -1 },
- { ReplacementCodeuivSUN_names, ReplacementCodeuivSUN_remap_index, -1 },
{ ReplacementCodeusvSUN_names, ReplacementCodeusvSUN_remap_index, -1 },
{ ReplacementCodePointerSUN_names, ReplacementCodePointerSUN_remap_index, -1 },
{ ReplacementCodeusSUN_names, ReplacementCodeusSUN_remap_index, -1 },
{ ReplacementCodeuiSUN_names, ReplacementCodeuiSUN_remap_index, -1 },
+ { ReplacementCodeuivSUN_names, ReplacementCodeuivSUN_remap_index, -1 },
{ NULL, 0, 0 }
};
#endif
@@ -5853,7 +6062,6 @@ static const struct dri_extension_function GL_SUN_vertex_functions[] = {
{ ReplacementCodeuiTexCoord2fVertex3fSUN_names, ReplacementCodeuiTexCoord2fVertex3fSUN_remap_index, -1 },
{ TexCoord2fNormal3fVertex3fSUN_names, TexCoord2fNormal3fVertex3fSUN_remap_index, -1 },
{ Color3fVertex3fSUN_names, Color3fVertex3fSUN_remap_index, -1 },
- { ReplacementCodeuiNormal3fVertex3fvSUN_names, ReplacementCodeuiNormal3fVertex3fvSUN_remap_index, -1 },
{ Color3fVertex3fvSUN_names, Color3fVertex3fvSUN_remap_index, -1 },
{ Color4fNormal3fVertex3fvSUN_names, Color4fNormal3fVertex3fvSUN_remap_index, -1 },
{ ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN_names, ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN_remap_index, -1 },
@@ -5864,18 +6072,19 @@ static const struct dri_extension_function GL_SUN_vertex_functions[] = {
{ Color4ubVertex2fvSUN_names, Color4ubVertex2fvSUN_remap_index, -1 },
{ Normal3fVertex3fSUN_names, Normal3fVertex3fSUN_remap_index, -1 },
{ ReplacementCodeuiColor4fNormal3fVertex3fSUN_names, ReplacementCodeuiColor4fNormal3fVertex3fSUN_remap_index, -1 },
+ { TexCoord2fColor4fNormal3fVertex3fvSUN_names, TexCoord2fColor4fNormal3fVertex3fvSUN_remap_index, -1 },
{ TexCoord2fVertex3fvSUN_names, TexCoord2fVertex3fvSUN_remap_index, -1 },
{ Color4ubVertex2fSUN_names, Color4ubVertex2fSUN_remap_index, -1 },
{ ReplacementCodeuiColor4ubVertex3fSUN_names, ReplacementCodeuiColor4ubVertex3fSUN_remap_index, -1 },
{ TexCoord2fColor4ubVertex3fSUN_names, TexCoord2fColor4ubVertex3fSUN_remap_index, -1 },
{ Normal3fVertex3fvSUN_names, Normal3fVertex3fvSUN_remap_index, -1 },
{ Color4fNormal3fVertex3fSUN_names, Color4fNormal3fVertex3fSUN_remap_index, -1 },
- { TexCoord2fColor4fNormal3fVertex3fvSUN_names, TexCoord2fColor4fNormal3fVertex3fvSUN_remap_index, -1 },
{ ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN_names, ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN_remap_index, -1 },
{ ReplacementCodeuiColor4ubVertex3fvSUN_names, ReplacementCodeuiColor4ubVertex3fvSUN_remap_index, -1 },
{ ReplacementCodeuiColor3fVertex3fSUN_names, ReplacementCodeuiColor3fVertex3fSUN_remap_index, -1 },
{ TexCoord4fVertex4fSUN_names, TexCoord4fVertex4fSUN_remap_index, -1 },
{ TexCoord2fColor3fVertex3fvSUN_names, TexCoord2fColor3fVertex3fvSUN_remap_index, -1 },
+ { ReplacementCodeuiNormal3fVertex3fvSUN_names, ReplacementCodeuiNormal3fVertex3fvSUN_remap_index, -1 },
{ TexCoord4fVertex4fvSUN_names, TexCoord4fVertex4fvSUN_remap_index, -1 },
{ ReplacementCodeuiVertex3fSUN_names, ReplacementCodeuiVertex3fSUN_remap_index, -1 },
{ NULL, 0, 0 }
@@ -6012,11 +6221,106 @@ static const struct dri_extension_function GL_VERSION_1_5_functions[] = {
#if defined(need_GL_VERSION_2_0)
static const struct dri_extension_function GL_VERSION_2_0_functions[] = {
+ { UniformMatrix3fvARB_names, UniformMatrix3fvARB_remap_index, -1 },
+ { GetProgramiv_names, GetProgramiv_remap_index, -1 },
{ BlendEquationSeparateEXT_names, BlendEquationSeparateEXT_remap_index, -1 },
+ { AttachShader_names, AttachShader_remap_index, -1 },
+ { VertexAttrib2fARB_names, VertexAttrib2fARB_remap_index, -1 },
+ { VertexAttrib3fARB_names, VertexAttrib3fARB_remap_index, -1 },
+ { Uniform2fARB_names, Uniform2fARB_remap_index, -1 },
+ { VertexAttrib1svARB_names, VertexAttrib1svARB_remap_index, -1 },
+ { Uniform2ivARB_names, Uniform2ivARB_remap_index, -1 },
+ { UniformMatrix4fvARB_names, UniformMatrix4fvARB_remap_index, -1 },
+ { VertexAttrib4NusvARB_names, VertexAttrib4NusvARB_remap_index, -1 },
+ { DisableVertexAttribArrayARB_names, DisableVertexAttribArrayARB_remap_index, -1 },
{ StencilMaskSeparate_names, StencilMaskSeparate_remap_index, -1 },
+ { VertexAttrib1fARB_names, VertexAttrib1fARB_remap_index, -1 },
+ { GetProgramInfoLog_names, GetProgramInfoLog_remap_index, -1 },
+ { VertexAttrib4NbvARB_names, VertexAttrib4NbvARB_remap_index, -1 },
+ { GetActiveAttribARB_names, GetActiveAttribARB_remap_index, -1 },
+ { Uniform3iARB_names, Uniform3iARB_remap_index, -1 },
+ { GetShaderInfoLog_names, GetShaderInfoLog_remap_index, -1 },
+ { VertexAttrib1sARB_names, VertexAttrib1sARB_remap_index, -1 },
+ { Uniform1fARB_names, Uniform1fARB_remap_index, -1 },
{ StencilOpSeparate_names, StencilOpSeparate_remap_index, -1 },
+ { UniformMatrix2fvARB_names, UniformMatrix2fvARB_remap_index, -1 },
+ { VertexAttrib3dvARB_names, VertexAttrib3dvARB_remap_index, -1 },
+ { Uniform3fvARB_names, Uniform3fvARB_remap_index, -1 },
+ { GetVertexAttribivARB_names, GetVertexAttribivARB_remap_index, -1 },
+ { CreateProgram_names, CreateProgram_remap_index, -1 },
{ StencilFuncSeparate_names, StencilFuncSeparate_remap_index, -1 },
+ { VertexAttrib3dARB_names, VertexAttrib3dARB_remap_index, -1 },
+ { VertexAttrib4fARB_names, VertexAttrib4fARB_remap_index, -1 },
+ { VertexAttrib4fvARB_names, VertexAttrib4fvARB_remap_index, -1 },
+ { GetActiveUniformARB_names, GetActiveUniformARB_remap_index, -1 },
+ { IsShader_names, IsShader_remap_index, -1 },
+ { GetUniformivARB_names, GetUniformivARB_remap_index, -1 },
+ { IsProgram_names, IsProgram_remap_index, -1 },
+ { Uniform2fvARB_names, Uniform2fvARB_remap_index, -1 },
+ { ValidateProgramARB_names, ValidateProgramARB_remap_index, -1 },
+ { VertexAttrib2dARB_names, VertexAttrib2dARB_remap_index, -1 },
+ { VertexAttrib1dvARB_names, VertexAttrib1dvARB_remap_index, -1 },
+ { GetVertexAttribfvARB_names, GetVertexAttribfvARB_remap_index, -1 },
+ { GetAttribLocationARB_names, GetAttribLocationARB_remap_index, -1 },
+ { Uniform3ivARB_names, Uniform3ivARB_remap_index, -1 },
+ { GetVertexAttribPointervARB_names, GetVertexAttribPointervARB_remap_index, -1 },
+ { VertexAttrib4sARB_names, VertexAttrib4sARB_remap_index, -1 },
+ { VertexAttrib2dvARB_names, VertexAttrib2dvARB_remap_index, -1 },
+ { VertexAttrib2fvARB_names, VertexAttrib2fvARB_remap_index, -1 },
+ { VertexAttrib4NivARB_names, VertexAttrib4NivARB_remap_index, -1 },
+ { GetAttachedShaders_names, GetAttachedShaders_remap_index, -1 },
+ { CompileShaderARB_names, CompileShaderARB_remap_index, -1 },
+ { DeleteShader_names, DeleteShader_remap_index, -1 },
+ { Uniform3fARB_names, Uniform3fARB_remap_index, -1 },
+ { VertexAttrib4NuivARB_names, VertexAttrib4NuivARB_remap_index, -1 },
+ { Uniform4fARB_names, Uniform4fARB_remap_index, -1 },
+ { VertexAttrib1dARB_names, VertexAttrib1dARB_remap_index, -1 },
+ { LinkProgramARB_names, LinkProgramARB_remap_index, -1 },
+ { ShaderSourceARB_names, ShaderSourceARB_remap_index, -1 },
+ { VertexAttrib3svARB_names, VertexAttrib3svARB_remap_index, -1 },
+ { Uniform4ivARB_names, Uniform4ivARB_remap_index, -1 },
+ { GetVertexAttribdvARB_names, GetVertexAttribdvARB_remap_index, -1 },
+ { Uniform1ivARB_names, Uniform1ivARB_remap_index, -1 },
+ { VertexAttrib4dvARB_names, VertexAttrib4dvARB_remap_index, -1 },
+ { BindAttribLocationARB_names, BindAttribLocationARB_remap_index, -1 },
+ { Uniform1iARB_names, Uniform1iARB_remap_index, -1 },
+ { VertexAttribPointerARB_names, VertexAttribPointerARB_remap_index, -1 },
+ { VertexAttrib4NsvARB_names, VertexAttrib4NsvARB_remap_index, -1 },
+ { VertexAttrib3fvARB_names, VertexAttrib3fvARB_remap_index, -1 },
+ { CreateShader_names, CreateShader_remap_index, -1 },
+ { DetachShader_names, DetachShader_remap_index, -1 },
+ { VertexAttrib4NubARB_names, VertexAttrib4NubARB_remap_index, -1 },
+ { Uniform4fvARB_names, Uniform4fvARB_remap_index, -1 },
+ { GetUniformfvARB_names, GetUniformfvARB_remap_index, -1 },
+ { Uniform4iARB_names, Uniform4iARB_remap_index, -1 },
+ { UseProgramObjectARB_names, UseProgramObjectARB_remap_index, -1 },
+ { DeleteProgram_names, DeleteProgram_remap_index, -1 },
+ { Uniform2iARB_names, Uniform2iARB_remap_index, -1 },
+ { VertexAttrib4dARB_names, VertexAttrib4dARB_remap_index, -1 },
+ { GetUniformLocationARB_names, GetUniformLocationARB_remap_index, -1 },
+ { VertexAttrib3sARB_names, VertexAttrib3sARB_remap_index, -1 },
+ { GetShaderSourceARB_names, GetShaderSourceARB_remap_index, -1 },
{ DrawBuffersARB_names, DrawBuffersARB_remap_index, -1 },
+ { Uniform1fvARB_names, Uniform1fvARB_remap_index, -1 },
+ { EnableVertexAttribArrayARB_names, EnableVertexAttribArrayARB_remap_index, -1 },
+ { VertexAttrib4svARB_names, VertexAttrib4svARB_remap_index, -1 },
+ { GetShaderiv_names, GetShaderiv_remap_index, -1 },
+ { VertexAttrib2svARB_names, VertexAttrib2svARB_remap_index, -1 },
+ { VertexAttrib4NubvARB_names, VertexAttrib4NubvARB_remap_index, -1 },
+ { VertexAttrib2sARB_names, VertexAttrib2sARB_remap_index, -1 },
+ { VertexAttrib1fvARB_names, VertexAttrib1fvARB_remap_index, -1 },
+ { NULL, 0, 0 }
+};
+#endif
+
+#if defined(need_GL_VERSION_2_1)
+static const struct dri_extension_function GL_VERSION_2_1_functions[] = {
+ { UniformMatrix2x4fv_names, UniformMatrix2x4fv_remap_index, -1 },
+ { UniformMatrix4x3fv_names, UniformMatrix4x3fv_remap_index, -1 },
+ { UniformMatrix4x2fv_names, UniformMatrix4x2fv_remap_index, -1 },
+ { UniformMatrix2x3fv_names, UniformMatrix2x3fv_remap_index, -1 },
+ { UniformMatrix3x4fv_names, UniformMatrix3x4fv_remap_index, -1 },
+ { UniformMatrix3x2fv_names, UniformMatrix3x2fv_remap_index, -1 },
{ NULL, 0, 0 }
};
#endif
diff --git a/src/mesa/drivers/dri/common/xmlpool/.gitignore b/src/mesa/drivers/dri/common/xmlpool/.gitignore
new file mode 100644
index 0000000000..a5a437849b
--- /dev/null
+++ b/src/mesa/drivers/dri/common/xmlpool/.gitignore
@@ -0,0 +1,5 @@
+de
+es
+fr
+nl
+sv
diff --git a/src/mesa/drivers/dri/common/xmlpool/Makefile b/src/mesa/drivers/dri/common/xmlpool/Makefile
index ef94541c37..b077809cd1 100644
--- a/src/mesa/drivers/dri/common/xmlpool/Makefile
+++ b/src/mesa/drivers/dri/common/xmlpool/Makefile
@@ -41,7 +41,7 @@
# - info gettext
# The set of supported languages. Add languages as needed.
-POS=de.po es.po nl.po fr.po
+POS=de.po es.po nl.po fr.po sv.po
#
# Don't change anything below, unless you know what you're doing.
diff --git a/src/mesa/drivers/dri/common/xmlpool/options.h b/src/mesa/drivers/dri/common/xmlpool/options.h
index 5cef72867b..d5f4fc3491 100644
--- a/src/mesa/drivers/dri/common/xmlpool/options.h
+++ b/src/mesa/drivers/dri/common/xmlpool/options.h
@@ -58,7 +58,8 @@ DRI_CONF_SECTION_BEGIN \
DRI_CONF_DESC(de,"Fehlersuche") \
DRI_CONF_DESC(es,"Depurando") \
DRI_CONF_DESC(nl,"Debuggen") \
- DRI_CONF_DESC(fr,"Debogage")
+ DRI_CONF_DESC(fr,"Debogage") \
+ DRI_CONF_DESC(sv,"Felsökning")
#define DRI_CONF_NO_RAST(def) \
DRI_CONF_OPT_BEGIN(no_rast,bool,def) \
@@ -67,6 +68,7 @@ DRI_CONF_OPT_BEGIN(no_rast,bool,def) \
DRI_CONF_DESC(es,"Desactivar aceleración 3D") \
DRI_CONF_DESC(nl,"3D versnelling uitschakelen") \
DRI_CONF_DESC(fr,"Désactiver l'accélération 3D") \
+ DRI_CONF_DESC(sv,"Inaktivera 3D-accelerering") \
DRI_CONF_OPT_END
#define DRI_CONF_PERFORMANCE_BOXES(def) \
@@ -76,6 +78,7 @@ DRI_CONF_OPT_BEGIN(performance_boxes,bool,def) \
DRI_CONF_DESC(es,"Mostrar cajas de rendimiento") \
DRI_CONF_DESC(nl,"Laat prestatie boxjes zien") \
DRI_CONF_DESC(fr,"Afficher les boîtes de performance") \
+ DRI_CONF_DESC(sv,"Visa prestandarutor") \
DRI_CONF_OPT_END
@@ -86,7 +89,8 @@ DRI_CONF_SECTION_BEGIN \
DRI_CONF_DESC(de,"Bildqualität") \
DRI_CONF_DESC(es,"Calidad de imagen") \
DRI_CONF_DESC(nl,"Beeldkwaliteit") \
- DRI_CONF_DESC(fr,"Qualité d'image")
+ DRI_CONF_DESC(fr,"Qualité d'image") \
+ DRI_CONF_DESC(sv,"Bildkvalitet")
#define DRI_CONF_EXCESS_MIPMAP(def) \
DRI_CONF_OPT_BEGIN(excess_mipmap,bool,def) \
@@ -129,6 +133,12 @@ DRI_CONF_OPT_BEGIN_V(texture_depth,enum,def,"0:3") \
DRI_CONF_ENUM(2,"Prérérer 16 bits par texel") \
DRI_CONF_ENUM(3,"Forcer 16 bits par texel") \
DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(sv,"Färgdjup för texturer") \
+ DRI_CONF_ENUM(0,"Föredra färgdjupet för framebuffer") \
+ DRI_CONF_ENUM(1,"Föredra 32 bitar per texel") \
+ DRI_CONF_ENUM(2,"Föredra 16 bitar per texel") \
+ DRI_CONF_ENUM(3,"Tvinga 16 bitar per texel") \
+ DRI_CONF_DESC_END \
DRI_CONF_OPT_END
#define DRI_CONF_DEF_MAX_ANISOTROPY(def,range) \
@@ -138,6 +148,7 @@ DRI_CONF_OPT_BEGIN_V(def_max_anisotropy,float,def,range) \
DRI_CONF_DESC(es,"Valor máximo inicial para filtrado anisotrópico de textura") \
DRI_CONF_DESC(nl,"Initïele maximum waarde voor anisotrophische textuur filtering") \
DRI_CONF_DESC(fr,"Valeur maximale initiale pour le filtrage anisotropique de texture") \
+ DRI_CONF_DESC(sv,"Initialt maximalt värde för anisotropisk texturfiltrering") \
DRI_CONF_OPT_END
#define DRI_CONF_NO_NEG_LOD_BIAS(def) \
@@ -147,6 +158,7 @@ DRI_CONF_OPT_BEGIN(no_neg_lod_bias,bool,def) \
DRI_CONF_DESC(es,"Prohibir valores negativos de Nivel De Detalle (LOD) de texturas") \
DRI_CONF_DESC(nl,"Verbied negatief niveau detailonderscheid (LOD) van texturen") \
DRI_CONF_DESC(fr,"Interdire le LOD bias negatif") \
+ DRI_CONF_DESC(sv,"Förbjud negativ LOD-kompensation för texturer") \
DRI_CONF_OPT_END
#define DRI_CONF_FORCE_S3TC_ENABLE(def) \
@@ -156,6 +168,7 @@ DRI_CONF_OPT_BEGIN(force_s3tc_enable,bool,def) \
DRI_CONF_DESC(es,"Activar la compresión de texturas S3TC incluso si el soporte por software no está disponible") \
DRI_CONF_DESC(nl,"Schakel S3TC textuurcompressie in, zelfs als softwareondersteuning niet aanwezig is") \
DRI_CONF_DESC(fr,"Activer la compression de texture S3TC même si le support logiciel est absent") \
+ DRI_CONF_DESC(sv,"Aktivera S3TC-texturkomprimering även om programvarustöd saknas") \
DRI_CONF_OPT_END
#define DRI_CONF_COLOR_REDUCTION_ROUND 0
@@ -182,6 +195,10 @@ DRI_CONF_OPT_BEGIN_V(color_reduction,enum,def,"0:1") \
DRI_CONF_ENUM(0,"Arrondir les valeurs de couleur") \
DRI_CONF_ENUM(1,"Tramer les couleurs") \
DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(sv,"Initial färgminskningsmetod") \
+ DRI_CONF_ENUM(0,"Avrunda färger") \
+ DRI_CONF_ENUM(1,"Utjämna färger") \
+ DRI_CONF_DESC_END \
DRI_CONF_OPT_END
#define DRI_CONF_ROUND_TRUNC 0
@@ -208,6 +225,10 @@ DRI_CONF_OPT_BEGIN_V(round_mode,enum,def,"0:1") \
DRI_CONF_ENUM(0,"Arrondi à l'inférieur") \
DRI_CONF_ENUM(1,"Arrondi au plus proche") \
DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(sv,"Färgavrundningsmetod") \
+ DRI_CONF_ENUM(0,"Avrunda färdkomponenter nedåt") \
+ DRI_CONF_ENUM(1,"Avrunda till närmsta färg") \
+ DRI_CONF_DESC_END \
DRI_CONF_OPT_END
#define DRI_CONF_DITHER_XERRORDIFF 0
@@ -240,6 +261,11 @@ DRI_CONF_OPT_BEGIN_V(dither_mode,enum,def,"0:2") \
DRI_CONF_ENUM(1,"Diffusion d'erreur horizontale, réinitialisé pour chaque ligne") \
DRI_CONF_ENUM(2,"Tramage ordonné des couleurs") \
DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(sv,"Färgutjämningsmetod") \
+ DRI_CONF_ENUM(0,"Horisontell felspridning") \
+ DRI_CONF_ENUM(1,"Horisontell felspridning, återställ fel vid radbörjan") \
+ DRI_CONF_ENUM(2,"Ordnad 2D-färgutjämning") \
+ DRI_CONF_DESC_END \
DRI_CONF_OPT_END
#define DRI_CONF_FLOAT_DEPTH(def) \
@@ -249,6 +275,7 @@ DRI_CONF_OPT_BEGIN(float_depth,bool,def) \
DRI_CONF_DESC(es,"Búfer de profundidad en coma flotante") \
DRI_CONF_DESC(nl,"Dieptebuffer als commagetal") \
DRI_CONF_DESC(fr,"Z-buffer en virgule flottante") \
+ DRI_CONF_DESC(sv,"Buffert för flytande punktdjup") \
DRI_CONF_OPT_END
/** \brief Performance-related options */
@@ -258,7 +285,8 @@ DRI_CONF_SECTION_BEGIN \
DRI_CONF_DESC(de,"Leistung") \
DRI_CONF_DESC(es,"Rendimiento") \
DRI_CONF_DESC(nl,"Prestatie") \
- DRI_CONF_DESC(fr,"Performance")
+ DRI_CONF_DESC(fr,"Performance") \
+ DRI_CONF_DESC(sv,"Prestanda")
#define DRI_CONF_TCL_SW 0
#define DRI_CONF_TCL_PIPELINED 1
@@ -296,6 +324,12 @@ DRI_CONF_OPT_BEGIN_V(tcl_mode,enum,def,"0:3") \
DRI_CONF_ENUM(2,"Court-circuiter le pipeline TCL") \
DRI_CONF_ENUM(3,"Court-circuiter le pipeline TCL par une machine à états qui génère le codede TCL à la volée") \
DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(sv,"TCL-läge (Transformation, Clipping, Lighting)") \
+ DRI_CONF_ENUM(0,"Använd programvaru-TCL-rörledning") \
+ DRI_CONF_ENUM(1,"Använd maskinvaru-TCL som första TCL-rörledningssteg") \
+ DRI_CONF_ENUM(2,"Kringgå TCL-rörledningen") \
+ DRI_CONF_ENUM(3,"Kringgå TCL-rörledningen med tillståndsbaserad maskinkod som direktgenereras") \
+ DRI_CONF_DESC_END \
DRI_CONF_OPT_END
#define DRI_CONF_FTHROTTLE_BUSY 0
@@ -328,6 +362,11 @@ DRI_CONF_OPT_BEGIN_V(fthrottle_mode,enum,def,"0:2") \
DRI_CONF_ENUM(1,"Attente utilisant usleep()") \
DRI_CONF_ENUM(2,"Utiliser les interruptions") \
DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(sv,"Metod för att begränsa renderingslatens") \
+ DRI_CONF_ENUM(0,"Upptagen med att vänta på grafikhårdvaran") \
+ DRI_CONF_ENUM(1,"Sov i korta intervall under väntan på grafikhårdvaran") \
+ DRI_CONF_ENUM(2,"Låt grafikhårdvaran sända ut ett programvaruavbrott och sov") \
+ DRI_CONF_DESC_END \
DRI_CONF_OPT_END
#define DRI_CONF_VBLANK_NEVER 0
@@ -366,6 +405,12 @@ DRI_CONF_OPT_BEGIN_V(vblank_mode,enum,def,"0:3") \
DRI_CONF_ENUM(2,"Synchroniser avec le balayage vertical par défaut, mais obéir au choix de l'application") \
DRI_CONF_ENUM(3,"Toujours synchroniser avec le balayage vertical, l'application choisit l'intervalle minimal") \
DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(sv,"Synkronisering med vertikal uppdatering (växlingsintervall)") \
+ DRI_CONF_ENUM(0,"Synkronisera aldrig med vertikal uppdatering, ignorera programmets val") \
+ DRI_CONF_ENUM(1,"Initialt växlingsintervall 0, följ programmets val") \
+ DRI_CONF_ENUM(2,"Initialt växlingsintervall 1, följ programmets val") \
+ DRI_CONF_ENUM(3,"Synkronisera alltid med vertikal uppdatering, programmet väljer den minsta växlingsintervallen") \
+ DRI_CONF_DESC_END \
DRI_CONF_OPT_END
#define DRI_CONF_HYPERZ_DISABLED 0
@@ -377,6 +422,7 @@ DRI_CONF_OPT_BEGIN(hyperz,bool,def) \
DRI_CONF_DESC(es,"Usar HyperZ para potenciar rendimiento") \
DRI_CONF_DESC(nl,"Gebruik HyperZ om de prestaties te verbeteren") \
DRI_CONF_DESC(fr,"Utiliser le HyperZ pour améliorer les performances") \
+ DRI_CONF_DESC(sv,"Använd HyperZ för att maximera prestandan") \
DRI_CONF_OPT_END
#define DRI_CONF_MAX_TEXTURE_UNITS(def,min,max) \
@@ -386,6 +432,7 @@ DRI_CONF_OPT_BEGIN_V(texture_units,int,def, # min ":" # max ) \
DRI_CONF_DESC(es,"Número de unidades de textura usadas") \
DRI_CONF_DESC(nl,"Aantal textuureenheden in gebruik") \
DRI_CONF_DESC(fr,"Nombre d'unités de texture") \
+ DRI_CONF_DESC(sv,"Antal använda texturenheter") \
DRI_CONF_OPT_END
#define DRI_CONF_ALLOW_LARGE_TEXTURES(def) \
@@ -415,6 +462,11 @@ DRI_CONF_OPT_BEGIN_V(allow_large_textures,enum,def,"0:2") \
DRI_CONF_ENUM(1,"At least 1 texture must fit under worst-case assumptions") \
DRI_CONF_ENUM(2,"Announce hardware limits") \
DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(sv,"Stöd för större texturer är inte garanterat att passa i grafikminnet") \
+ DRI_CONF_ENUM(0,"Nej") \
+ DRI_CONF_ENUM(1,"Åtminstone en textur måste passa för antaget sämsta förhållande") \
+ DRI_CONF_ENUM(2,"Annonsera hårdvarubegränsningar") \
+ DRI_CONF_DESC_END \
DRI_CONF_OPT_END
#define DRI_CONF_TEXTURE_BLEND_QUALITY(def,range) \
@@ -424,6 +476,7 @@ DRI_CONF_OPT_BEGIN_V(texture_blend_quality,float,def,range) \
DRI_CONF_DESC(es,"Calidad de filtrado de textura vs. velocidad, alias filtrado ”brilinear“ de textura") \
DRI_CONF_DESC(nl,"Textuurfilterkwaliteit versus -snelheid, ookwel bekend als “brilineaire” textuurfiltering") \
DRI_CONF_DESC(fr,"Qualité/performance du filtrage trilinéaire de texture (filtrage brilinéaire)") \
+ DRI_CONF_DESC(sv,"Texturfiltreringskvalitet mot hastighet, även kallad ”brilinear”-texturfiltrering") \
DRI_CONF_OPT_END
#define DRI_CONF_TEXTURE_HEAPS_ALL 0
@@ -456,6 +509,11 @@ DRI_CONF_OPT_BEGIN_V(texture_heaps,enum,def,"0:2") \
DRI_CONF_ENUM(1,"Utiliser uniquement la mémoire graphique (si disponible)") \
DRI_CONF_ENUM(2,"Utiliser uniquement la mémoire GART (AGP/PCIE) (si disponible)") \
DRI_CONF_DESC_END \
+ DRI_CONF_DESC_BEGIN(sv,"Använda typer av texturminne") \
+ DRI_CONF_ENUM(0,"Allt tillgängligt minne") \
+ DRI_CONF_ENUM(1,"Endast kortminne (om tillgängligt)") \
+ DRI_CONF_ENUM(2,"Endast GART-minne (AGP/PCIE) (om tillgängligt)") \
+ DRI_CONF_DESC_END \
DRI_CONF_OPT_END
/* Options for features that are not done in hardware by the driver (like GL_ARB_vertex_program
@@ -466,7 +524,8 @@ DRI_CONF_SECTION_BEGIN \
DRI_CONF_DESC(de,"Funktionalität, die nicht hardwarebeschleunigt ist") \
DRI_CONF_DESC(es,"Características no aceleradas por hardware") \
DRI_CONF_DESC(nl,"Eigenschappen die niet hardwareversneld zijn") \
- DRI_CONF_DESC(fr,"Fonctionnalités ne bénéficiant pas d'une accélération matérielle")
+ DRI_CONF_DESC(fr,"Fonctionnalités ne bénéficiant pas d'une accélération matérielle") \
+ DRI_CONF_DESC(sv,"Funktioner som inte är hårdvaruaccelererade")
#define DRI_CONF_ARB_VERTEX_PROGRAM(def) \
DRI_CONF_OPT_BEGIN(arb_vertex_program,bool,def) \
@@ -475,6 +534,7 @@ DRI_CONF_OPT_BEGIN(arb_vertex_program,bool,def) \
DRI_CONF_DESC(es,"Activar la extensión GL_ARB_vertex_program") \
DRI_CONF_DESC(nl,"Zet uitbreiding GL_ARB_vertex_program aan") \
DRI_CONF_DESC(fr,"Activer l'extension GL_ARB_vertex_program") \
+ DRI_CONF_DESC(sv,"Aktivera tillägget GL_ARB_vertex_program") \
DRI_CONF_OPT_END
#define DRI_CONF_NV_VERTEX_PROGRAM(def) \
@@ -484,4 +544,5 @@ DRI_CONF_OPT_BEGIN(nv_vertex_program,bool,def) \
DRI_CONF_DESC(es,"Activar extensión GL_NV_vertex_program") \
DRI_CONF_DESC(nl,"Zet uitbreiding GL_NV_vertex_program aan") \
DRI_CONF_DESC(fr,"Activer l'extension GL_NV_vertex_program") \
+ DRI_CONF_DESC(sv,"Aktivera tillägget GL_NV_vertex_program") \
DRI_CONF_OPT_END
diff --git a/src/mesa/drivers/dri/common/xmlpool/sv.po b/src/mesa/drivers/dri/common/xmlpool/sv.po
new file mode 100644
index 0000000000..ba32b2ff15
--- /dev/null
+++ b/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/src/mesa/drivers/dri/i915/i830_metaops.c b/src/mesa/drivers/dri/i915/i830_metaops.c
index dbf5f04349..c1d7fe349c 100644
--- a/src/mesa/drivers/dri/i915/i830_metaops.c
+++ b/src/mesa/drivers/dri/i915/i830_metaops.c
@@ -50,7 +50,6 @@
#define SET_STATE( i830, STATE ) \
do { \
- assert(!i830->intel.prim.flush); \
i830->current->emitted = 0; \
i830->current = &i830->STATE; \
i830->current->emitted = 0; \
@@ -907,7 +906,6 @@ i830RotateWindow(intelContextPtr intel, __DRIdrawablePrivate *dPriv,
} /* cliprect loop */
- assert(!intel->prim.flush);
intelFlushBatchLocked( intel, GL_FALSE, GL_FALSE, GL_FALSE );
done:
diff --git a/src/mesa/drivers/dri/i915/i830_state.c b/src/mesa/drivers/dri/i915/i830_state.c
index ec9dca6231..9512519010 100644
--- a/src/mesa/drivers/dri/i915/i830_state.c
+++ b/src/mesa/drivers/dri/i915/i830_state.c
@@ -225,7 +225,7 @@ static void i830EvalLogicOpBlendState(GLcontext *ctx)
I830_STATECHANGE(i830, I830_UPLOAD_CTX);
- if (ctx->Color._LogicOpEnabled) {
+ if (RGBA_LOGICOP_ENABLED(ctx)) {
i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND |
ENABLE_LOGIC_OP_MASK);
i830->state.Ctx[I830_CTXREG_ENABLES_1] |= (DISABLE_COLOR_BLEND |
diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c
index 7160234bce..ef14f3eef7 100644
--- a/src/mesa/drivers/dri/i915/i915_fragprog.c
+++ b/src/mesa/drivers/dri/i915/i915_fragprog.c
@@ -39,6 +39,7 @@
#include "program_instruction.h"
#include "program.h"
+#include "programopt.h"
@@ -123,6 +124,7 @@ static GLuint src_vector( struct i915_fragment_program *p,
p, p->ctx->FragmentProgram.Parameters[source->Index]);
break;
+ case PROGRAM_CONSTANT:
case PROGRAM_STATE_VAR:
case PROGRAM_NAMED_PARAM:
src = i915_emit_param4fv(
@@ -937,6 +939,12 @@ static void i915ProgramStringNotify( GLcontext *ctx,
*/
ctx->Driver.Enable( ctx, GL_FRAGMENT_PROGRAM_ARB,
ctx->FragmentProgram.Enabled );
+
+ if (p->FragProg.FogOption) {
+ /* add extra instructions to do fog, then turn off FogOption field */
+ _mesa_append_fog_code(ctx, &p->FragProg);
+ p->FragProg.FogOption = GL_NONE;
+ }
}
_tnl_program_string(ctx, target, prog);
@@ -1010,7 +1018,10 @@ void i915ValidateFragmentProgram( i915ContextPtr i915 )
EMIT_PAD( 1 );
}
-#if 0
+ /* XXX this was disabled, but enabling this code helped fix the Glean
+ * tfragprog1 fog tests.
+ */
+#if 1
if ((inputsRead & FRAG_BIT_FOGC) || i915->vertex_fog != I915_FOG_NONE) {
EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1F, S4_VFMT_FOG_PARAM, 4 );
}
diff --git a/src/mesa/drivers/dri/i915/i915_program.c b/src/mesa/drivers/dri/i915/i915_program.c
index 0faadb4f1a..9c13290d11 100644
--- a/src/mesa/drivers/dri/i915/i915_program.c
+++ b/src/mesa/drivers/dri/i915/i915_program.c
@@ -369,10 +369,7 @@ GLuint i915_emit_param4fv( struct i915_fragment_program *p,
void i915_program_error( struct i915_fragment_program *p, const char *msg )
{
- /* XXX we shouldn't print anything to stdout, record GL error or
- * call _mesa_problem()
- */
- fprintf(stderr, "%s\n", msg);
+ _mesa_problem(NULL, "i915_program_error: %s", msg);
p->error = 1;
}
diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c
index db5bb9ddc7..3cec6a2ddf 100644
--- a/src/mesa/drivers/dri/i915/i915_state.c
+++ b/src/mesa/drivers/dri/i915/i915_state.c
@@ -141,7 +141,7 @@ static void i915EvalLogicOpBlendState(GLcontext *ctx)
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
- if (ctx->Color._LogicOpEnabled) {
+ if (RGBA_LOGICOP_ENABLED(ctx)) {
i915->state.Ctx[I915_CTXREG_LIS5] |= S5_LOGICOP_ENABLE;
i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE;
} else {
diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c
index 3d543b2485..7bb00d9833 100644
--- a/src/mesa/drivers/dri/i915/intel_context.c
+++ b/src/mesa/drivers/dri/i915/intel_context.c
@@ -242,7 +242,6 @@ void intelInitDriverFunctions( struct dd_function_table *functions )
functions->Clear = intelClear;
functions->Flush = intelglFlush;
functions->Finish = intelFinish;
- functions->GetBufferSize = NULL; /* OBSOLETE */
functions->GetString = intelGetString;
functions->UpdateState = intelInvalidateState;
diff --git a/src/mesa/drivers/dri/i915tex/Makefile b/src/mesa/drivers/dri/i915tex/Makefile
index 94879d209f..3b3f3f5a3f 100644
--- a/src/mesa/drivers/dri/i915tex/Makefile
+++ b/src/mesa/drivers/dri/i915tex/Makefile
@@ -20,6 +20,7 @@ DRIVER_SOURCES = \
intel_batchbuffer.c \
intel_mipmap_tree.c \
i915_tex_layout.c \
+ intel_tex_layout.c \
intel_tex_image.c \
intel_tex_subimage.c \
intel_tex_copy.c \
@@ -59,8 +60,10 @@ C_SOURCES = \
ASM_SOURCES =
-
+DRIVER_DEFINES = -I../intel
include ../Makefile.template
+intel_tex_layout.o: ../intel/intel_tex_layout.c
+
symlinks:
diff --git a/src/mesa/drivers/dri/i915tex/i830_context.h b/src/mesa/drivers/dri/i915tex/i830_context.h
index e5377b300a..3d754103c0 100644
--- a/src/mesa/drivers/dri/i915tex/i830_context.h
+++ b/src/mesa/drivers/dri/i915tex/i830_context.h
@@ -156,6 +156,11 @@ do { \
*/
extern void i830InitVtbl(struct i830_context *i830);
+extern void
+i830_state_draw_region(struct intel_context *intel,
+ struct i830_hw_state *state,
+ struct intel_region *color_region,
+ struct intel_region *depth_region);
/* i830_context.c
*/
extern GLboolean
diff --git a/src/mesa/drivers/dri/i915tex/i830_metaops.c b/src/mesa/drivers/dri/i915tex/i830_metaops.c
index c90f502222..f76646d89d 100644
--- a/src/mesa/drivers/dri/i915tex/i830_metaops.c
+++ b/src/mesa/drivers/dri/i915tex/i830_metaops.c
@@ -400,40 +400,12 @@ meta_import_pixel_state(struct intel_context *intel)
*/
static void
meta_draw_region(struct intel_context *intel,
- struct intel_region *draw_region,
+ struct intel_region *color_region,
struct intel_region *depth_region)
{
struct i830_context *i830 = i830_context(&intel->ctx);
- GLuint format;
- GLuint depth_format = DEPTH_FRMT_16_FIXED;
- intel_region_release(&i830->meta.draw_region);
- intel_region_reference(&i830->meta.draw_region, draw_region);
-
- intel_region_release(&i830->meta.depth_region);
- intel_region_reference(&i830->meta.depth_region, depth_region);
-
- /* XXX FBO: grab code from i915 meta_draw_region */
-
- /* XXX: 555 support?
- */
- if (draw_region->cpp == 2)
- format = DV_PF_565;
- else
- format = DV_PF_8888;
-
- if (depth_region) {
- if (depth_region->cpp == 2)
- depth_format = DEPTH_FRMT_16_FIXED;
- else
- depth_format = DEPTH_FRMT_24_FIXED_8_OTHER;
- }
-
- i830->meta.Buffer[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
- DSTORG_VERT_BIAS(0x8) | /* .5 */
- format | DEPTH_IS_Z | depth_format);
-
- i830->meta.emitted &= ~I830_UPLOAD_BUFFERS;
+ i830_state_draw_region(intel, &i830->meta, color_region, depth_region);
}
diff --git a/src/mesa/drivers/dri/i915tex/i830_state.c b/src/mesa/drivers/dri/i915tex/i830_state.c
index 83d82882a6..812daa6524 100644
--- a/src/mesa/drivers/dri/i915tex/i830_state.c
+++ b/src/mesa/drivers/dri/i915tex/i830_state.c
@@ -231,7 +231,7 @@ i830EvalLogicOpBlendState(GLcontext * ctx)
I830_STATECHANGE(i830, I830_UPLOAD_CTX);
- if (ctx->Color._LogicOpEnabled) {
+ if (RGBA_LOGICOP_ENABLED(ctx)) {
i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND |
ENABLE_LOGIC_OP_MASK);
i830->state.Ctx[I830_CTXREG_ENABLES_1] |= (DISABLE_COLOR_BLEND |
@@ -1042,6 +1042,7 @@ i830_init_packets(struct i830_context *i830)
i830->state.Buffer[I830_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD;
+#if 0
switch (screen->fbFormat) {
case DV_PF_565:
i830->state.Buffer[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
@@ -1058,7 +1059,7 @@ i830_init_packets(struct i830_context *i830)
DEPTH_FRMT_24_FIXED_8_OTHER);
break;
}
-
+#endif
i830->state.Buffer[I830_DESTREG_SENABLE] = (_3DSTATE_SCISSOR_ENABLE_CMD |
DISABLE_SCISSOR_RECT);
i830->state.Buffer[I830_DESTREG_SR0] = _3DSTATE_SCISSOR_RECT_0_CMD;
diff --git a/src/mesa/drivers/dri/i915tex/i830_texstate.c b/src/mesa/drivers/dri/i915tex/i830_texstate.c
index ba79cf9459..e3f34e3944 100644
--- a/src/mesa/drivers/dri/i915tex/i830_texstate.c
+++ b/src/mesa/drivers/dri/i915tex/i830_texstate.c
@@ -25,21 +25,13 @@
*
**************************************************************************/
-#include "glheader.h"
-#include "macros.h"
#include "mtypes.h"
-#include "simple_list.h"
#include "enums.h"
#include "texformat.h"
-#include "texstore.h"
+#include "dri_bufmgr.h"
-#include "mm.h"
-
-#include "intel_screen.h"
-#include "intel_ioctl.h"
-#include "intel_tex.h"
#include "intel_mipmap_tree.h"
-#include "intel_regions.h"
+#include "intel_tex.h"
#include "i830_context.h"
#include "i830_reg.h"
@@ -129,6 +121,13 @@ i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
memset(state, 0, sizeof(state));
+ /*We need to refcount these. */
+
+ if (i830->state.tex_buffer[unit] != NULL) {
+ driBOUnReference(i830->state.tex_buffer[unit]);
+ i830->state.tex_buffer[unit] = NULL;
+ }
+
if (!intel_finalize_mipmap_tree(intel, unit))
return GL_FALSE;
@@ -137,7 +136,7 @@ i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
*/
firstImage = tObj->Image[0][intelObj->firstLevel];
- i830->state.tex_buffer[unit] = intelObj->mt->region->buffer;
+ i830->state.tex_buffer[unit] = driBOReference(intelObj->mt->region->buffer);
i830->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt, 0,
intelObj->
firstLevel);
@@ -298,10 +297,17 @@ i830UpdateTextureState(struct intel_context *intel)
case TEXTURE_RECT_BIT:
ok = i830_update_tex_unit(intel, i, TEXCOORDS_ARE_IN_TEXELUNITS);
break;
- case 0:
- if (i830->state.active & I830_UPLOAD_TEX(i))
+ case 0:{
+ struct i830_context *i830 = i830_context(&intel->ctx);
+ if (i830->state.active & I830_UPLOAD_TEX(i))
I830_ACTIVESTATE(i830, I830_UPLOAD_TEX(i), GL_FALSE);
+
+ if (i830->state.tex_buffer[i] != NULL) {
+ driBOUnReference(i830->state.tex_buffer[i]);
+ i830->state.tex_buffer[i] = NULL;
+ }
break;
+ }
case TEXTURE_3D_BIT:
default:
ok = GL_FALSE;
diff --git a/src/mesa/drivers/dri/i915tex/i830_vtbl.c b/src/mesa/drivers/dri/i915tex/i830_vtbl.c
index 45502da290..dd0670dec3 100644
--- a/src/mesa/drivers/dri/i915tex/i830_vtbl.c
+++ b/src/mesa/drivers/dri/i915tex/i830_vtbl.c
@@ -451,14 +451,16 @@ i830_emit_state(struct intel_context *intel)
OUT_BATCH(state->Buffer[I830_DESTREG_CBUFADDR1]);
OUT_RELOC(state->draw_region->buffer,
DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
- DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0);
+ DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE,
+ state->draw_region->draw_offset);
if (state->depth_region) {
OUT_BATCH(state->Buffer[I830_DESTREG_DBUFADDR0]);
OUT_BATCH(state->Buffer[I830_DESTREG_DBUFADDR1]);
OUT_RELOC(state->depth_region->buffer,
DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
- DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0);
+ DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE,
+ state->depth_region->draw_offset);
}
OUT_BATCH(state->Buffer[I830_DESTREG_DV0]);
@@ -469,7 +471,7 @@ i830_emit_state(struct intel_context *intel)
OUT_BATCH(state->Buffer[I830_DESTREG_SR2]);
ADVANCE_BATCH();
}
-
+
if (dirty & I830_UPLOAD_STIPPLE) {
DBG("I830_UPLOAD_STIPPLE:\n");
emit(i830, state->Stipple, sizeof(state->Stipple));
@@ -518,28 +520,79 @@ i830_destroy_context(struct intel_context *intel)
_tnl_free_vertices(&intel->ctx);
}
-static void
-i830_set_draw_region(struct intel_context *intel,
- struct intel_region *draw_region,
- struct intel_region *depth_region)
+
+void
+i830_state_draw_region(struct intel_context *intel,
+ struct i830_hw_state *state,
+ struct intel_region *color_region,
+ struct intel_region *depth_region)
{
struct i830_context *i830 = i830_context(&intel->ctx);
+ GLuint value;
- intel_region_release(&i830->state.draw_region);
- intel_region_release(&i830->state.depth_region);
- intel_region_reference(&i830->state.draw_region, draw_region);
- intel_region_reference(&i830->state.depth_region, depth_region);
+ ASSERT(state == &i830->state || state == &i830->meta);
- /* XXX FBO: Need code from i915_set_draw_region() */
+ if (state->draw_region != color_region) {
+ intel_region_release(&state->draw_region);
+ intel_region_reference(&state->draw_region, color_region);
+ }
+ if (state->depth_region != depth_region) {
+ intel_region_release(&state->depth_region);
+ intel_region_reference(&state->depth_region, depth_region);
+ }
+
+ /*
+ * Set stride/cpp values
+ */
+ if (color_region) {
+ state->Buffer[I830_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD;
+ state->Buffer[I830_DESTREG_CBUFADDR1] =
+ (BUF_3D_ID_COLOR_BACK |
+ BUF_3D_PITCH(color_region->pitch * color_region->cpp) |
+ BUF_3D_USE_FENCE);
+ }
+
+ if (depth_region) {
+ state->Buffer[I830_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD;
+ state->Buffer[I830_DESTREG_DBUFADDR1] =
+ (BUF_3D_ID_DEPTH |
+ BUF_3D_PITCH(depth_region->pitch * depth_region->cpp) |
+ BUF_3D_USE_FENCE);
+ }
+
+ /*
+ * Compute/set I830_DESTREG_DV1 value
+ */
+ value = (DSTORG_HORT_BIAS(0x8) | /* .5 */
+ DSTORG_VERT_BIAS(0x8) | DEPTH_IS_Z); /* .5 */
+
+ if (color_region && color_region->cpp == 4) {
+ value |= DV_PF_8888;
+ }
+ else {
+ value |= DV_PF_565;
+ }
+ if (depth_region && depth_region->cpp == 4) {
+ value |= DEPTH_FRMT_24_FIXED_8_OTHER;
+ }
+ else {
+ value |= DEPTH_FRMT_16_FIXED;
+ }
+ state->Buffer[I830_DESTREG_DV1] = value;
I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS);
- I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS);
- i830->state.Buffer[I830_DESTREG_CBUFADDR1] =
- (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(draw_region->pitch) |
- BUF_3D_USE_FENCE);
- i830->state.Buffer[I830_DESTREG_DBUFADDR1] =
- (BUF_3D_ID_DEPTH | BUF_3D_PITCH(depth_region->pitch) |
- BUF_3D_USE_FENCE);
+
+
+}
+
+
+static void
+i830_set_draw_region(struct intel_context *intel,
+ struct intel_region *color_region,
+ struct intel_region *depth_region)
+{
+ struct i830_context *i830 = i830_context(&intel->ctx);
+ i830_state_draw_region(intel, &i830->state, color_region, depth_region);
}
#if 0
diff --git a/src/mesa/drivers/dri/i915tex/i915_context.c b/src/mesa/drivers/dri/i915tex/i915_context.c
index 4cbe29d79d..9b4d72eab3 100644
--- a/src/mesa/drivers/dri/i915tex/i915_context.c
+++ b/src/mesa/drivers/dri/i915tex/i915_context.c
@@ -36,7 +36,6 @@
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
-#include "array_cache/acache.h"
#include "utils.h"
#include "i915_reg.h"
@@ -67,7 +66,7 @@ i915InvalidateState(GLcontext * ctx, GLuint new_state)
{
_swrast_InvalidateState(ctx, new_state);
_swsetup_InvalidateState(ctx, new_state);
- _ac_InvalidateState(ctx, new_state);
+ _vbo_InvalidateState(ctx, new_state);
_tnl_InvalidateState(ctx, new_state);
_tnl_invalidate_vertex_state(ctx, new_state);
intel_context(ctx)->NewGLState |= new_state;
diff --git a/src/mesa/drivers/dri/i915tex/i915_context.h b/src/mesa/drivers/dri/i915tex/i915_context.h
index 5ae76fcd18..d2713e88f9 100644
--- a/src/mesa/drivers/dri/i915tex/i915_context.h
+++ b/src/mesa/drivers/dri/i915tex/i915_context.h
@@ -243,7 +243,6 @@ struct i915_context
GLuint lodbias_ss2[MAX_TEXTURE_UNITS];
- struct i915_fragment_program tex_program;
struct i915_fragment_program *current_program;
struct i915_hw_state meta, initial, state, *current;
diff --git a/src/mesa/drivers/dri/i915tex/i915_fragprog.c b/src/mesa/drivers/dri/i915tex/i915_fragprog.c
index 2ddcbc4325..8772e70230 100644
--- a/src/mesa/drivers/dri/i915tex/i915_fragprog.c
+++ b/src/mesa/drivers/dri/i915tex/i915_fragprog.c
@@ -39,6 +39,7 @@
#include "program_instruction.h"
#include "program.h"
+#include "programopt.h"
@@ -127,6 +128,7 @@ src_vector(struct i915_fragment_program *p,
Index]);
break;
+ case PROGRAM_CONSTANT:
case PROGRAM_STATE_VAR:
case PROGRAM_NAMED_PARAM:
src =
@@ -928,6 +930,12 @@ i915ProgramStringNotify(GLcontext * ctx,
*/
ctx->Driver.Enable(ctx, GL_FRAGMENT_PROGRAM_ARB,
ctx->FragmentProgram.Enabled);
+
+ if (p->FragProg.FogOption) {
+ /* add extra instructions to do fog, then turn off FogOption field */
+ _mesa_append_fog_code(ctx, &p->FragProg);
+ p->FragProg.FogOption = GL_NONE;
+ }
}
_tnl_program_string(ctx, target, prog);
@@ -1001,7 +1009,10 @@ i915ValidateFragmentProgram(struct i915_context *i915)
EMIT_PAD(1);
}
-#if 0
+ /* XXX this was disabled, but enabling this code helped fix the Glean
+ * tfragprog1 fog tests.
+ */
+#if 1
if ((inputsRead & FRAG_BIT_FOGC) || i915->vertex_fog != I915_FOG_NONE) {
EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1F, S4_VFMT_FOG_PARAM, 4);
}
diff --git a/src/mesa/drivers/dri/i915tex/i915_program.c b/src/mesa/drivers/dri/i915tex/i915_program.c
index 4fb56222c6..0be89d3320 100644
--- a/src/mesa/drivers/dri/i915tex/i915_program.c
+++ b/src/mesa/drivers/dri/i915tex/i915_program.c
@@ -379,17 +379,14 @@ i915_emit_param4fv(struct i915_fragment_program * p, const GLfloat * values)
-
void
i915_program_error(struct i915_fragment_program *p, const char *msg)
{
- /* XXX we shouldn't print anything to stdout, record GL error or
- * call _mesa_problem()
- */
- fprintf(stderr, "%s\n", msg);
+ _mesa_problem(NULL, "i915_program_error: %s", msg);
p->error = 1;
}
+
void
i915_init_program(struct i915_context *i915, struct i915_fragment_program *p)
{
diff --git a/src/mesa/drivers/dri/i915tex/i915_state.c b/src/mesa/drivers/dri/i915tex/i915_state.c
index d68801d3f9..7c742a7bd9 100644
--- a/src/mesa/drivers/dri/i915tex/i915_state.c
+++ b/src/mesa/drivers/dri/i915tex/i915_state.c
@@ -144,7 +144,7 @@ i915EvalLogicOpBlendState(GLcontext * ctx)
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
- if (ctx->Color._LogicOpEnabled) {
+ if (RGBA_LOGICOP_ENABLED(ctx)) {
i915->state.Ctx[I915_CTXREG_LIS5] |= S5_LOGICOP_ENABLE;
i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE;
}
@@ -520,7 +520,6 @@ update_specular(GLcontext * ctx)
/* A hack to trigger the rebuild of the fragment program.
*/
intel_context(ctx)->NewGLState |= _NEW_TEXTURE;
- I915_CONTEXT(ctx)->tex_program.translated = 0;
}
static void
diff --git a/src/mesa/drivers/dri/i915tex/i915_tex.c b/src/mesa/drivers/dri/i915tex/i915_tex.c
index a53abe9a92..59e148ca04 100644
--- a/src/mesa/drivers/dri/i915tex/i915_tex.c
+++ b/src/mesa/drivers/dri/i915tex/i915_tex.c
@@ -52,27 +52,6 @@ i915TexEnv(GLcontext * ctx, GLenum target,
struct i915_context *i915 = I915_CONTEXT(ctx);
switch (pname) {
- case GL_TEXTURE_ENV_COLOR: /* Should be a tracked param */
- case GL_TEXTURE_ENV_MODE:
- case GL_COMBINE_RGB:
- case GL_COMBINE_ALPHA:
- case GL_SOURCE0_RGB:
- case GL_SOURCE1_RGB:
- case GL_SOURCE2_RGB:
- case GL_SOURCE0_ALPHA:
- case GL_SOURCE1_ALPHA:
- case GL_SOURCE2_ALPHA:
- case GL_OPERAND0_RGB:
- case GL_OPERAND1_RGB:
- case GL_OPERAND2_RGB:
- case GL_OPERAND0_ALPHA:
- case GL_OPERAND1_ALPHA:
- case GL_OPERAND2_ALPHA:
- case GL_RGB_SCALE:
- case GL_ALPHA_SCALE:
- i915->tex_program.translated = 0;
- break;
-
case GL_TEXTURE_LOD_BIAS:{
GLuint unit = ctx->Texture.CurrentUnit;
GLint b = (int) ((*param) * 16.0);
@@ -92,22 +71,8 @@ i915TexEnv(GLcontext * ctx, GLenum target,
}
-static void
-i915BindTexture(GLcontext * ctx, GLenum target,
- struct gl_texture_object *texobj)
-{
- /* Need this if image format changes between bound textures.
- * Could try and shortcircuit by checking for differences in
- * state between incoming and outgoing textures:
- */
- I915_CONTEXT(ctx)->tex_program.translated = 0;
-}
-
-
-
void
i915InitTextureFuncs(struct dd_function_table *functions)
{
- functions->BindTexture = i915BindTexture;
functions->TexEnv = i915TexEnv;
}
diff --git a/src/mesa/drivers/dri/i915tex/i915_tex_layout.c b/src/mesa/drivers/dri/i915tex/i915_tex_layout.c
index e9360ecea8..333fefef85 100644
--- a/src/mesa/drivers/dri/i915tex/i915_tex_layout.c
+++ b/src/mesa/drivers/dri/i915tex/i915_tex_layout.c
@@ -30,6 +30,7 @@
*/
#include "intel_mipmap_tree.h"
+#include "intel_tex_layout.h"
#include "macros.h"
#include "intel_context.h"
@@ -52,12 +53,6 @@ static GLint step_offsets[6][2] = { {0, 2},
{-1, 1}
};
-static GLuint
-minify(GLuint d)
-{
- return MAX2(1, d >> 1);
-}
-
GLboolean
i915_miptree_layout(struct intel_mipmap_tree * mt)
{
@@ -217,7 +212,7 @@ i945_miptree_layout(struct intel_mipmap_tree * mt)
y = mt->total_height - 4;
x = (face - 4) * 8;
}
- else if (dim < 4) {
+ else if (dim < 4 && (face > 0 || mt->first_level > 0)) {
y = mt->total_height - 4;
x = face * 8;
}
@@ -322,52 +317,9 @@ i945_miptree_layout(struct intel_mipmap_tree * mt)
case GL_TEXTURE_1D:
case GL_TEXTURE_2D:
- case GL_TEXTURE_RECTANGLE_ARB:{
- GLuint x = 0;
- GLuint y = 0;
- GLuint width = mt->width0;
- GLuint height = mt->height0;
- GLint align_h = 2;
-
- mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
- mt->total_height = 0;
-
- for (level = mt->first_level; level <= mt->last_level; level++) {
- GLuint img_height;
-
- intel_miptree_set_level_info(mt, level, 1,
- x, y,
- width,
- mt->compressed ? height/4 : height, 1);
-
-
- if (mt->compressed)
- img_height = MAX2(1, height / 4);
- else
- img_height = MAX2(align_h, height);
-
- /* LPT change: step right after second mipmap.
- */
- if (level == mt->first_level + 1) {
- x += mt->pitch / 2;
- x = (x + 3) & ~3;
- }
- else {
- y += img_height;
- y += align_h - 1;
- y &= ~(align_h - 1);
- }
-
- /* Because the images are packed better, the final offset
- * might not be the maximal one:
- */
- mt->total_height = MAX2(mt->total_height, y);
-
- width = minify(width);
- height = minify(height);
- }
+ case GL_TEXTURE_RECTANGLE_ARB:
+ i945_miptree_layout_2d(mt);
break;
- }
default:
_mesa_problem(NULL, "Unexpected tex target in i945_miptree_layout()");
}
diff --git a/src/mesa/drivers/dri/i915tex/i915_vtbl.c b/src/mesa/drivers/dri/i915tex/i915_vtbl.c
index 827990d2cf..52db9a95e6 100644
--- a/src/mesa/drivers/dri/i915tex/i915_vtbl.c
+++ b/src/mesa/drivers/dri/i915tex/i915_vtbl.c
@@ -314,6 +314,7 @@ i915_emit_state(struct intel_context *intel)
if (dirty & I915_UPLOAD_CTX) {
if (INTEL_DEBUG & DEBUG_STATE)
fprintf(stderr, "I915_UPLOAD_CTX:\n");
+
emit(intel, state->Ctx, sizeof(state->Ctx));
}
diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c
index b4e0b74f16..be2750d041 100644
--- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c
@@ -252,6 +252,7 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch)
{
struct intel_context *intel = batch->intel;
GLuint used = batch->ptr - batch->map;
+ GLboolean was_locked = intel->locked;
if (used == 0)
return batch->last_fence;
@@ -278,17 +279,14 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch)
/* TODO: Just pass the relocation list and dma buffer up to the
* kernel.
*/
- if (!intel->locked) {
- assert(!(batch->flags & INTEL_BATCH_NO_CLIPRECTS));
-
+ if (!was_locked)
LOCK_HARDWARE(intel);
- do_flush_locked(batch, used, GL_FALSE, GL_TRUE);
+
+ do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS),
+ GL_FALSE);
+
+ if (!was_locked)
UNLOCK_HARDWARE(intel);
- }
- else {
- GLboolean ignore_cliprects = !(batch->flags & INTEL_BATCH_CLIPRECTS);
- do_flush_locked(batch, used, ignore_cliprects, GL_FALSE);
- }
/* Reset the buffer:
*/
diff --git a/src/mesa/drivers/dri/i915tex/intel_blit.c b/src/mesa/drivers/dri/i915tex/intel_blit.c
index b6b6543908..550669ab0c 100644
--- a/src/mesa/drivers/dri/i915tex/intel_blit.c
+++ b/src/mesa/drivers/dri/i915tex/intel_blit.c
@@ -277,6 +277,30 @@ intelEmitFillBlit(struct intel_context *intel,
}
+static GLuint translate_raster_op(GLenum logicop)
+{
+ switch(logicop) {
+ case GL_CLEAR: return 0x00;
+ case GL_AND: return 0x88;
+ case GL_AND_REVERSE: return 0x44;
+ case GL_COPY: return 0xCC;
+ case GL_AND_INVERTED: return 0x22;
+ case GL_NOOP: return 0xAA;
+ case GL_XOR: return 0x66;
+ case GL_OR: return 0xEE;
+ case GL_NOR: return 0x11;
+ case GL_EQUIV: return 0x99;
+ case GL_INVERT: return 0x55;
+ case GL_OR_REVERSE: return 0xDD;
+ case GL_COPY_INVERTED: return 0x33;
+ case GL_OR_INVERTED: return 0xBB;
+ case GL_NAND: return 0x77;
+ case GL_SET: return 0xFF;
+ default: return 0;
+ }
+}
+
+
/* Copy BitBlt
*/
void
@@ -289,7 +313,9 @@ intelEmitCopyBlit(struct intel_context *intel,
struct _DriBufferObject *dst_buffer,
GLuint dst_offset,
GLshort src_x, GLshort src_y,
- GLshort dst_x, GLshort dst_y, GLshort w, GLshort h)
+ GLshort dst_x, GLshort dst_y,
+ GLshort w, GLshort h,
+ GLenum logic_op)
{
GLuint CMD, BR13;
int dst_y2 = dst_y + h;
@@ -309,13 +335,14 @@ intelEmitCopyBlit(struct intel_context *intel,
case 1:
case 2:
case 3:
- BR13 = (((GLint) dst_pitch) & 0xffff) | (0xCC << 16) | (1 << 24);
+ BR13 = (((GLint) dst_pitch) & 0xffff) |
+ (translate_raster_op(logic_op) << 16) | (1 << 24);
CMD = XY_SRC_COPY_BLT_CMD;
break;
case 4:
BR13 =
- (((GLint) dst_pitch) & 0xffff) | (0xCC << 16) | (1 << 24) | (1 <<
- 25);
+ (((GLint) dst_pitch) & 0xffff) |
+ (translate_raster_op(logic_op) << 16) | (1 << 24) | (1 << 25);
CMD =
(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
XY_SRC_COPY_BLT_WRITE_RGB);
diff --git a/src/mesa/drivers/dri/i915tex/intel_blit.h b/src/mesa/drivers/dri/i915tex/intel_blit.h
index ee85c62633..e7bc280f58 100644
--- a/src/mesa/drivers/dri/i915tex/intel_blit.h
+++ b/src/mesa/drivers/dri/i915tex/intel_blit.h
@@ -47,7 +47,8 @@ extern void intelEmitCopyBlit(struct intel_context *intel,
GLuint dst_offset,
GLshort srcx, GLshort srcy,
GLshort dstx, GLshort dsty,
- GLshort w, GLshort h);
+ GLshort w, GLshort h,
+ GLenum logicop );
extern void intelEmitFillBlit(struct intel_context *intel,
GLuint cpp,
diff --git a/src/mesa/drivers/dri/i915tex/intel_buffers.c b/src/mesa/drivers/dri/i915tex/intel_buffers.c
index d3925bbc1e..1ded0b5417 100644
--- a/src/mesa/drivers/dri/i915tex/intel_buffers.c
+++ b/src/mesa/drivers/dri/i915tex/intel_buffers.c
@@ -36,6 +36,7 @@
#include "intel_batchbuffer.h"
#include "context.h"
#include "utils.h"
+#include "drirenderbuffer.h"
#include "framebuffer.h"
#include "swrast/swrast.h"
#include "vblank.h"
@@ -105,32 +106,6 @@ intel_readbuf_region(struct intel_context *intel)
-static void
-intelBufferSize(GLframebuffer * buffer, GLuint * width, GLuint * height)
-{
- GET_CURRENT_CONTEXT(ctx);
- struct intel_context *intel = intel_context(ctx);
- /* Need to lock to make sure the driDrawable is uptodate. This
- * information is used to resize Mesa's software buffers, so it has
- * to be correct.
- */
- /* XXX This isn't 100% correct, the given buffer might not be
- * bound to the current context!
- */
- LOCK_HARDWARE(intel);
- if (intel->driDrawable) {
- *width = intel->driDrawable->w;
- *height = intel->driDrawable->h;
- }
- else {
- *width = 0;
- *height = 0;
- }
- UNLOCK_HARDWARE(intel);
-}
-
-
-
/**
* Update the following fields for rendering to a user-created FBO:
* intel->numClipRects
@@ -209,6 +184,8 @@ void
intelWindowMoved(struct intel_context *intel)
{
GLcontext *ctx = &intel->ctx;
+ __DRIdrawablePrivate *dPriv = intel->driDrawable;
+ GLframebuffer *drawFb = (GLframebuffer *) dPriv->driverPrivate;
if (!intel->ctx.DrawBuffer) {
/* when would this happen? -BP */
@@ -220,7 +197,7 @@ intelWindowMoved(struct intel_context *intel)
}
else {
/* drawing to a window */
- switch (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0]) {
+ switch (drawFb->_ColorDrawBufferMask[0]) {
case BUFFER_BIT_FRONT_LEFT:
intelSetFrontClipRects(intel);
break;
@@ -233,14 +210,11 @@ intelWindowMoved(struct intel_context *intel)
}
}
- /* this update Mesa's notion of window size */
- if (ctx->WinSysDrawBuffer) {
- _mesa_resize_framebuffer(ctx, ctx->WinSysDrawBuffer,
- intel->driDrawable->w, intel->driDrawable->h);
- }
+ /* Update Mesa's notion of window size */
+ driUpdateFramebufferSize(ctx, dPriv);
+ drawFb->Initialized = GL_TRUE; /* XXX remove someday */
- if (intel->intelScreen->driScrnPriv->ddxMinor >= 7 && intel->driDrawable) {
- __DRIdrawablePrivate *dPriv = intel->driDrawable;
+ if (intel->intelScreen->driScrnPriv->ddxMinor >= 7) {
drmI830Sarea *sarea = intel->sarea;
drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w,
.y1 = dPriv->y, .y2 = dPriv->y + dPriv->h };
@@ -271,6 +245,9 @@ intelWindowMoved(struct intel_context *intel)
/* Update hardware scissor */
ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
ctx->Scissor.Width, ctx->Scissor.Height);
+
+ /* Re-calculate viewport related state */
+ ctx->Driver.DepthRange( ctx, ctx->Viewport.Near, ctx->Viewport.Far );
}
@@ -853,7 +830,7 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)
***/
if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) {
irbDepth = intel_renderbuffer(fb->_DepthBuffer->Wrapped);
- if (irbDepth->region) {
+ if (irbDepth && irbDepth->region) {
FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE);
depthRegion = irbDepth->region;
}
@@ -949,8 +926,6 @@ void
intelInitBufferFuncs(struct dd_function_table *functions)
{
functions->Clear = intelClear;
- functions->GetBufferSize = intelBufferSize;
- functions->ResizeBuffers = _mesa_resize_framebuffer;
functions->DrawBuffer = intelDrawBuffer;
functions->ReadBuffer = intelReadBuffer;
}
diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c b/src/mesa/drivers/dri/i915tex/intel_context.c
index 3d51a6341c..946f9e8041 100644
--- a/src/mesa/drivers/dri/i915tex/intel_context.c
+++ b/src/mesa/drivers/dri/i915tex/intel_context.c
@@ -37,7 +37,6 @@
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
-#include "array_cache/acache.h"
#include "tnl/t_pipeline.h"
#include "tnl/t_vertex.h"
@@ -86,7 +85,7 @@ int INTEL_DEBUG = (0);
#include "extension_helper.h"
-#define DRIVER_DATE "20060929"
+#define DRIVER_DATE "20061102"
_glthread_Mutex lockMutex;
static GLboolean lockMutexInit = GL_FALSE;
@@ -241,7 +240,7 @@ intelInvalidateState(GLcontext * ctx, GLuint new_state)
{
_swrast_InvalidateState(ctx, new_state);
_swsetup_InvalidateState(ctx, new_state);
- _ac_InvalidateState(ctx, new_state);
+ _vbo_InvalidateState(ctx, new_state);
_tnl_InvalidateState(ctx, new_state);
_tnl_invalidate_vertex_state(ctx, new_state);
intel_context(ctx)->NewGLState |= new_state;
@@ -390,7 +389,7 @@ intelInitContext(struct intel_context *intel,
/* Initialize the software rasterizer and helper modules. */
_swrast_CreateContext(ctx);
- _ac_CreateContext(ctx);
+ _vbo_CreateContext(ctx);
_tnl_CreateContext(ctx);
_swsetup_CreateContext(ctx);
@@ -500,7 +499,7 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv)
release_texture_heaps = (intel->ctx.Shared->RefCount == 1);
_swsetup_DestroyContext(&intel->ctx);
_tnl_DestroyContext(&intel->ctx);
- _ac_DestroyContext(&intel->ctx);
+ _vbo_DestroyContext(&intel->ctx);
_swrast_DestroyContext(&intel->ctx);
intel->Fallback = 0; /* don't call _swrast_Flush later */
@@ -577,6 +576,16 @@ intelMakeCurrent(__DRIcontextPrivate * driContextPriv,
}
}
+ /* set initial GLframebuffer size to match window, if needed */
+ if (drawFb->Width == 0 && driDrawPriv->w) {
+ _mesa_resize_framebuffer(&intel->ctx, drawFb,
+ driDrawPriv->w, driDrawPriv->h);
+ }
+ if (readFb->Width == 0 && driReadPriv->w) {
+ _mesa_resize_framebuffer(&intel->ctx, readFb,
+ driReadPriv->w, driReadPriv->h);
+ }
+
_mesa_make_current(&intel->ctx, drawFb, readFb);
/* The drawbuffer won't always be updated by _mesa_make_current:
@@ -655,9 +664,6 @@ intelContendedLock(struct intel_context *intel, GLuint flags)
}
-extern _glthread_Mutex lockMutex;
-
-
/* Lock the hardware and validate our state.
*/
void LOCK_HARDWARE( struct intel_context *intel )
diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h b/src/mesa/drivers/dri/i915tex/intel_context.h
index fa3cf58571..7654e4ecd5 100644
--- a/src/mesa/drivers/dri/i915tex/intel_context.h
+++ b/src/mesa/drivers/dri/i915tex/intel_context.h
@@ -354,7 +354,7 @@ __memcpy(void *to, const void *from, size_t n)
/* ================================================================
* Debugging:
*/
-#define DO_DEBUG 1
+#define DO_DEBUG 0
#if DO_DEBUG
extern int INTEL_DEBUG;
#else
diff --git a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c
index 2ebe3ae14e..2b1077aee0 100644
--- a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c
@@ -56,7 +56,7 @@ intel_miptree_create(struct intel_context *intel,
GLuint last_level,
GLuint width0,
GLuint height0,
- GLuint depth0, GLuint cpp, GLboolean compressed)
+ GLuint depth0, GLuint cpp, GLuint compress_byte)
{
GLboolean ok;
struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1);
@@ -72,8 +72,8 @@ intel_miptree_create(struct intel_context *intel,
mt->width0 = width0;
mt->height0 = height0;
mt->depth0 = depth0;
- mt->cpp = compressed ? 2 : cpp;
- mt->compressed = compressed;
+ mt->cpp = compress_byte ? compress_byte : cpp;
+ mt->compressed = compress_byte ? 1 : 0;
mt->refcount = 1;
switch (intel->intelScreen->deviceID) {
@@ -302,11 +302,15 @@ intel_miptree_image_data(struct intel_context *intel,
GLuint dst_offset = intel_miptree_image_offset(dst, face, level);
const GLuint *dst_depth_offset = intel_miptree_depth_offsets(dst, level);
GLuint i;
+ GLuint height = 0;
DBG("%s\n", __FUNCTION__);
for (i = 0; i < depth; i++) {
+ height = dst->level[level].height;
+ if(dst->compressed)
+ height /= 4;
intel_region_data(intel->intelScreen, dst->region, dst_offset + dst_depth_offset[i], 0, 0, src, src_row_pitch, 0, 0, /* source x,y */
- dst->level[level].width, dst->level[level].height);
+ dst->level[level].width, height);
src += src_image_pitch;
}
@@ -329,6 +333,8 @@ intel_miptree_image_copy(struct intel_context *intel,
const GLuint *src_depth_offset = intel_miptree_depth_offsets(src, level);
GLuint i;
+ if (dst->compressed)
+ height /= 4;
for (i = 0; i < depth; i++) {
intel_region_copy(intel->intelScreen,
dst->region, dst_offset + dst_depth_offset[i],
diff --git a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.h b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.h
index e6dd5bb600..ecdb7be244 100644
--- a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.h
@@ -121,7 +121,7 @@ struct intel_mipmap_tree *intel_miptree_create(struct intel_context *intel,
GLuint height0,
GLuint depth0,
GLuint cpp,
- GLboolean compressed);
+ GLuint compress_byte);
void intel_miptree_reference(struct intel_mipmap_tree **dst,
struct intel_mipmap_tree *src);
diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel.c b/src/mesa/drivers/dri/i915tex/intel_pixel.c
index 4fe128deea..9018e3daef 100644
--- a/src/mesa/drivers/dri/i915tex/intel_pixel.c
+++ b/src/mesa/drivers/dri/i915tex/intel_pixel.c
@@ -56,8 +56,9 @@ intel_check_blit_fragment_ops(GLcontext * ctx)
!ctx->Color.ColorMask[1] ||
!ctx->Color.ColorMask[2] ||
!ctx->Color.ColorMask[3] ||
- ctx->Color.ColorLogicOpEnabled ||
- ctx->Texture._EnabledUnits || ctx->FragmentProgram._Enabled);
+ ctx->Texture._EnabledUnits ||
+ ctx->FragmentProgram._Enabled ||
+ ctx->Color.BlendEnabled);
}
diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel_copy.c b/src/mesa/drivers/dri/i915tex/intel_pixel_copy.c
index 5eb021f008..9d478283e4 100644
--- a/src/mesa/drivers/dri/i915tex/intel_pixel_copy.c
+++ b/src/mesa/drivers/dri/i915tex/intel_pixel_copy.c
@@ -95,9 +95,9 @@ intel_check_copypixel_blit_fragment_ops(GLcontext * ctx)
!ctx->Color.ColorMask[1] ||
!ctx->Color.ColorMask[2] ||
!ctx->Color.ColorMask[3] ||
- ctx->Color.ColorLogicOpEnabled ||
ctx->Texture._EnabledUnits ||
- ctx->FragmentProgram._Enabled);
+ ctx->FragmentProgram._Enabled ||
+ ctx->Color.BlendEnabled);
}
/* Doesn't work for overlapping regions. Could do a double copy or
@@ -344,9 +344,12 @@ do_blit_copypixels(GLcontext * ctx,
intelEmitCopyBlit(intel, dst->cpp,
src->pitch, src->buffer, 0,
dst->pitch, dst->buffer, 0,
- rect.x1 + delta_x, rect.y1 + delta_y, /* srcx, srcy */
+ rect.x1 + delta_x,
+ rect.y1 + delta_y, /* srcx, srcy */
rect.x1, rect.y1, /* dstx, dsty */
- rect.x2 - rect.x1, rect.y2 - rect.y1);
+ rect.x2 - rect.x1, rect.y2 - rect.y1,
+ ctx->Color.ColorLogicOpEnabled ?
+ ctx->Color.LogicOp : GL_COPY);
}
out:
diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c b/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c
index 616101aef9..10a079896a 100644
--- a/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c
+++ b/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c
@@ -252,9 +252,9 @@ do_blit_drawpixels(GLcontext * ctx,
return GL_FALSE;
}
- if (!intel_check_meta_tex_fragment_ops(ctx)) {
+ if (!intel_check_blit_fragment_ops(ctx)) {
if (INTEL_DEBUG & DEBUG_PIXEL)
- _mesa_printf("%s - bad GL fragment state for meta tex\n",
+ _mesa_printf("%s - bad GL fragment state for blitter\n",
__FUNCTION__);
return GL_FALSE;
}
@@ -320,17 +320,19 @@ do_blit_drawpixels(GLcontext * ctx,
rect.x1 - dest_rect.x1,
rect.y2 - dest_rect.y2,
rect.x1,
- rect.y1, rect.x2 - rect.x1, rect.y2 - rect.y1);
+ rect.y1, rect.x2 - rect.x1, rect.y2 - rect.y1,
+ ctx->Color.ColorLogicOpEnabled ?
+ ctx->Color.LogicOp : GL_COPY);
}
fence = intel_batchbuffer_flush(intel->batch);
driFenceReference(fence);
}
UNLOCK_HARDWARE(intel);
- if (intel->driDrawable->numClipRects)
+ if (fence) {
driFenceFinish(fence, DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW, GL_FALSE);
-
- driFenceUnReference(fence);
+ driFenceUnReference(fence);
+ }
if (INTEL_DEBUG & DEBUG_PIXEL)
_mesa_printf("%s - DONE\n", __FUNCTION__);
diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel_read.c b/src/mesa/drivers/dri/i915tex/intel_pixel_read.c
index c1cc65674d..24e49ae066 100644
--- a/src/mesa/drivers/dri/i915tex/intel_pixel_read.c
+++ b/src/mesa/drivers/dri/i915tex/intel_pixel_read.c
@@ -271,7 +271,8 @@ do_blit_readpixels(GLcontext * ctx,
rect.y1,
rect.x1 - src_rect.x1,
rect.y2 - src_rect.y2,
- rect.x2 - rect.x1, rect.y2 - rect.y1);
+ rect.x2 - rect.x1, rect.y2 - rect.y1,
+ GL_COPY);
}
fence = intel_batchbuffer_flush(intel->batch);
@@ -280,11 +281,12 @@ do_blit_readpixels(GLcontext * ctx,
}
UNLOCK_HARDWARE(intel);
- if (intel->driDrawable->numClipRects)
+ if (fence) {
driFenceFinish(fence, DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW,
GL_FALSE);
+ driFenceUnReference(fence);
+ }
- driFenceUnReference(fence);
if (INTEL_DEBUG & DEBUG_PIXEL)
_mesa_printf("%s - DONE\n", __FUNCTION__);
diff --git a/src/mesa/drivers/dri/i915tex/intel_regions.c b/src/mesa/drivers/dri/i915tex/intel_regions.c
index 064a34cda8..1205b180ca 100644
--- a/src/mesa/drivers/dri/i915tex/intel_regions.c
+++ b/src/mesa/drivers/dri/i915tex/intel_regions.c
@@ -318,7 +318,8 @@ intel_region_copy(intelScreenPrivate *intelScreen,
dst->cpp,
src->pitch, src->buffer, src_offset,
dst->pitch, dst->buffer, dst_offset,
- srcx, srcy, dstx, dsty, width, height);
+ srcx, srcy, dstx, dsty, width, height,
+ GL_COPY);
}
/* Fill a rectangular sub-region. Need better logic about when to
@@ -433,7 +434,9 @@ intel_region_cow(intelScreenPrivate *intelScreen, struct intel_region *region)
region->buffer, 0,
region->pitch,
pbo->buffer, 0,
- 0, 0, 0, 0, region->pitch, region->height);
+ 0, 0, 0, 0,
+ region->pitch, region->height,
+ GL_COPY);
intel_batchbuffer_flush(intel->batch);
UNLOCK_HARDWARE(intel);
@@ -445,7 +448,9 @@ intel_region_cow(intelScreenPrivate *intelScreen, struct intel_region *region)
region->buffer, 0,
region->pitch,
pbo->buffer, 0,
- 0, 0, 0, 0, region->pitch, region->height);
+ 0, 0, 0, 0,
+ region->pitch, region->height,
+ GL_COPY);
intel_batchbuffer_flush(intel->batch);
}
diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c
index 9bbfabbb8c..efa1b014a6 100644
--- a/src/mesa/drivers/dri/i915tex/intel_screen.c
+++ b/src/mesa/drivers/dri/i915tex/intel_screen.c
@@ -737,6 +737,9 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits,
*/
stencil_bits_array[0] = 0;
stencil_bits_array[1] = 0;
+ if (depth_bits == 24)
+ stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits;
+
stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits;
depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1;
diff --git a/src/mesa/drivers/dri/i915tex/intel_tex.c b/src/mesa/drivers/dri/i915tex/intel_tex.c
index 51875ab292..b08dee43bc 100644
--- a/src/mesa/drivers/dri/i915tex/intel_tex.c
+++ b/src/mesa/drivers/dri/i915tex/intel_tex.c
@@ -75,6 +75,31 @@ intelFreeTextureImageData(GLcontext * ctx, struct gl_texture_image *texImage)
}
+/* The system memcpy (at least on ubuntu 5.10) has problems copying
+ * to agp (writecombined) memory from a source which isn't 64-byte
+ * aligned - there is a 4x performance falloff.
+ *
+ * The x86 __memcpy is immune to this but is slightly slower
+ * (10%-ish) than the system memcpy.
+ *
+ * The sse_memcpy seems to have a slight cliff at 64/32 bytes, but
+ * isn't much faster than x86_memcpy for agp copies.
+ *
+ * TODO: switch dynamically.
+ */
+static void *
+do_memcpy(void *dest, const void *src, size_t n)
+{
+ if ((((unsigned) src) & 63) || (((unsigned) dest) & 63)) {
+ return __memcpy(dest, src, n);
+ }
+ else
+ return memcpy(dest, src, n);
+}
+
+
+#if DO_DEBUG
+
#ifndef __x86_64__
static unsigned
fastrdtsc(void)
@@ -109,29 +134,6 @@ time_diff(unsigned t, unsigned t2)
}
-/* The system memcpy (at least on ubuntu 5.10) has problems copying
- * to agp (writecombined) memory from a source which isn't 64-byte
- * aligned - there is a 4x performance falloff.
- *
- * The x86 __memcpy is immune to this but is slightly slower
- * (10%-ish) than the system memcpy.
- *
- * The sse_memcpy seems to have a slight cliff at 64/32 bytes, but
- * isn't much faster than x86_memcpy for agp copies.
- *
- * TODO: switch dynamically.
- */
-static void *
-do_memcpy(void *dest, const void *src, size_t n)
-{
- if ((((unsigned) src) & 63) || (((unsigned) dest) & 63)) {
- return __memcpy(dest, src, n);
- }
- else
- return memcpy(dest, src, n);
-}
-
-
static void *
timed_memcpy(void *dest, const void *src, size_t n)
{
@@ -151,6 +153,7 @@ timed_memcpy(void *dest, const void *src, size_t n)
_mesa_printf("timed_memcpy: %u %u --> %f clocks/byte\n", t1, t2, rate);
return ret;
}
+#endif /* DO_DEBUG */
void
@@ -168,6 +171,11 @@ intelInitTextureFuncs(struct dd_function_table *functions)
functions->CopyTexSubImage1D = intelCopyTexSubImage1D;
functions->CopyTexSubImage2D = intelCopyTexSubImage2D;
functions->GetTexImage = intelGetTexImage;
+
+ /* compressed texture functions */
+ functions->CompressedTexImage2D = intelCompressedTexImage2D;
+ functions->GetCompressedTexImage = intelGetCompressedTexImage;
+
functions->NewTextureObject = intelNewTextureObject;
functions->NewTextureImage = intelNewTextureImage;
functions->DeleteTexture = intelDeleteTextureObject;
@@ -175,8 +183,10 @@ intelInitTextureFuncs(struct dd_function_table *functions)
functions->UpdateTexturePalette = 0;
functions->IsTextureResident = intelIsTextureResident;
+#if DO_DEBUG
if (INTEL_DEBUG & DEBUG_BUFMGR)
functions->TextureMemCpy = timed_memcpy;
else
+#endif
functions->TextureMemCpy = do_memcpy;
}
diff --git a/src/mesa/drivers/dri/i915tex/intel_tex.h b/src/mesa/drivers/dri/i915tex/intel_tex.h
index 2f3d4ec2d1..6e9938fe53 100644
--- a/src/mesa/drivers/dri/i915tex/intel_tex.h
+++ b/src/mesa/drivers/dri/i915tex/intel_tex.h
@@ -123,6 +123,18 @@ void intelGetTexImage(GLcontext * ctx, GLenum target, GLint level,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage);
+void intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint border,
+ GLsizei imageSize, const GLvoid *data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage );
+
+void intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
+ GLvoid *pixels,
+ const struct gl_texture_object *texObj,
+ const struct gl_texture_image *texImage);
+
GLuint intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit);
void intel_tex_map_images(struct intel_context *intel,
@@ -131,4 +143,6 @@ void intel_tex_map_images(struct intel_context *intel,
void intel_tex_unmap_images(struct intel_context *intel,
struct intel_texture_object *intelObj);
+int intel_compressed_num_bytes(GLuint mesaFormat);
+
#endif
diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_copy.c b/src/mesa/drivers/dri/i915tex/intel_tex_copy.c
index 88b62e781c..b85a25642a 100644
--- a/src/mesa/drivers/dri/i915tex/intel_tex_copy.c
+++ b/src/mesa/drivers/dri/i915tex/intel_tex_copy.c
@@ -145,7 +145,8 @@ do_copy_texsubimage(struct intel_context *intel,
intelImage->mt->pitch,
intelImage->mt->region->buffer,
image_offset,
- x, y + height, dstx, dsty, width, height);
+ x, y + height, dstx, dsty, width, height,
+ GL_COPY); /* ? */
intel_batchbuffer_flush(intel->batch);
}
diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_format.c b/src/mesa/drivers/dri/i915tex/intel_tex_format.c
index d7612dcbaa..6e058dff69 100644
--- a/src/mesa/drivers/dri/i915tex/intel_tex_format.c
+++ b/src/mesa/drivers/dri/i915tex/intel_tex_format.c
@@ -136,6 +136,10 @@ intelChooseTextureFormat(GLcontext * ctx, GLint internalFormat,
case GL_DEPTH_COMPONENT32:
return &_mesa_texformat_z16;
+ case GL_DEPTH_STENCIL_EXT:
+ case GL_DEPTH24_STENCIL8_EXT:
+ return &_mesa_texformat_z24_s8;
+
default:
fprintf(stderr, "unexpected texture format %s in %s\n",
_mesa_lookup_enum_by_nr(internalFormat), __FUNCTION__);
@@ -144,3 +148,25 @@ intelChooseTextureFormat(GLcontext * ctx, GLint internalFormat,
return NULL; /* never get here */
}
+
+int intel_compressed_num_bytes(GLuint mesaFormat)
+{
+ int bytes = 0;
+ switch(mesaFormat) {
+
+ case MESA_FORMAT_RGB_FXT1:
+ case MESA_FORMAT_RGBA_FXT1:
+ case MESA_FORMAT_RGB_DXT1:
+ case MESA_FORMAT_RGBA_DXT1:
+ bytes = 2;
+ break;
+
+ case MESA_FORMAT_RGBA_DXT3:
+ case MESA_FORMAT_RGBA_DXT5:
+ bytes = 4;
+ default:
+ break;
+ }
+
+ return bytes;
+}
diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_image.c b/src/mesa/drivers/dri/i915tex/intel_tex_image.c
index 48c2f35d3b..22221e7322 100644
--- a/src/mesa/drivers/dri/i915tex/intel_tex_image.c
+++ b/src/mesa/drivers/dri/i915tex/intel_tex_image.c
@@ -69,7 +69,7 @@ guess_and_alloc_mipmap_tree(struct intel_context *intel,
GLuint height = intelImage->base.Height;
GLuint depth = intelImage->base.Depth;
GLuint l2width, l2height, l2depth;
- GLuint i;
+ GLuint i, comp_byte = 0;
DBG("%s\n", __FUNCTION__);
@@ -121,6 +121,8 @@ guess_and_alloc_mipmap_tree(struct intel_context *intel,
}
assert(!intelObj->mt);
+ if (intelImage->base.IsCompressed)
+ comp_byte = intel_compressed_num_bytes(intelImage->base.TexFormat->MesaFormat);
intelObj->mt = intel_miptree_create(intel,
intelObj->base.Target,
intelImage->base.InternalFormat,
@@ -130,7 +132,7 @@ guess_and_alloc_mipmap_tree(struct intel_context *intel,
height,
depth,
intelImage->base.TexFormat->TexelBytes,
- intelImage->base.IsCompressed);
+ comp_byte);
DBG("%s - success\n", __FUNCTION__);
}
@@ -230,7 +232,8 @@ try_pbo_upload(struct intel_context *intel,
intelImage->mt->cpp,
src_stride, src_buffer, src_offset,
dst_stride, dst_buffer, dst_offset,
- 0, 0, 0, 0, width, height);
+ 0, 0, 0, 0, width, height,
+ GL_COPY);
intel_batchbuffer_flush(intel->batch);
}
@@ -298,7 +301,7 @@ intelTexImage(GLcontext * ctx,
GLenum format, GLenum type, const void *pixels,
const struct gl_pixelstore_attrib *unpack,
struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
+ struct gl_texture_image *texImage, GLsizei imageSize, int compressed)
{
struct intel_context *intel = intel_context(ctx);
struct intel_texture_object *intelObj = intel_texture_object(texObj);
@@ -346,17 +349,26 @@ intelTexImage(GLcontext * ctx,
break;
}
- texelBytes = texImage->TexFormat->TexelBytes;
-
-
- /* Minimum pitch of 32 bytes */
- if (postConvWidth * texelBytes < 32) {
- postConvWidth = 32 / texelBytes;
- texImage->RowStride = postConvWidth;
+ if (texImage->TexFormat->TexelBytes == 0) {
+ /* must be a compressed format */
+ texelBytes = 0;
+ texImage->IsCompressed = GL_TRUE;
+ texImage->CompressedSize =
+ ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
+ texImage->Height, texImage->Depth,
+ texImage->TexFormat->MesaFormat);
+ } else {
+ texelBytes = texImage->TexFormat->TexelBytes;
+
+ /* Minimum pitch of 32 bytes */
+ if (postConvWidth * texelBytes < 32) {
+ postConvWidth = 32 / texelBytes;
+ texImage->RowStride = postConvWidth;
+ }
+
+ assert(texImage->RowStride == postConvWidth);
}
- assert(texImage->RowStride == postConvWidth);
-
/* Release the reference to a potentially orphaned buffer.
* Release any old malloced memory.
*/
@@ -453,9 +465,15 @@ intelTexImage(GLcontext * ctx,
* the expectation that the mipmap tree will be set up but nothing
* more will be done. This is where those calls return:
*/
- pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1,
- format, type,
- pixels, unpack, "glTexImage");
+ if (compressed) {
+ pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels,
+ unpack,
+ "glCompressedTexImage");
+ } else {
+ pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1,
+ format, type,
+ pixels, unpack, "glTexImage");
+ }
if (!pixels)
return;
@@ -478,7 +496,7 @@ intelTexImage(GLcontext * ctx,
if (texImage->IsCompressed) {
sizeInBytes = texImage->CompressedSize;
dstRowStride =
- _mesa_compressed_row_stride(texImage->InternalFormat, width);
+ _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
assert(dims != 3);
}
else {
@@ -497,14 +515,16 @@ intelTexImage(GLcontext * ctx,
* the blitter to copy. Or, use the hardware to do the format
* conversion and copy:
*/
- if (!texImage->TexFormat->StoreImage(ctx, dims,
- texImage->_BaseFormat,
- texImage->TexFormat,
- texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */
- dstRowStride,
- texImage->ImageOffsets,
- width, height, depth,
- format, type, pixels, unpack)) {
+ if (compressed) {
+ memcpy(texImage->Data, pixels, imageSize);
+ } else if (!texImage->TexFormat->StoreImage(ctx, dims,
+ texImage->_BaseFormat,
+ texImage->TexFormat,
+ texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */
+ dstRowStride,
+ texImage->ImageOffsets,
+ width, height, depth,
+ format, type, pixels, unpack)) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
}
@@ -541,7 +561,7 @@ intelTexImage3D(GLcontext * ctx,
{
intelTexImage(ctx, 3, target, level,
internalFormat, width, height, depth, border,
- format, type, pixels, unpack, texObj, texImage);
+ format, type, pixels, unpack, texObj, texImage, 0, 0);
}
@@ -557,7 +577,7 @@ intelTexImage2D(GLcontext * ctx,
{
intelTexImage(ctx, 2, target, level,
internalFormat, width, height, 1, border,
- format, type, pixels, unpack, texObj, texImage);
+ format, type, pixels, unpack, texObj, texImage, 0, 0);
}
void
@@ -572,20 +592,30 @@ intelTexImage1D(GLcontext * ctx,
{
intelTexImage(ctx, 1, target, level,
internalFormat, width, 1, 1, border,
- format, type, pixels, unpack, texObj, texImage);
+ format, type, pixels, unpack, texObj, texImage, 0, 0);
}
-
+void intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint border,
+ GLsizei imageSize, const GLvoid *data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage )
+{
+ intelTexImage(ctx, 2, target, level,
+ internalFormat, width, height, 1, border,
+ 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, 1);
+}
/**
* Need to map texture image into memory before copying image data,
* then unmap it.
*/
-void
-intelGetTexImage(GLcontext * ctx, GLenum target, GLint level,
- GLenum format, GLenum type, GLvoid * pixels,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
+static void
+intel_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
+ GLenum format, GLenum type, GLvoid * pixels,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage, int compressed)
{
struct intel_context *intel = intel_context(ctx);
struct intel_texture_image *intelImage = intel_texture_image(texImage);
@@ -615,8 +645,15 @@ intelGetTexImage(GLcontext * ctx, GLenum target, GLint level,
assert(intelImage->base.Data);
}
- _mesa_get_teximage(ctx, target, level, format, type, pixels,
- texObj, texImage);
+
+ if (compressed) {
+ _mesa_get_compressed_teximage(ctx, target, level, pixels,
+ texObj, texImage);
+ } else {
+ _mesa_get_teximage(ctx, target, level, format, type, pixels,
+ texObj, texImage);
+ }
+
/* Unmap */
if (intelImage->mt) {
@@ -624,3 +661,26 @@ intelGetTexImage(GLcontext * ctx, GLenum target, GLint level,
intelImage->base.Data = NULL;
}
}
+
+void
+intelGetTexImage(GLcontext * ctx, GLenum target, GLint level,
+ GLenum format, GLenum type, GLvoid * pixels,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ intel_get_tex_image(ctx, target, level, format, type, pixels,
+ texObj, texImage, 0);
+
+
+}
+
+void
+intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
+ GLvoid *pixels,
+ const struct gl_texture_object *texObj,
+ const struct gl_texture_image *texImage)
+{
+ intel_get_tex_image(ctx, target, level, 0, 0, pixels,
+ texObj, texImage, 1);
+
+}
diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_layout.c b/src/mesa/drivers/dri/i915tex/intel_tex_layout.c
new file mode 120000
index 0000000000..fe61b44194
--- /dev/null
+++ b/src/mesa/drivers/dri/i915tex/intel_tex_layout.c
@@ -0,0 +1 @@
+../intel/intel_tex_layout.c \ No newline at end of file
diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_subimage.c b/src/mesa/drivers/dri/i915tex/intel_tex_subimage.c
index 25a2dca685..3935787806 100644
--- a/src/mesa/drivers/dri/i915tex/intel_tex_subimage.c
+++ b/src/mesa/drivers/dri/i915tex/intel_tex_subimage.c
@@ -50,7 +50,6 @@ intelTexSubimage(GLcontext * ctx,
{
struct intel_context *intel = intel_context(ctx);
struct intel_texture_image *intelImage = intel_texture_image(texImage);
- GLuint dstImageStride;
GLuint dstRowStride;
DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__,
@@ -79,7 +78,7 @@ intelTexSubimage(GLcontext * ctx,
intelImage->face,
intelImage->level,
&dstRowStride,
- &dstImageStride);
+ texImage->ImageOffsets);
assert(dstRowStride);
diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_validate.c b/src/mesa/drivers/dri/i915tex/intel_tex_validate.c
index e273716b09..79d587a174 100644
--- a/src/mesa/drivers/dri/i915tex/intel_tex_validate.c
+++ b/src/mesa/drivers/dri/i915tex/intel_tex_validate.c
@@ -2,6 +2,7 @@
#include "macros.h"
#include "intel_context.h"
+#include "intel_batchbuffer.h"
#include "intel_mipmap_tree.h"
#include "intel_tex.h"
@@ -109,6 +110,8 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
GLuint nr_faces = 0;
struct intel_texture_image *firstImage;
+ GLboolean need_flush = GL_FALSE;
+
/* We know/require this is true by now:
*/
assert(intelObj->base.Complete);
@@ -155,9 +158,15 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
* leaving the tree alone.
*/
if (intelObj->mt &&
- ((intelObj->mt->first_level > intelObj->firstLevel) ||
- (intelObj->mt->last_level < intelObj->lastLevel) ||
- (intelObj->mt->internal_format != firstImage->base.InternalFormat))) {
+ (intelObj->mt->target != intelObj->base.Target ||
+ intelObj->mt->internal_format != firstImage->base.InternalFormat ||
+ intelObj->mt->first_level != intelObj->firstLevel ||
+ intelObj->mt->last_level != intelObj->lastLevel ||
+ intelObj->mt->width0 != firstImage->base.Width ||
+ intelObj->mt->height0 != firstImage->base.Height ||
+ intelObj->mt->depth0 != firstImage->base.Depth ||
+ intelObj->mt->cpp != firstImage->base.TexFormat->TexelBytes ||
+ intelObj->mt->compressed != firstImage->base.IsCompressed)) {
intel_miptree_release(intel, &intelObj->mt);
}
@@ -165,6 +174,10 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
/* May need to create a new tree:
*/
if (!intelObj->mt) {
+ int comp_byte = 0;
+
+ if (firstImage->base.IsCompressed)
+ comp_byte = intel_compressed_num_bytes(firstImage->base.TexFormat->MesaFormat);
intelObj->mt = intel_miptree_create(intel,
intelObj->base.Target,
firstImage->base.InternalFormat,
@@ -175,7 +188,7 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
firstImage->base.Depth,
firstImage->base.TexFormat->
TexelBytes,
- firstImage->base.IsCompressed);
+ comp_byte);
}
/* Pull in any images not in the object's tree:
@@ -190,10 +203,14 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
*/
if (intelObj->mt != intelImage->mt) {
copy_image_data_to_tree(intel, intelObj, intelImage);
+ need_flush = GL_TRUE;
}
}
}
+ if (need_flush)
+ intel_batchbuffer_flush(intel->batch);
+
return GL_TRUE;
}
diff --git a/src/mesa/drivers/dri/i915tex/server/i830_common.h b/src/mesa/drivers/dri/i915tex/server/i830_common.h
index fb6ceaa52d..06f28ed19a 100644
--- a/src/mesa/drivers/dri/i915tex/server/i830_common.h
+++ b/src/mesa/drivers/dri/i915tex/server/i830_common.h
@@ -52,6 +52,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define DRM_I830_INIT_HEAP 0x0a
#define DRM_I830_CMDBUFFER 0x0b
#define DRM_I830_DESTROY_HEAP 0x0c
+#define DRM_I830_SET_VBLANK_PIPE 0x0d
+#define DRM_I830_GET_VBLANK_PIPE 0x0e
typedef struct {
enum {
@@ -208,5 +210,11 @@ typedef struct {
int region;
} drmI830MemDestroyHeap;
+#define DRM_I830_VBLANK_PIPE_A 1
+#define DRM_I830_VBLANK_PIPE_B 2
+
+typedef struct {
+ int pipe;
+} drmI830VBlankPipe;
#endif /* _I830_DRM_H_ */
diff --git a/src/mesa/drivers/dri/i915tex/server/i830_dri.h b/src/mesa/drivers/dri/i915tex/server/i830_dri.h
index 6c9a709021..c2a3af8cbf 100644
--- a/src/mesa/drivers/dri/i915tex/server/i830_dri.h
+++ b/src/mesa/drivers/dri/i915tex/server/i830_dri.h
@@ -9,8 +9,8 @@
#define I830_MAX_DRAWABLES 256
#define I830_MAJOR_VERSION 1
-#define I830_MINOR_VERSION 3
-#define I830_PATCHLEVEL 0
+#define I830_MINOR_VERSION 7
+#define I830_PATCHLEVEL 2
#define I830_REG_SIZE 0x80000
@@ -18,20 +18,20 @@ typedef struct _I830DRIRec {
drm_handle_t regs;
drmSize regsSize;
- drmSize backbufferSize;
- drm_handle_t backbuffer;
+ drmSize unused1; /* backbufferSize */
+ drm_handle_t unused2; /* backbuffer */
- drmSize depthbufferSize;
- drm_handle_t depthbuffer;
+ drmSize unused3; /* depthbufferSize */
+ drm_handle_t unused4; /* depthbuffer */
- drmSize rotatedSize;
- drm_handle_t rotatedbuffer;
+ drmSize unused5; /* rotatedSize */
+ drm_handle_t unused6; /* rotatedbuffer */
- drm_handle_t textures;
- int textureSize;
+ drm_handle_t unused7; /* textures */
+ int unused8; /* textureSize */
- drm_handle_t agp_buffers;
- drmSize agp_buf_size;
+ drm_handle_t unused9; /* agp_buffers */
+ drmSize unused10; /* agp_buf_size */
int deviceID;
int width;
@@ -40,20 +40,10 @@ typedef struct _I830DRIRec {
int cpp;
int bitsPerPixel;
- int fbOffset;
- int fbStride;
-
- int backOffset;
- int backPitch;
-
- int depthOffset;
- int depthPitch;
-
- int rotatedOffset;
- int rotatedPitch;
-
- int logTextureGranularity;
- int textureOffset;
+ int unused11[8]; /* was front/back/depth/rotated offset/pitch */
+
+ int unused12; /* logTextureGranularity */
+ int unused13; /* textureOffset */
int irq;
int sarea_priv_offset;
diff --git a/src/mesa/drivers/dri/i915tex/server/intel.h b/src/mesa/drivers/dri/i915tex/server/intel.h
index d7858a20c8..6ea72499c1 100644
--- a/src/mesa/drivers/dri/i915tex/server/intel.h
+++ b/src/mesa/drivers/dri/i915tex/server/intel.h
@@ -75,6 +75,9 @@
#define I830_GMCH_CTRL 0x52
+#define I830_GMCH_MEM_MASK 0x1
+#define I830_GMCH_MEM_64M 0x1
+#define I830_GMCH_MEM_128M 0
#define I830_GMCH_GMS_MASK 0x70
#define I830_GMCH_GMS_DISABLED 0x00
@@ -141,7 +144,7 @@ typedef struct _I830Rec {
unsigned char *MMIOBase;
unsigned char *FbBase;
int cpp;
-
+ uint32_t aper_size;
unsigned int bios_version;
/* These are set in PreInit and never changed. */
diff --git a/src/mesa/drivers/dri/i915tex/server/intel_dri.c b/src/mesa/drivers/dri/i915tex/server/intel_dri.c
index 169fdbece3..4d1ac09f64 100644
--- a/src/mesa/drivers/dri/i915tex/server/intel_dri.c
+++ b/src/mesa/drivers/dri/i915tex/server/intel_dri.c
@@ -292,15 +292,43 @@ static void I830SetupMemoryTiling(const DRIDriverContext *ctx, I830Rec *pI830)
static int I830DetectMemory(const DRIDriverContext *ctx, I830Rec *pI830)
{
- struct pci_device host_bridge;
+ struct pci_device host_bridge, ig_dev;
uint32_t gmch_ctrl;
int memsize = 0;
int range;
-
+ uint32_t aper_size;
+ uint32_t membase2 = 0;
+
memset(&host_bridge, 0, sizeof(host_bridge));
+ memset(&ig_dev, 0, sizeof(ig_dev));
+
+ ig_dev.dev = 2;
pci_device_cfg_read_u32(&host_bridge, &gmch_ctrl, I830_GMCH_CTRL);
-
+
+ if (IS_I830(pI830) || IS_845G(pI830)) {
+ if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) {
+ aper_size = 0x80000000;
+ } else {
+ aper_size = 0x40000000;
+ }
+ } else {
+ if (IS_I9XX(pI830)) {
+ int ret;
+ ret = pci_device_cfg_read_u32(&ig_dev, &membase2, 0x18);
+ if (membase2 & 0x08000000)
+ aper_size = 0x8000000;
+ else
+ aper_size = 0x10000000;
+
+ fprintf(stderr,"aper size is %08X %08x %d\n", aper_size, membase2, ret);
+ } else
+ aper_size = 0x8000000;
+ }
+
+ pI830->aper_size = aper_size;
+
+
/* We need to reduce the stolen size, by the GTT and the popup.
* The GTT varying according the the FbMapSize and the popup is 4KB */
range = (ctx->shared.fbSize / (1024*1024)) + 4;
@@ -576,7 +604,8 @@ I830AllocateMemory(const DRIDriverContext *ctx, I830Rec *pI830)
fprintf(stderr,"unable to allocate context buffer %ld\n", ret);
return FALSE;
}
-
+
+#if 0
memset(&(pI830->TexMem), 0, sizeof(pI830->TexMem));
pI830->TexMem.Key = -1;
@@ -587,6 +616,7 @@ I830AllocateMemory(const DRIDriverContext *ctx, I830Rec *pI830)
fprintf(stderr,"unable to allocate texture memory %ld\n", ret);
return FALSE;
}
+#endif
return TRUE;
}
@@ -604,12 +634,29 @@ I830BindMemory(const DRIDriverContext *ctx, I830Rec *pI830)
return FALSE;
if (!BindAgpRange(ctx, &pI830->ContextMem))
return FALSE;
+#if 0
if (!BindAgpRange(ctx, &pI830->TexMem))
return FALSE;
-
+#endif
return TRUE;
}
+static void SetupDRIMM(const DRIDriverContext *ctx, I830Rec *pI830)
+{
+ unsigned long aperEnd = ROUND_DOWN_TO(pI830->aper_size, GTT_PAGE_SIZE) / GTT_PAGE_SIZE;
+ unsigned long aperStart = ROUND_TO(pI830->aper_size - KB(32768), GTT_PAGE_SIZE) / GTT_PAGE_SIZE;
+
+ fprintf(stderr, "aper size is %08X\n", ctx->shared.fbSize);
+ if (drmMMInit(ctx->drmFD, aperStart, aperEnd - aperStart, DRM_BO_MEM_TT)) {
+ fprintf(stderr,
+ "DRM MM Initialization Failed\n");
+ } else {
+ fprintf(stderr,
+ "DRM MM Initialized at offset 0x%lx length %d page\n", aperStart, aperEnd-aperStart);
+ }
+
+}
+
static Bool
I830CleanupDma(const DRIDriverContext *ctx)
{
@@ -809,6 +856,7 @@ I830DRIMapScreenRegions(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sar
fprintf(stderr, "[drm] Depth Buffer = 0x%08x\n",
sarea->depth_handle);
+#if 0
if (drmAddMap(ctx->drmFD,
(drm_handle_t)sarea->tex_offset,
sarea->tex_size, DRM_AGP, 0,
@@ -819,7 +867,7 @@ I830DRIMapScreenRegions(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sar
}
fprintf(stderr, "[drm] textures = 0x%08x\n",
sarea->tex_handle);
-
+#endif
return TRUE;
}
@@ -847,6 +895,7 @@ I830DRIUnmapScreenRegions(const DRIDriverContext *ctx, I830Rec *pI830, drmI830Sa
}
}
+#if 0
static void
I830InitTextureHeap(const DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea)
{
@@ -869,6 +918,7 @@ I830InitTextureHeap(const DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *s
sarea->log_tex_granularity);
}
}
+#endif
static Bool
I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea)
@@ -891,8 +941,11 @@ I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea)
/* init to zero to be safe */
I830DRIMapScreenRegions(ctx, pI830, sarea);
- I830InitTextureHeap(ctx, pI830, sarea);
+ SetupDRIMM(ctx, pI830);
+#if 0
+ I830InitTextureHeap(ctx, pI830, sarea);
+#endif
if (ctx->pciDevice != PCI_CHIP_845_G &&
ctx->pciDevice != PCI_CHIP_I830_M) {
I830SetParam(ctx, I830_SETPARAM_USE_MI_BATCHBUFFER_START, 1 );
@@ -1083,6 +1136,10 @@ I830ScreenInit(DRIDriverContext *ctx, I830Rec *pI830)
return FALSE;
}
+ pSAREAPriv->rotated_offset = -1;
+ pSAREAPriv->rotated_size = 0;
+ pSAREAPriv->rotated_pitch = ctx->shared.virtualWidth;
+
pSAREAPriv->front_offset = pI830->FrontBuffer.Start;
pSAREAPriv->front_size = pI830->FrontBuffer.Size;
pSAREAPriv->width = ctx->shared.virtualWidth;
@@ -1094,8 +1151,10 @@ I830ScreenInit(DRIDriverContext *ctx, I830Rec *pI830)
pSAREAPriv->back_size = pI830->BackBuffer.Size;
pSAREAPriv->depth_offset = pI830->DepthBuffer.Start;
pSAREAPriv->depth_size = pI830->DepthBuffer.Size;
+#if 0
pSAREAPriv->tex_offset = pI830->TexMem.Start;
pSAREAPriv->tex_size = pI830->TexMem.Size;
+#endif
pSAREAPriv->log_tex_granularity = pI830->TexGranularity;
ctx->driverClientMsg = malloc(sizeof(I830DRIRec));
@@ -1107,14 +1166,6 @@ I830ScreenInit(DRIDriverContext *ctx, I830Rec *pI830)
pI830DRI->height = ctx->shared.virtualHeight;
pI830DRI->mem = ctx->shared.fbSize;
pI830DRI->cpp = ctx->cpp;
- pI830DRI->backOffset = pI830->BackBuffer.Start;
- pI830DRI->backPitch = pI830->BackBuffer.Pitch;
-
- pI830DRI->depthOffset = pI830->DepthBuffer.Start;
- pI830DRI->depthPitch = pI830->DepthBuffer.Pitch;
-
- pI830DRI->fbOffset = pI830->FrontBuffer.Start;
- pI830DRI->fbStride = pI830->FrontBuffer.Pitch;
pI830DRI->bitsPerPixel = ctx->bpp;
pI830DRI->sarea_priv_offset = sizeof(drm_sarea_t);
diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile
index 02fb93486e..9e4ff112dc 100644
--- a/src/mesa/drivers/dri/i965/Makefile
+++ b/src/mesa/drivers/dri/i965/Makefile
@@ -20,6 +20,7 @@ DRIVER_SOURCES = \
intel_pixel_bitmap.c \
intel_state.c \
intel_tex.c \
+ intel_tex_layout.c \
intel_tex_validate.c \
brw_aub.c \
brw_aub_playback.c \
@@ -83,8 +84,10 @@ C_SOURCES = \
ASM_SOURCES =
-
+DRIVER_DEFINES = -I../intel
include ../Makefile.template
+intel_tex_layout.o: ../intel/intel_tex_layout.c
+
symlinks:
diff --git a/src/mesa/drivers/dri/i965/brw_clip.c b/src/mesa/drivers/dri/i965/brw_clip.c
index 0e8591aaa8..3bec153075 100644
--- a/src/mesa/drivers/dri/i965/brw_clip.c
+++ b/src/mesa/drivers/dri/i965/brw_clip.c
@@ -62,6 +62,8 @@ static void compile_clip_prog( struct brw_context *brw,
*/
brw_init_compile(&c.func);
+ c.func.single_program_flow = 1;
+
c.key = *key;
diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index 263110bf5e..6faee65542 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -154,6 +154,7 @@ GLboolean brwCreateContext( const __GLcontextModes *mesaVis,
brw_ProgramCacheInit( ctx );
+ brw_FrameBufferTexInit( brw );
{
const char *filename = getenv("INTEL_REPLAY");
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index 0a61926ee8..08fdc54520 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -478,7 +478,7 @@ struct brw_context
*/
struct brw_state_pointers attribs;
struct gl_vertex_program *vp;
- struct gl_fragment_program *fp;
+ struct gl_fragment_program *fp, *fp_tex;
struct gl_buffer_object *vbo;
@@ -486,6 +486,8 @@ struct brw_context
struct intel_region *saved_depth_region;
GLuint restore_draw_mask;
+ struct gl_fragment_program *restore_fp;
+
GLboolean active;
} metaops;
@@ -496,8 +498,8 @@ struct brw_context
/* Active vertex program:
*/
- struct gl_vertex_program *vertex_program;
- struct gl_fragment_program *fragment_program;
+ const struct gl_vertex_program *vertex_program;
+ const struct gl_fragment_program *fragment_program;
/* For populating the gtt:
@@ -590,6 +592,7 @@ struct brw_context
struct {
struct brw_wm_prog_data *prog_data;
+ struct brw_wm_compile *compile_data;
/* Input sizes, calculated from active vertex program:
*/
@@ -665,6 +668,8 @@ void brw_destroy_state( struct brw_context *brw );
*/
void brwUpdateTextureState( struct intel_context *intel );
void brwInitTextureFuncs( struct dd_function_table *functions );
+void brw_FrameBufferTexInit( struct brw_context *brw );
+void brw_FrameBufferTexDestroy( struct brw_context *brw );
/*======================================================================
* brw_metaops.c
diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c
index dfb598acdf..90637d16ea 100644
--- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
@@ -411,7 +411,7 @@ GLboolean brw_upload_vertices( struct brw_context *brw,
*/
while (tmp) {
- GLuint i = ffs(tmp)-1;
+ GLuint i = ffsll(tmp)-1;
struct brw_vertex_element *input = &brw->vb.inputs[i];
tmp &= ~(1<<i);
diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h
index 1afa0f816b..d4dbcf38a7 100644
--- a/src/mesa/drivers/dri/i965/brw_eu.h
+++ b/src/mesa/drivers/dri/i965/brw_eu.h
@@ -104,6 +104,7 @@ struct brw_compile {
struct brw_instruction *current;
GLuint flag_value;
+ GLboolean single_program_flow;
};
diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
index 6425c91450..9992b47d8a 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
@@ -464,7 +464,6 @@ struct brw_instruction *brw_JMPI(struct brw_compile *p,
return insn;
}
-
/* EU takes the value from the flag register and pushes it onto some
* sort of a stack (presumably merging with any flag value already on
* the stack). Within an if block, the flags at the top of the stack
@@ -482,7 +481,16 @@ struct brw_instruction *brw_JMPI(struct brw_compile *p,
*/
struct brw_instruction *brw_IF(struct brw_compile *p, GLuint execute_size)
{
- struct brw_instruction *insn = next_insn(p, BRW_OPCODE_IF);
+ struct brw_instruction *insn;
+
+ if (p->single_program_flow) {
+ assert(execute_size == BRW_EXECUTE_1);
+
+ insn = next_insn(p, BRW_OPCODE_ADD);
+ insn->header.predicate_inverse = 1;
+ } else {
+ insn = next_insn(p, BRW_OPCODE_IF);
+ }
/* Override the defaults for this instruction:
*/
@@ -504,7 +512,13 @@ struct brw_instruction *brw_IF(struct brw_compile *p, GLuint execute_size)
struct brw_instruction *brw_ELSE(struct brw_compile *p,
struct brw_instruction *if_insn)
{
- struct brw_instruction *insn = next_insn(p, BRW_OPCODE_ELSE);
+ struct brw_instruction *insn;
+
+ if (p->single_program_flow) {
+ insn = next_insn(p, BRW_OPCODE_ADD);
+ } else {
+ insn = next_insn(p, BRW_OPCODE_ELSE);
+ }
brw_set_dest(insn, brw_ip_reg());
brw_set_src0(insn, brw_ip_reg());
@@ -516,11 +530,17 @@ struct brw_instruction *brw_ELSE(struct brw_compile *p,
/* Patch the if instruction to point at this instruction.
*/
- assert(if_insn->header.opcode == BRW_OPCODE_IF);
+ if (p->single_program_flow) {
+ assert(if_insn->header.opcode == BRW_OPCODE_ADD);
- if_insn->bits3.if_else.jump_count = insn - if_insn;
- if_insn->bits3.if_else.pop_count = 1;
- if_insn->bits3.if_else.pad0 = 0;
+ if_insn->bits3.ud = (insn - if_insn + 1) * 16;
+ } else {
+ assert(if_insn->header.opcode == BRW_OPCODE_IF);
+
+ if_insn->bits3.if_else.jump_count = insn - if_insn;
+ if_insn->bits3.if_else.pop_count = 1;
+ if_insn->bits3.if_else.pad0 = 0;
+ }
return insn;
}
@@ -528,63 +548,76 @@ struct brw_instruction *brw_ELSE(struct brw_compile *p,
void brw_ENDIF(struct brw_compile *p,
struct brw_instruction *patch_insn)
{
- struct brw_instruction *insn = next_insn(p, BRW_OPCODE_ENDIF);
+ if (p->single_program_flow) {
+ /* In single program flow mode, there's no need to execute an ENDIF,
+ * since we don't need to do any stack operations, and if we're executing
+ * currently, we want to just continue executing.
+ */
+ struct brw_instruction *next = &p->store[p->nr_insn];
- brw_set_dest(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD));
- brw_set_src0(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD));
- brw_set_src1(insn, brw_imm_d(0x0));
+ assert(patch_insn->header.opcode == BRW_OPCODE_ADD);
- insn->header.compression_control = BRW_COMPRESSION_NONE;
- insn->header.execution_size = patch_insn->header.execution_size;
- insn->header.mask_control = BRW_MASK_ENABLE;
+ patch_insn->bits3.ud = (next - patch_insn) * 16;
+ } else {
+ struct brw_instruction *insn = next_insn(p, BRW_OPCODE_ENDIF);
- assert(patch_insn->bits3.if_else.jump_count == 0);
-
- /* Patch the if or else instructions to point at this or the next
- * instruction respectively.
- */
- if (patch_insn->header.opcode == BRW_OPCODE_IF) {
- /* Automagically turn it into an IFF:
+ brw_set_dest(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD));
+ brw_set_src0(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD));
+ brw_set_src1(insn, brw_imm_d(0x0));
+
+ insn->header.compression_control = BRW_COMPRESSION_NONE;
+ insn->header.execution_size = patch_insn->header.execution_size;
+ insn->header.mask_control = BRW_MASK_ENABLE;
+
+ assert(patch_insn->bits3.if_else.jump_count == 0);
+
+ /* Patch the if or else instructions to point at this or the next
+ * instruction respectively.
*/
- patch_insn->header.opcode = BRW_OPCODE_IFF;
- patch_insn->bits3.if_else.jump_count = insn - patch_insn + 1;
- patch_insn->bits3.if_else.pop_count = 0;
- patch_insn->bits3.if_else.pad0 = 0;
+ if (patch_insn->header.opcode == BRW_OPCODE_IF) {
+ /* Automagically turn it into an IFF:
+ */
+ patch_insn->header.opcode = BRW_OPCODE_IFF;
+ patch_insn->bits3.if_else.jump_count = insn - patch_insn + 1;
+ patch_insn->bits3.if_else.pop_count = 0;
+ patch_insn->bits3.if_else.pad0 = 0;
+ } else if (patch_insn->header.opcode == BRW_OPCODE_ELSE) {
+ patch_insn->bits3.if_else.jump_count = insn - patch_insn + 1;
+ patch_insn->bits3.if_else.pop_count = 1;
+ patch_insn->bits3.if_else.pad0 = 0;
+ } else {
+ assert(0);
+ }
+ /* Also pop item off the stack in the endif instruction:
+ */
+ insn->bits3.if_else.jump_count = 0;
+ insn->bits3.if_else.pop_count = 1;
+ insn->bits3.if_else.pad0 = 0;
}
- else if (patch_insn->header.opcode == BRW_OPCODE_ELSE) {
- patch_insn->bits3.if_else.jump_count = insn - patch_insn + 1;
- patch_insn->bits3.if_else.pop_count = 1;
- patch_insn->bits3.if_else.pad0 = 0;
- }
- else {
- assert(0);
- }
-
- /* Also pop item off the stack in the endif instruction:
- */
- insn->bits3.if_else.jump_count = 0;
- insn->bits3.if_else.pop_count = 1;
- insn->bits3.if_else.pad0 = 0;
}
/* DO/WHILE loop:
*/
struct brw_instruction *brw_DO(struct brw_compile *p, GLuint execute_size)
{
- struct brw_instruction *insn = next_insn(p, BRW_OPCODE_DO);
+ if (p->single_program_flow) {
+ return &p->store[p->nr_insn];
+ } else {
+ struct brw_instruction *insn = next_insn(p, BRW_OPCODE_DO);
- /* Override the defaults for this instruction:
- */
- brw_set_dest(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD));
- brw_set_src0(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD));
- brw_set_src1(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD));
+ /* Override the defaults for this instruction:
+ */
+ brw_set_dest(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD));
+ brw_set_src0(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD));
+ brw_set_src1(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD));
- insn->header.compression_control = BRW_COMPRESSION_NONE;
- insn->header.execution_size = execute_size;
-/* insn->header.mask_control = BRW_MASK_ENABLE; */
+ insn->header.compression_control = BRW_COMPRESSION_NONE;
+ insn->header.execution_size = execute_size;
+ /* insn->header.mask_control = BRW_MASK_ENABLE; */
- return insn;
+ return insn;
+ }
}
@@ -592,19 +625,31 @@ struct brw_instruction *brw_DO(struct brw_compile *p, GLuint execute_size)
void brw_WHILE(struct brw_compile *p,
struct brw_instruction *do_insn)
{
- struct brw_instruction *insn = next_insn(p, BRW_OPCODE_WHILE);
+ struct brw_instruction *insn;
+
+ if (p->single_program_flow)
+ insn = next_insn(p, BRW_OPCODE_ADD);
+ else
+ insn = next_insn(p, BRW_OPCODE_WHILE);
brw_set_dest(insn, brw_ip_reg());
brw_set_src0(insn, brw_ip_reg());
brw_set_src1(insn, brw_imm_d(0x0));
insn->header.compression_control = BRW_COMPRESSION_NONE;
- insn->header.execution_size = do_insn->header.execution_size;
- assert(do_insn->header.opcode == BRW_OPCODE_DO);
- insn->bits3.if_else.jump_count = do_insn - insn;
- insn->bits3.if_else.pop_count = 0;
- insn->bits3.if_else.pad0 = 0;
+ if (p->single_program_flow) {
+ insn->header.execution_size = BRW_EXECUTE_1;
+
+ insn->bits3.d = (do_insn - insn) * 16;
+ } else {
+ insn->header.execution_size = do_insn->header.execution_size;
+
+ assert(do_insn->header.opcode == BRW_OPCODE_DO);
+ insn->bits3.if_else.jump_count = do_insn - insn;
+ insn->bits3.if_else.pop_count = 0;
+ insn->bits3.if_else.pad0 = 0;
+ }
/* insn->header.mask_control = BRW_MASK_ENABLE; */
diff --git a/src/mesa/drivers/dri/i965/brw_gs.c b/src/mesa/drivers/dri/i965/brw_gs.c
index 7d3f9dd5e3..9066e42252 100644
--- a/src/mesa/drivers/dri/i965/brw_gs.c
+++ b/src/mesa/drivers/dri/i965/brw_gs.c
@@ -66,7 +66,9 @@ static void compile_gs_prog( struct brw_context *brw,
/* Begin the compilation:
*/
brw_init_compile(&c.func);
-
+
+ c.func.single_program_flow = 1;
+
/* For some reason the thread is spawned with only 4 channels
* unmasked.
*/
diff --git a/src/mesa/drivers/dri/i965/brw_metaops.c b/src/mesa/drivers/dri/i965/brw_metaops.c
index 2d4c84f612..1728fc8f56 100644
--- a/src/mesa/drivers/dri/i965/brw_metaops.c
+++ b/src/mesa/drivers/dri/i965/brw_metaops.c
@@ -27,6 +27,7 @@
/*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
+ * frame buffer texture by Gary Wong <gtw@gnu.org>
*/
@@ -143,6 +144,15 @@ static const char *fp_prog =
"MOV result.color, fragment.color;\n"
"END\n";
+static const char *fp_tex_prog =
+ "!!ARBfp1.0\n"
+ "TEMP a;\n"
+ "ADD a, fragment.position, program.local[0];\n"
+ "MUL a, a, program.local[1];\n"
+ "TEX result.color, a, texture[0], 2D;\n"
+ "MOV result.depth.z, fragment.position;\n"
+ "END\n";
+
/* Derived values of importance:
*
* FragmentProgram->_Current
@@ -169,6 +179,9 @@ static void init_metaops_state( struct brw_context *brw )
brw->metaops.fp = (struct gl_fragment_program *)
ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 1 );
+ brw->metaops.fp_tex = (struct gl_fragment_program *)
+ ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 1 );
+
brw->metaops.vp = (struct gl_vertex_program *)
ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 1 );
@@ -176,6 +189,10 @@ static void init_metaops_state( struct brw_context *brw )
fp_prog, strlen(fp_prog),
brw->metaops.fp);
+ _mesa_parse_arb_fragment_program(ctx, GL_FRAGMENT_PROGRAM_ARB,
+ fp_tex_prog, strlen(fp_tex_prog),
+ brw->metaops.fp_tex);
+
_mesa_parse_arb_vertex_program(ctx, GL_VERTEX_PROGRAM_ARB,
vp_prog, strlen(vp_prog),
brw->metaops.vp);
@@ -266,7 +283,76 @@ static void meta_color_mask( struct intel_context *intel, GLboolean state )
static void meta_no_texture( struct intel_context *intel )
{
- /* Nothing to do */
+ struct brw_context *brw = brw_context(&intel->ctx);
+
+ brw->metaops.attribs.FragmentProgram->_Current = brw->metaops.fp;
+
+ brw->metaops.attribs.Texture->CurrentUnit = 0;
+ brw->metaops.attribs.Texture->_EnabledUnits = 0;
+ brw->metaops.attribs.Texture->_EnabledCoordUnits = 0;
+ brw->metaops.attribs.Texture->Unit[ 0 ].Enabled = 0;
+ brw->metaops.attribs.Texture->Unit[ 0 ]._ReallyEnabled = 0;
+
+ brw->state.dirty.mesa |= _NEW_TEXTURE | _NEW_PROGRAM;
+}
+
+static void meta_texture_blend_replace(struct intel_context *intel)
+{
+ struct brw_context *brw = brw_context(&intel->ctx);
+
+ brw->metaops.attribs.Texture->CurrentUnit = 0;
+ brw->metaops.attribs.Texture->_EnabledUnits = 1;
+ brw->metaops.attribs.Texture->_EnabledCoordUnits = 1;
+ brw->metaops.attribs.Texture->Unit[ 0 ].Enabled = TEXTURE_2D_BIT;
+ brw->metaops.attribs.Texture->Unit[ 0 ]._ReallyEnabled = TEXTURE_2D_BIT;
+ brw->metaops.attribs.Texture->Unit[ 0 ].Current2D =
+ intel->frame_buffer_texobj;
+ brw->metaops.attribs.Texture->Unit[ 0 ]._Current =
+ intel->frame_buffer_texobj;
+
+ brw->state.dirty.mesa |= _NEW_TEXTURE | _NEW_PROGRAM;
+}
+
+static void meta_import_pixel_state(struct intel_context *intel)
+{
+ struct brw_context *brw = brw_context(&intel->ctx);
+
+ RESTORE(brw, Color, _NEW_COLOR);
+ RESTORE(brw, Depth, _NEW_DEPTH);
+ RESTORE(brw, Fog, _NEW_FOG);
+ RESTORE(brw, Scissor, _NEW_SCISSOR);
+ RESTORE(brw, Stencil, _NEW_STENCIL);
+ RESTORE(brw, Texture, _NEW_TEXTURE);
+ RESTORE(brw, FragmentProgram, _NEW_PROGRAM);
+}
+
+static void meta_frame_buffer_texture( struct intel_context *intel,
+ GLint xoff, GLint yoff )
+{
+ struct brw_context *brw = brw_context(&intel->ctx);
+ struct intel_region *region = intel_drawbuf_region( intel );
+
+ INSTALL(brw, FragmentProgram, _NEW_PROGRAM);
+
+ brw->metaops.attribs.FragmentProgram->_Current = brw->metaops.fp_tex;
+ /* This is unfortunate, but seems to be necessary, since later on we
+ will end up calling _mesa_load_state_parameters to lookup the
+ local params (below), and that will want to look in ctx.FragmentProgram
+ instead of brw->attribs.FragmentProgram. */
+ intel->ctx.FragmentProgram.Current = brw->metaops.fp_tex;
+
+ brw->metaops.fp_tex->Base.LocalParams[ 0 ][ 0 ] = xoff;
+ brw->metaops.fp_tex->Base.LocalParams[ 0 ][ 1 ] = yoff;
+ brw->metaops.fp_tex->Base.LocalParams[ 0 ][ 2 ] = 0.0;
+ brw->metaops.fp_tex->Base.LocalParams[ 0 ][ 3 ] = 0.0;
+ brw->metaops.fp_tex->Base.LocalParams[ 1 ][ 0 ] =
+ 1.0 / region->pitch;
+ brw->metaops.fp_tex->Base.LocalParams[ 1 ][ 1 ] =
+ -1.0 / region->height;
+ brw->metaops.fp_tex->Base.LocalParams[ 1 ][ 2 ] = 0.0;
+ brw->metaops.fp_tex->Base.LocalParams[ 1 ][ 3 ] = 1.0;
+
+ brw->state.dirty.mesa |= _NEW_PROGRAM;
}
@@ -408,9 +494,11 @@ static void install_meta_state( struct intel_context *intel )
}
install_attribs(brw);
+
meta_no_texture(&brw->intel);
meta_flat_shade(&brw->intel);
brw->metaops.restore_draw_mask = ctx->DrawBuffer->_ColorDrawBufferMask[0];
+ brw->metaops.restore_fp = ctx->FragmentProgram.Current;
/* This works without adjusting refcounts. Fix later?
*/
@@ -429,6 +517,7 @@ static void leave_meta_state( struct intel_context *intel )
restore_attribs(brw);
ctx->DrawBuffer->_ColorDrawBufferMask[0] = brw->metaops.restore_draw_mask;
+ ctx->FragmentProgram.Current = brw->metaops.restore_fp;
brw->state.draw_region = brw->metaops.saved_draw_region;
brw->state.depth_region = brw->metaops.saved_depth_region;
@@ -455,10 +544,11 @@ void brw_init_metaops( struct brw_context *brw )
brw->intel.vtbl.meta_depth_replace = meta_depth_replace;
brw->intel.vtbl.meta_color_mask = meta_color_mask;
brw->intel.vtbl.meta_no_texture = meta_no_texture;
+ brw->intel.vtbl.meta_import_pixel_state = meta_import_pixel_state;
+ brw->intel.vtbl.meta_frame_buffer_texture = meta_frame_buffer_texture;
brw->intel.vtbl.meta_draw_region = meta_draw_region;
brw->intel.vtbl.meta_draw_quad = meta_draw_quad;
-
-/* brw->intel.vtbl.meta_texture_blend_replace = meta_texture_blend_replace; */
+ brw->intel.vtbl.meta_texture_blend_replace = meta_texture_blend_replace;
/* brw->intel.vtbl.meta_tex_rect_source = meta_tex_rect_source; */
/* brw->intel.vtbl.meta_draw_format = set_draw_format; */
}
@@ -471,5 +561,6 @@ void brw_destroy_metaops( struct brw_context *brw )
ctx->Driver.DeleteBuffer( ctx, brw->metaops.vbo );
/* ctx->Driver.DeleteProgram( ctx, brw->metaops.fp ); */
+/* ctx->Driver.DeleteProgram( ctx, brw->metaops.fp_tex ); */
/* ctx->Driver.DeleteProgram( ctx, brw->metaops.vp ); */
}
diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c
index 6a6c4503c7..d5779680ff 100644
--- a/src/mesa/drivers/dri/i965/brw_misc_state.c
+++ b/src/mesa/drivers/dri/i965/brw_misc_state.c
@@ -88,10 +88,10 @@ static void upload_drawing_rect(struct brw_context *brw)
if (brw->intel.numClipRects > 1)
return;
- x1 = dPriv->x;
- y1 = dPriv->y;
- x2 = dPriv->x + dPriv->w;
- y2 = dPriv->y + dPriv->h;
+ x1 = brw->intel.pClipRects[0].x1;
+ y1 = brw->intel.pClipRects[0].y1;
+ x2 = brw->intel.pClipRects[0].x2;
+ y2 = brw->intel.pClipRects[0].y2;
if (x1 < 0) x1 = 0;
if (y1 < 0) y1 = 0;
diff --git a/src/mesa/drivers/dri/i965/brw_structs.h b/src/mesa/drivers/dri/i965/brw_structs.h
index 25acdcfe94..10fee944e8 100644
--- a/src/mesa/drivers/dri/i965/brw_structs.h
+++ b/src/mesa/drivers/dri/i965/brw_structs.h
@@ -519,7 +519,22 @@ struct thread3
struct brw_clip_unit_state
{
struct thread0 thread0;
- struct thread1 thread1;
+ struct
+ {
+ GLuint pad0:7;
+ GLuint sw_exception_enable:1;
+ GLuint pad1:3;
+ GLuint mask_stack_exception_enable:1;
+ GLuint pad2:1;
+ GLuint illegal_op_exception_enable:1;
+ GLuint pad3:2;
+ GLuint floating_point_mode:1;
+ GLuint thread_priority:1;
+ GLuint binding_table_entry_count:8;
+ GLuint pad4:5;
+ GLuint single_program_flow:1;
+ } thread1;
+
struct thread2 thread2;
struct thread3 thread3;
@@ -532,8 +547,8 @@ struct brw_clip_unit_state
GLuint pad1:1;
GLuint urb_entry_allocation_size:5;
GLuint pad2:1;
- GLuint max_threads:6; /* may be less */
- GLuint pad3:1;
+ GLuint max_threads:1; /* may be less */
+ GLuint pad3:6;
} thread4;
struct
@@ -1322,6 +1337,7 @@ struct brw_instruction
GLuint end_of_thread:1;
} generic;
+ GLint d;
GLuint ud;
} bits3;
};
diff --git a/src/mesa/drivers/dri/i965/brw_tex.c b/src/mesa/drivers/dri/i965/brw_tex.c
index 8332d869e1..c3ffa9e657 100644
--- a/src/mesa/drivers/dri/i965/brw_tex.c
+++ b/src/mesa/drivers/dri/i965/brw_tex.c
@@ -36,11 +36,14 @@
#include "simple_list.h"
#include "enums.h"
#include "image.h"
+#include "teximage.h"
#include "texstore.h"
#include "texformat.h"
#include "texmem.h"
+#include "intel_context.h"
#include "intel_ioctl.h"
+#include "intel_regions.h"
#include "brw_context.h"
#include "brw_defines.h"
@@ -179,3 +182,32 @@ void brwInitTextureFuncs( struct dd_function_table *functions )
{
functions->ChooseTextureFormat = brwChooseTextureFormat;
}
+
+void brw_FrameBufferTexInit( struct brw_context *brw )
+{
+ struct intel_context *intel = &brw->intel;
+ GLcontext *ctx = &intel->ctx;
+ struct intel_region *region = intel->front_region;
+ struct gl_texture_object *obj;
+ struct gl_texture_image *img;
+
+ intel->frame_buffer_texobj = obj =
+ ctx->Driver.NewTextureObject( ctx, (GLuint) -1, GL_TEXTURE_2D );
+
+ obj->MinFilter = GL_NEAREST;
+ obj->MagFilter = GL_NEAREST;
+
+ img = ctx->Driver.NewTextureImage( ctx );
+
+ _mesa_init_teximage_fields( ctx, GL_TEXTURE_2D, img,
+ region->pitch, region->height, 1, 0,
+ region->cpp == 4 ? GL_RGBA : GL_RGB );
+
+ _mesa_set_tex_image( obj, GL_TEXTURE_2D, 0, img );
+}
+
+void brw_FrameBufferTexDestroy( struct brw_context *brw )
+{
+ brw->intel.ctx.Driver.DeleteTexture( &brw->intel.ctx,
+ brw->intel.frame_buffer_texobj );
+}
diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c
index 1353325aff..af1ad0f1ef 100644
--- a/src/mesa/drivers/dri/i965/brw_tex_layout.c
+++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c
@@ -34,21 +34,15 @@
*/
#include "intel_mipmap_tree.h"
+#include "intel_tex_layout.h"
#include "macros.h"
-static GLuint minify( GLuint d )
-{
- return MAX2(1, d>>1);
-}
-
GLboolean brw_miptree_layout( struct intel_mipmap_tree *mt )
{
/* XXX: these vary depending on image format:
*/
/* GLint align_w = 4; */
- GLint align_h = 2;
-
switch (mt->target) {
case GL_TEXTURE_CUBE_MAP:
@@ -107,53 +101,10 @@ GLboolean brw_miptree_layout( struct intel_mipmap_tree *mt )
break;
}
- default: {
- GLuint level;
- GLuint x = 0;
- GLuint y = 0;
- GLuint width = mt->width0;
- GLuint height = mt->height0;
-
- mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
- mt->total_height = 0;
-
- for ( level = mt->first_level ; level <= mt->last_level ; level++ ) {
- GLuint img_height;
-
- intel_miptree_set_level_info(mt, level, 1,
- x, y,
- width,
- mt->compressed ? height/4 : height, 1);
-
- if (mt->compressed)
- img_height = MAX2(1, height/4);
- else
- img_height = MAX2(align_h, height);
-
-
- /* 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 += mt->pitch / 2;
- x = (x + 3) & ~ 3;
- }
- else {
- y += img_height;
- y += align_h - 1;
- y &= ~(align_h - 1);
- }
-
- width = minify(width);
- height = minify(height);
- }
+ default:
+ i945_miptree_layout_2d(mt);
break;
}
- }
DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
mt->pitch,
mt->total_height,
diff --git a/src/mesa/drivers/dri/i965/brw_vs_tnl.c b/src/mesa/drivers/dri/i965/brw_vs_tnl.c
index dc580998e3..0d61092247 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_tnl.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_tnl.c
@@ -114,7 +114,7 @@ static GLuint translate_texgen( GLboolean enabled, GLenum mode )
static void make_state_key( GLcontext *ctx, struct state_key *key )
{
struct brw_context *brw = brw_context(ctx);
- struct gl_fragment_program *fp = brw->fragment_program;
+ const struct gl_fragment_program *fp = brw->fragment_program;
GLuint i;
/* This now relies on texenvprogram.c being active:
@@ -402,7 +402,7 @@ static struct ureg register_const4f( struct tnl_program *p,
values[1] = s1;
values[2] = s2;
values[3] = s3;
- idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values );
+ idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4 );
return make_ureg(PROGRAM_STATE_VAR, idx);
}
@@ -1625,7 +1625,7 @@ const struct brw_tracked_state brw_tnl_vertprog = {
static void update_active_vertprog( struct brw_context *brw )
{
- struct gl_vertex_program *prev = brw->vertex_program;
+ const struct gl_vertex_program *prev = brw->vertex_program;
/* NEW_PROGRAM */
if (brw->attribs.VertexProgram->_Enabled) {
diff --git a/src/mesa/drivers/dri/i965/brw_vtbl.c b/src/mesa/drivers/dri/i965/brw_vtbl.c
index a5738e5774..786f30e641 100644
--- a/src/mesa/drivers/dri/i965/brw_vtbl.c
+++ b/src/mesa/drivers/dri/i965/brw_vtbl.c
@@ -67,6 +67,7 @@ static void brw_destroy_context( struct intel_context *intel )
brw_draw_destroy( brw );
brw_ProgramCacheDestroy( ctx );
+ brw_FrameBufferTexDestroy( brw );
}
/* called from intelDrawBuffer()
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
index 3e2f2d06b8..0f842d289d 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -138,64 +138,75 @@ static void do_wm_prog( struct brw_context *brw,
struct brw_fragment_program *fp,
struct brw_wm_prog_key *key)
{
- struct brw_wm_compile c;
+ struct brw_wm_compile *c;
const GLuint *program;
GLuint program_size;
- memset(&c, 0, sizeof(c));
- memcpy(&c.key, key, sizeof(*key));
+ c = brw->wm.compile_data;
+ if (c == NULL) {
+ brw->wm.compile_data = calloc(1, sizeof(*brw->wm.compile_data));
+ c = brw->wm.compile_data;
+ } else {
+ memset(c, 0, sizeof(*brw->wm.compile_data));
+ }
+ memcpy(&c->key, key, sizeof(*key));
- c.fp = fp;
- c.env_param = brw->intel.ctx.FragmentProgram.Parameters;
+ c->fp = fp;
+ c->env_param = brw->intel.ctx.FragmentProgram.Parameters;
/* Augment fragment program. Add instructions for pre- and
* post-fragment-program tasks such as interpolation and fogging.
*/
- brw_wm_pass_fp(&c);
+ brw_wm_pass_fp(c);
/* Translate to intermediate representation. Build register usage
* chains.
*/
- brw_wm_pass0(&c);
+ brw_wm_pass0(c);
/* Dead code removal.
*/
- brw_wm_pass1(&c);
+ brw_wm_pass1(c);
/* Hal optimization
*/
- brw_wm_pass_hal (&c);
+ brw_wm_pass_hal (c);
/* Register allocation.
*/
- c.grf_limit = BRW_WM_MAX_GRF/2;
+ c->grf_limit = BRW_WM_MAX_GRF/2;
/* This is where we start emitting gen4 code:
*/
- brw_init_compile(&c.func);
+ brw_init_compile(&c->func);
- brw_wm_pass2(&c);
+ brw_wm_pass2(c);
- c.prog_data.total_grf = c.max_wm_grf;
- c.prog_data.total_scratch = c.last_scratch ? c.last_scratch + 0x40 : 0;
+ c->prog_data.total_grf = c->max_wm_grf;
+ if (c->last_scratch) {
+ c->prog_data.total_scratch =
+ c->last_scratch + 0x40;
+ } else {
+ c->prog_data.total_scratch = 0;
+ }
/* Emit GEN4 code.
*/
- brw_wm_emit(&c);
+ brw_wm_emit(c);
/* get the program
*/
- program = brw_get_program(&c.func, &program_size);
+ program = brw_get_program(&c->func, &program_size);
/*
*/
brw->wm.prog_gs_offset = brw_upload_cache( &brw->cache[BRW_WM_PROG],
- &c.key,
- sizeof(c.key),
+ &c->key,
+ sizeof(c->key),
program,
program_size,
- &c.prog_data,
+ &c->prog_data,
&brw->wm.prog_data );
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c
index 04c7555b9b..bb0aa35615 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_fp.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c
@@ -432,7 +432,7 @@ static struct prog_src_register search_or_add_const4f( struct brw_wm_compile *c,
return src_reg(PROGRAM_STATE_VAR, idx);
}
- idx = _mesa_add_unnamed_constant( paramList, values );
+ idx = _mesa_add_unnamed_constant( paramList, values, 4 );
return src_reg(PROGRAM_STATE_VAR, idx);
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c
index 4707a709e7..ff5cb31bdd 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_state.c
@@ -122,7 +122,7 @@ static void upload_wm_unit(struct brw_context *brw )
/* BRW_NEW_FRAGMENT_PROGRAM */
{
- struct gl_fragment_program *fp = brw->fragment_program;
+ const struct gl_fragment_program *fp = brw->fragment_program;
if (fp->Base.InputsRead & (1<<FRAG_ATTRIB_WPOS))
wm.wm5.program_uses_depth = 1; /* as far as we can tell */
@@ -168,7 +168,7 @@ static void upload_wm_unit(struct brw_context *brw )
wm.wm5.line_stipple = 1;
}
- if (INTEL_DEBUG & DEBUG_STATS)
+ if (INTEL_DEBUG & DEBUG_STATS || intel->stats_wm)
wm.wm4.stats_enable = 1;
brw->wm.state_gs_offset = brw_cache_data( &brw->cache[BRW_WM_UNIT], &wm );
diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
index 5c7dc500ca..d24c618a66 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -239,6 +239,12 @@ static void upload_wm_surfaces(struct brw_context *brw )
brw->wm.bind.surf_ss_offset[i+1] = brw_cache_data( &brw->cache[BRW_SS_SURFACE], &surf );
brw->wm.nr_surfaces = i+2;
}
+ else if( texUnit->_ReallyEnabled &&
+ texUnit->_Current == intel->frame_buffer_texobj )
+ {
+ brw->wm.bind.surf_ss_offset[i+1] = brw->wm.bind.surf_ss_offset[0];
+ brw->wm.nr_surfaces = i+2;
+ }
else {
brw->wm.bind.surf_ss_offset[i+1] = 0;
}
diff --git a/src/mesa/drivers/dri/i965/bufmgr.h b/src/mesa/drivers/dri/i965/bufmgr.h
index 6932522d3d..e748c0d6d0 100644
--- a/src/mesa/drivers/dri/i965/bufmgr.h
+++ b/src/mesa/drivers/dri/i965/bufmgr.h
@@ -199,9 +199,11 @@ void *bmFindVirtual( struct intel_context *intel,
* For now they can stay, but will likely change/move before final:
*/
unsigned bmSetFence( struct intel_context * );
+unsigned bmSetFenceLock( struct intel_context * );
unsigned bmLockAndFence( struct intel_context *intel );
int bmTestFence( struct intel_context *, unsigned fence );
void bmFinishFence( struct intel_context *, unsigned fence );
+void bmFinishFenceLock( struct intel_context *, unsigned fence );
void bm_fake_NotifyContendedLockTake( struct intel_context * );
diff --git a/src/mesa/drivers/dri/i965/bufmgr_fake.c b/src/mesa/drivers/dri/i965/bufmgr_fake.c
index ed88ab3797..24ee11edd8 100644
--- a/src/mesa/drivers/dri/i965/bufmgr_fake.c
+++ b/src/mesa/drivers/dri/i965/bufmgr_fake.c
@@ -338,7 +338,6 @@ static int evict_mru( struct intel_context *intel, GLuint *pool )
}
-
static int check_fenced( struct intel_context *intel )
{
struct bufmgr *bm = intel->bm;
@@ -1328,11 +1327,21 @@ unsigned bmSetFence( struct intel_context *intel )
return intel->bm->last_fence;
}
+unsigned bmSetFenceLock( struct intel_context *intel )
+{
+ unsigned last;
+ LOCK(intel->bm);
+ last = bmSetFence(intel);
+ UNLOCK(intel->bm);
+ return last;
+}
unsigned bmLockAndFence( struct intel_context *intel )
{
if (intel->bm->need_fence) {
LOCK_HARDWARE(intel);
+ LOCK(intel->bm);
bmSetFence(intel);
+ UNLOCK(intel->bm);
UNLOCK_HARDWARE(intel);
}
@@ -1350,7 +1359,12 @@ void bmFinishFence( struct intel_context *intel, unsigned fence )
check_fenced(intel);
}
-
+void bmFinishFenceLock( struct intel_context *intel, unsigned fence )
+{
+ LOCK(intel->bm);
+ bmFinishFence(intel, fence);
+ UNLOCK(intel->bm);
+}
/* Specifically ignore texture memory sharing.
diff --git a/src/mesa/drivers/dri/i965/intel_blit.c b/src/mesa/drivers/dri/i965/intel_blit.c
index 0974f1f80a..173d1d5b6c 100644
--- a/src/mesa/drivers/dri/i965/intel_blit.c
+++ b/src/mesa/drivers/dri/i965/intel_blit.c
@@ -66,7 +66,7 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv,
intelFlush( &intel->ctx );
- bmFinishFence(intel, intel->last_swap_fence);
+ bmFinishFenceLock(intel, intel->last_swap_fence);
/* The LOCK_HARDWARE is required for the cliprects. Buffer offsets
* should work regardless.
@@ -155,7 +155,7 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv,
intel_batchbuffer_flush( intel->batch );
intel->second_last_swap_fence = intel->last_swap_fence;
- intel->last_swap_fence = bmSetFence( intel );
+ intel->last_swap_fence = bmSetFenceLock( intel );
UNLOCK_HARDWARE( intel );
if (!rect)
@@ -221,6 +221,29 @@ void intelEmitFillBlit( struct intel_context *intel,
ADVANCE_BATCH();
}
+static GLuint translate_raster_op(GLenum logicop)
+{
+ switch(logicop) {
+ case GL_CLEAR: return 0x00;
+ case GL_AND: return 0x88;
+ case GL_AND_REVERSE: return 0x44;
+ case GL_COPY: return 0xCC;
+ case GL_AND_INVERTED: return 0x22;
+ case GL_NOOP: return 0xAA;
+ case GL_XOR: return 0x66;
+ case GL_OR: return 0xEE;
+ case GL_NOR: return 0x11;
+ case GL_EQUIV: return 0x99;
+ case GL_INVERT: return 0x55;
+ case GL_OR_REVERSE: return 0xDD;
+ case GL_COPY_INVERTED: return 0x33;
+ case GL_OR_INVERTED: return 0xBB;
+ case GL_NAND: return 0x77;
+ case GL_SET: return 0xFF;
+ default: return 0;
+ }
+}
+
/* Copy BitBlt
*/
@@ -236,7 +259,8 @@ void intelEmitCopyBlit( struct intel_context *intel,
GLboolean dst_tiled,
GLshort src_x, GLshort src_y,
GLshort dst_x, GLshort dst_y,
- GLshort w, GLshort h )
+ GLshort w, GLshort h,
+ GLenum logic_op )
{
GLuint CMD, BR13;
int dst_y2 = dst_y + h;
@@ -244,12 +268,15 @@ void intelEmitCopyBlit( struct intel_context *intel,
BATCH_LOCALS;
- DBG("%s src:buf(%d)/%d %d,%d dst:buf(%d)/%d %d,%d sz:%dx%d\n",
+ DBG("%s src:buf(%d)/%d %d,%d dst:buf(%d)/%d %d,%d sz:%dx%d op:%d\n",
__FUNCTION__,
src_buffer, src_pitch, src_x, src_y,
dst_buffer, dst_pitch, dst_x, dst_y,
- w,h);
+ w,h,logic_op);
+ assert( logic_op - GL_CLEAR >= 0 );
+ assert( logic_op - GL_CLEAR < 0x10 );
+
src_pitch *= cpp;
dst_pitch *= cpp;
@@ -257,11 +284,12 @@ void intelEmitCopyBlit( struct intel_context *intel,
case 1:
case 2:
case 3:
- BR13 = (0xCC << 16) | (1<<24);
+ BR13 = (translate_raster_op(logic_op) << 16) | (1<<24);
CMD = XY_SRC_COPY_BLT_CMD;
break;
case 4:
- BR13 = (0xCC << 16) | (1<<24) | (1<<25);
+ BR13 = (translate_raster_op(logic_op) << 16) | (1<<24) |
+ (1<<25);
CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
XY_SRC_COPY_BLT_WRITE_RGB);
break;
diff --git a/src/mesa/drivers/dri/i965/intel_blit.h b/src/mesa/drivers/dri/i965/intel_blit.h
index b15fb1c2b7..8b0cc65243 100644
--- a/src/mesa/drivers/dri/i965/intel_blit.h
+++ b/src/mesa/drivers/dri/i965/intel_blit.h
@@ -49,7 +49,8 @@ extern void intelEmitCopyBlit( struct intel_context *intel,
GLboolean dst_tiled,
GLshort srcx, GLshort srcy,
GLshort dstx, GLshort dsty,
- GLshort w, GLshort h );
+ GLshort w, GLshort h,
+ GLenum logic_op );
extern void intelEmitFillBlit( struct intel_context *intel,
GLuint cpp,
diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c
index c4c5488cbb..60fcf95892 100644
--- a/src/mesa/drivers/dri/i965/intel_context.c
+++ b/src/mesa/drivers/dri/i965/intel_context.c
@@ -33,6 +33,7 @@
#include "extensions.h"
#include "framebuffer.h"
#include "imports.h"
+#include "points.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
@@ -70,6 +71,7 @@ int INTEL_DEBUG = (0);
#define need_GL_ARB_vertex_buffer_object
#define need_GL_ARB_vertex_program
#define need_GL_ARB_window_pos
+#define need_GL_ARB_occlusion_query
#define need_GL_EXT_blend_color
#define need_GL_EXT_blend_equation_separate
#define need_GL_EXT_blend_func_separate
@@ -182,7 +184,8 @@ const struct dri_extension card_extensions[] =
{ NULL, NULL }
};
-
+static const struct dri_extension arb_oc_extension =
+ { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions};
static const struct dri_debug_control debug_control[] =
{
@@ -241,6 +244,36 @@ void intelFinish( GLcontext *ctx )
bmFinishFence(intel, bmLockAndFence(intel));
}
+static void
+intelBeginQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q)
+{
+ struct intel_context *intel = intel_context( ctx );
+ GLuint64EXT tmp = 0;
+ drmI830MMIO io = {
+ .read_write = MMIO_WRITE,
+ .reg = MMIO_REGS_PS_DEPTH_COUNT,
+ .data = &tmp
+ };
+ intel->stats_wm = GL_TRUE;
+ intelFinish(&intel->ctx);
+ drmCommandWrite(intel->driFd, DRM_I830_MMIO, &io, sizeof(io));
+}
+
+static void
+intelEndQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q)
+{
+ struct intel_context *intel = intel_context( ctx );
+ drmI830MMIO io = {
+ .read_write = MMIO_READ,
+ .reg = MMIO_REGS_PS_DEPTH_COUNT,
+ .data = &q->Result
+ };
+ intelFinish(&intel->ctx);
+ drmCommandRead(intel->driFd, DRM_I830_MMIO, &io, sizeof(io));
+ q->Ready = GL_TRUE;
+ intel->stats_wm = GL_FALSE;
+}
+
void intelInitDriverFunctions( struct dd_function_table *functions )
{
@@ -250,6 +283,8 @@ void intelInitDriverFunctions( struct dd_function_table *functions )
functions->Finish = intelFinish;
functions->GetString = intelGetString;
functions->UpdateState = intelInvalidateState;
+ functions->BeginQuery = intelBeginQuery;
+ functions->EndQuery = intelEndQuery;
/* CopyPixels can be accelerated even with the current memory
* manager:
@@ -320,6 +355,11 @@ GLboolean intelInitContext( struct intel_context *intel,
ctx->Const.MaxPointSizeAA = 3.0;
ctx->Const.PointSizeGranularity = 1.0;
+ /* reinitialize the context point state.
+ * It depend on constants in __GLcontextRec::Const
+ */
+ _mesa_init_point(ctx);
+
/* Initialize the software rasterizer and helper modules. */
_swrast_CreateContext( ctx );
_vbo_CreateContext( ctx );
@@ -373,6 +413,9 @@ GLboolean intelInitContext( struct intel_context *intel,
driInitExtensions( ctx, card_extensions,
GL_TRUE );
+ if (intel->intelScreen->drmMinor >= 8)
+ driInitSingleExtension (ctx, &arb_oc_extension);
+
INTEL_DEBUG = driParseDebugString( getenv( "INTEL_DEBUG" ),
debug_control );
@@ -398,7 +441,7 @@ GLboolean intelInitContext( struct intel_context *intel,
intelScreen->cpp,
intelScreen->front.pitch / intelScreen->cpp,
intelScreen->height,
- GL_FALSE);
+ intelScreen->front.tiled != 0); /* 0: LINEAR */
intel->back_region =
@@ -409,7 +452,7 @@ GLboolean intelInitContext( struct intel_context *intel,
intelScreen->cpp,
intelScreen->back.pitch / intelScreen->cpp,
intelScreen->height,
- (INTEL_DEBUG & DEBUG_TILE) ? 0 : 1);
+ intelScreen->back.tiled != 0);
/* Still assuming front.cpp == depth.cpp
*
@@ -425,7 +468,7 @@ GLboolean intelInitContext( struct intel_context *intel,
intelScreen->cpp,
intelScreen->depth.pitch / intelScreen->cpp,
intelScreen->height,
- (INTEL_DEBUG & DEBUG_TILE) ? 0 : 1);
+ intelScreen->depth.tiled != 0);
intel_bufferobj_init( intel );
intel->batch = intel_batchbuffer_alloc( intel );
diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h
index 2df8faef28..fe7ee382a1 100644
--- a/src/mesa/drivers/dri/i965/intel_context.h
+++ b/src/mesa/drivers/dri/i965/intel_context.h
@@ -86,7 +86,6 @@ struct intel_texture_object
-
struct intel_context
{
GLcontext ctx; /* the parent class */
@@ -148,9 +147,14 @@ struct intel_context
void (*meta_depth_replace)( struct intel_context *intel );
+ void (*meta_texture_blend_replace) (struct intel_context * intel);
+
void (*meta_no_stencil_write)( struct intel_context *intel );
void (*meta_no_depth_write)( struct intel_context *intel );
void (*meta_no_texture)( struct intel_context *intel );
+ void (*meta_import_pixel_state) (struct intel_context * intel);
+ void (*meta_frame_buffer_texture)( struct intel_context *intel,
+ GLint xoff, GLint yoff );
void (*meta_draw_quad)(struct intel_context *intel,
GLfloat x0, GLfloat x1,
@@ -173,6 +177,7 @@ struct intel_context
GLuint second_last_swap_fence;
GLboolean aub_wrap;
+ GLboolean stats_wm;
struct intel_batchbuffer *batch;
@@ -218,6 +223,7 @@ struct intel_context
int drawY;
GLuint numClipRects; /* cliprects for that buffer */
drm_clip_rect_t *pClipRects;
+ struct gl_texture_object *frame_buffer_texobj;
GLboolean scissor;
drm_clip_rect_t draw_rect;
diff --git a/src/mesa/drivers/dri/i965/intel_ioctl.c b/src/mesa/drivers/dri/i965/intel_ioctl.c
index d1f2e3f27c..4da31277ea 100644
--- a/src/mesa/drivers/dri/i965/intel_ioctl.c
+++ b/src/mesa/drivers/dri/i965/intel_ioctl.c
@@ -43,6 +43,26 @@
#include "drm.h"
#include "bufmgr.h"
+static int intelWaitIdleLocked( struct intel_context *intel )
+{
+ static int in_wait_idle = 0;
+ unsigned int fence;
+
+ if (!in_wait_idle) {
+ if (INTEL_DEBUG & DEBUG_SYNC) {
+ fprintf(stderr, "waiting for idle\n");
+ }
+
+ in_wait_idle = 1;
+ fence = bmSetFence(intel);
+ intelWaitIrq(intel, fence);
+ in_wait_idle = 0;
+
+ return bmTestFence(intel, fence);
+ } else {
+ return 1;
+ }
+}
int intelEmitIrqLocked( struct intel_context *intel )
{
@@ -75,7 +95,7 @@ void intelWaitIrq( struct intel_context *intel, int seq )
{
if (!intel->no_hw) {
drmI830IrqWait iw;
- int ret;
+ int ret, lastdispatch;
if (0)
fprintf(stderr, "%s %d\n", __FUNCTION__, seq );
@@ -83,11 +103,12 @@ void intelWaitIrq( struct intel_context *intel, int seq )
iw.irq_seq = seq;
do {
+ lastdispatch = intel->sarea->last_dispatch;
ret = drmCommandWrite( intel->driFd, DRM_I830_IRQ_WAIT, &iw, sizeof(iw) );
/* This seems quite often to return before it should!?!
*/
- } while (ret == -EAGAIN || ret == -EINTR || (ret == 0 && seq > intel->sarea->last_dispatch));
+ } while (ret == -EAGAIN || ret == -EINTR || (ret == -EBUSY && lastdispatch != intel->sarea->last_dispatch) || (ret == 0 && seq > intel->sarea->last_dispatch));
if ( ret ) {
@@ -139,7 +160,11 @@ void intel_batch_ioctl( struct intel_context *intel,
UNLOCK_HARDWARE(intel);
exit(1);
}
- }
+
+ if (INTEL_DEBUG & DEBUG_SYNC) {
+ intelWaitIdleLocked(intel);
+ }
+ }
}
void intel_cmd_ioctl( struct intel_context *intel,
@@ -171,5 +196,9 @@ void intel_cmd_ioctl( struct intel_context *intel,
UNLOCK_HARDWARE(intel);
exit(1);
}
- }
+
+ if (INTEL_DEBUG & DEBUG_SYNC) {
+ intelWaitIdleLocked(intel);
+ }
+ }
}
diff --git a/src/mesa/drivers/dri/i965/intel_pixel_copy.c b/src/mesa/drivers/dri/i965/intel_pixel_copy.c
index d5d4899452..58dc49505f 100644
--- a/src/mesa/drivers/dri/i965/intel_pixel_copy.c
+++ b/src/mesa/drivers/dri/i965/intel_pixel_copy.c
@@ -80,8 +80,6 @@ intel_check_blit_fragment_ops(GLcontext * ctx)
if (ctx->NewState)
_mesa_update_state(ctx);
- /* Could do logicop with the blitter:
- */
return !(ctx->_ImageTransferState ||
ctx->RenderMode != GL_RENDER ||
ctx->Color.AlphaEnabled ||
@@ -92,12 +90,112 @@ intel_check_blit_fragment_ops(GLcontext * ctx)
!ctx->Color.ColorMask[1] ||
!ctx->Color.ColorMask[2] ||
!ctx->Color.ColorMask[3] || /* can do this! */
- ctx->Color.ColorLogicOpEnabled || /* can do this! */
ctx->Texture._EnabledUnits ||
- ctx->FragmentProgram._Enabled);
+ ctx->FragmentProgram._Enabled ||
+ ctx->Color.BlendEnabled);
}
+/* Doesn't work for overlapping regions. Could do a double copy or
+ * just fallback.
+ */
+static GLboolean
+do_texture_copypixels(GLcontext * ctx,
+ GLint srcx, GLint srcy,
+ GLsizei width, GLsizei height,
+ GLint dstx, GLint dsty, GLenum type)
+{
+ struct intel_context *intel = intel_context(ctx);
+ struct intel_region *dst = intel_drawbuf_region(intel);
+ struct intel_region *src = copypix_src_region(intel, type);
+ GLenum src_format;
+ GLenum src_type;
+
+ DBG("%s %d,%d %dx%d --> %d,%d\n", __FUNCTION__,
+ srcx, srcy, width, height, dstx, dsty);
+
+ if (!src || !dst || type != GL_COLOR ||
+ ctx->_ImageTransferState ||
+ ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F ||
+ ctx->RenderMode != GL_RENDER ||
+ ctx->Texture._EnabledUnits ||
+ ctx->FragmentProgram._Enabled ||
+ src != dst )
+ return GL_FALSE;
+
+ /* Can't handle overlapping regions. Don't have sufficient control
+ * over rasterization to pull it off in-place. Punt on these for
+ * now.
+ *
+ * XXX: do a copy to a temporary.
+ */
+ if (src->buffer == dst->buffer) {
+ drm_clip_rect_t srcbox;
+ drm_clip_rect_t dstbox;
+ drm_clip_rect_t tmp;
+
+ srcbox.x1 = srcx;
+ srcbox.y1 = srcy;
+ srcbox.x2 = srcx + width - 1;
+ srcbox.y2 = srcy + height - 1;
+
+ dstbox.x1 = dstx;
+ dstbox.y1 = dsty;
+ dstbox.x2 = dstx + width - 1;
+ dstbox.y2 = dsty + height - 1;
+
+ DBG("src %d,%d %d,%d\n", srcbox.x1, srcbox.y1, srcbox.x2, srcbox.y2);
+ DBG("dst %d,%d %d,%d (%dx%d) (%f,%f)\n", dstbox.x1, dstbox.y1, dstbox.x2, dstbox.y2,
+ width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
+
+ if (intel_intersect_cliprects(&tmp, &srcbox, &dstbox)) {
+ DBG("%s: regions overlap\n", __FUNCTION__);
+ return GL_FALSE;
+ }
+ }
+ intelFlush(&intel->ctx);
+
+ intel->vtbl.install_meta_state(intel);
+
+ /* Is this true? Also will need to turn depth testing on according
+ * to state:
+ */
+ intel->vtbl.meta_no_stencil_write(intel);
+ intel->vtbl.meta_no_depth_write(intel);
+
+ /* Set the 3d engine to draw into the destination region:
+ */
+ intel->vtbl.meta_draw_region(intel, dst, intel->depth_region);
+
+ intel->vtbl.meta_import_pixel_state(intel);
+
+ if (src->cpp == 2) {
+ src_format = GL_RGB;
+ src_type = GL_UNSIGNED_SHORT_5_6_5;
+ }
+ else {
+ src_format = GL_BGRA;
+ src_type = GL_UNSIGNED_BYTE;
+ }
+
+ /* Set the frontbuffer up as a large rectangular texture.
+ */
+ intel->vtbl.meta_frame_buffer_texture( intel, srcx - dstx, srcy - dsty );
+
+ intel->vtbl.meta_texture_blend_replace(intel);
+
+ if (intel->driDrawable->numClipRects)
+ intel->vtbl.meta_draw_quad( intel,
+ dstx, dstx + width,
+ dsty, dsty + height,
+ ctx->Current.RasterPos[ 2 ],
+ 0, 0, 0, 0, 0.0, 0.0, 0.0, 0.0 );
+
+ intel->vtbl.leave_meta_state( intel );
+
+ DBG("%s: success\n", __FUNCTION__);
+ return GL_TRUE;
+}
/**
* CopyPixels with the blitter. Don't support zooming, pixel transfer, etc.
@@ -210,7 +308,9 @@ do_blit_copypixels(GLcontext * ctx,
rect.x1 + delta_x,
rect.y1 + delta_y, /* srcx, srcy */
rect.x1, rect.y1, /* dstx, dsty */
- rect.x2 - rect.x1, rect.y2 - rect.y1);
+ rect.x2 - rect.x1, rect.y2 - rect.y1,
+ ctx->Color.ColorLogicOpEnabled ?
+ ctx->Color.LogicOp : GL_COPY);
}
intel->need_flush = GL_TRUE;
@@ -233,6 +333,9 @@ intelCopyPixels(GLcontext * ctx,
if (do_blit_copypixels(ctx, srcx, srcy, width, height, destx, desty, type))
return;
+ if (do_texture_copypixels(ctx, srcx, srcy, width, height, destx, desty, type))
+ return;
+
if (INTEL_DEBUG & DEBUG_PIXEL)
_mesa_printf("fallback to _swrast_CopyPixels\n");
diff --git a/src/mesa/drivers/dri/i965/intel_regions.c b/src/mesa/drivers/dri/i965/intel_regions.c
index 53f0561237..398b0a0a3b 100644
--- a/src/mesa/drivers/dri/i965/intel_regions.c
+++ b/src/mesa/drivers/dri/i965/intel_regions.c
@@ -269,7 +269,8 @@ void intel_region_copy( struct intel_context *intel,
dst->pitch, dst->buffer, dst_offset, dst->tiled,
srcx, srcy,
dstx, dsty,
- width, height);
+ width, height,
+ GL_COPY );
}
/* Fill a rectangular sub-region. Need better logic about when to
diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c
index 56e6a792fa..8269deba66 100644
--- a/src/mesa/drivers/dri/i965/intel_screen.c
+++ b/src/mesa/drivers/dri/i965/intel_screen.c
@@ -230,16 +230,19 @@ intelUpdateScreenFromSAREA(intelScreenPrivate *intelScreen,
intelScreen->front.pitch = sarea->pitch * intelScreen->cpp;
intelScreen->front.handle = sarea->front_handle;
intelScreen->front.size = sarea->front_size;
+ intelScreen->front.tiled = sarea->front_tiled;
intelScreen->back.offset = sarea->back_offset;
intelScreen->back.pitch = sarea->pitch * intelScreen->cpp;
intelScreen->back.handle = sarea->back_handle;
intelScreen->back.size = sarea->back_size;
-
+ intelScreen->back.tiled = sarea->back_tiled;
+
intelScreen->depth.offset = sarea->depth_offset;
intelScreen->depth.pitch = sarea->pitch * intelScreen->cpp;
intelScreen->depth.handle = sarea->depth_handle;
intelScreen->depth.size = sarea->depth_size;
+ intelScreen->depth.tiled = sarea->depth_tiled;
intelScreen->tex.offset = sarea->tex_offset;
intelScreen->logTextureGranularity = sarea->log_tex_granularity;
@@ -249,6 +252,7 @@ intelUpdateScreenFromSAREA(intelScreenPrivate *intelScreen,
intelScreen->rotated.offset = sarea->rotated_offset;
intelScreen->rotated.pitch = sarea->rotated_pitch * intelScreen->cpp;
intelScreen->rotated.size = sarea->rotated_size;
+ intelScreen->rotated.tiled = sarea->rotated_tiled;
intelScreen->current_rotation = sarea->rotation;
#if 0
matrix23Rotate(&intelScreen->rotMatrix,
diff --git a/src/mesa/drivers/dri/i965/intel_screen.h b/src/mesa/drivers/dri/i965/intel_screen.h
index 094158afd8..bf9a716082 100644
--- a/src/mesa/drivers/dri/i965/intel_screen.h
+++ b/src/mesa/drivers/dri/i965/intel_screen.h
@@ -42,6 +42,7 @@ typedef struct {
char *map; /* memory map */
int offset; /* from start of video mem, in bytes */
int pitch; /* row stride, in pixels */
+ unsigned int tiled;
} intelRegion;
typedef struct
diff --git a/src/mesa/drivers/dri/i965/intel_tex_layout.c b/src/mesa/drivers/dri/i965/intel_tex_layout.c
new file mode 120000
index 0000000000..fe61b44194
--- /dev/null
+++ b/src/mesa/drivers/dri/i965/intel_tex_layout.c
@@ -0,0 +1 @@
+../intel/intel_tex_layout.c \ No newline at end of file
diff --git a/src/mesa/drivers/dri/i965/intel_tex_validate.c b/src/mesa/drivers/dri/i965/intel_tex_validate.c
index 91ae0970a0..cb23b9dd87 100644
--- a/src/mesa/drivers/dri/i965/intel_tex_validate.c
+++ b/src/mesa/drivers/dri/i965/intel_tex_validate.c
@@ -133,6 +133,9 @@ GLuint intel_finalize_mipmap_tree( struct intel_context *intel,
GLuint nr_faces = 0;
struct gl_texture_image *firstImage;
+ if( tObj == intel->frame_buffer_texobj )
+ return GL_FALSE;
+
/* We know/require this is true by now:
*/
assert(intelObj->base.Complete);
diff --git a/src/mesa/drivers/dri/i965/server/i830_common.h b/src/mesa/drivers/dri/i965/server/i830_common.h
index e3bbdc7907..f320378c2a 100644
--- a/src/mesa/drivers/dri/i965/server/i830_common.h
+++ b/src/mesa/drivers/dri/i965/server/i830_common.h
@@ -52,6 +52,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define DRM_I830_INIT_HEAP 0x0a
#define DRM_I830_CMDBUFFER 0x0b
#define DRM_I830_DESTROY_HEAP 0x0c
+#define DRM_I830_MMIO 0x10
typedef struct {
enum {
@@ -199,5 +200,23 @@ typedef struct {
int region;
} drmI830MemDestroyHeap;
+#define MMIO_READ 0
+#define MMIO_WRITE 1
+
+#define MMIO_REGS_IA_PRIMATIVES_COUNT 0
+#define MMIO_REGS_IA_VERTICES_COUNT 1
+#define MMIO_REGS_VS_INVOCATION_COUNT 2
+#define MMIO_REGS_GS_PRIMITIVES_COUNT 3
+#define MMIO_REGS_GS_INVOCATION_COUNT 4
+#define MMIO_REGS_CL_PRIMITIVES_COUNT 5
+#define MMIO_REGS_CL_INVOCATION_COUNT 6
+#define MMIO_REGS_PS_INVOCATION_COUNT 7
+#define MMIO_REGS_PS_DEPTH_COUNT 8
+
+typedef struct {
+ unsigned int read_write:1;
+ unsigned int reg:31;
+ void __user *data;
+} drmI830MMIO;
#endif /* _I830_DRM_H_ */
diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.c b/src/mesa/drivers/dri/intel/intel_tex_layout.c
new file mode 100644
index 0000000000..f356480217
--- /dev/null
+++ b/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,
+ mt->compressed ? height/4 : 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/src/mesa/drivers/dri/intel/intel_tex_layout.h b/src/mesa/drivers/dri/intel/intel_tex_layout.h
new file mode 100644
index 0000000000..1e37f8f525
--- /dev/null
+++ b/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/src/mesa/drivers/dri/mach64/mach64_context.c b/src/mesa/drivers/dri/mach64/mach64_context.c
index eeb4cbcf71..5a6c301da2 100644
--- a/src/mesa/drivers/dri/mach64/mach64_context.c
+++ b/src/mesa/drivers/dri/mach64/mach64_context.c
@@ -102,6 +102,7 @@ GLboolean mach64CreateContext( const __GLcontextModes *glVisual,
mach64ContextPtr mmesa;
mach64ScreenPtr mach64Screen;
int i, heap;
+ GLuint *c_textureSwapsPtr = NULL;
#if DO_DEBUG
MACH64_DEBUG = driParseDebugString(getenv("MACH64_DEBUG"), debug_control);
@@ -153,15 +154,28 @@ GLboolean mach64CreateContext( const __GLcontextModes *glVisual,
mmesa->CurrentTexObj[0] = NULL;
mmesa->CurrentTexObj[1] = NULL;
- make_empty_list( &mmesa->SwappedOut );
+ (void) memset( mmesa->texture_heaps, 0, sizeof( mmesa->texture_heaps ) );
+ make_empty_list( &mmesa->swapped );
mmesa->firstTexHeap = mach64Screen->firstTexHeap;
mmesa->lastTexHeap = mach64Screen->firstTexHeap + mach64Screen->numTexHeaps;
for ( i = mmesa->firstTexHeap ; i < mmesa->lastTexHeap ; i++ ) {
- make_empty_list( &mmesa->TexObjList[i] );
- mmesa->texHeap[i] = mmInit( 0, mach64Screen->texSize[i] );
- mmesa->lastTexAge[i] = -1;
+ mmesa->texture_heaps[i] = driCreateTextureHeap( i, mmesa,
+ mach64Screen->texSize[i],
+ 6, /* align to 64-byte boundary, use 12 for page-size boundary */
+ MACH64_NR_TEX_REGIONS,
+ (drmTextureRegionPtr)mmesa->sarea->tex_list[i],
+ &mmesa->sarea->tex_age[i],
+ &mmesa->swapped,
+ sizeof( mach64TexObj ),
+ (destroy_texture_object_t *) mach64DestroyTexObj );
+
+#if ENABLE_PERF_BOXES
+ c_textureSwapsPtr = & mmesa->c_textureSwaps;
+#endif
+ driSetTextureSwapCounterLocation( mmesa->texture_heaps[i],
+ c_textureSwapsPtr );
}
mmesa->RenderIndex = -1; /* Impossible value */
@@ -176,17 +190,25 @@ GLboolean mach64CreateContext( const __GLcontextModes *glVisual,
* Test for 2 textures * bytes/texel * size * size. There's no
* need to account for mipmaps since we only upload one level.
*/
- heap = mach64Screen->IsPCI ? MACH64_CARD_HEAP : MACH64_AGP_HEAP;
-
- if ( mach64Screen->texSize[heap] >= 2 * mach64Screen->cpp * 1024*1024 ) {
- ctx->Const.MaxTextureLevels = 11; /* 1024x1024 */
- } else if ( mach64Screen->texSize[heap] >= 2 * mach64Screen->cpp * 512*512 ) {
- ctx->Const.MaxTextureLevels = 10; /* 512x512 */
- } else {
- ctx->Const.MaxTextureLevels = 9; /* 256x256 */
- }
ctx->Const.MaxTextureUnits = 2;
+ ctx->Const.MaxTextureImageUnits = 2;
+ ctx->Const.MaxTextureCoordUnits = 2;
+
+ heap = mach64Screen->IsPCI ? MACH64_CARD_HEAP : MACH64_AGP_HEAP;
+
+ driCalculateMaxTextureLevels( & mmesa->texture_heaps[heap],
+ 1,
+ & ctx->Const,
+ mach64Screen->cpp,
+ 10, /* max 2D texture size is 1024x1024 */
+ 0, /* 3D textures unsupported. */
+ 0, /* cube textures unsupported. */
+ 0, /* texture rectangles unsupported. */
+ 1, /* mipmapping unsupported. */
+ GL_TRUE, /* need to have both textures in
+ either local or AGP memory */
+ 0 );
#if ENABLE_PERF_BOXES
mmesa->boxes = ( getenv( "LIBGL_PERFORMANCE_BOXES" ) != NULL );
@@ -250,31 +272,29 @@ void mach64DestroyContext( __DRIcontextPrivate *driContextPriv )
assert(mmesa); /* should never be null */
if ( mmesa ) {
- if (mmesa->glCtx->Shared->RefCount == 1) {
+ GLboolean release_texture_heaps;
+
+ release_texture_heaps = (mmesa->glCtx->Shared->RefCount == 1);
+
+ _swsetup_DestroyContext( mmesa->glCtx );
+ _tnl_DestroyContext( mmesa->glCtx );
+ _vbo_DestroyContext( mmesa->glCtx );
+ _swrast_DestroyContext( mmesa->glCtx );
+
+ if (release_texture_heaps) {
/* This share group is about to go away, free our private
* texture object data.
*/
- mach64TexObjPtr t, next_t;
int i;
for ( i = mmesa->firstTexHeap ; i < mmesa->lastTexHeap ; i++ ) {
- foreach_s ( t, next_t, &mmesa->TexObjList[i] ) {
- mach64DestroyTexObj( mmesa, t );
- }
- mmDestroy( mmesa->texHeap[i] );
- mmesa->texHeap[i] = NULL;
+ driDestroyTextureHeap( mmesa->texture_heaps[i] );
+ mmesa->texture_heaps[i] = NULL;
}
- foreach_s ( t, next_t, &mmesa->SwappedOut ) {
- mach64DestroyTexObj( mmesa, t );
- }
+ assert( is_empty_list( & mmesa->swapped ) );
}
- _swsetup_DestroyContext( mmesa->glCtx );
- _tnl_DestroyContext( mmesa->glCtx );
- _vbo_DestroyContext( mmesa->glCtx );
- _swrast_DestroyContext( mmesa->glCtx );
-
mach64FreeVB( mmesa->glCtx );
/* Free the vertex buffer */
diff --git a/src/mesa/drivers/dri/mach64/mach64_context.h b/src/mesa/drivers/dri/mach64/mach64_context.h
index e718b96c18..8d89452412 100644
--- a/src/mesa/drivers/dri/mach64/mach64_context.h
+++ b/src/mesa/drivers/dri/mach64/mach64_context.h
@@ -134,46 +134,17 @@ typedef void (*mach64_line_func)( mach64ContextPtr,
typedef void (*mach64_point_func)( mach64ContextPtr,
mach64Vertex * );
-#ifdef TEXMEM
struct mach64_texture_object {
driTextureObject base;
- GLuint offset;
+ GLuint bufAddr;
- GLuint dirty;
- GLuint age;
+ GLint heap; /* same as base.heap->heapId */
- GLint widthLog2;
- GLint heightLog2;
- GLint maxLog2;
-
- GLint hasAlpha;
- GLint textureFormat;
-
- /* Have to keep these separate due to how they are programmed.
- * FIXME: Why don't we just use the tObj values?
+ /* For communicating values from mach64AllocTexObj(), mach64SetTexImages()
+ * to mach64UpdateTextureUnit(). Alternately, we can use the tObj values or
+ * set the context registers directly.
*/
- GLboolean BilinearMin;
- GLboolean BilinearMag;
- GLboolean ClampS;
- GLboolean ClampT;
-};
-#else
-struct mach64_texture_object {
- struct mach64_texture_object *next;
- struct mach64_texture_object *prev;
- struct gl_texture_object *tObj;
-
- struct mem_block *memBlock;
- GLuint offset;
- GLuint size;
-
- GLuint dirty;
- GLuint age;
-
- GLint bound;
- GLint heap;
-
GLint widthLog2;
GLint heightLog2;
GLint maxLog2;
@@ -181,19 +152,14 @@ struct mach64_texture_object {
GLint hasAlpha;
GLint textureFormat;
- /* Have to keep these separate due to how they are programmed.
- * FIXME: Why don't we just use the tObj values?
- */
GLboolean BilinearMin;
GLboolean BilinearMag;
GLboolean ClampS;
GLboolean ClampT;
};
-#endif
typedef struct mach64_texture_object mach64TexObj, *mach64TexObjPtr;
-
struct mach64_context {
GLcontext *glCtx;
@@ -229,17 +195,10 @@ struct mach64_context {
/* Texture object bookkeeping
*/
mach64TexObjPtr CurrentTexObj[2];
-#ifdef TEXMEM
- unsigned nr_heaps;
- driTexHeap * texture_heaps[ R128_NR_TEX_HEAPS ];
- driTextureObject swapped;
-#else
- mach64TexObj TexObjList[MACH64_NR_TEX_HEAPS];
- mach64TexObj SwappedOut;
- struct mem_block *texHeap[MACH64_NR_TEX_HEAPS];
- GLuint lastTexAge[MACH64_NR_TEX_HEAPS];
+
GLint firstTexHeap, lastTexHeap;
-#endif
+ driTexHeap *texture_heaps[MACH64_NR_TEX_HEAPS];
+ driTextureObject swapped;
/* Fallback rasterization functions
*/
diff --git a/src/mesa/drivers/dri/mach64/mach64_lock.c b/src/mesa/drivers/dri/mach64/mach64_lock.c
index b214495d9a..b73e350111 100644
--- a/src/mesa/drivers/dri/mach64/mach64_lock.c
+++ b/src/mesa/drivers/dri/mach64/mach64_lock.c
@@ -82,14 +82,15 @@ void mach64GetLock( mach64ContextPtr mmesa, GLuint flags )
| MACH64_UPLOAD_MISC
| MACH64_UPLOAD_CLIPRECTS);
+ /* EXA render acceleration uses the texture engine, so restore it */
+ mmesa->dirty |= (MACH64_UPLOAD_TEXTURE);
+
if ( sarea->ctx_owner != mmesa->hHWContext ) {
sarea->ctx_owner = mmesa->hHWContext;
mmesa->dirty = MACH64_UPLOAD_ALL;
}
for ( i = mmesa->firstTexHeap ; i < mmesa->lastTexHeap ; i++ ) {
- if ( mmesa->texHeap[i] && (sarea->tex_age[i] != mmesa->lastTexAge[i]) ) {
- mach64AgeTextures( mmesa, i );
- }
+ DRI_AGE_TEXTURES( mmesa->texture_heaps[i] );
}
}
diff --git a/src/mesa/drivers/dri/mach64/mach64_screen.c b/src/mesa/drivers/dri/mach64/mach64_screen.c
index b17de01acc..1014b8acd5 100644
--- a/src/mesa/drivers/dri/mach64/mach64_screen.c
+++ b/src/mesa/drivers/dri/mach64/mach64_screen.c
@@ -305,7 +305,7 @@ mach64CreateScreen( __DRIscreenPrivate *sPriv )
mach64Screen->texSize[MACH64_AGP_HEAP] = 0;
mach64Screen->logTexGranularity[MACH64_AGP_HEAP] = 0;
} else {
- if (mach64Screen->texSize[MACH64_CARD_HEAP] > 0) {
+ if (serverInfo->textureSize > 0) {
mach64Screen->numTexHeaps = MACH64_NR_TEX_HEAPS;
mach64Screen->firstTexHeap = MACH64_CARD_HEAP;
} else {
diff --git a/src/mesa/drivers/dri/mach64/mach64_tex.c b/src/mesa/drivers/dri/mach64/mach64_tex.c
index 6459deef78..5288d321ce 100644
--- a/src/mesa/drivers/dri/mach64/mach64_tex.c
+++ b/src/mesa/drivers/dri/mach64/mach64_tex.c
@@ -116,21 +116,20 @@ mach64AllocTexObj( struct gl_texture_object *texObj )
fprintf( stderr, "%s( %p )\n", __FUNCTION__, texObj );
t = (mach64TexObjPtr) CALLOC_STRUCT( mach64_texture_object );
+ texObj->DriverData = t;
if ( !t )
return NULL;
/* Initialize non-image-dependent parts of the state:
*/
- t->tObj = texObj;
+ t->base.tObj = texObj;
+ t->base.dirty_images[0] = (1 << 0);
- t->offset = 0;
+ t->bufAddr = 0;
- t->dirty = 1;
-
- make_empty_list( t );
+ make_empty_list( (driTextureObject *) t );
mach64SetTexWrap( t, texObj->WrapS, texObj->WrapT );
- /*mach64SetTexMaxAnisotropy( t, texObj->MaxAnisotropy );*/
mach64SetTexFilter( t, texObj->MinFilter, texObj->MagFilter );
mach64SetTexBorderColor( t, texObj->_BorderChan );
@@ -251,18 +250,17 @@ static void mach64TexImage1D( GLcontext *ctx, GLenum target, GLint level,
struct gl_texture_image *texImage )
{
mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
- mach64TexObjPtr t = (mach64TexObjPtr) texObj->DriverData;
+ driTextureObject * t = (driTextureObject *) texObj->DriverData;
if ( t ) {
- mach64SwapOutTexObj( mmesa, t );
+ driSwapOutTextureObject( t );
}
else {
- t = mach64AllocTexObj(texObj);
+ t = (driTextureObject *) mach64AllocTexObj(texObj);
if (!t) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
return;
}
- texObj->DriverData = t;
}
/* Note, this will call mach64ChooseTextureFormat */
@@ -285,19 +283,18 @@ static void mach64TexSubImage1D( GLcontext *ctx,
struct gl_texture_image *texImage )
{
mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
- mach64TexObjPtr t = (mach64TexObjPtr) texObj->DriverData;
+ driTextureObject * t = (driTextureObject *) texObj->DriverData;
assert( t ); /* this _should_ be true */
if ( t ) {
- mach64SwapOutTexObj( mmesa, t );
+ driSwapOutTextureObject( t );
}
else {
- t = mach64AllocTexObj(texObj);
+ t = (driTextureObject *) mach64AllocTexObj(texObj);
if (!t) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
return;
}
- texObj->DriverData = t;
}
_mesa_store_texsubimage1d(ctx, target, level, xoffset, width,
@@ -316,18 +313,17 @@ static void mach64TexImage2D( GLcontext *ctx, GLenum target, GLint level,
struct gl_texture_image *texImage )
{
mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
- mach64TexObjPtr t = (mach64TexObjPtr) texObj->DriverData;
+ driTextureObject * t = (driTextureObject *) texObj->DriverData;
if ( t ) {
- mach64SwapOutTexObj( mmesa, t );
+ driSwapOutTextureObject( t );
}
else {
- t = mach64AllocTexObj(texObj);
+ t = (driTextureObject *) mach64AllocTexObj(texObj);
if (!t) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
return;
}
- texObj->DriverData = t;
}
/* Note, this will call mach64ChooseTextureFormat */
@@ -350,19 +346,18 @@ static void mach64TexSubImage2D( GLcontext *ctx,
struct gl_texture_image *texImage )
{
mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
- mach64TexObjPtr t = (mach64TexObjPtr) texObj->DriverData;
+ driTextureObject * t = (driTextureObject *) texObj->DriverData;
assert( t ); /* this _should_ be true */
if ( t ) {
- mach64SwapOutTexObj( mmesa, t );
+ driSwapOutTextureObject( t );
}
else {
- t = mach64AllocTexObj(texObj);
+ t = (driTextureObject *) mach64AllocTexObj(texObj);
if (!t) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
return;
}
- texObj->DriverData = t;
}
_mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
@@ -372,44 +367,6 @@ static void mach64TexSubImage2D( GLcontext *ctx,
mmesa->new_state |= MACH64_NEW_TEXTURE;
}
-/* Due to the way we must program texture state into the Rage Pro,
- * we must leave these calculations to the absolute last minute.
- */
-void mach64EmitTexStateLocked( mach64ContextPtr mmesa,
- mach64TexObjPtr t0,
- mach64TexObjPtr t1 )
-{
- drm_mach64_sarea_t *sarea = mmesa->sarea;
- drm_mach64_context_regs_t *regs = &(mmesa->setup);
-
- /* for multitex, both textures must be local or AGP */
- if ( t0 && t1 )
- assert(t0->heap == t1->heap);
-
- if ( t0 ) {
- if (t0->heap == MACH64_CARD_HEAP) {
-#if ENABLE_PERF_BOXES
- mmesa->c_texsrc_card++;
-#endif
- mmesa->setup.tex_cntl &= ~MACH64_TEX_SRC_AGP;
- } else {
-#if ENABLE_PERF_BOXES
- mmesa->c_texsrc_agp++;
-#endif
- mmesa->setup.tex_cntl |= MACH64_TEX_SRC_AGP;
- }
- mmesa->setup.tex_offset = t0->offset;
- }
-
- if ( t1 ) {
- mmesa->setup.secondary_tex_off = t1->offset;
- }
-
- memcpy( &sarea->context_state.tex_size_pitch, &regs->tex_size_pitch,
- MACH64_NR_TEXTURE_REGS * sizeof(GLuint) );
-}
-
-
/* ================================================================
* Device Driver API texture functions
*/
@@ -491,24 +448,23 @@ static void mach64DDTexParameter( GLcontext *ctx, GLenum target,
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexParameter");
return;
}
- tObj->DriverData = t;
}
switch ( pname ) {
case GL_TEXTURE_MIN_FILTER:
case GL_TEXTURE_MAG_FILTER:
- if ( t->bound ) FLUSH_BATCH( mmesa );
+ if ( t->base.bound ) FLUSH_BATCH( mmesa );
mach64SetTexFilter( t, tObj->MinFilter, tObj->MagFilter );
break;
case GL_TEXTURE_WRAP_S:
case GL_TEXTURE_WRAP_T:
- if ( t->bound ) FLUSH_BATCH( mmesa );
+ if ( t->base.bound ) FLUSH_BATCH( mmesa );
mach64SetTexWrap( t, tObj->WrapS, tObj->WrapT );
break;
case GL_TEXTURE_BORDER_COLOR:
- if ( t->bound ) FLUSH_BATCH( mmesa );
+ if ( t->base.bound ) FLUSH_BATCH( mmesa );
mach64SetTexBorderColor( t, tObj->_BorderChan );
break;
@@ -522,8 +478,8 @@ static void mach64DDTexParameter( GLcontext *ctx, GLenum target,
* For mach64 we're only concerned with the base level
* since that's the only texture we upload.
*/
- if ( t->bound ) FLUSH_BATCH( mmesa );
- mach64SwapOutTexObj( mmesa, t );
+ if ( t->base.bound ) FLUSH_BATCH( mmesa );
+ driSwapOutTextureObject( (driTextureObject *) t );
break;
default:
@@ -547,7 +503,7 @@ static void mach64DDBindTexture( GLcontext *ctx, GLenum target,
FLUSH_BATCH( mmesa );
if ( mmesa->CurrentTexObj[unit] ) {
- mmesa->CurrentTexObj[unit]->bound &= ~(unit+1);
+ mmesa->CurrentTexObj[unit]->base.bound &= ~(1 << unit);
mmesa->CurrentTexObj[unit] = NULL;
}
@@ -558,33 +514,37 @@ static void mach64DDDeleteTexture( GLcontext *ctx,
struct gl_texture_object *tObj )
{
mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
- mach64TexObjPtr t = (mach64TexObjPtr)tObj->DriverData;
+ driTextureObject * t = (driTextureObject *) tObj->DriverData;
if ( t ) {
if ( t->bound && mmesa ) {
FLUSH_BATCH( mmesa );
- mmesa->CurrentTexObj[t->bound-1] = 0;
mmesa->new_state |= MACH64_NEW_TEXTURE;
}
- mach64DestroyTexObj( mmesa, t );
- tObj->DriverData = NULL;
+ driDestroyTextureObject( t );
+
/* Free mipmap images and the texture object itself */
_mesa_delete_texture_object(ctx, tObj);
-
}
}
-static GLboolean mach64DDIsTextureResident( GLcontext *ctx,
- struct gl_texture_object *tObj )
+/**
+ * Allocate a new texture object.
+ * Called via ctx->Driver.NewTextureObject.
+ * Note: we could use containment here to 'derive' the driver-specific
+ * texture object from the core mesa gl_texture_object. Not done at this time.
+ */
+static struct gl_texture_object *
+mach64NewTextureObject( GLcontext *ctx, GLuint name, GLenum target )
{
- mach64TexObjPtr t = (mach64TexObjPtr)tObj->DriverData;
-
- return ( t && t->memBlock );
+ struct gl_texture_object *obj;
+ obj = _mesa_new_texture_object(ctx, name, target);
+ mach64AllocTexObj( obj );
+ return obj;
}
-
void mach64InitTextureFuncs( struct dd_function_table *functions )
{
functions->TexEnv = mach64DDTexEnv;
@@ -593,18 +553,15 @@ void mach64InitTextureFuncs( struct dd_function_table *functions )
functions->TexSubImage1D = mach64TexSubImage1D;
functions->TexImage2D = mach64TexImage2D;
functions->TexSubImage2D = mach64TexSubImage2D;
- functions->TexImage3D = _mesa_store_teximage3d;
- functions->TexSubImage3D = _mesa_store_texsubimage3d;
- functions->CopyTexImage1D = _swrast_copy_teximage1d;
- functions->CopyTexImage2D = _swrast_copy_teximage2d;
- functions->CopyTexSubImage1D = _swrast_copy_texsubimage1d;
- functions->CopyTexSubImage2D = _swrast_copy_texsubimage2d;
- functions->CopyTexSubImage3D = _swrast_copy_texsubimage3d;
functions->TexParameter = mach64DDTexParameter;
functions->BindTexture = mach64DDBindTexture;
+ functions->NewTextureObject = mach64NewTextureObject;
functions->DeleteTexture = mach64DDDeleteTexture;
+ functions->IsTextureResident = driIsTextureResident;
+
functions->UpdateTexturePalette = NULL;
functions->ActiveTexture = NULL;
- functions->IsTextureResident = mach64DDIsTextureResident;
- functions->PrioritizeTexture = NULL;
+ functions->PrioritizeTexture = NULL;
+
+ driInitTextureFormats();
}
diff --git a/src/mesa/drivers/dri/mach64/mach64_tex.h b/src/mesa/drivers/dri/mach64/mach64_tex.h
index d950dd12b4..f6cf1cf802 100644
--- a/src/mesa/drivers/dri/mach64/mach64_tex.h
+++ b/src/mesa/drivers/dri/mach64/mach64_tex.h
@@ -34,25 +34,15 @@
extern void mach64UpdateTextureState( GLcontext *ctx );
-extern void mach64SwapOutTexObj( mach64ContextPtr mach64ctx,
- mach64TexObjPtr t );
-
extern void mach64UploadTexImages( mach64ContextPtr mach64ctx,
mach64TexObjPtr t );
extern void mach64UploadMultiTexImages( mach64ContextPtr mach64ctx,
mach64TexObjPtr t0, mach64TexObjPtr t1 );
-extern void mach64AgeTextures( mach64ContextPtr mach64ctx, int heap );
extern void mach64DestroyTexObj( mach64ContextPtr mach64ctx,
mach64TexObjPtr t );
-extern void mach64UpdateTexLRU( mach64ContextPtr mach64ctx,
- mach64TexObjPtr t );
-
-extern void mach64PrintLocalLRU( mach64ContextPtr mach64ctx, int heap );
-extern void mach64PrintGlobalLRU( mach64ContextPtr mach64ctx, int heap );
-
extern void mach64EmitTexStateLocked( mach64ContextPtr mmesa,
mach64TexObjPtr t0,
mach64TexObjPtr t1 );
diff --git a/src/mesa/drivers/dri/mach64/mach64_texmem.c b/src/mesa/drivers/dri/mach64/mach64_texmem.c
index 017fd3535d..3b7b93b984 100644
--- a/src/mesa/drivers/dri/mach64/mach64_texmem.c
+++ b/src/mesa/drivers/dri/mach64/mach64_texmem.c
@@ -49,333 +49,19 @@
*/
void mach64DestroyTexObj( mach64ContextPtr mmesa, mach64TexObjPtr t )
{
-#if ENABLE_PERF_BOXES
- /* Bump the performace counter */
- if (mmesa)
- mmesa->c_textureSwaps++;
-#endif
- if ( !t ) return;
-
-#if 0
- if ( t->tObj && t->memBlock && mmesa ) {
- /* not a placeholder, so release from global LRU if necessary */
- int heap = t->heap;
- drmTextureRegion *list = mmesa->sarea->tex_list[heap];
- int log2sz = mmesa->mach64Screen->logTexGranularity[heap];
- int start = t->memBlock->ofs >> log2sz;
- int end = (t->memBlock->ofs + t->memBlock->size - 1) >> log2sz;
- int i;
-
- mmesa->lastTexAge[heap] = ++mmesa->sarea->tex_age[heap];
-
- /* Update the global LRU */
- for ( i = start ; i <= end ; i++ ) {
- /* do we own this block? */
- if (list[i].in_use == mmesa->hHWContext) {
- list[i].in_use = 0;
- list[i].age = mmesa->lastTexAge[heap];
-
- /* remove_from_list(i) */
- list[(GLuint)list[i].next].prev = list[i].prev;
- list[(GLuint)list[i].prev].next = list[i].next;
- }
- }
- }
-#endif
-
- if ( t->memBlock ) {
- mmFreeMem( t->memBlock );
- t->memBlock = NULL;
- }
-
- if ( t->tObj ) {
- t->tObj->DriverData = NULL;
- }
-
- if ( t->bound && mmesa )
- mmesa->CurrentTexObj[t->bound-1] = NULL;
-
- remove_from_list( t );
- FREE( t );
-}
-
-/* Keep track of swapped out texture objects.
- */
-void mach64SwapOutTexObj( mach64ContextPtr mmesa,
- mach64TexObjPtr t )
-{
-#if ENABLE_PERF_BOXES
- /* Bump the performace counter */
- if (mmesa)
- mmesa->c_textureSwaps++;
-#endif
-
-#if 0
- if ( t->tObj && t->memBlock && mmesa ) {
- /* not a placeholder, so release from global LRU if necessary */
- int heap = t->heap;
- drmTextureRegion *list = mmesa->sarea->tex_list[heap];
- int log2sz = mmesa->mach64Screen->logTexGranularity[heap];
- int start = t->memBlock->ofs >> log2sz;
- int end = (t->memBlock->ofs + t->memBlock->size - 1) >> log2sz;
- int i;
-
- mmesa->lastTexAge[heap] = ++mmesa->sarea->tex_age[heap];
-
- /* Update the global LRU */
- for ( i = start ; i <= end ; i++ ) {
- /* do we own this block? */
- if (list[i].in_use == mmesa->hHWContext) {
- list[i].in_use = 0;
- list[i].age = mmesa->lastTexAge[heap];
-
- /* remove_from_list(i) */
- list[(GLuint)list[i].next].prev = list[i].prev;
- list[(GLuint)list[i].prev].next = list[i].next;
- }
- }
- }
-#endif
-
- if ( t->memBlock ) {
- mmFreeMem( t->memBlock );
- t->memBlock = NULL;
- }
-
- t->dirty = ~0;
- move_to_tail( &mmesa->SwappedOut, t );
-}
-
-/* Print out debugging information about texture LRU.
- */
-void mach64PrintLocalLRU( mach64ContextPtr mmesa, int heap )
-{
- mach64TexObjPtr t;
- int sz = 1 << (mmesa->mach64Screen->logTexGranularity[heap]);
-
- fprintf( stderr, "\nLocal LRU, heap %d:\n", heap );
-
- foreach( t, &mmesa->TexObjList[heap] ) {
- if ( !t->tObj ) {
- fprintf( stderr, "Placeholder %d at 0x%x sz 0x%x\n",
- t->memBlock->ofs / sz,
- t->memBlock->ofs,
- t->memBlock->size );
- } else {
- fprintf( stderr, "Texture (bound %d) at 0x%x sz 0x%x\n",
- t->bound,
- t->memBlock->ofs,
- t->memBlock->size );
- }
- }
-
- fprintf( stderr, "\n" );
-}
-
-void mach64PrintGlobalLRU( mach64ContextPtr mmesa, int heap )
-{
- drm_tex_region_t *list = mmesa->sarea->tex_list[heap];
- int i, j;
-
- fprintf( stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list );
-
- for ( i = 0, j = MACH64_NR_TEX_REGIONS ; i < MACH64_NR_TEX_REGIONS ; i++ ) {
- fprintf( stderr, "list[%d] age %d in_use %d next %d prev %d\n",
- j, list[j].age, list[j].in_use, list[j].next, list[j].prev );
- j = list[j].next;
- if ( j == MACH64_NR_TEX_REGIONS ) break;
- }
-
- if ( j != MACH64_NR_TEX_REGIONS ) {
- fprintf( stderr, "Loop detected in global LRU\n" );
- for ( i = 0 ; i < MACH64_NR_TEX_REGIONS ; i++ ) {
- fprintf( stderr, "list[%d] age %d in_use %d next %d prev %d\n",
- i, list[i].age, list[i].in_use, list[i].next, list[i].prev );
- }
- }
+ unsigned i;
- fprintf( stderr, "\n" );
-}
-
-/* Reset the global texture LRU.
- */
-/* NOTE: This function is only called while holding the hardware lock */
-static void mach64ResetGlobalLRU( mach64ContextPtr mmesa, int heap )
-{
- drm_tex_region_t *list = mmesa->sarea->tex_list[heap];
- int sz = 1 << mmesa->mach64Screen->logTexGranularity[heap];
- int i;
-
- /* (Re)initialize the global circular LRU list. The last element in
- * the array (MACH64_NR_TEX_REGIONS) is the sentinal. Keeping it at
- * the end of the array allows it to be addressed rationally when
- * looking up objects at a particular location in texture memory.
+ /* See if it was the driver's current object.
*/
- for ( i = 0 ; (i+1) * sz <= mmesa->mach64Screen->texSize[heap] ; i++ ) {
- list[i].prev = i-1;
- list[i].next = i+1;
- list[i].age = 0;
- list[i].in_use = 0;
- }
-
- i--;
- list[0].prev = MACH64_NR_TEX_REGIONS;
- list[i].prev = i-1;
- list[i].next = MACH64_NR_TEX_REGIONS;
- list[MACH64_NR_TEX_REGIONS].prev = i;
- list[MACH64_NR_TEX_REGIONS].next = 0;
- mmesa->sarea->tex_age[heap] = 0;
-}
-
-/* Update the local and global texture LRUs.
- */
-/* NOTE: This function is only called while holding the hardware lock */
-void mach64UpdateTexLRU( mach64ContextPtr mmesa,
- mach64TexObjPtr t )
-{
- int heap = t->heap;
- drm_tex_region_t *list = mmesa->sarea->tex_list[heap];
- int log2sz = mmesa->mach64Screen->logTexGranularity[heap];
- int start = t->memBlock->ofs >> log2sz;
- int end = (t->memBlock->ofs + t->memBlock->size - 1) >> log2sz;
- int i;
-
- mmesa->lastTexAge[heap] = ++mmesa->sarea->tex_age[heap];
-
- if ( !t->memBlock ) {
- fprintf( stderr, "no memblock\n\n" );
- return;
- }
-
- /* Update our local LRU */
- move_to_head( &mmesa->TexObjList[heap], t );
-
- /* Update the global LRU */
- for ( i = start ; i <= end ; i++ ) {
- list[i].in_use = mmesa->hHWContext;
- list[i].age = mmesa->lastTexAge[heap];
-
-#if 0
- /* if this is the last region, it's not in the list */
- if ( !(i*(1<<log2sz) > mmesa->mach64Screen->texSize[heap] ) ) {
-#endif
- /* remove_from_list(i) */
- list[(GLuint)list[i].next].prev = list[i].prev;
- list[(GLuint)list[i].prev].next = list[i].next;
-#if 0
- }
-#endif
-
- /* insert_at_head(list, i) */
- list[i].prev = MACH64_NR_TEX_REGIONS;
- list[i].next = list[MACH64_NR_TEX_REGIONS].next;
- list[(GLuint)list[MACH64_NR_TEX_REGIONS].next].prev = i;
- list[MACH64_NR_TEX_REGIONS].next = i;
- }
-
- if ( MACH64_DEBUG & DEBUG_VERBOSE_LRU ) {
- mach64PrintGlobalLRU( mmesa, t->heap );
- mach64PrintLocalLRU( mmesa, t->heap );
- }
-}
-
-/* Update our notion of what textures have been changed since we last
- * held the lock. This pertains to both our local textures and the
- * textures belonging to other clients. Keep track of other client's
- * textures by pushing a placeholder texture onto the LRU list -- these
- * are denoted by (tObj == NULL).
- */
-/* NOTE: This function is only called while holding the hardware lock */
-static void mach64TexturesGone( mach64ContextPtr mmesa, int heap,
- int offset, int size, int in_use )
-{
- mach64TexObjPtr t, tmp;
-
- foreach_s ( t, tmp, &mmesa->TexObjList[heap] ) {
- if ( t->memBlock->ofs >= offset + size ||
- t->memBlock->ofs + t->memBlock->size <= offset )
- continue;
-
- /* It overlaps - kick it out. Need to hold onto the currently
- * bound objects, however.
- */
- if ( t->bound ) {
- mach64SwapOutTexObj( mmesa, t );
- } else {
- mach64DestroyTexObj( mmesa, t );
- }
- }
-
- if ( in_use > 0 && in_use != mmesa->hHWContext ) {
- t = (mach64TexObjPtr) CALLOC( sizeof(*t) );
- if (!t) return;
-
- t->memBlock = mmAllocMem( mmesa->texHeap[heap], size, 0, offset );
- if ( !t->memBlock ) {
- fprintf( stderr, "Couldn't alloc placeholder sz %x ofs %x\n",
- (int)size, (int)offset );
- mmDumpMemInfo( mmesa->texHeap[heap] );
- return;
- }
- insert_at_head( &mmesa->TexObjList[heap], t );
- }
-}
-
-/* Update our client's shared texture state. If another client has
- * modified a region in which we have textures, then we need to figure
- * out which of our textures has been removed, and update our global
- * LRU.
- */
-void mach64AgeTextures( mach64ContextPtr mmesa, int heap )
-{
- drm_mach64_sarea_t *sarea = mmesa->sarea;
-
- if ( sarea->tex_age[heap] != mmesa->lastTexAge[heap] ) {
- int sz = 1 << mmesa->mach64Screen->logTexGranularity[heap];
- int nr = 0;
- int idx;
-
- /* Have to go right round from the back to ensure stuff ends up
- * LRU in our local list... Fix with a cursor pointer.
- */
- for ( idx = sarea->tex_list[heap][MACH64_NR_TEX_REGIONS].prev ;
- idx != MACH64_NR_TEX_REGIONS && nr < MACH64_NR_TEX_REGIONS ;
- idx = sarea->tex_list[heap][idx].prev, nr++ )
+ if ( mmesa != NULL )
+ {
+ for ( i = 0 ; i < mmesa->glCtx->Const.MaxTextureUnits ; i++ )
{
- /* If switching texturing schemes, then the SAREA might not
- * have been properly cleared, so we need to reset the
- * global texture LRU.
- */
- if ( idx * sz > mmesa->mach64Screen->texSize[heap] ) {
- nr = MACH64_NR_TEX_REGIONS;
- break;
- }
-
- if ( sarea->tex_list[heap][idx].age > mmesa->lastTexAge[heap] ) {
- mach64TexturesGone( mmesa, heap, idx * sz, sz,
- sarea->tex_list[heap][idx].in_use );
- }
- }
-
- /* If switching texturing schemes, then the SAREA might not
- * have been properly cleared, so we need to reset the
- * global texture LRU.
- */
- if ( nr == MACH64_NR_TEX_REGIONS ) {
- mach64TexturesGone( mmesa, heap, 0,
- mmesa->mach64Screen->texSize[heap], 0 );
- mach64ResetGlobalLRU( mmesa, heap );
+ if ( t == mmesa->CurrentTexObj[ i ] ) {
+ assert( t->base.bound & (1 << i) );
+ mmesa->CurrentTexObj[ i ] = NULL;
+ }
}
-
- if ( 0 ) {
- mach64PrintGlobalLRU( mmesa, heap );
- mach64PrintLocalLRU( mmesa, heap );
- }
-
- mmesa->dirty |= (MACH64_UPLOAD_CONTEXT |
- MACH64_UPLOAD_TEX0IMAGE |
- MACH64_UPLOAD_TEX1IMAGE);
- mmesa->lastTexAge[heap] = sarea->tex_age[heap];
}
}
@@ -395,7 +81,7 @@ static void mach64UploadAGPSubImage( mach64ContextPtr mmesa,
if ( ( level < 0 ) || ( level > mmesa->glCtx->Const.MaxTextureLevels ) )
return;
- image = t->tObj->Image[0][level];
+ image = t->base.tObj->Image[0][level];
if ( !image )
return;
@@ -424,14 +110,13 @@ static void mach64UploadAGPSubImage( mach64ContextPtr mmesa,
fprintf( stderr, "mach64UploadSubImage: %d,%d of %d,%d at %d,%d\n",
width, height, image->Width, image->Height, x, y );
fprintf( stderr, " blit ofs: 0x%07x pitch: 0x%x dwords: %d\n",
- (GLuint)t->offset, (GLint)width, dwords );
- mmDumpMemInfo( mmesa->texHeap[t->heap] );
+ (GLuint)t->bufAddr, (GLint)width, dwords );
}
assert(image->Data);
{
- CARD32 *dst = (CARD32 *)((char *)mach64Screen->agpTextures.map + t->memBlock->ofs);
+ CARD32 *dst = (CARD32 *)((char *)mach64Screen->agpTextures.map + t->base.memBlock->ofs);
const GLubyte *src = (const GLubyte *) image->Data +
(y * image->Width + x) * image->TexFormat->TexelBytes;
const GLuint bytes = width * height * image->TexFormat->TexelBytes;
@@ -460,7 +145,7 @@ static void mach64UploadLocalSubImage( mach64ContextPtr mmesa,
if ( ( level < 0 ) || ( level > mmesa->glCtx->Const.MaxTextureLevels ) )
return;
- image = t->tObj->Image[0][level];
+ image = t->base.tObj->Image[0][level];
if ( !image )
return;
@@ -543,7 +228,7 @@ static void mach64UploadLocalSubImage( mach64ContextPtr mmesa,
}
dwords = width * height / texelsPerDword;
- offset = t->offset;
+ offset = t->bufAddr;
#if ENABLE_PERF_BOXES
/* Bump the performance counter */
@@ -555,7 +240,6 @@ static void mach64UploadLocalSubImage( mach64ContextPtr mmesa,
width, height, image->Width, image->Height, x, y );
fprintf( stderr, " blit ofs: 0x%07x pitch: 0x%x dwords: %d\n",
(GLuint)offset, (GLint)width, dwords );
- mmDumpMemInfo( mmesa->texHeap[t->heap] );
}
/* Subdivide the texture if required (account for the registers added by the drm) */
@@ -594,78 +278,32 @@ static void mach64UploadLocalSubImage( mach64ContextPtr mmesa,
*/
void mach64UploadTexImages( mach64ContextPtr mmesa, mach64TexObjPtr t )
{
- GLint heap;
-
if ( MACH64_DEBUG & DEBUG_VERBOSE_API ) {
fprintf( stderr, "%s( %p, %p )\n",
__FUNCTION__, mmesa->glCtx, t );
}
assert(t);
- assert(t->tObj);
-
- /* Choose the heap appropriately */
- heap = MACH64_CARD_HEAP;
+ assert(t->base.tObj);
- if ( !mmesa->mach64Screen->IsPCI &&
- t->size > mmesa->mach64Screen->texSize[heap] ) {
- heap = MACH64_AGP_HEAP;
- }
-
- /* Do we need to eject LRU texture objects? */
- if ( !t->memBlock ) {
- t->heap = heap;
+ if ( !t->base.memBlock ) {
+ int heap;
- /* Allocate a memory block on a 64-byte boundary */
- t->memBlock = mmAllocMem( mmesa->texHeap[heap], t->size, 6, 0 );
+ /* NULL heaps are skipped */
+ heap = driAllocateTexture( mmesa->texture_heaps, MACH64_NR_TEX_HEAPS,
+ (driTextureObject *) t );
- /* Try AGP before kicking anything out of local mem */
- if ( !mmesa->mach64Screen->IsPCI && !t->memBlock && heap == MACH64_CARD_HEAP ) {
- t->memBlock = mmAllocMem( mmesa->texHeap[MACH64_AGP_HEAP],
- t->size, 6, 0 );
-
- if ( t->memBlock )
- heap = t->heap = MACH64_AGP_HEAP;
+ if ( heap == -1 ) {
+ fprintf( stderr, "%s: upload texture failure, sz=%d\n", __FUNCTION__,
+ t->base.totalSize );
+ exit(-1);
+ return;
}
- /* Kick out textures until the requested texture fits */
- while ( !t->memBlock ) {
- if ( mmesa->TexObjList[heap].prev->bound ) {
- fprintf( stderr,
- "mach64UploadTexImages: ran into bound texture\n" );
- return;
- }
- if ( mmesa->TexObjList[heap].prev == &mmesa->TexObjList[heap] ) {
- if ( mmesa->mach64Screen->IsPCI ) {
- fprintf( stderr, "%s: upload texture failure on "
- "local texture heaps, sz=%d\n", __FUNCTION__,
- t->size );
- return;
- } else if ( heap == MACH64_CARD_HEAP ) {
- heap = t->heap = MACH64_AGP_HEAP;
- continue;
- } else {
- int i;
- fprintf( stderr, "%s: upload texture failure on "
- "%sAGP texture heaps, sz=%d\n", __FUNCTION__,
- mmesa->firstTexHeap == MACH64_CARD_HEAP ? "both local and " : "",
- t->size );
- for ( i = mmesa->firstTexHeap ; i < mmesa->lastTexHeap ; i++ ) {
- mach64PrintLocalLRU( mmesa, i );
- mmDumpMemInfo( mmesa->texHeap[i] );
- }
- exit(-1);
- return;
- }
- }
-
- mach64SwapOutTexObj( mmesa, mmesa->TexObjList[heap].prev );
-
- t->memBlock = mmAllocMem( mmesa->texHeap[heap], t->size, 6, 0 );
- }
+ t->heap = heap;
/* Set the base offset of the texture image */
- t->offset = mmesa->mach64Screen->texOffset[heap] + t->memBlock->ofs;
+ t->bufAddr = mmesa->mach64Screen->texOffset[heap] + t->base.memBlock->ofs;
/* Force loading the new state into the hardware */
mmesa->dirty |= (MACH64_UPLOAD_SCALE_3D_CNTL |
@@ -673,142 +311,152 @@ void mach64UploadTexImages( mach64ContextPtr mmesa, mach64TexObjPtr t )
}
/* Let the world know we've used this memory recently */
- mach64UpdateTexLRU( mmesa, t );
+ driUpdateTextureLRU( (driTextureObject *) t );
/* Upload any images that are new */
- if ( t->dirty ) {
+ if ( t->base.dirty_images[0] ) {
+ const GLint j = t->base.tObj->BaseLevel;
if (t->heap == MACH64_AGP_HEAP) {
/* Need to make sure any vertex buffers in the queue complete */
mach64WaitForIdleLocked( mmesa );
- mach64UploadAGPSubImage( mmesa, t, t->tObj->BaseLevel, 0, 0,
- t->tObj->Image[0][t->tObj->BaseLevel]->Width,
- t->tObj->Image[0][t->tObj->BaseLevel]->Height );
+ mach64UploadAGPSubImage( mmesa, t, j, 0, 0,
+ t->base.tObj->Image[0][j]->Width,
+ t->base.tObj->Image[0][j]->Height );
} else {
- mach64UploadLocalSubImage( mmesa, t, t->tObj->BaseLevel, 0, 0,
- t->tObj->Image[0][t->tObj->BaseLevel]->Width,
- t->tObj->Image[0][t->tObj->BaseLevel]->Height );
+ mach64UploadLocalSubImage( mmesa, t, j, 0, 0,
+ t->base.tObj->Image[0][j]->Width,
+ t->base.tObj->Image[0][j]->Height );
}
mmesa->setup.tex_cntl |= MACH64_TEX_CACHE_FLUSH;
+ t->base.dirty_images[0] = 0;
}
mmesa->dirty |= MACH64_UPLOAD_TEXTURE;
+}
+
+
+/* Allocate memory from the same texture heap `heap' for both textures
+ * `u0' and `u1'.
+ */
+static int mach64AllocateMultiTex( mach64ContextPtr mmesa,
+ mach64TexObjPtr u0,
+ mach64TexObjPtr u1,
+ int heap, GLboolean alloc_u0 )
+{
+ /* Both objects should be bound */
+ assert( u0->base.bound && u1->base.bound );
+
+ if ( alloc_u0 ) {
+ /* Evict u0 from its current heap */
+ if ( u0->base.memBlock ) {
+ assert( u0->heap != heap );
+ driSwapOutTextureObject( (driTextureObject *) u0 );
+ }
+
+ /* Try to allocate u0 in the chosen heap */
+ u0->heap = driAllocateTexture( &mmesa->texture_heaps[heap], 1,
+ (driTextureObject *) u0 );
+
+ if ( u0->heap == -1 ) {
+ return -1;
+ }
+ }
+
+ /* Evict u1 from its current heap */
+ if ( u1->base.memBlock ) {
+ assert( u1->heap != heap );
+ driSwapOutTextureObject( (driTextureObject *) u1 );
+ }
+
+ /* Try to allocate u1 in the same heap as u0 */
+ u1->heap = driAllocateTexture( &mmesa->texture_heaps[heap], 1,
+ (driTextureObject *) u1 );
+
+ if ( u1->heap == -1 ) {
+ return -1;
+ }
- t->dirty = 0;
+ /* Bound objects are not evicted */
+ assert( u0->base.memBlock && u1->base.memBlock );
+ assert( u0->heap == u1->heap );
+
+ return heap;
}
/* The mach64 needs to have both primary and secondary textures in either
* local or AGP memory, so we need a "buddy system" to make sure that allocation
* succeeds or fails for both textures.
- * FIXME: This needs to be optimized better.
*/
void mach64UploadMultiTexImages( mach64ContextPtr mmesa,
mach64TexObjPtr t0,
mach64TexObjPtr t1 )
{
- GLint heap;
-
if ( MACH64_DEBUG & DEBUG_VERBOSE_API ) {
fprintf( stderr, "%s( %p, %p %p )\n",
__FUNCTION__, mmesa->glCtx, t0, t1 );
}
assert(t0 && t1);
- assert(t0->tObj && t1->tObj);
+ assert(t0->base.tObj && t1->base.tObj);
- /* Choose the heap appropriately */
- heap = MACH64_CARD_HEAP;
+ if ( !t0->base.memBlock || !t1->base.memBlock || t0->heap != t1->heap ) {
+ mach64TexObjPtr u0 = NULL;
+ mach64TexObjPtr u1 = NULL;
+ unsigned totalSize = t0->base.totalSize + t1->base.totalSize;
- if ( !mmesa->mach64Screen->IsPCI &&
- ((t0->size + t1->size) > mmesa->mach64Screen->texSize[heap]) ) {
- heap = MACH64_AGP_HEAP;
- }
+ int heap, ret;
- /* Do we need to eject LRU texture objects? */
- if ( !t0->memBlock || !t1->memBlock || t0->heap != t1->heap ) {
- /* FIXME: starting from scratch for now to keep it simple */
- if ( t0->memBlock ) {
- mach64SwapOutTexObj( mmesa, t0 );
- }
- if ( t1->memBlock ) {
- mach64SwapOutTexObj( mmesa, t1 );
- }
- t0->heap = t1->heap = heap;
- /* Allocate a memory block on a 64-byte boundary */
- t0->memBlock = mmAllocMem( mmesa->texHeap[heap], t0->size, 6, 0 );
- if ( t0->memBlock ) {
- t1->memBlock = mmAllocMem( mmesa->texHeap[heap], t1->size, 6, 0 );
- if ( !t1->memBlock ) {
- mmFreeMem( t0->memBlock );
- t0->memBlock = NULL;
- }
+ /* Check if one of the textures is already swapped in a heap and the
+ * other texture fits in that heap.
+ */
+ if ( t0->base.memBlock && totalSize <= t0->base.heap->size ) {
+ u0 = t0;
+ u1 = t1;
+ } else if ( t1->base.memBlock && totalSize <= t1->base.heap->size ) {
+ u0 = t1;
+ u1 = t0;
}
- /* Try AGP before kicking anything out of local mem */
- if ( (!t0->memBlock || !t1->memBlock) && heap == MACH64_CARD_HEAP ) {
- t0->memBlock = mmAllocMem( mmesa->texHeap[MACH64_AGP_HEAP], t0->size, 6, 0 );
- if ( t0->memBlock ) {
- t1->memBlock = mmAllocMem( mmesa->texHeap[MACH64_AGP_HEAP], t1->size, 6, 0 );
- if ( !t1->memBlock ) {
- mmFreeMem( t0->memBlock );
- t0->memBlock = NULL;
- }
+
+ if ( u0 ) {
+ heap = u0->heap;
+
+ ret = mach64AllocateMultiTex( mmesa, u0, u1, heap, GL_FALSE );
+ } else {
+ /* Both textures are swapped out or collocation is impossible */
+ u0 = t0;
+ u1 = t1;
+
+ /* Choose the heap appropriately */
+ heap = MACH64_CARD_HEAP;
+
+ if ( totalSize > mmesa->texture_heaps[heap]->size ) {
+ heap = MACH64_AGP_HEAP;
}
- if ( t0->memBlock && t1->memBlock )
- heap = t0->heap = t1->heap = MACH64_AGP_HEAP;
+ ret = mach64AllocateMultiTex( mmesa, u0, u1, heap, GL_TRUE );
}
- /* Kick out textures until the requested texture fits */
- while ( !t0->memBlock || !t1->memBlock ) {
- if ( mmesa->TexObjList[heap].prev->bound ) {
- fprintf( stderr,
- "%s: ran into bound texture\n", __FUNCTION__ );
- return;
- }
- if ( mmesa->TexObjList[heap].prev == &mmesa->TexObjList[heap] ) {
- if ( mmesa->mach64Screen->IsPCI ) {
- fprintf( stderr, "%s: upload texture failure on local "
- "texture heaps, tex0 sz=%d tex1 sz=%d\n", __FUNCTION__,
- t0->size, t1->size );
- return;
- } else if ( heap == MACH64_CARD_HEAP ) {
- /* If only one allocation succeeded, start over again in AGP */
- if (t0->memBlock) {
- mmFreeMem( t0->memBlock );
- t0->memBlock = NULL;
- }
- if (t1->memBlock) {
- mmFreeMem( t1->memBlock );
- t1->memBlock = NULL;
- }
- heap = t0->heap = t1->heap = MACH64_AGP_HEAP;
- continue;
- } else {
- int i;
- fprintf( stderr, "%s: upload texture failure on %s"
- "AGP texture heaps, tex0 sz=%d tex1 sz=%d\n", __FUNCTION__,
- mmesa->firstTexHeap == MACH64_CARD_HEAP ? "both local and " : "",
- t0->size, t1->size );
- for ( i = mmesa->firstTexHeap ; i < mmesa->lastTexHeap ; i++ ) {
- mach64PrintLocalLRU( mmesa, i );
- mmDumpMemInfo( mmesa->texHeap[i] );
- }
- exit(-1);
- return;
- }
- }
+ if ( ret == -1 && heap == MACH64_CARD_HEAP ) {
+ /* Try AGP if local memory failed */
+ heap = MACH64_AGP_HEAP;
- mach64SwapOutTexObj( mmesa, mmesa->TexObjList[heap].prev );
-
- if (!t0->memBlock)
- t0->memBlock = mmAllocMem( mmesa->texHeap[heap], t0->size, 6, 0 );
- if (!t1->memBlock)
- t1->memBlock = mmAllocMem( mmesa->texHeap[heap], t1->size, 6, 0 );
+ ret = mach64AllocateMultiTex( mmesa, u0, u1, heap, GL_TRUE );
+ }
+
+ if ( ret == -1 ) {
+ /* FIXME:
+ * Swap out all textures from the AGP heap and re-run allocation, this
+ * should succeed in all cases.
+ */
+ fprintf( stderr, "%s: upload multi-texture failure, sz0=%d sz1=%d\n",
+ __FUNCTION__, t0->base.totalSize, t1->base.totalSize );
+ exit(-1);
}
/* Set the base offset of the texture image */
- t0->offset = mmesa->mach64Screen->texOffset[heap] + t0->memBlock->ofs;
- t1->offset = mmesa->mach64Screen->texOffset[heap] + t1->memBlock->ofs;
+ t0->bufAddr = mmesa->mach64Screen->texOffset[heap] + t0->base.memBlock->ofs;
+ t1->bufAddr = mmesa->mach64Screen->texOffset[heap] + t1->base.memBlock->ofs;
/* Force loading the new state into the hardware */
mmesa->dirty |= (MACH64_UPLOAD_SCALE_3D_CNTL |
@@ -816,42 +464,43 @@ void mach64UploadMultiTexImages( mach64ContextPtr mmesa,
}
/* Let the world know we've used this memory recently */
- mach64UpdateTexLRU( mmesa, t0 );
- mach64UpdateTexLRU( mmesa, t1 );
+ driUpdateTextureLRU( (driTextureObject *) t0 );
+ driUpdateTextureLRU( (driTextureObject *) t1 );
/* Upload any images that are new */
- if ( t0->dirty ) {
+ if ( t0->base.dirty_images[0] ) {
+ const GLint j0 = t0->base.tObj->BaseLevel;
if (t0->heap == MACH64_AGP_HEAP) {
/* Need to make sure any vertex buffers in the queue complete */
mach64WaitForIdleLocked( mmesa );
- mach64UploadAGPSubImage( mmesa, t0, t0->tObj->BaseLevel, 0, 0,
- t0->tObj->Image[0][t0->tObj->BaseLevel]->Width,
- t0->tObj->Image[0][t0->tObj->BaseLevel]->Height );
+ mach64UploadAGPSubImage( mmesa, t0, j0, 0, 0,
+ t0->base.tObj->Image[0][j0]->Width,
+ t0->base.tObj->Image[0][j0]->Height );
} else {
- mach64UploadLocalSubImage( mmesa, t0, t0->tObj->BaseLevel, 0, 0,
- t0->tObj->Image[0][t0->tObj->BaseLevel]->Width,
- t0->tObj->Image[0][t0->tObj->BaseLevel]->Height );
+ mach64UploadLocalSubImage( mmesa, t0, j0, 0, 0,
+ t0->base.tObj->Image[0][j0]->Width,
+ t0->base.tObj->Image[0][j0]->Height );
}
mmesa->setup.tex_cntl |= MACH64_TEX_CACHE_FLUSH;
+ t0->base.dirty_images[0] = 0;
}
- if ( t1->dirty ) {
+ if ( t1->base.dirty_images[0] ) {
+ const GLint j1 = t1->base.tObj->BaseLevel;
if (t1->heap == MACH64_AGP_HEAP) {
/* Need to make sure any vertex buffers in the queue complete */
mach64WaitForIdleLocked( mmesa );
- mach64UploadAGPSubImage( mmesa, t1, t1->tObj->BaseLevel, 0, 0,
- t1->tObj->Image[0][t1->tObj->BaseLevel]->Width,
- t1->tObj->Image[0][t1->tObj->BaseLevel]->Height );
+ mach64UploadAGPSubImage( mmesa, t1, j1, 0, 0,
+ t1->base.tObj->Image[0][j1]->Width,
+ t1->base.tObj->Image[0][j1]->Height );
} else {
- mach64UploadLocalSubImage( mmesa, t1, t1->tObj->BaseLevel, 0, 0,
- t1->tObj->Image[0][t1->tObj->BaseLevel]->Width,
- t1->tObj->Image[0][t1->tObj->BaseLevel]->Height );
+ mach64UploadLocalSubImage( mmesa, t1, j1, 0, 0,
+ t1->base.tObj->Image[0][j1]->Width,
+ t1->base.tObj->Image[0][j1]->Height );
}
mmesa->setup.tex_cntl |= MACH64_TEX_CACHE_FLUSH;
+ t1->base.dirty_images[0] = 0;
}
mmesa->dirty |= MACH64_UPLOAD_TEXTURE;
-
- t0->dirty = 0;
- t1->dirty = 0;
}
diff --git a/src/mesa/drivers/dri/mach64/mach64_texstate.c b/src/mesa/drivers/dri/mach64/mach64_texstate.c
index b6a9e3f931..3ace370d70 100644
--- a/src/mesa/drivers/dri/mach64/mach64_texstate.c
+++ b/src/mesa/drivers/dri/mach64/mach64_texstate.c
@@ -47,11 +47,6 @@ static void mach64SetTexImages( mach64ContextPtr mmesa,
{
mach64TexObjPtr t = (mach64TexObjPtr) tObj->DriverData;
struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel];
-#if 0
- int log2Pitch, log2Height, log2Size, log2MinSize;
- int i;
- GLint firstLevel, lastLevel;
-#endif
int totalSize;
assert(t);
@@ -92,77 +87,17 @@ static void mach64SetTexImages( mach64ContextPtr mmesa,
_mesa_problem(mmesa->glCtx, "Bad texture format in %s", __FUNCTION__);
};
-#if 0
- /* Compute which mipmap levels we really want to send to the hardware.
- * This depends on the base image size, GL_TEXTURE_MIN_LOD,
- * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
- * Yes, this looks overly complicated, but it's all needed.
- */
- firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5);
- firstLevel = MAX2(firstLevel, tObj->BaseLevel);
- lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5);
- lastLevel = MAX2(lastLevel, tObj->BaseLevel);
- lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2);
- lastLevel = MIN2(lastLevel, tObj->MaxLevel);
- lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
-
- log2Pitch = tObj->Image[firstLevel]->WidthLog2;
- log2Height = tObj->Image[firstLevel]->HeightLog2;
- log2Size = MAX2(log2Pitch, log2Height);
- log2MinSize = log2Size;
-
- t->dirty = 0;
- totalSize = 0;
- for ( i = firstLevel; i <= lastLevel; i++ ) {
- const struct gl_texture_image *texImage;
-
- texImage = tObj->Image[i];
- if ( !texImage || !texImage->Data ) {
- lastLevel = i - 1;
- break;
- }
-
- log2MinSize = texImage->MaxLog2;
-
- t->image[i - firstLevel].offset = totalSize;
- t->image[i - firstLevel].width = tObj->Image[i]->Width;
- t->image[i - firstLevel].height = tObj->Image[i]->Height;
+ totalSize = ( baseImage->Height *
+ baseImage->Width *
+ baseImage->TexFormat->TexelBytes );
- t->dirty |= (1 << i);
-
- totalSize += (tObj->Image[i]->Height *
- tObj->Image[i]->Width *
- tObj->Image[i]->TexFormat->TexelBytes);
-
- /* Offsets must be 32-byte aligned for host data blits and tiling */
- totalSize = (totalSize + 31) & ~31;
- }
+ totalSize = (totalSize + 31) & ~31;
- t->totalSize = totalSize;
- t->firstLevel = firstLevel;
- t->lastLevel = lastLevel;
+ t->base.totalSize = totalSize;
+ t->base.firstLevel = tObj->BaseLevel;
+ t->base.lastLevel = tObj->BaseLevel;
/* Set the texture format */
- t->setup.tex_cntl &= ~(0xf << 16);
- t->setup.tex_cntl |= t->textureFormat;
-
- t->setup.tex_combine_cntl = 0x00000000; /* XXX is this right? */
-
- t->setup.tex_size_pitch = ((log2Pitch << R128_TEX_PITCH_SHIFT) |
- (log2Size << R128_TEX_SIZE_SHIFT) |
- (log2Height << R128_TEX_HEIGHT_SHIFT) |
- (log2MinSize << R128_TEX_MIN_SIZE_SHIFT));
-
- for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) {
- t->setup.tex_offset[i] = 0x00000000;
- }
-
- if (firstLevel == lastLevel)
- t->setup.tex_cntl |= R128_MIP_MAP_DISABLE;
- else
- t->setup.tex_cntl &= ~R128_MIP_MAP_DISABLE;
-
-#else
if ( ( baseImage->_BaseFormat == GL_RGBA ) ||
( baseImage->_BaseFormat == GL_ALPHA ) ||
( baseImage->_BaseFormat == GL_LUMINANCE_ALPHA ) ) {
@@ -171,15 +106,9 @@ static void mach64SetTexImages( mach64ContextPtr mmesa,
t->hasAlpha = 0;
}
- totalSize = ( baseImage->Width * baseImage->Height *
- baseImage->TexFormat->TexelBytes );
- totalSize = (totalSize + 31) & ~31;
- t->size = totalSize;
t->widthLog2 = baseImage->WidthLog2;
t->heightLog2 = baseImage->HeightLog2;
t->maxLog2 = baseImage->MaxLog2;
-
-#endif
}
static void mach64UpdateTextureEnv( GLcontext *ctx, int unit )
@@ -387,17 +316,17 @@ static void mach64UpdateTextureUnit( GLcontext *ctx, int unit )
}
/* Upload teximages */
- if (t->dirty) {
+ if (t->base.dirty_images[0]) {
mach64SetTexImages( mmesa, tObj );
mmesa->dirty |= (MACH64_UPLOAD_TEX0IMAGE << unit);
}
/* Bind to the given texture unit */
mmesa->CurrentTexObj[unit] = t;
- t->bound |= (1 << unit);
+ t->base.bound |= (1 << unit);
- if ( t->memBlock )
- mach64UpdateTexLRU( mmesa, t );
+ if ( t->base.memBlock )
+ driUpdateTextureLRU( (driTextureObject *) t ); /* XXX: should be locked! */
/* register setup */
if ( unit == 0 ) {
@@ -515,8 +444,8 @@ void mach64UpdateTextureState( GLcontext *ctx )
FALLBACK( mmesa, MACH64_FALLBACK_TEXTURE, GL_FALSE );
/* Unbind any currently bound textures */
- if ( mmesa->CurrentTexObj[0] ) mmesa->CurrentTexObj[0]->bound = 0;
- if ( mmesa->CurrentTexObj[1] ) mmesa->CurrentTexObj[1]->bound = 0;
+ if ( mmesa->CurrentTexObj[0] ) mmesa->CurrentTexObj[0]->base.bound = 0;
+ if ( mmesa->CurrentTexObj[1] ) mmesa->CurrentTexObj[1]->base.bound = 0;
mmesa->CurrentTexObj[0] = NULL;
mmesa->CurrentTexObj[1] = NULL;
@@ -556,3 +485,41 @@ void mach64UpdateTextureState( GLcontext *ctx )
MACH64_UPLOAD_TEXTURE);
}
+
+/* Due to the way we must program texture state into the Rage Pro,
+ * we must leave these calculations to the absolute last minute.
+ */
+void mach64EmitTexStateLocked( mach64ContextPtr mmesa,
+ mach64TexObjPtr t0,
+ mach64TexObjPtr t1 )
+{
+ drm_mach64_sarea_t *sarea = mmesa->sarea;
+ drm_mach64_context_regs_t *regs = &(mmesa->setup);
+
+ /* for multitex, both textures must be local or AGP */
+ if ( t0 && t1 )
+ assert(t0->heap == t1->heap);
+
+ if ( t0 ) {
+ if (t0->heap == MACH64_CARD_HEAP) {
+#if ENABLE_PERF_BOXES
+ mmesa->c_texsrc_card++;
+#endif
+ mmesa->setup.tex_cntl &= ~MACH64_TEX_SRC_AGP;
+ } else {
+#if ENABLE_PERF_BOXES
+ mmesa->c_texsrc_agp++;
+#endif
+ mmesa->setup.tex_cntl |= MACH64_TEX_SRC_AGP;
+ }
+ mmesa->setup.tex_offset = t0->bufAddr;
+ }
+
+ if ( t1 ) {
+ mmesa->setup.secondary_tex_off = t1->bufAddr;
+ }
+
+ memcpy( &sarea->context_state.tex_size_pitch, &regs->tex_size_pitch,
+ MACH64_NR_TEXTURE_REGS * sizeof(GLuint) );
+}
+
diff --git a/src/mesa/drivers/dri/mach64/mach64_tris.c b/src/mesa/drivers/dri/mach64/mach64_tris.c
index 4a0044be88..08cc1849a1 100644
--- a/src/mesa/drivers/dri/mach64/mach64_tris.c
+++ b/src/mesa/drivers/dri/mach64/mach64_tris.c
@@ -1583,7 +1583,10 @@ static void mach64FastRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
mach64ContextPtr mmesa = MACH64_CONTEXT( ctx );
const GLuint vertsize = mmesa->vertex_size;
GLint a;
- GLfloat ooa;
+ union {
+ GLfloat f;
+ CARD32 u;
+ } ooa;
GLuint xy;
const GLuint xyoffset = 9;
GLint xx[3], yy[3]; /* 2 fractional bits for hardware */
@@ -1621,7 +1624,7 @@ static void mach64FastRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
return;
}
- ooa = 16.0 / a;
+ ooa.f = 16.0 / a;
vb = (CARD32 *)mach64AllocDmaLow( mmesa, vbsiz * sizeof(CARD32) );
vbchk = vb + vbsiz;
@@ -1629,7 +1632,7 @@ static void mach64FastRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
COPY_VERTEX( vb, vertsize, v0, 1 );
COPY_VERTEX( vb, vertsize, v1, 2 );
COPY_VERTEX_OOA( vb, vertsize, v2, 3 );
- LE32_OUT( vb++, *(CARD32 *)&ooa );
+ LE32_OUT( vb++, ooa.u );
i = 3;
while (1) {
@@ -1644,10 +1647,10 @@ static void mach64FastRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
a = (xx[0] - xx[2]) * (yy[1] - yy[2]) -
(yy[0] - yy[2]) * (xx[1] - xx[2]);
- ooa = 16.0 / a;
+ ooa.f = 16.0 / a;
COPY_VERTEX_OOA( vb, vertsize, v0, 1 );
- LE32_OUT( vb++, *(CARD32 *)&ooa );
+ LE32_OUT( vb++, ooa.u );
if (i >= n)
break;
@@ -1660,10 +1663,10 @@ static void mach64FastRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
a = (xx[0] - xx[2]) * (yy[1] - yy[2]) -
(yy[0] - yy[2]) * (xx[1] - xx[2]);
- ooa = 16.0 / a;
+ ooa.f = 16.0 / a;
COPY_VERTEX_OOA( vb, vertsize, v1, 2 );
- LE32_OUT( vb++, *(CARD32 *)&ooa );
+ LE32_OUT( vb++, ooa.u );
}
assert( vb == vbchk );
diff --git a/src/mesa/drivers/dri/mga/mgastate.c b/src/mesa/drivers/dri/mga/mgastate.c
index f7e07c330a..c20a76f29e 100644
--- a/src/mesa/drivers/dri/mga/mgastate.c
+++ b/src/mesa/drivers/dri/mga/mgastate.c
@@ -24,7 +24,6 @@
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*/
-/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgastate.c,v 1.13 2002/10/30 12:51:36 alanh Exp $ */
#include "mtypes.h"
@@ -49,6 +48,8 @@
#include "swrast_setup/swrast_setup.h"
#include "xmlpool.h"
+#include "drirenderbuffer.h"
+
static void updateSpecularLighting( GLcontext *ctx );
@@ -113,14 +114,15 @@ static void mgaDDAlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
static void updateBlendLogicOp(GLcontext *ctx)
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+ GLboolean logicOp = RGBA_LOGICOP_ENABLED(ctx);
MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
mmesa->hw.blend_func_enable =
- (ctx->Color.BlendEnabled && !ctx->Color._LogicOpEnabled) ? ~0 : 0;
+ (ctx->Color.BlendEnabled && !logicOp) ? ~0 : 0;
FALLBACK( ctx, MGA_FALLBACK_BLEND,
- ctx->Color.BlendEnabled && !ctx->Color._LogicOpEnabled &&
+ ctx->Color.BlendEnabled && !logicOp &&
mmesa->hw.blend_func == (AC_src_src_alpha_sat | AC_dst_zero) );
}
@@ -195,7 +197,7 @@ static void mgaDDBlendFuncSeparate( GLcontext *ctx, GLenum sfactorRGB,
mmesa->hw.blend_func = (src | dst);
FALLBACK( ctx, MGA_FALLBACK_BLEND,
- ctx->Color.BlendEnabled && !ctx->Color._LogicOpEnabled &&
+ ctx->Color.BlendEnabled && !RGBA_LOGICOP_ENABLED(ctx) &&
mmesa->hw.blend_func == (AC_src_src_alpha_sat | AC_dst_zero) );
}
@@ -965,7 +967,7 @@ void mgaEmitHwStateLocked( mgaContextPtr mmesa )
? mmesa->hw.zmode : (DC_zmode_nozcmp | DC_atype_i);
mmesa->setup.dwgctl &= DC_bop_MASK;
- mmesa->setup.dwgctl |= (ctx->Color._LogicOpEnabled)
+ mmesa->setup.dwgctl |= RGBA_LOGICOP_ENABLED(ctx)
? mmesa->hw.rop : mgarop_NoBLK[ GL_COPY & 0x0f ];
mmesa->setup.alphactrl &= AC_src_MASK & AC_dst_MASK & AC_atmode_MASK
diff --git a/src/mesa/drivers/dri/mga/mgatex.c b/src/mesa/drivers/dri/mga/mgatex.c
index 8caa1f8580..a7d74317a5 100644
--- a/src/mesa/drivers/dri/mga/mgatex.c
+++ b/src/mesa/drivers/dri/mga/mgatex.c
@@ -502,6 +502,9 @@ mgaDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj )
driDestroyTextureObject( t );
}
+
+ /* Free mipmap images and the texture object itself */
+ _mesa_delete_texture_object(ctx, tObj);
}
diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile
new file mode 100644
index 0000000000..9eb40fb9c1
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/Makefile
@@ -0,0 +1,50 @@
+# 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_shader.c \
+ nouveau_shader_0_arb.c \
+ nouveau_shader_1.c \
+ nouveau_shader_2.c \
+ nouveau_tex.c \
+ nouveau_swtcl.c \
+ nouveau_sync.c \
+ nv04_swtcl.c \
+ nv10_swtcl.c \
+ nv10_state.c \
+ nv20_state.c \
+ nv30_state.c \
+ nouveau_state_cache.c \
+ nv20_vertprog.c \
+ nv30_fragprog.c \
+ nv30_vertprog.c \
+ nv40_fragprog.c \
+ nv40_vertprog.c
+
+C_SOURCES = \
+ $(COMMON_SOURCES) \
+ $(DRIVER_SOURCES)
+
+ASM_SOURCES =
+
+
+include ../Makefile.template
+
+symlinks:
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c
new file mode 100644
index 0000000000..d36196aeef
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c
@@ -0,0 +1,272 @@
+#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 DEBUG(fmt,args...) do { \
+ if (NOUVEAU_DEBUG & DEBUG_BUFFEROBJ) { \
+ fprintf(stderr, "%s: "fmt, __func__, ##args); \
+ } \
+} while(0)
+
+/* Wrapper for nouveau_mem_gpu_offset_get() that marks the bufferobj dirty
+ * if the GPU modifies the data.
+ */
+uint32_t
+nouveau_bufferobj_gpu_ref(GLcontext *ctx, GLenum access,
+ struct gl_buffer_object *obj)
+{
+ nouveau_buffer_object *nbo = (nouveau_buffer_object *)obj;
+
+ DEBUG("obj=%p, access=%s\n", obj, _mesa_lookup_enum_by_nr(access));
+
+ if (access == GL_WRITE_ONLY_ARB || access == GL_READ_WRITE_ARB)
+ nbo->gpu_dirty = GL_TRUE;
+
+ return nouveau_mem_gpu_offset_get(ctx, nbo->gpu_mem);
+}
+
+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);
+ DEBUG("name=0x%08x, target=%s, obj=%p\n",
+ buffer, _mesa_lookup_enum_by_nr(target), nbo);
+ _mesa_initialize_buffer_object(&nbo->mesa, buffer, target);
+ return &nbo->mesa;
+}
+
+static void
+nouveauDeleteBuffer(GLcontext *ctx, struct gl_buffer_object *obj)
+{
+ nouveau_buffer_object *nbo = (nouveau_buffer_object *)obj;
+
+ DEBUG("obj=%p\n", obj);
+
+ 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)
+{
+ nouveau_buffer_object *nbo = (nouveau_buffer_object *)obj;
+
+ DEBUG("obj=%p, target=%s, usage=%s, size=%d, data=%p\n",
+ obj,
+ _mesa_lookup_enum_by_nr(target),
+ _mesa_lookup_enum_by_nr(usage),
+ (unsigned int)size,
+ data);
+
+ if (nbo->gpu_mem && nbo->gpu_mem->size != size)
+ nouveau_mem_free(ctx, nbo->gpu_mem);
+
+ /* Always have the GPU access the data from VRAM if possible. For
+ * some "usage" values it may be better from AGP be default?
+ *
+ * TODO: At some point we should drop the NOUVEAU_MEM_MAPPED flag.
+ * TODO: Use the NOUVEAU_MEM_AGP_ACCEPTABLE flag.
+ * TODO: What about PCI-E and shared system memory?
+ */
+ if (!nbo->gpu_mem)
+ nbo->gpu_mem = nouveau_mem_alloc(ctx,
+ NOUVEAU_MEM_FB |
+ NOUVEAU_MEM_MAPPED,
+ size,
+ 0);
+
+ if (!nbo->gpu_mem) {
+ MESSAGE("AIII bufferobj malloc failed\n");
+ return;
+ }
+
+ obj->Usage = usage;
+ obj->Size = size;
+ if (!data)
+ return;
+
+ ctx->Driver.MapBuffer(ctx, target, GL_WRITE_ONLY_ARB, obj);
+ _mesa_memcpy(nbo->cpu_mem->map, data, size);
+ ctx->Driver.UnmapBuffer(ctx, target, obj);
+}
+
+/*TODO: we don't need to DMA the entire buffer like MapBuffer does.. */
+static void
+nouveauBufferSubData(GLcontext *ctx, GLenum target, GLintptrARB offset,
+ GLsizeiptrARB size, const GLvoid *data,
+ struct gl_buffer_object *obj)
+{
+ DEBUG("obj=%p, target=%s, offset=0x%x, size=%d, data=%p\n",
+ obj,
+ _mesa_lookup_enum_by_nr(target),
+ (unsigned int)offset,
+ (unsigned int)size,
+ data);
+
+ ctx->Driver.MapBuffer(ctx, target, GL_WRITE_ONLY_ARB, obj);
+ _mesa_memcpy((GLubyte *)obj->Pointer + offset, data, size);
+ ctx->Driver.UnmapBuffer(ctx, target, obj);
+}
+
+/*TODO: we don't need to DMA the entire buffer like MapBuffer does.. */
+static void
+nouveauGetBufferSubData(GLcontext *ctx, GLenum target, GLintptrARB offset,
+ GLsizeiptrARB size, GLvoid *data,
+ struct gl_buffer_object *obj)
+{
+ DEBUG("obj=%p, target=%s, offset=0x%x, size=%d, data=%p\n",
+ obj,
+ _mesa_lookup_enum_by_nr(target),
+ (unsigned int)offset,
+ (unsigned int)size,
+ data);
+
+ ctx->Driver.MapBuffer(ctx, target, GL_READ_ONLY_ARB, obj);
+ _mesa_memcpy(data, (GLubyte *)obj->Pointer + offset, size);
+ ctx->Driver.UnmapBuffer(ctx, target, obj);
+}
+
+static void *
+nouveauMapBuffer(GLcontext *ctx, GLenum target, GLenum access,
+ struct gl_buffer_object *obj)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nouveau_buffer_object *nbo = (nouveau_buffer_object *)obj;
+
+ DEBUG("obj=%p, target=%s, access=%s\n",
+ obj,
+ _mesa_lookup_enum_by_nr(target),
+ _mesa_lookup_enum_by_nr(access));
+
+ if (obj->Pointer) {
+ DEBUG("already mapped, return NULL\n");
+ return NULL;
+ }
+
+#ifdef ALLOW_MULTI_SUBCHANNEL
+ /* If GPU is accessing the data from VRAM, copy to faster AGP memory
+ * before CPU access to the buffer.
+ */
+ if (nbo->gpu_mem->type & NOUVEAU_MEM_FB) {
+ DEBUG("Data in VRAM, copying to AGP for CPU access\n");
+
+ /* This can happen if BufferData grows the GPU-access buffer */
+ if (nbo->cpu_mem && nbo->cpu_mem->size != nbo->gpu_mem->size) {
+ nouveau_mem_free(ctx, nbo->cpu_mem);
+ nbo->cpu_mem = NULL;
+ }
+
+ if (!nbo->cpu_mem) {
+ nbo->cpu_mem = nouveau_mem_alloc(ctx,
+ NOUVEAU_MEM_AGP |
+ NOUVEAU_MEM_MAPPED,
+ nbo->gpu_mem->size,
+ 0);
+
+ /* Mark GPU data as modified, so it gets copied to
+ * the new buffer */
+ nbo->gpu_dirty = GL_TRUE;
+ }
+
+ if (nbo->cpu_mem && nbo->gpu_dirty) {
+ nouveau_memformat_flat_emit(ctx, nbo->cpu_mem,
+ nbo->gpu_mem,
+ 0, 0,
+ nbo->gpu_mem->size);
+
+ nouveau_notifier_wait_nop(ctx,
+ nmesa->syncNotifier,
+ NvSubMemFormat);
+ nbo->gpu_dirty = GL_FALSE;
+ }
+
+ /* buffer isn't guaranteed to be up-to-date on the card now */
+ nbo->cpu_dirty = GL_TRUE;
+ }
+#endif
+
+ /* If the copy to AGP failed for some reason, just return a pointer
+ * directly to vram..
+ */
+ if (!nbo->cpu_mem) {
+ DEBUG("Returning direct pointer to VRAM\n");
+ nbo->cpu_mem = nbo->gpu_mem;
+ nbo->cpu_dirty = GL_FALSE;
+ }
+
+ obj->Pointer = nbo->cpu_mem->map;
+ return obj->Pointer;
+}
+
+static GLboolean
+nouveauUnmapBuffer(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nouveau_buffer_object *nbo = (nouveau_buffer_object *)obj;
+
+ DEBUG("obj=%p, target=%s\n", obj, _mesa_lookup_enum_by_nr(target));
+
+#ifdef ALLOW_MULTI_SUBCHANNEL
+ if (nbo->cpu_dirty && nbo->cpu_mem != nbo->gpu_mem) {
+ DEBUG("Copying potentially modified data back to GPU\n");
+
+ /* blit from GPU buffer -> CPU buffer */
+ nouveau_memformat_flat_emit(ctx, nbo->gpu_mem, nbo->cpu_mem,
+ 0, 0, nbo->cpu_mem->size);
+
+ /* buffer is now up-to-date on the hardware (or rather, will
+ * be by the time any other commands in this channel reference
+ * the data.)
+ */
+ nbo->cpu_dirty = GL_FALSE;
+
+ /* we can avoid this wait in some cases.. */
+ nouveau_notifier_wait_nop(ctx,
+ nmesa->syncNotifier,
+ NvSubMemFormat);
+
+ /* If it's likely CPU access to the buffer will occur often,
+ * keep the cpu_mem around to avoid repeated allocs.
+ */
+ if (obj->Usage != GL_DYNAMIC_DRAW_ARB) {
+
+ nouveau_mem_free(ctx, nbo->cpu_mem);
+ nbo->cpu_mem = NULL;
+ }
+ }
+#endif
+
+ 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/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h
new file mode 100644
index 0000000000..fccc349b83
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h
@@ -0,0 +1,27 @@
+#ifndef __NOUVEAU_BUFFEROBJ_H__
+#define __NOUVEAU_BUFFEROBJ_H__
+
+#include "mtypes.h"
+#include "nouveau_buffers.h"
+
+typedef struct nouveau_buffer_object_t {
+ /* Base class, must be first */
+ struct gl_buffer_object mesa;
+
+ /* Memory used for GPU access to the buffer*/
+ nouveau_mem * gpu_mem;
+ /* Buffer has been dirtied by the GPU */
+ GLboolean gpu_dirty;
+
+ /* Memory used for CPU access to the buffer */
+ nouveau_mem * cpu_mem;
+ /* Buffer has possibly been dirtied by the CPU */
+ GLboolean cpu_dirty;
+} nouveau_buffer_object;
+
+extern uint32_t nouveau_bufferobj_gpu_ref(GLcontext *ctx, GLenum access,
+ struct gl_buffer_object *obj);
+
+extern void nouveauInitBufferObjects(GLcontext *ctx);
+
+#endif
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c
new file mode 100644
index 0000000000..b54f68f402
--- /dev/null
+++ b/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/src/mesa/drivers/dri/nouveau/nouveau_buffers.h b/src/mesa/drivers/dri/nouveau/nouveau_buffers.h
new file mode 100644
index 0000000000..d86455184c
--- /dev/null
+++ b/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/src/mesa/drivers/dri/nouveau/nouveau_card.c b/src/mesa/drivers/dri/nouveau/nouveau_card.c
new file mode 100644
index 0000000000..91f12f0d70
--- /dev/null
+++ b/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/src/mesa/drivers/dri/nouveau/nouveau_card.h b/src/mesa/drivers/dri/nouveau/nouveau_card.h
new file mode 100644
index 0000000000..8a4c5f2244
--- /dev/null
+++ b/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/src/mesa/drivers/dri/nouveau/nouveau_card_list.h b/src/mesa/drivers/dri/nouveau/nouveau_card_list.h
new file mode 100644
index 0000000000..14e7b69802
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_card_list.h
@@ -0,0 +1,230 @@
+static nouveau_card nouveau_card_list[]={
+{0x0008, "EDGE 3D", 0, NV_03, 0},
+{0x0009, "EDGE 3D", 0, NV_03, 0},
+{0x0010, "Mutara V08", 0, NV_03, 0},
+{0x0020, "RIVA TNT", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0},
+{0x0028, "RIVA TNT2/TNT2 Pro", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0},
+{0x0029, "RIVA TNT2 Ultra", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0},
+{0x002A, "Riva TnT2", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0},
+{0x002B, "Riva TnT2", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0},
+{0x002C, "Vanta/Vanta LT", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0},
+{0x002D, "RIVA TNT2 Model 64/Model 64 Pro", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0},
+{0x002E, "Vanta", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0},
+{0x002F, "Vanta", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0},
+{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_DX6_MULTITEX_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|0x3000, NV_30, 0},
+{0x00FB, "GeForce PCX 5900", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
+{0x00FC, "Quadro FX 330/GeForce PCX 5300", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
+{0x00FD, "Quadro FX 330/Quadro NVS280", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
+{0x00FE, "Quadro FX 1300", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{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},
+{0x014D, "Quadro FX 550", NV17_TCL_PRIMITIVE_3D, NV_17, 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|0x2000, NV_20, 0},
+{0x0201, "GeForce3 Ti 200", NV20_TCL_PRIMITIVE_3D|0x2000, NV_20, 0},
+{0x0202, "GeForce3 Ti 500", NV20_TCL_PRIMITIVE_3D|0x2000, NV_20, 0},
+{0x0203, "Quadro DCC", NV20_TCL_PRIMITIVE_3D|0x2000, NV_20, 0},
+{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|0x2500, NV_25, 0},
+{0x0251, "GeForce4 Ti 4400", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0},
+{0x0252, "GeForce4 Ti", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0},
+{0x0253, "GeForce4 Ti 4200", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0},
+{0x0258, "Quadro4 900 XGL", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0},
+{0x0259, "Quadro4 750 XGL", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0},
+{0x025B, "Quadro4 700 XGL", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0},
+{0x0280, "GeForce4 Ti 4800", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0},
+{0x0281, "GeForce4 Ti 4200 AGP 8x", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0},
+{0x0282, "GeForce4 Ti 4800 SE", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0},
+{0x0286, "GeForce4 Ti 4200 Go AGP 8x", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0},
+{0x0288, "Quadro4 980 XGL", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0},
+{0x0289, "Quadro4 780 XGL", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0},
+{0x028C, "Quadro4 700 GoGL", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0},
+{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|0x2000, NV_20, 0},
+{0x02E1, "GeForce 7600 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0300, "GeForce FX", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x0301, "GeForce FX 5800 Ultra", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x0302, "GeForce FX 5800", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x0308, "Quadro FX 2000", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x0309, "Quadro FX 1000", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x0311, "GeForce FX 5600 Ultra", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x0312, "GeForce FX 5600", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x0313, "NV31", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x0314, "GeForce FX 5600XT", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x0316, "NV31M", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x0317, "NV31M Pro", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x031A, "GeForce FX Go5600", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x031B, "GeForce FX Go5650", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x031D, "NV31GLM", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x031E, "NV31GLM Pro", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x031F, "NV31GLM Pro", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x0320, "GeForce FX 5200", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0},
+{0x0321, "GeForce FX 5200 Ultra", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0},
+{0x0322, "GeForce FX 5200", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0},
+{0x0323, "GeForce FX 5200LE", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0},
+{0x0324, "GeForce FX Go5200", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0},
+{0x0325, "GeForce FX Go5250", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0},
+{0x0326, "GeForce FX 5500", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0},
+{0x0327, "GeForce FX 5100", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0},
+{0x0328, "GeForce FX Go5200 32M/64M", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0},
+{0x0329, "GeForce FX Go5200", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0},
+{0x032A, "Quadro NVS 280 PCI", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0},
+{0x032B, "Quadro FX 500/600 PCI", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0},
+{0x032C, "GeForce FX Go 5300", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0},
+{0x032D, "GeForce FX Go5100", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0},
+{0x032F, "NV34GL", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0},
+{0x0330, "GeForce FX 5900 Ultra", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
+{0x0331, "GeForce FX 5900", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
+{0x0332, "GeForce FX 5900XT", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
+{0x0333, "GeForce FX 5950 Ultra", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x0334, "GeForce FX 5900ZT", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
+{0x0338, "Quadro FX 3000", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x033F, "Quadro FX 700", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x0341, "GeForce FX 5700 Ultra", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x0342, "GeForce FX 5700", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x0343, "GeForce FX 5700LE", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x0344, "GeForce FX 5700VE", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x0345, "NV36.5", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x0347, "GeForce FX Go5700", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x0348, "GeForce FX Go5700", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x0349, "NV36M Pro", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x034B, "NV36MAP", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x034C, "Quadro FX Go1000", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x034E, "Quadro FX 1100", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{0x034F, "NV36GL", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0},
+{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_DX6_MULTITEX_TRIANGLE, NV_04, 0},
+{0x0028, "TNT2", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0},
+{0x0029, "UTNT2", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0},
+{0x002C, "VTNT2", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0},
+{0x00A0, "ITNT2", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0},
+};
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c
new file mode 100644
index 0000000000..c86ff603f6
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c
@@ -0,0 +1,366 @@
+/**************************************************************************
+
+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 "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
+#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 },
+ { 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_AGP_PHYSICAL,
+ &nmesa->agp_phys))
+ 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->_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;
+ 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));
+ }
+
+ 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/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h
new file mode 100644
index 0000000000..c7bf387210
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h
@@ -0,0 +1,227 @@
+/**************************************************************************
+
+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{
+ 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 agp_phys;
+
+ /* Channel synchronisation */
+ nouveau_notifier *syncNotifier;
+
+ /* 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;
+
+ 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/src/mesa/drivers/dri/nouveau/nouveau_ctrlreg.h b/src/mesa/drivers/dri/nouveau/nouveau_ctrlreg.h
new file mode 100644
index 0000000000..c9b2d59007
--- /dev/null
+++ b/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/src/mesa/drivers/dri/nouveau/nouveau_dri.h b/src/mesa/drivers/dri/nouveau/nouveau_dri.h
new file mode 100644
index 0000000000..ce3c3fb9cc
--- /dev/null
+++ b/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/src/mesa/drivers/dri/nouveau/nouveau_driver.c b/src/mesa/drivers/dri/nouveau/nouveau_driver.c
new file mode 100644
index 0000000000..00956aa8f8
--- /dev/null
+++ b/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/src/mesa/drivers/dri/nouveau/nouveau_driver.h b/src/mesa/drivers/dri/nouveau/nouveau_driver.h
new file mode 100644
index 0000000000..6164012b5b
--- /dev/null
+++ b/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/src/mesa/drivers/dri/nouveau/nouveau_fifo.c b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c
new file mode 100644
index 0000000000..7af9f1e3c2
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c
@@ -0,0 +1,137 @@
+/**************************************************************************
+
+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"
+
+
+#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.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/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h
new file mode 100644
index 0000000000..9056bfb255
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h
@@ -0,0 +1,156 @@
+/**************************************************************************
+
+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_DEBUG
+//#define NOUVEAU_STATE_CACHE_DISABLE
+
+#define NV_READ(reg) *(volatile u_int32_t *)(nmesa->mmio + (reg))
+
+#define NV_FIFO_READ(reg) *(volatile u_int32_t *)(nmesa->fifo.mmio + (reg/4))
+#define NV_FIFO_WRITE(reg,value) *(volatile u_int32_t *)(nmesa->fifo.mmio + (reg/4)) = value;
+#define NV_FIFO_READ_GET() ((NV_FIFO_READ(NV03_FIFO_REGS_DMAGET) - nmesa->fifo.put_base) >> 2)
+#define NV_FIFO_WRITE_PUT(val) NV_FIFO_WRITE(NV03_FIFO_REGS_DMAPUT, ((val)<<2) + nmesa->fifo.put_base)
+
+/*
+ * 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
+
+#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))); \
+}while(0)
+
+#define OUT_RING(n) do { \
+ printf("OUT_RINGn: 0x%08x (%s)\n", n, __func__); \
+}while(0)
+
+#define OUT_RINGf(n) do { \
+ printf("OUT_RINGf: %.04f (%s)\n", n, __func__); \
+}while(0)
+
+#else
+
+#define OUT_RINGp(ptr,sz) do{ \
+ memcpy(nmesa->fifo.buffer+nmesa->fifo.current,ptr,(sz)*4); \
+ nmesa->fifo.current+=(sz); \
+}while(0)
+
+#define OUT_RING(n) do { \
+nmesa->fifo.buffer[nmesa->fifo.current++]=(n); \
+}while(0)
+
+#define OUT_RINGf(n) do { \
+*((float*)(nmesa->fifo.buffer+nmesa->fifo.current++))=(n); \
+}while(0)
+
+#endif
+
+#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)
+
+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/src/mesa/drivers/dri/nouveau/nouveau_lock.c b/src/mesa/drivers/dri/nouveau/nouveau_lock.c
new file mode 100644
index 0000000000..c119d14dd7
--- /dev/null
+++ b/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/src/mesa/drivers/dri/nouveau/nouveau_lock.h b/src/mesa/drivers/dri/nouveau/nouveau_lock.h
new file mode 100644
index 0000000000..38bb001425
--- /dev/null
+++ b/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/src/mesa/drivers/dri/nouveau/nouveau_msg.h b/src/mesa/drivers/dri/nouveau/nouveau_msg.h
new file mode 100644
index 0000000000..5dea2189c7
--- /dev/null
+++ b/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/src/mesa/drivers/dri/nouveau/nouveau_object.c b/src/mesa/drivers/dri/nouveau/nouveau_object.c
new file mode 100644
index 0000000000..1558f2963d
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_object.c
@@ -0,0 +1,92 @@
+
+#include "nouveau_fifo.h"
+#include "nouveau_object.h"
+#include "nouveau_reg.h"
+
+
+GLboolean nouveauCreateContextObject(nouveauContextPtr nmesa, int handle, int class, uint32_t flags, uint32_t dma_in, uint32_t dma_out, uint32_t dma_notifier)
+{
+ drm_nouveau_object_init_t cto;
+ int ret;
+
+ cto.handle = handle;
+ cto.class = class;
+ cto.flags = flags;
+ cto.dma0= dma_in;
+ cto.dma1= dma_out;
+ cto.dma_notifier = dma_notifier;
+ ret = drmCommandWrite(nmesa->driFd, DRM_NOUVEAU_OBJECT_INIT, &cto, sizeof(cto));
+
+ return ret == 0;
+}
+
+GLboolean nouveauCreateDmaObject(nouveauContextPtr nmesa,
+ uint32_t handle,
+ uint32_t offset,
+ uint32_t size,
+ int target,
+ int access)
+{
+ drm_nouveau_dma_object_init_t dma;
+ int ret;
+
+ 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;
+}
+
+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,
+ 0, (256*1024*1024),
+ 0 /*NV_DMA_TARGET_FB*/, 0 /*NV_DMA_ACCESS_RW*/);
+ nouveauCreateDmaObject( nmesa, NvDmaAGP,
+ nmesa->agp_phys, (128*1024*1024),
+ 3 /* AGP */, 0 /* RW */);
+
+ nouveauCreateContextObject(nmesa, Nv3D, nmesa->screen->card->class_3d,
+ 0, 0, 0, 0);
+ nouveauCreateContextObject(nmesa, NvCtxSurf2D, NV10_CONTEXT_SURFACES_2D,
+ 0, 0, 0, 0);
+ nouveauCreateContextObject(nmesa, NvImageBlit, NV10_IMAGE_BLIT,
+ NV_DMA_CONTEXT_FLAGS_PATCH_SRCCOPY, 0, 0, 0);
+ nouveauCreateContextObject(nmesa, NvMemFormat,
+ NV_MEMORY_TO_MEMORY_FORMAT,
+ 0, 0, 0, 0);
+
+#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/src/mesa/drivers/dri/nouveau/nouveau_object.h b/src/mesa/drivers/dri/nouveau/nouveau_object.h
new file mode 100644
index 0000000000..b1ff5a5d0d
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_object.h
@@ -0,0 +1,41 @@
+#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,
+ NvDmaFB = 0xD0FB0001,
+ NvDmaAGP = 0xD0AA0001,
+ NvSyncNotify = 0xD0000001
+};
+
+enum DMASubchannel {
+ NvSubCtxSurf2D = 0,
+ NvSubImageBlit = 1,
+ NvSubMemFormat = 2,
+ NvSub3D = 7,
+};
+
+extern void nouveauObjectOnSubchannel(nouveauContextPtr nmesa, int subchannel, int handle);
+
+extern GLboolean nouveauCreateContextObject(nouveauContextPtr nmesa,
+ int handle, int class,
+ uint32_t flags,
+ uint32_t dma_in,
+ uint32_t dma_out,
+ uint32_t dma_notifier);
+extern GLboolean nouveauCreateDmaObject(nouveauContextPtr nmesa,
+ uint32_t handle,
+ uint32_t offset,
+ uint32_t size,
+ int target,
+ int access);
+#endif
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_reg.h b/src/mesa/drivers/dri/nouveau/nouveau_reg.h
new file mode 100644
index 0000000000..8758b538c8
--- /dev/null
+++ b/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/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c
new file mode 100644
index 0000000000..ab7742df14
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c
@@ -0,0 +1,376 @@
+/**************************************************************************
+
+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_destroy_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, 2 };
+
+ 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)
+ 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/src/mesa/drivers/dri/nouveau/nouveau_screen.h b/src/mesa/drivers/dri/nouveau/nouveau_screen.h
new file mode 100644
index 0000000000..decdafa86d
--- /dev/null
+++ b/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/src/mesa/drivers/dri/nouveau/nouveau_shader.c b/src/mesa/drivers/dri/nouveau/nouveau_shader.c
new file mode 100644
index 0000000000..dc366b36c0
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.c
@@ -0,0 +1,798 @@
+/*
+ * 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 "program.h"
+#include "tnl/tnl.h"
+#include "shader/arbprogparse.h"
+
+#include "nouveau_context.h"
+#include "nouveau_shader.h"
+
+/*****************************************************************************
+ * Mesa entry points
+ */
+static void
+nouveauBindProgram(GLcontext *ctx, GLenum target, struct gl_program *prog)
+{
+}
+
+static struct gl_program *
+nouveauNewProgram(GLcontext *ctx, GLenum target, GLuint id)
+{
+ nouveauShader *nvs;
+
+ nvs = CALLOC_STRUCT(_nouveauShader);
+ 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;
+
+ 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;
+
+ if (nvs->translated)
+ FREE(nvs->program);
+ nvs->translated = 0;
+
+ _tnl_program_string(ctx, target, prog);
+}
+
+static GLboolean
+nouveauIsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog)
+{
+ nouveauShader *nvs = (nouveauShader *)prog;
+
+ return nvs->translated;
+}
+
+GLboolean
+nvsUpdateShader(GLcontext *ctx, nouveauShader *nvs)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ struct gl_program_parameter_list *plist;
+ int i;
+
+ /* Translate to HW format now if necessary */
+ if (!nvs->translated) {
+ /* Mesa ASM shader -> nouveauShader */
+ if (!nouveau_shader_pass0_arb(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<plist->NumParameters; i++) {
+ if (!nvs->on_hardware) {
+ /* if we've been kicked off the hardware there's no guarantee our
+ * consts are still there.. reupload them all
+ */
+ nvs->func->UpdateConst(ctx, nvs, i);
+ } else if (plist->Parameters[i].Type == PROGRAM_STATE_VAR) {
+ if (!nvs->params[i].source_val) /* this is a workaround when consts aren't alloc'd from id=0.. */
+ continue;
+ /* 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_VERTEX_PROGRAM_ARB, 0);
+ _mesa_parse_arb_fragment_program(ctx,
+ GL_FRAGMENT_PROGRAM_ARB,
+ text,
+ strlen(text),
+ &nvs->mesa.fp);
+ }
+
+ nouveau_shader_pass0_arb(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);
+}
+
+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);
+
+ 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(nvsFragmentList *f, int lvl)
+{
+ while (f) {
+ switch (f->fragment->type) {
+ case NVS_INSTRUCTION:
+ nvsDumpInstruction((nvsInstruction*)f->fragment, 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/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h
new file mode 100644
index 0000000000..08cb7817cf
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h
@@ -0,0 +1,374 @@
+#ifndef __SHADER_COMMON_H__
+#define __SHADER_COMMON_H__
+
+#include "mtypes.h"
+#include "bufferobj.h"
+
+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 {
+ enum {
+ NVS_INSTRUCTION,
+ } type;
+ int position;
+} nvsFragmentHeader;
+
+typedef struct _nvs_fragment_list {
+ struct _nvs_fragment_list *prev;
+ struct _nvs_fragment_list *next;
+ nvsFragmentHeader *fragment;
+} nvsFragmentList;
+
+typedef struct _nouveauShader {
+ union {
+ struct gl_vertex_program vp;
+ struct gl_fragment_program fp;
+ } mesa;
+ GLcontext *ctx;
+ nvsFunc *func;
+
+ /* State of the final program */
+ 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;
+ unsigned int inputs_read;
+ unsigned int outputs_written;
+ int inst_count;
+
+ struct {
+ 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];
+
+ struct {
+ int last_use;
+ } temps[NVS_MAX_TEMPS];
+
+ /* Pass-private data */
+ void *pass_rec;
+
+ nvsFragmentList *list_head;
+ nvsFragmentList *list_tail;
+} 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,
+ NVS_FR_WEIGHT,
+ NVS_FR_NORMAL,
+ NVS_FR_COL0,
+ NVS_FR_COL1,
+ NVS_FR_BFC0,
+ NVS_FR_BFC1,
+ NVS_FR_FOGCOORD,
+ NVS_FR_POINTSZ,
+ NVS_FR_TEXCOORD0,
+ NVS_FR_TEXCOORD1,
+ NVS_FR_TEXCOORD2,
+ NVS_FR_TEXCOORD3,
+ NVS_FR_TEXCOORD4,
+ NVS_FR_TEXCOORD5,
+ NVS_FR_TEXCOORD6,
+ NVS_FR_TEXCOORD7,
+ NVS_FR_FRAGDATA0,
+ NVS_FR_FRAGDATA1,
+ NVS_FR_FRAGDATA2,
+ NVS_FR_FRAGDATA3,
+ NVS_FR_CLIP0,
+ NVS_FR_CLIP1,
+ NVS_FR_CLIP2,
+ NVS_FR_CLIP3,
+ NVS_FR_CLIP4,
+ NVS_FR_CLIP5,
+ NVS_FR_CLIP6,
+ NVS_FR_FACING,
+ NVS_FR_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 struct {
+ nvsFragmentHeader header;
+
+ nvsOpcode op;
+ unsigned int saturate;
+
+ nvsRegister dest;
+ unsigned int mask;
+
+ 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;
+
+#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 {
+ 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);
+ 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 (*SetSource) (nvsFunc *, nvsRegister *, int pos);
+ void (*SetTexImageUnit) (nvsFunc *, int unit);
+ void (*SetSaturate) (nvsFunc *);
+ void (*SetLastInst) (nvsFunc *);
+
+ 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;
+}
+
+extern GLboolean nvsUpdateShader(GLcontext *ctx, nouveauShader *nvs);
+extern void nvsDisasmHWShader(nvsPtr);
+extern void nvsDumpFragmentList(nvsFragmentList *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_arb(GLcontext *ctx, nouveauShader *nvs);
+extern GLboolean nouveau_shader_pass0_slang(GLcontext *ctx, nouveauShader *nvs);
+extern GLboolean nouveau_shader_pass1(nvsPtr nvs);
+extern GLboolean nouveau_shader_pass2(nvsPtr nvs);
+
+#endif
+
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0_arb.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0_arb.c
new file mode 100644
index 0000000000..afb889d421
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0_arb.c
@@ -0,0 +1,710 @@
+/*
+ * Copyright (C) 2006 Ben Skeggs.
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/*
+ * Authors:
+ * Ben Skeggs <darktama@iinet.net.au>
+ */
+
+#include "glheader.h"
+#include "macros.h"
+#include "enums.h"
+
+#include "program.h"
+#include "programopt.h"
+#include "program_instruction.h"
+
+#include "nouveau_context.h"
+#include "nouveau_shader.h"
+
+static nvsFixedReg _tx_mesa_vp_dst_reg[VERT_RESULT_MAX] = {
+ NVS_FR_POSITION, NVS_FR_COL0, NVS_FR_COL1, NVS_FR_FOGCOORD,
+ NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3,
+ NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7,
+ NVS_FR_POINTSZ, NVS_FR_BFC0, NVS_FR_BFC1, NVS_FR_UNKNOWN /* EDGE */
+};
+
+static nvsFixedReg _tx_mesa_fp_dst_reg[FRAG_RESULT_MAX] = {
+ NVS_FR_FRAGDATA0 /* COLR */, NVS_FR_FRAGDATA0 /* COLH */,
+ NVS_FR_UNKNOWN /* DEPR */
+};
+
+static nvsFixedReg _tx_mesa_vp_src_reg[VERT_ATTRIB_MAX] = {
+ NVS_FR_POSITION, NVS_FR_WEIGHT, NVS_FR_NORMAL, NVS_FR_COL0, NVS_FR_COL1,
+ NVS_FR_FOGCOORD, NVS_FR_UNKNOWN /* COLOR_INDEX */, NVS_FR_UNKNOWN,
+ NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3,
+ NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7,
+/* Generic attribs 0-15, aliased to the above */
+ NVS_FR_POSITION, NVS_FR_WEIGHT, NVS_FR_NORMAL, NVS_FR_COL0, NVS_FR_COL1,
+ NVS_FR_FOGCOORD, NVS_FR_UNKNOWN /* COLOR_INDEX */, NVS_FR_UNKNOWN,
+ NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3,
+ NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7
+};
+
+static nvsFixedReg _tx_mesa_fp_src_reg[FRAG_ATTRIB_MAX] = {
+ NVS_FR_POSITION, NVS_FR_COL0, NVS_FR_COL1, NVS_FR_FOGCOORD,
+ NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3,
+ NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7
+};
+
+static nvsSwzComp _tx_mesa_swizzle[4] = {
+ NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W
+};
+
+static nvsOpcode _tx_mesa_opcode[] = {
+ [OPCODE_ABS] = NVS_OP_ABS, [OPCODE_ADD] = NVS_OP_ADD,
+ [OPCODE_ARA] = NVS_OP_ARA, [OPCODE_ARL] = NVS_OP_ARL,
+ [OPCODE_ARL_NV] = NVS_OP_ARL, [OPCODE_ARR] = NVS_OP_ARR,
+ [OPCODE_CMP] = NVS_OP_CMP, [OPCODE_COS] = NVS_OP_COS,
+ [OPCODE_DDX] = NVS_OP_DDX, [OPCODE_DDY] = NVS_OP_DDY,
+ [OPCODE_DP3] = NVS_OP_DP3, [OPCODE_DP4] = NVS_OP_DP4,
+ [OPCODE_DPH] = NVS_OP_DPH, [OPCODE_DST] = NVS_OP_DST,
+ [OPCODE_EX2] = NVS_OP_EX2, [OPCODE_EXP] = NVS_OP_EXP,
+ [OPCODE_FLR] = NVS_OP_FLR, [OPCODE_FRC] = NVS_OP_FRC,
+ [OPCODE_KIL] = NVS_OP_EMUL, [OPCODE_KIL_NV] = NVS_OP_KIL,
+ [OPCODE_LG2] = NVS_OP_LG2, [OPCODE_LIT] = NVS_OP_LIT,
+ [OPCODE_LOG] = NVS_OP_LOG,
+ [OPCODE_LRP] = NVS_OP_LRP,
+ [OPCODE_MAD] = NVS_OP_MAD, [OPCODE_MAX] = NVS_OP_MAX,
+ [OPCODE_MIN] = NVS_OP_MIN, [OPCODE_MOV] = NVS_OP_MOV,
+ [OPCODE_MUL] = NVS_OP_MUL,
+ [OPCODE_PK2H] = NVS_OP_PK2H, [OPCODE_PK2US] = NVS_OP_PK2US,
+ [OPCODE_PK4B] = NVS_OP_PK4B, [OPCODE_PK4UB] = NVS_OP_PK4UB,
+ [OPCODE_POW] = NVS_OP_POW, [OPCODE_POPA] = NVS_OP_POPA,
+ [OPCODE_PUSHA] = NVS_OP_PUSHA,
+ [OPCODE_RCC] = NVS_OP_RCC, [OPCODE_RCP] = NVS_OP_RCP,
+ [OPCODE_RFL] = NVS_OP_RFL, [OPCODE_RSQ] = NVS_OP_RSQ,
+ [OPCODE_SCS] = NVS_OP_SCS, [OPCODE_SEQ] = NVS_OP_SEQ,
+ [OPCODE_SFL] = NVS_OP_SFL, [OPCODE_SGE] = NVS_OP_SGE,
+ [OPCODE_SGT] = NVS_OP_SGT, [OPCODE_SIN] = NVS_OP_SIN,
+ [OPCODE_SLE] = NVS_OP_SLE, [OPCODE_SLT] = NVS_OP_SLT,
+ [OPCODE_SNE] = NVS_OP_SNE, [OPCODE_SSG] = NVS_OP_SSG,
+ [OPCODE_STR] = NVS_OP_STR, [OPCODE_SUB] = NVS_OP_SUB,
+ [OPCODE_SWZ] = NVS_OP_MOV,
+ [OPCODE_TEX] = NVS_OP_TEX, [OPCODE_TXB] = NVS_OP_TXB,
+ [OPCODE_TXD] = NVS_OP_TXD,
+ [OPCODE_TXL] = NVS_OP_TXL, [OPCODE_TXP] = NVS_OP_TXP,
+ [OPCODE_TXP_NV] = NVS_OP_TXP,
+ [OPCODE_UP2H] = NVS_OP_UP2H, [OPCODE_UP2US] = NVS_OP_UP2US,
+ [OPCODE_UP4B] = NVS_OP_UP4B, [OPCODE_UP4UB] = NVS_OP_UP4UB,
+ [OPCODE_X2D] = NVS_OP_X2D,
+ [OPCODE_XPD] = NVS_OP_XPD
+};
+
+static nvsCond _tx_mesa_condmask[] = {
+ NVS_COND_UNKNOWN, NVS_COND_GT, NVS_COND_LT, NVS_COND_UN, NVS_COND_GE,
+ NVS_COND_LE, NVS_COND_NE, NVS_COND_NE, NVS_COND_TR, NVS_COND_FL
+};
+
+struct pass0_rec {
+ int nvs_ipos;
+ int next_temp;
+ int swzconst_done;
+ int swzconst_id;
+ nvsRegister const_half;
+};
+
+#define X NVS_SWZ_X
+#define Y NVS_SWZ_Y
+#define Z NVS_SWZ_Z
+#define W NVS_SWZ_W
+
+static void
+pass0_append_fragment(nouveauShader *nvs, nvsFragmentHeader *fragment)
+{
+ nvsFragmentList *list = calloc(1, sizeof(nvsFragmentList));
+ if (!list)
+ return;
+
+ list->fragment = fragment;
+ list->prev = nvs->list_tail;
+ if ( nvs->list_tail)
+ nvs->list_tail->next = list;
+ if (!nvs->list_head)
+ nvs->list_head = list;
+ nvs->list_tail = list;
+
+ nvs->inst_count++;
+}
+
+static void
+pass0_make_reg(nouveauShader *nvs, nvsRegister *reg,
+ nvsRegFile file, unsigned int index)
+{
+ struct pass0_rec *rec = nvs->pass_rec;
+
+ /* defaults */
+ *reg = nvr_unused;
+ /* -1 == quick-and-dirty temp alloc */
+ if (file == NVS_FILE_TEMP && index == -1) {
+ index = rec->next_temp++;
+ assert(index < NVS_MAX_TEMPS);
+ }
+ reg->file = file;
+ reg->index = index;
+}
+
+static void
+pass0_make_swizzle(nvsSwzComp *swz, unsigned int mesa)
+{
+ int i;
+
+ for (i=0;i<4;i++)
+ swz[i] = _tx_mesa_swizzle[GET_SWZ(mesa, i)];
+}
+
+static nvsOpcode
+pass0_make_opcode(enum prog_opcode op)
+{
+ if (op > MAX_OPCODE)
+ return NVS_OP_UNKNOWN;
+ return _tx_mesa_opcode[op];
+}
+
+static nvsCond
+pass0_make_condmask(GLuint mesa)
+{
+ if (mesa > COND_FL)
+ return NVS_COND_UNKNOWN;
+ return _tx_mesa_condmask[mesa];
+}
+
+static unsigned int
+pass0_make_mask(GLuint mesa_mask)
+{
+ unsigned int mask = 0;
+
+ if (mesa_mask & WRITEMASK_X) mask |= SMASK_X;
+ if (mesa_mask & WRITEMASK_Y) mask |= SMASK_Y;
+ if (mesa_mask & WRITEMASK_Z) mask |= SMASK_Z;
+ if (mesa_mask & WRITEMASK_W) mask |= SMASK_W;
+
+ return mask;
+}
+
+static nvsTexTarget
+pass0_make_tex_target(GLuint mesa)
+{
+ switch (mesa) {
+ case TEXTURE_1D_INDEX: return NVS_TEX_TARGET_1D;
+ case TEXTURE_2D_INDEX: return NVS_TEX_TARGET_2D;
+ case TEXTURE_3D_INDEX: return NVS_TEX_TARGET_3D;
+ case TEXTURE_CUBE_INDEX: return NVS_TEX_TARGET_CUBE;
+ case TEXTURE_RECT_INDEX: return NVS_TEX_TARGET_RECT;
+ default:
+ return NVS_TEX_TARGET_UNKNOWN;
+ }
+}
+
+static void
+pass0_make_dst_reg(nvsPtr nvs, nvsRegister *reg,
+ struct prog_dst_register *dst)
+{
+ struct gl_program *mesa = (struct gl_program*)&nvs->mesa.vp;
+ nvsFixedReg sfr;
+
+ switch (dst->File) {
+ case PROGRAM_OUTPUT:
+ if (mesa->Target == GL_VERTEX_PROGRAM_ARB) {
+ sfr = (dst->Index < VERT_RESULT_MAX) ?
+ _tx_mesa_vp_dst_reg[dst->Index] : NVS_FR_UNKNOWN;
+ } else {
+ sfr = (dst->Index < FRAG_RESULT_MAX) ?
+ _tx_mesa_fp_dst_reg[dst->Index] : NVS_FR_UNKNOWN;
+ }
+ pass0_make_reg(nvs, reg, NVS_FILE_RESULT, sfr);
+ break;
+ case PROGRAM_TEMPORARY:
+ pass0_make_reg(nvs, reg, NVS_FILE_TEMP, dst->Index);
+ break;
+ case PROGRAM_ADDRESS:
+ pass0_make_reg(nvs, reg, NVS_FILE_ADDRESS, dst->Index);
+ break;
+ default:
+ fprintf(stderr, "Unknown dest file %d\n", dst->File);
+ assert(0);
+ }
+}
+
+static void
+pass0_make_src_reg(nvsPtr nvs, nvsRegister *reg, struct prog_src_register *src)
+{
+ struct gl_program *mesa = (struct gl_program *)&nvs->mesa.vp.Base;
+ struct gl_program_parameter_list *p = mesa->Parameters;
+
+ *reg = nvr_unused;
+
+ switch (src->File) {
+ case PROGRAM_INPUT:
+ reg->file = NVS_FILE_ATTRIB;
+ if (mesa->Target == GL_VERTEX_PROGRAM_ARB) {
+ reg->index = (src->Index < VERT_ATTRIB_MAX) ?
+ _tx_mesa_vp_src_reg[src->Index] : NVS_FR_UNKNOWN;
+ } else {
+ reg->index = (src->Index < FRAG_ATTRIB_MAX) ?
+ _tx_mesa_fp_src_reg[src->Index] : NVS_FR_UNKNOWN;
+ }
+ break;
+ /* All const types seem to get shoved into here, not really sure why */
+ case PROGRAM_STATE_VAR:
+ switch (p->Parameters[src->Index].Type) {
+ case PROGRAM_NAMED_PARAM:
+ case PROGRAM_CONSTANT:
+ nvs->params[src->Index].source_val = NULL;
+ COPY_4V(nvs->params[src->Index].val, p->ParameterValues[src->Index]);
+ break;
+ case PROGRAM_STATE_VAR:
+ nvs->params[src->Index].source_val = p->ParameterValues[src->Index];
+ break;
+ default:
+ fprintf(stderr, "Unknown parameter type %d\n",
+ p->Parameters[src->Index].Type);
+ assert(0);
+ break;
+ }
+
+ if (src->RelAddr) {
+ reg->indexed = 1;
+ reg->addr_reg = 0;
+ reg->addr_comp = NVS_SWZ_X;
+ } else
+ reg->indexed = 0;
+ reg->file = NVS_FILE_CONST;
+ reg->index = src->Index;
+ break;
+ case PROGRAM_TEMPORARY:
+ reg->file = NVS_FILE_TEMP;
+ reg->index = src->Index;
+ break;
+ default:
+ fprintf(stderr, "Unknown source type %d\n", src->File);
+ assert(0);
+ }
+
+ /* per-component negate handled elsewhere */
+ reg->negate = src->NegateBase != 0;
+ reg->abs = src->Abs;
+ pass0_make_swizzle(reg->swizzle, src->Swizzle);
+}
+
+static nvsInstruction *
+pass0_emit(nouveauShader *nvs, nvsOpcode op, nvsRegister dst,
+ unsigned int mask, int saturate,
+ nvsRegister src0, nvsRegister src1, nvsRegister src2)
+{
+ struct pass0_rec *rec = nvs->pass_rec;
+ nvsInstruction *sif = NULL;
+
+ /* Seems mesa doesn't explicitly 0 this.. */
+ if (nvs->mesa.vp.Base.Target == GL_VERTEX_PROGRAM_ARB)
+ saturate = 0;
+
+ sif = calloc(1, sizeof(nvsInstruction));
+ if (sif) {
+ sif->header.type = NVS_INSTRUCTION;
+ sif->header.position = rec->nvs_ipos++;
+ sif->op = op;
+ sif->saturate = saturate;
+ sif->dest = dst;
+ sif->mask = mask;
+ sif->src[0] = src0;
+ sif->src[1] = src1;
+ sif->src[2] = src2;
+ sif->cond = COND_TR;
+ sif->cond_reg = 0;
+ sif->cond_test = 0;
+ sif->cond_update = 0;
+ pass0_make_swizzle(sif->cond_swizzle, SWIZZLE_NOOP);
+ pass0_append_fragment(nvs, (nvsFragmentHeader *)sif);
+ }
+
+ return sif;
+}
+
+static void
+pass0_fixup_swizzle(nvsPtr nvs,
+ struct prog_src_register *src,
+ unsigned int sm1,
+ unsigned int sm2)
+{
+ static const float sc[4] = { 1.0, 0.0, -1.0, 0.0 };
+ struct pass0_rec *rec = nvs->pass_rec;
+ int fixup_1, fixup_2;
+ nvsRegister sr, dr = nvr_unused;
+ nvsRegister sm1const, sm2const;
+
+ if (!rec->swzconst_done) {
+ struct gl_program *prog = &nvs->mesa.vp.Base;
+ rec->swzconst_id = _mesa_add_unnamed_constant(prog->Parameters, sc, 4);
+ rec->swzconst_done = 1;
+ COPY_4V(nvs->params[rec->swzconst_id].val, sc);
+ }
+
+ fixup_1 = (sm1 != MAKE_SWIZZLE4(0,0,0,0) && sm2 != MAKE_SWIZZLE4(2,2,2,2));
+ fixup_2 = (sm2 != MAKE_SWIZZLE4(2,2,2,2));
+
+ if (src->File != PROGRAM_TEMPORARY && src->File != PROGRAM_INPUT) {
+ /* We can't use more than one const in an instruction, so move the const
+ * into a temp, and swizzle from there.
+ *TODO: should just emit the swizzled const, instead of swizzling it
+ * in the shader.. would need to reswizzle any state params when they
+ * change however..
+ */
+ pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1);
+ pass0_make_src_reg(nvs, &sr, src);
+ pass0_emit(nvs, NVS_OP_MOV, dr, SMASK_ALL, 0, sr, nvr_unused, nvr_unused);
+ pass0_make_reg(nvs, &sr, NVS_FILE_TEMP, dr.index);
+ } else {
+ if (fixup_1)
+ src->NegateBase = 0;
+ pass0_make_src_reg(nvs, &sr, src);
+ pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1);
+ }
+
+ pass0_make_reg(nvs, &sm1const, NVS_FILE_CONST, rec->swzconst_id);
+ pass0_make_swizzle(sm1const.swizzle, sm1);
+ if (fixup_1 && fixup_2) {
+ /* Any combination with SWIZZLE_ONE */
+ pass0_make_reg(nvs, &sm2const, NVS_FILE_CONST, rec->swzconst_id);
+ pass0_make_swizzle(sm2const.swizzle, sm2);
+ pass0_emit(nvs, NVS_OP_MAD, dr, SMASK_ALL, 0, sr, sm1const, sm2const);
+ } else {
+ /* SWIZZLE_ZERO || arbitrary negate */
+ pass0_emit(nvs, NVS_OP_MUL, dr, SMASK_ALL, 0, sr, sm1const, nvr_unused);
+ }
+
+ src->File = PROGRAM_TEMPORARY;
+ src->Index = dr.index;
+ src->Swizzle = SWIZZLE_NOOP;
+}
+
+#define SET_SWZ(fs, cp, c) fs = (fs & ~(0x7<<(cp*3))) | (c<<(cp*3))
+static void
+pass0_check_sources(nvsPtr nvs, struct prog_instruction *inst)
+{
+ unsigned int insrc = -1, constsrc = -1;
+ int i;
+
+ for (i=0;i<_mesa_num_inst_src_regs(inst->Opcode);i++) {
+ struct prog_src_register *src = &inst->SrcReg[i];
+ unsigned int sm_1 = 0, sm_2 = 0;
+ nvsRegister sr, dr;
+ int do_mov = 0, c;
+
+ /* Build up swizzle masks as if we were going to use
+ * "MAD new, src, const1, const2" to support arbitrary negation
+ * and SWIZZLE_ZERO/SWIZZLE_ONE.
+ */
+ for (c=0;c<4;c++) {
+ if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ZERO) {
+ SET_SWZ(sm_1, c, SWIZZLE_Y); /* 0.0 */
+ SET_SWZ(sm_2, c, SWIZZLE_Y);
+ SET_SWZ(src->Swizzle, c, SWIZZLE_X);
+ } else if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ONE) {
+ SET_SWZ(sm_1, c, SWIZZLE_Y);
+ if (src->NegateBase & (1<<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, 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, NVS_OP_MOV, dr, SMASK_ALL, 0,
+ sr, nvr_unused, nvr_unused);
+
+ src->File = PROGRAM_TEMPORARY;
+ src->Index = dr.index;
+ src->Swizzle= SWIZZLE_NOOP;
+ }
+ }
+}
+
+static GLboolean
+pass0_emulate_instruction(nouveauShader *nvs, struct prog_instruction *inst)
+{
+ nvsFunc *shader = nvs->func;
+ nvsRegister src[3], dest, temp;
+ nvsInstruction *nvsinst;
+ struct pass0_rec *rec = nvs->pass_rec;
+ unsigned int mask = pass0_make_mask(inst->DstReg.WriteMask);
+ int i, sat;
+
+ sat = (inst->SaturateMode == SATURATE_ZERO_ONE);
+
+ /* Build all the "real" regs for the instruction */
+ for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++)
+ pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]);
+ if (inst->Opcode != OPCODE_KIL)
+ pass0_make_dst_reg(nvs, &dest, &inst->DstReg);
+
+ switch (inst->Opcode) {
+ case OPCODE_ABS:
+ if (shader->caps & SCAP_SRC_ABS)
+ pass0_emit(nvs, NVS_OP_MOV, dest, mask, sat,
+ nvsAbs(src[0]), nvr_unused, nvr_unused);
+ else
+ pass0_emit(nvs, NVS_OP_MAX, dest, mask, sat,
+ src[0], nvsNegate(src[0]), nvr_unused);
+ break;
+ case OPCODE_KIL:
+ /* This is only in ARB shaders, so we don't have to worry
+ * about clobbering a CC reg as they aren't supported anyway.
+ */
+ /* MOVC0 temp, src */
+ pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
+ nvsinst = pass0_emit(nvs, NVS_OP_MOV, temp, SMASK_ALL, 0,
+ src[0], nvr_unused, nvr_unused);
+ nvsinst->cond_update = 1;
+ nvsinst->cond_reg = 0;
+ /* KIL_NV (LT0.xyzw) temp */
+ nvsinst = pass0_emit(nvs, NVS_OP_KIL, nvr_unused, 0, 0,
+ nvr_unused, nvr_unused, nvr_unused);
+ nvsinst->cond = COND_LT;
+ nvsinst->cond_reg = 0;
+ nvsinst->cond_test = 1;
+ pass0_make_swizzle(nvsinst->cond_swizzle, MAKE_SWIZZLE4(0,1,2,3));
+ break;
+ case OPCODE_LIT:
+ break;
+ case OPCODE_LRP:
+ pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
+ pass0_emit(nvs, NVS_OP_MAD, temp, mask, 0,
+ nvsNegate(src[0]), src[2], src[2]);
+ pass0_emit(nvs, NVS_OP_MAD, dest, mask, sat,
+ src[0], src[1], temp);
+ break;
+ case OPCODE_POW:
+ if (shader->SupportsOpcode(shader, NVS_OP_LG2) &&
+ shader->SupportsOpcode(shader, NVS_OP_EX2)) {
+ pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
+ /* LG2 temp.x, src0.c */
+ pass0_emit(nvs, NVS_OP_LG2, temp, SMASK_X, 0,
+ nvsSwizzle(src[0], X, X, X, X),
+ nvr_unused,
+ nvr_unused);
+ /* MUL temp.x, temp.x, src1.c */
+ pass0_emit(nvs, NVS_OP_MUL, temp, SMASK_X, 0,
+ nvsSwizzle(temp, X, X, X, X),
+ nvsSwizzle(src[1], X, X, X, X),
+ nvr_unused);
+ /* EX2 dest, temp.x */
+ pass0_emit(nvs, NVS_OP_EX2, dest, mask, sat,
+ nvsSwizzle(temp, X, X, X, X),
+ nvr_unused,
+ nvr_unused);
+ } else {
+ /* can we use EXP/LOG instead of EX2/LG2?? */
+ fprintf(stderr, "Implement POW for NV20 vtxprog!\n");
+ return GL_FALSE;
+ }
+ break;
+ case OPCODE_RSQ:
+ if (rec->const_half.file != NVS_FILE_CONST) {
+ GLfloat const_half[4] = { 0.5, 0.0, 0.0, 0.0 };
+ pass0_make_reg(nvs, &rec->const_half, NVS_FILE_CONST,
+ _mesa_add_unnamed_constant(nvs->mesa.vp.Base.Parameters,
+ const_half, 4));
+ COPY_4V(nvs->params[rec->const_half.index].val, const_half);
+ }
+ pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
+ pass0_emit(nvs, NVS_OP_LG2, temp, SMASK_X, 0,
+ nvsAbs(nvsSwizzle(src[0], X, X, X, X)),
+ nvr_unused,
+ nvr_unused);
+ pass0_emit(nvs, NVS_OP_MUL, temp, SMASK_X, 0,
+ nvsSwizzle(temp, X, X, X, X),
+ nvsNegate(rec->const_half),
+ nvr_unused);
+ pass0_emit(nvs, NVS_OP_EX2, dest, mask, sat,
+ nvsSwizzle(temp, X, X, X, X),
+ nvr_unused,
+ nvr_unused);
+ break;
+ case OPCODE_SCS:
+ if (mask & SMASK_X)
+ pass0_emit(nvs, NVS_OP_COS, dest, SMASK_X, sat,
+ nvsSwizzle(src[0], X, X, X, X),
+ nvr_unused,
+ nvr_unused);
+ if (mask & SMASK_Y)
+ pass0_emit(nvs, NVS_OP_SIN, dest, SMASK_Y, sat,
+ nvsSwizzle(src[0], X, X, X, X),
+ nvr_unused,
+ nvr_unused);
+ break;
+ case OPCODE_SUB:
+ pass0_emit(nvs, NVS_OP_ADD, dest, mask, sat,
+ src[0], nvsNegate(src[1]), nvr_unused);
+ break;
+ case OPCODE_XPD:
+ pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
+ pass0_emit(nvs, NVS_OP_MUL, temp, SMASK_ALL, 0,
+ nvsSwizzle(src[0], Z, X, Y, Y),
+ nvsSwizzle(src[1], Y, Z, X, X),
+ nvr_unused);
+ pass0_emit(nvs, NVS_OP_MAD, dest, (mask & ~SMASK_W), sat,
+ nvsSwizzle(src[0], Y, Z, X, X),
+ nvsSwizzle(src[1], Z, X, Y, Y),
+ nvsNegate(temp));
+ break;
+ default:
+ fprintf(stderr, "hw doesn't support opcode \"%s\", and no emulation found\n",
+ _mesa_opcode_string(inst->Opcode));
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+static GLboolean
+pass0_translate_instructions(nouveauShader *nvs)
+{
+ struct gl_program *prog = (struct gl_program *)&nvs->mesa.vp;
+ nvsFunc *shader = nvs->func;
+ int ipos;
+
+ for (ipos=0; ipos<prog->NumInstructions; ipos++) {
+ struct prog_instruction *inst = &prog->Instructions[ipos];
+
+ if (inst->Opcode == OPCODE_END)
+ break;
+
+ /* Deal with multiple ATTRIB/PARAM in a single instruction */
+ pass0_check_sources(nvs, inst);
+
+ /* Now it's safe to do the prog_instruction->nvsInstruction conversion */
+ if (shader->SupportsOpcode(shader, pass0_make_opcode(inst->Opcode))) {
+ nvsInstruction *nvsinst;
+ nvsRegister src[3], dest;
+ int i;
+
+ for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++)
+ pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]);
+ pass0_make_dst_reg(nvs, &dest, &inst->DstReg);
+
+ nvsinst = pass0_emit(nvs,
+ pass0_make_opcode(inst->Opcode),
+ dest,
+ pass0_make_mask(inst->DstReg.WriteMask),
+ (inst->SaturateMode != SATURATE_OFF),
+ src[0], src[1], src[2]);
+ nvsinst->tex_unit = inst->TexSrcUnit;
+ nvsinst->tex_target = pass0_make_tex_target(inst->TexSrcTarget);
+ /* TODO when NV_fp/vp is implemented */
+ nvsinst->cond = COND_TR;
+ } else {
+ if (!pass0_emulate_instruction(nvs, inst))
+ return GL_FALSE;
+ }
+ }
+
+ return GL_TRUE;
+}
+
+GLboolean
+nouveau_shader_pass0_arb(GLcontext *ctx, nouveauShader *nvs)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ struct gl_program *prog = (struct gl_program*)nvs;
+ struct gl_vertex_program *vp = (struct gl_vertex_program *)prog;
+ struct gl_fragment_program *fp = (struct gl_fragment_program *)prog;
+ struct pass0_rec *rec;
+ int ret;
+
+ switch (prog->Target) {
+ case GL_VERTEX_PROGRAM_ARB:
+ nvs->func = &nmesa->VPfunc;
+ if (vp->IsPositionInvariant)
+ _mesa_insert_mvp_code(ctx, vp);
+#if 0
+ if (IS_FIXEDFUNCTION_PROG && CLIP_PLANES_USED)
+ pass0_insert_ff_clip_planes();
+#endif
+ break;
+ case GL_FRAGMENT_PROGRAM_ARB:
+ nvs->func = &nmesa->FPfunc;
+ if (fp->FogOption != GL_NONE)
+ _mesa_append_fog_code(ctx, fp);
+ break;
+ default:
+ fprintf(stderr, "Unknown program type %d", prog->Target);
+ return GL_FALSE;
+ }
+
+ rec = calloc(1, sizeof(struct pass0_rec));
+ rec->next_temp = prog->NumTemporaries;
+ nvs->pass_rec = rec;
+
+ ret = pass0_translate_instructions(nvs);
+ if (!ret) {
+ /* DESTROY list */
+ }
+
+ free(nvs->pass_rec);
+ return ret;
+}
+
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_1.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_1.c
new file mode 100644
index 0000000000..5de9017f58
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_1.c
@@ -0,0 +1,318 @@
+/*
+ * 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 "nouveau_shader.h"
+
+#define PASS1_OK 0
+#define PASS1_KILL 1
+#define PASS1_FAIL 2
+
+struct pass1_rec {
+ unsigned int temp[NVS_MAX_TEMPS];
+ unsigned int result[NVS_MAX_ATTRIBS];
+ unsigned int address[NVS_MAX_ADDRESS];
+ unsigned int cc[2];
+};
+
+static void
+pass1_remove_fragment(nvsPtr nvs, nvsFragmentList *item)
+{
+ if (item->prev) item->prev->next = item->next;
+ if (item->next) item->next->prev = item->prev;
+ if (nvs->list_head == item) nvs->list_head = item->next;
+ if (nvs->list_tail == item) nvs->list_tail = item->prev;
+
+ nvs->inst_count--;
+}
+
+static int
+pass1_result_needed(struct pass1_rec *rec, nvsInstruction *inst)
+{
+ if (inst->cond_update && rec->cc[inst->cond_reg])
+ return 1;
+ /* Only write components that are read later */
+ if (inst->dest.file == NVS_FILE_TEMP)
+ return (inst->mask & rec->temp[inst->dest.index]);
+ if (inst->dest.file == NVS_FILE_ADDRESS)
+ return (inst->mask & rec->address[inst->dest.index]);
+ /* No point writing result components that are written later */
+ if (inst->dest.file == NVS_FILE_RESULT)
+ return (inst->mask & ~rec->result[inst->dest.index]);
+ assert(0);
+}
+
+static void
+pass1_track_result(struct pass1_rec *rec, nvsInstruction *inst)
+{
+ if (inst->cond_test)
+ rec->cc[inst->cond_reg] = 1;
+ if (inst->dest.file == NVS_FILE_TEMP) {
+ inst->mask &= rec->temp[inst->dest.index];
+ } else if (inst->dest.file == NVS_FILE_RESULT) {
+ inst->mask &= ~rec->result[inst->dest.index];
+ rec->result[inst->dest.index] |= inst->mask;
+ } else if (inst->dest.file == NVS_FILE_ADDRESS) {
+ inst->mask &= rec->address[inst->dest.index];
+ }
+}
+
+static void
+pass1_track_source(nouveauShader *nvs, nvsInstruction *inst, int pos,
+ unsigned int read)
+{
+ struct pass1_rec *rec = nvs->pass_rec;
+ nvsRegister *src = &inst->src[pos];
+ unsigned int really_read = 0;
+ int i,sc;
+
+ /* Account for swizzling */
+ for (i=0; i<4; i++)
+ if (read & (1<<i)) really_read |= (1 << src->swizzle[i]);
+
+ /* Track register reads */
+ if (src->file == NVS_FILE_TEMP) {
+ if (nvs->temps[src->index].last_use == -1)
+ nvs->temps[src->index].last_use = inst->header.position;
+ rec->temp [src->index] |= really_read;
+ } else if (src->indexed) {
+ rec->address[src->addr_reg] |= (1<<src->addr_comp);
+ }
+
+ /* Modify swizzle to only access read components */
+ /* Find a component that is used.. */
+ for (sc=0;sc<4;sc++)
+ if (really_read & (1<<sc))
+ break;
+ /* Now set all unused components to that value */
+ for (i=0;i<4;i++)
+ if (!(read & (1<<i))) src->swizzle[i] = sc;
+}
+
+static int
+pass1_check_instruction(nouveauShader *nvs, nvsInstruction *inst)
+{
+ struct pass1_rec *rec = nvs->pass_rec;
+ unsigned int read0, read1, read2;
+
+ if (inst->op != NVS_OP_KIL) {
+ if (!pass1_result_needed(rec, inst))
+ return PASS1_KILL;
+ }
+ pass1_track_result(rec, inst);
+
+ read0 = read1 = read2 = 0;
+
+ switch (inst->op) {
+ case NVS_OP_FLR:
+ case NVS_OP_FRC:
+ case NVS_OP_MOV:
+ case NVS_OP_SSG:
+ case NVS_OP_ARL:
+ read0 = inst->mask;
+ break;
+ case NVS_OP_ADD:
+ case NVS_OP_MAX:
+ case NVS_OP_MIN:
+ case NVS_OP_MUL:
+ case NVS_OP_SEQ:
+ case NVS_OP_SFL:
+ case NVS_OP_SGE:
+ case NVS_OP_SGT:
+ case NVS_OP_SLE:
+ case NVS_OP_SLT:
+ case NVS_OP_SNE:
+ case NVS_OP_STR:
+ case NVS_OP_SUB:
+ read0 = inst->mask;
+ read1 = inst->mask;
+ break;
+ case NVS_OP_CMP:
+ case NVS_OP_LRP:
+ case NVS_OP_MAD:
+ read0 = inst->mask;
+ read1 = inst->mask;
+ read2 = inst->mask;
+ break;
+ case NVS_OP_XPD:
+ if (inst->mask & SMASK_X) read0 |= SMASK_Y|SMASK_Z;
+ if (inst->mask & SMASK_Y) read0 |= SMASK_X|SMASK_Z;
+ if (inst->mask & SMASK_Z) read0 |= SMASK_X|SMASK_Y;
+ read1 = read0;
+ break;
+ case NVS_OP_COS:
+ case NVS_OP_EX2:
+ case NVS_OP_EXP:
+ case NVS_OP_LG2:
+ case NVS_OP_LOG:
+ case NVS_OP_RCC:
+ case NVS_OP_RCP:
+ case NVS_OP_RSQ:
+ case NVS_OP_SCS:
+ case NVS_OP_SIN:
+ read0 = SMASK_X;
+ break;
+ case NVS_OP_POW:
+ read0 = SMASK_X;
+ read1 = SMASK_X;
+ break;
+ case NVS_OP_DIV:
+ read0 = inst->mask;
+ read1 = SMASK_X;
+ break;
+ case NVS_OP_DP2:
+ read0 = SMASK_X|SMASK_Y;
+ read1 = SMASK_X|SMASK_Y;
+ break;
+ case NVS_OP_DP3:
+ case NVS_OP_RFL:
+ read0 = SMASK_X|SMASK_Y|SMASK_Z;
+ read1 = SMASK_X|SMASK_Y|SMASK_Z;
+ break;
+ case NVS_OP_DP4:
+ read0 = SMASK_ALL;
+ read1 = SMASK_ALL;
+ break;
+ case NVS_OP_DPH:
+ read0 = SMASK_X|SMASK_Y|SMASK_Z;
+ read1 = SMASK_ALL;
+ break;
+ case NVS_OP_DST:
+ if (inst->mask & SMASK_Y) read0 = read1 = SMASK_Y;
+ if (inst->mask & SMASK_Z) read0 |= SMASK_Z;
+ if (inst->mask & SMASK_W) read1 |= SMASK_W;
+ break;
+ case NVS_OP_NRM:
+ read0 = SMASK_X|SMASK_Y|SMASK_Z;
+ break;
+ case NVS_OP_PK2H:
+ case NVS_OP_PK2US:
+ read0 = SMASK_X|SMASK_Y;
+ break;
+ case NVS_OP_DDX:
+ case NVS_OP_DDY:
+ case NVS_OP_UP2H:
+ case NVS_OP_UP2US:
+ case NVS_OP_PK4B:
+ case NVS_OP_PK4UB:
+ case NVS_OP_UP4B:
+ case NVS_OP_UP4UB:
+ read0 = SMASK_ALL;
+ break;
+ case NVS_OP_X2D:
+ read1 = SMASK_X|SMASK_Y;
+ if (inst->mask & (SMASK_X|SMASK_Z)) {
+ read0 |= SMASK_X;
+ read2 |= SMASK_X|SMASK_Y;
+ }
+ if (inst->mask & (SMASK_Y|SMASK_W)) {
+ read0 |= SMASK_Y;
+ read2 |= SMASK_Z|SMASK_W;
+ }
+ break;
+ case NVS_OP_LIT:
+ read0 |= SMASK_X|SMASK_Y|SMASK_W;
+ break;
+ case NVS_OP_TEX:
+ case NVS_OP_TXP:
+ case NVS_OP_TXL:
+ case NVS_OP_TXB:
+ read0 = SMASK_ALL;
+ break;
+ case NVS_OP_TXD:
+ read0 = SMASK_ALL;
+ read1 = SMASK_ALL;
+ read2 = SMASK_ALL;
+ break;
+ case NVS_OP_KIL:
+ break;
+ default:
+ fprintf(stderr, "Unknown sop=%d", inst->op);
+ return PASS1_FAIL;
+ }
+
+ /* Any values that are written by this inst can't have been read further up */
+ if (inst->dest.file == NVS_FILE_TEMP)
+ rec->temp[inst->dest.index] &= ~inst->mask;
+
+ if (read0) pass1_track_source(nvs, inst, 0, read0);
+ if (read1) pass1_track_source(nvs, inst, 1, read1);
+ if (read2) pass1_track_source(nvs, inst, 2, read2);
+
+ return PASS1_OK;
+}
+
+/* Some basic dead code elimination
+ * - Remove unused instructions
+ * - Don't write unused register components
+ * - Modify swizzles to not reference unneeded components.
+ */
+GLboolean
+nouveau_shader_pass1(nvsPtr nvs)
+{
+ nvsFragmentList *list = nvs->list_tail;
+ int i;
+
+ for (i=0; i<NVS_MAX_TEMPS; i++)
+ nvs->temps[i].last_use = -1;
+
+ nvs->pass_rec = calloc(1, sizeof(struct pass1_rec));
+
+ while (list) {
+ assert(list->fragment->type == NVS_INSTRUCTION);
+
+ switch(pass1_check_instruction(nvs, (nvsInstruction *)list->fragment)) {
+ case PASS1_OK:
+ break;
+ case PASS1_KILL:
+ pass1_remove_fragment(nvs, list);
+ break;
+ case PASS1_FAIL:
+ default:
+ free(nvs->pass_rec);
+ nvs->pass_rec = NULL;
+ return GL_FALSE;
+ }
+
+ list = list->prev;
+ }
+
+ free(nvs->pass_rec);
+ nvs->pass_rec = NULL;
+
+ return GL_TRUE;
+}
+
+
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c
new file mode 100644
index 0000000000..2177413b66
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c
@@ -0,0 +1,243 @@
+/*
+ * 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 "program.h"
+
+#include "nouveau_context.h"
+#include "nouveau_shader.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 void
+pass2_free_hw_temp(nvsPtr nvs, int reg)
+{
+ struct pass2_rec *rec = nvs->pass_rec;
+ rec->hw_temps[reg] = 0;
+}
+
+static nvsRegister
+pass2_mangle_reg(nvsPtr nvs, nvsInstruction *inst, nvsRegister reg)
+{
+ struct pass2_rec *rec = nvs->pass_rec;
+
+ if (reg.file == NVS_FILE_TEMP) {
+ int hwidx;
+
+ if (rec->temps[reg.index] == -1)
+ rec->temps[reg.index] = pass2_alloc_hw_temp(nvs);
+ hwidx = rec->temps[reg.index];
+
+ if (nvs->temps[reg.index].last_use <= inst->header.position)
+ pass2_free_hw_temp(nvs, hwidx);
+
+ reg.index = hwidx;
+ }
+
+ 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]);
+ if (reg.file == NVS_FILE_ATTRIB)
+ nvs->inputs_read |= (1 << reg.index);
+ 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);
+ if (reg.file == NVS_FILE_RESULT)
+ nvs->outputs_written |= (1 << reg.index);
+ shader->SetResult(shader, &reg, inst->mask, slot);
+}
+
+static int
+pass2_assemble_instruction(nvsPtr nvs, nvsInstruction *inst, int last)
+{
+ nvsFunc *shader = nvs->func;
+ struct _op_xlat *op;
+ unsigned int hw_inst[8];
+ int slot;
+ int instsz;
+ int i;
+
+ shader->inst = hw_inst;
+
+ /* Assemble this instruction */
+ if (!(op = shader->GetOPTXFromSOP(inst->op, &slot)))
+ return 0;
+ shader->InitInstruction(shader);
+ pass2_add_instruction(nvs, inst, op, slot);
+ if (last)
+ shader->SetLastInst(shader);
+
+ instsz = shader->GetOffsetNext(nvs->func);
+ if (nvs->program_size + instsz >= nvs->program_alloc_size) {
+ nvs->program_alloc_size *= 2;
+ nvs->program = realloc(nvs->program,
+ nvs->program_alloc_size * sizeof(uint32_t));
+ }
+
+ for (i=0; i<instsz; i++)
+ nvs->program[nvs->program_current++] = hw_inst[i];
+ nvs->program_size = nvs->program_current;
+ return 1;
+}
+
+/* Translate program into hardware format */
+GLboolean
+nouveau_shader_pass2(nvsPtr nvs)
+{
+ nvsFragmentList *list = nvs->list_head;
+ struct pass2_rec *rec;
+ int i;
+
+ 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->inst_count * 4;
+ nvs->program = calloc(nvs->program_alloc_size, sizeof(uint32_t));
+ nvs->program_size = 0;
+ nvs->program_current = 0;
+
+ while (list) {
+ assert(list->fragment->type == NVS_INSTRUCTION);
+
+ if (!pass2_assemble_instruction(nvs, (nvsInstruction *)list->fragment, list->next ? 0 : 1)) {
+ free(nvs->program);
+ nvs->program = NULL;
+ return GL_FALSE;
+ }
+
+ list = list->next;
+ }
+
+ /* 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/src/mesa/drivers/dri/nouveau/nouveau_span.c b/src/mesa/drivers/dri/nouveau/nouveau_span.c
new file mode 100644
index 0000000000..74dec66afc
--- /dev/null
+++ b/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/src/mesa/drivers/dri/nouveau/nouveau_span.h b/src/mesa/drivers/dri/nouveau/nouveau_span.h
new file mode 100644
index 0000000000..bc39ecd17b
--- /dev/null
+++ b/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/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c
new file mode 100644
index 0000000000..8d3c018dff
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c
@@ -0,0 +1,341 @@
+/**************************************************************************
+
+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:
+ case NV_04:
+ case NV_05:
+ /* No TCL engines for these ones */
+ 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:
+ case NV_50:
+ nv30InitStateFuncs(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/src/mesa/drivers/dri/nouveau/nouveau_state.h b/src/mesa/drivers/dri/nouveau/nouveau_state.h
new file mode 100644
index 0000000000..16d63a6ac2
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_state.h
@@ -0,0 +1,48 @@
+/**************************************************************************
+
+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 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 nouveauInitState(GLcontext *ctx);
+
+/*
+extern void nouveauDDUpdateState(GLcontext *ctx);
+extern void nouveauDDUpdateHWState(GLcontext *ctx);
+
+extern void nouveauEmitHwStateLocked(nouveauContextPtr nmesa);
+*/
+#endif
+
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state_cache.c b/src/mesa/drivers/dri/nouveau/nouveau_state_cache.c
new file mode 100644
index 0000000000..cb4b9d3027
--- /dev/null
+++ b/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/src/mesa/drivers/dri/nouveau/nouveau_state_cache.h b/src/mesa/drivers/dri/nouveau/nouveau_state_cache.h
new file mode 100644
index 0000000000..5f9d426450
--- /dev/null
+++ b/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/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c b/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c
new file mode 100644
index 0000000000..f5c92a1b4e
--- /dev/null
+++ b/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/src/mesa/drivers/dri/nouveau/nouveau_swtcl.h b/src/mesa/drivers/dri/nouveau/nouveau_swtcl.h
new file mode 100644
index 0000000000..ba4d8725a6
--- /dev/null
+++ b/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/src/mesa/drivers/dri/nouveau/nouveau_sync.c b/src/mesa/drivers/dri/nouveau/nouveau_sync.c
new file mode 100644
index 0000000000..0bf20e723b
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.c
@@ -0,0 +1,136 @@
+#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)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nouveau_notifier *notifier;
+
+ notifier = CALLOC_STRUCT(nouveau_notifier_t);
+ if (!notifier)
+ return NULL;
+
+ notifier->mem = nouveau_mem_alloc(ctx,
+ NOUVEAU_MEM_FB | NOUVEAU_MEM_MAPPED,
+ 32,
+ 0);
+ if (!notifier->mem) {
+ FREE(notifier);
+ return NULL;
+ }
+
+ if (!nouveauCreateDmaObject(nmesa, handle, notifier->mem->offset,
+ notifier->mem->size,
+ 0 /* NV_DMA_TARGET_FB */,
+ 0 /* NV_DMA_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)
+{
+ volatile GLuint *n = notifier->mem->map;
+
+ 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);
+}
+
+GLboolean
+nouveau_notifier_wait_status(nouveau_notifier *notifier, GLuint status,
+ GLuint timeout)
+{
+ volatile GLuint *n = notifier->mem->map;
+ unsigned int time = 0;
+
+ 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] &
+ 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);
+
+ 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,
+ 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);
+
+ nmesa->syncNotifier = nouveau_notifier_new(ctx, NvSyncNotify);
+ 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/src/mesa/drivers/dri/nouveau/nouveau_sync.h b/src/mesa/drivers/dri/nouveau/nouveau_sync.h
new file mode 100644
index 0000000000..d9e3d4b80c
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.h
@@ -0,0 +1,36 @@
+#ifndef __NOUVEAU_SYNC_H__
+#define __NOUVEAU_SYNC_H__
+
+#include "nouveau_buffers.h"
+
+#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);
+extern void nouveau_notifier_destroy(GLcontext *, nouveau_notifier *);
+extern void nouveau_notifier_reset(nouveau_notifier *);
+extern GLboolean nouveau_notifier_wait_status(nouveau_notifier *r,
+ 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/src/mesa/drivers/dri/nouveau/nouveau_tex.c b/src/mesa/drivers/dri/nouveau/nouveau_tex.c
new file mode 100644
index 0000000000..0a8d279669
--- /dev/null
+++ b/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/src/mesa/drivers/dri/nouveau/nouveau_tex.h b/src/mesa/drivers/dri/nouveau/nouveau_tex.h
new file mode 100644
index 0000000000..7ac71f8300
--- /dev/null
+++ b/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/src/mesa/drivers/dri/nouveau/nv04_swtcl.c b/src/mesa/drivers/dri/nouveau/nv04_swtcl.c
new file mode 100644
index 0000000000..f31c0d692d
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nv04_swtcl.c
@@ -0,0 +1,570 @@
+/*
+ * 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);
+}
+
+/**********************************************************************/
+/* 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 nv04ChooseRenderState(GLcontext *ctx)
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+
+ tnl->Driver.Render.PrimTabVerts = nv04_render_tab_verts;
+ tnl->Driver.Render.PrimTabElts = nv04_render_tab_elts;
+ tnl->Driver.Render.ClippedLine = NULL;
+ tnl->Driver.Render.ClippedPolygon = NULL;
+}
+
+
+
+static inline void nv04OutputVertexFormat(struct nouveau_context* nmesa)
+{
+ GLcontext* ctx=nmesa->glCtx;
+ DECLARE_RENDERINPUTS(index);
+
+ /*
+ * Tell t_vertex about the vertex format
+ */
+ RENDERINPUTS_COPY(index, nmesa->render_inputs_bitset);
+
+ // SX SY SZ INVW
+ // FIXME : we use W instead of INVW, but since W=1 it doesn't matter
+ if (RENDERINPUTS_TEST(index, _TNL_ATTRIB_POS))
+ EMIT_ATTR(_TNL_ATTRIB_POS,EMIT_4F_VIEWPORT);
+ else
+ EMIT_PAD(4*sizeof(float));
+
+ // COLOR
+ if (RENDERINPUTS_TEST(index, _TNL_ATTRIB_COLOR0))
+ EMIT_ATTR(_TNL_ATTRIB_COLOR0,EMIT_4UB_4F_ABGR);
+ else
+ EMIT_PAD(4);
+
+ // SPECULAR
+ if (RENDERINPUTS_TEST(index, _TNL_ATTRIB_COLOR1))
+ EMIT_ATTR(_TNL_ATTRIB_COLOR1,EMIT_4UB_4F_ABGR);
+ else
+ EMIT_PAD(4);
+
+ // TEXTURE
+ if (RENDERINPUTS_TEST(index, _TNL_ATTRIB_TEX0))
+ EMIT_ATTR(_TNL_ATTRIB_TEX0,EMIT_2F);
+ else
+ EMIT_PAD(2*sizeof(float));
+
+ nmesa->vertex_size=_tnl_install_attrs( ctx,
+ nmesa->vertex_attrs,
+ nmesa->vertex_attr_count,
+ ctx->Viewport._WindowMap.m, 0 );
+}
+
+
+static void nv04ChooseVertexState( GLcontext *ctx )
+{
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ DECLARE_RENDERINPUTS(index);
+
+ RENDERINPUTS_COPY(index, tnl->render_inputs_bitset);
+ if (!RENDERINPUTS_EQUAL(index, nmesa->render_inputs_bitset))
+ {
+ RENDERINPUTS_COPY(nmesa->render_inputs_bitset, index);
+ nv04OutputVertexFormat(nmesa);
+ }
+}
+
+
+/**********************************************************************/
+/* High level hooks for t_vb_render.c */
+/**********************************************************************/
+
+
+static void nv04RenderStart(GLcontext *ctx)
+{
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+
+ if (nmesa->new_state) {
+ nmesa->new_render_state |= nmesa->new_state;
+ }
+
+ if (nmesa->new_render_state) {
+ nv04ChooseVertexState(ctx);
+ nv04ChooseRenderState(ctx);
+ nmesa->new_render_state = 0;
+ }
+}
+
+static void nv04RenderFinish(GLcontext *ctx)
+{
+}
+
+
+/* System to flush dma and emit state changes based on the rasterized
+ * primitive.
+ */
+void nv04RasterPrimitive(GLcontext *ctx,
+ GLenum glprim,
+ GLuint hwprim)
+{
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+
+ assert (!nmesa->new_state);
+
+ if (hwprim != nmesa->current_primitive)
+ {
+ nmesa->current_primitive=hwprim;
+
+ }
+}
+
+static const GLuint hw_prim[GL_POLYGON+1] = {
+ GL_POINTS+1,
+ GL_LINES+1,
+ GL_LINE_STRIP+1,
+ GL_LINE_LOOP+1,
+ GL_TRIANGLES+1,
+ GL_TRIANGLE_STRIP+1,
+ GL_TRIANGLE_FAN+1,
+ GL_QUADS+1,
+ GL_QUAD_STRIP+1,
+ GL_POLYGON+1
+};
+
+/* Callback for mesa:
+ */
+static void nv04RenderPrimitive( GLcontext *ctx, GLuint prim )
+{
+ nv04RasterPrimitive( ctx, prim, hw_prim[prim] );
+}
+
+static void nv04ResetLineStipple( GLcontext *ctx )
+{
+ /* FIXME do something here */
+ WARN_ONCE("Unimplemented nv04ResetLineStipple\n");
+}
+
+
+/**********************************************************************/
+/* Initialization. */
+/**********************************************************************/
+
+void nv04TriInitFunctions(GLcontext *ctx)
+{
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+
+ tnl->Driver.RunPipeline = nouveauRunPipeline;
+ tnl->Driver.Render.Start = nv04RenderStart;
+ tnl->Driver.Render.Finish = nv04RenderFinish;
+ tnl->Driver.Render.PrimitiveNotify = nv04RenderPrimitive;
+ tnl->Driver.Render.ResetLineStipple = nv04ResetLineStipple;
+ tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
+ tnl->Driver.Render.CopyPV = _tnl_copy_pv;
+ tnl->Driver.Render.Interp = _tnl_interp;
+
+ _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12, 32 );
+
+ nmesa->verts = (GLubyte *)tnl->clipspace.vertex_buf;
+}
+
+
diff --git a/src/mesa/drivers/dri/nouveau/nv04_swtcl.h b/src/mesa/drivers/dri/nouveau/nv04_swtcl.h
new file mode 100644
index 0000000000..42dde5383e
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nv04_swtcl.h
@@ -0,0 +1,12 @@
+#ifndef __NV04_SWTCL_H__
+#define __NV04_SWTCL_H__
+
+#include "mtypes.h"
+
+extern void nv04Fallback( GLcontext *ctx, GLuint bit, GLboolean mode );
+extern void nv04FinishPrimitive(struct nouveau_context *nmesa);
+extern void nv04TriInitFunctions(GLcontext *ctx);
+#define FALLBACK( nmesa, bit, mode ) nouveauFallback( nmesa->glCtx, bit, mode )
+
+#endif /* __NV04_SWTCL_H__ */
+
diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c
new file mode 100644
index 0000000000..0e912e73ff
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nv10_state.c
@@ -0,0 +1,746 @@
+/**************************************************************************
+
+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 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)
+{
+ /* FIXME: check if 16 or 24/32 bits depth buffer */
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nmesa->clear_value=((nmesa->clear_value&0x000000FF)|(((uint32_t)(d*0xFFFFFF))<<8));
+}
+
+static void nv10ClearStencil(GLcontext *ctx, GLint s)
+{
+ /* FIXME: not valid for 16 bits depth buffer (0 stencil bits) */
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nmesa->clear_value=((nmesa->clear_value&0xFFFFFF00)|(s&0x000000FF));
+}
+
+static void nv10ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation)
+{
+ 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);
+ BEGIN_RING_CACHE(NvSub3D, NV10_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 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_CACHE(NvSub3D,
+ NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 2);
+ OUT_RING_CACHE(((w+x) << 16) | x | 0x800);
+ OUT_RING_CACHE(((h+y) << 16) | y | 0x800);
+ for (i=1; i<7; i++) {
+ BEGIN_RING_CACHE(NvSub3D,
+ NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 1);
+ OUT_RING_CACHE(0);
+ BEGIN_RING_CACHE(NvSub3D,
+ NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(i), 1);
+ OUT_RING_CACHE(0);
+ }
+
+ /* viewport transform */
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X, 4);
+ OUT_RING_CACHEf ((GLfloat) x);
+ OUT_RING_CACHEf ((GLfloat) (y+h));
+ OUT_RING_CACHEf (0.0);
+ OUT_RING_CACHEf (0.0);
+
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X, 4);
+ OUT_RING_CACHEf ((((GLfloat) w) * 0.5) - 2048.0);
+ OUT_RING_CACHEf ((((GLfloat) h) * 0.5) - 2048.0);
+ OUT_RING_CACHEf (16777215.0 * 0.5);
+ OUT_RING_CACHEf (0.0);
+}
+
+/* Initialise any card-specific non-GL related state */
+static GLboolean nv10InitCard(nouveauContextPtr nmesa)
+{
+ nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D);
+
+ BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY0, 2);
+ OUT_RING(NvDmaFB); /* 184 dma_in_memory0 */
+ OUT_RING(NvDmaFB); /* 188 dma_in_memory1 */
+ BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY2, 2);
+ OUT_RING(NvDmaFB); /* 194 dma_in_memory2 */
+ OUT_RING(NvDmaFB); /* 198 dma_in_memory3 */
+
+ BEGIN_RING_SIZE(NvSub3D, 0x02b4, 1);
+ OUT_RING(0);
+ BEGIN_RING_SIZE(NvSub3D, 0x0290, 1);
+ OUT_RING(0x00100001);
+ BEGIN_RING_SIZE(NvSub3D, 0x03f4, 1);
+ OUT_RING(0);
+
+ return GL_FALSE;
+}
+
+/* Update buffer offset/pitch/format */
+static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color,
+ nouveau_renderbuffer **color,
+ nouveau_renderbuffer *depth)
+{
+ GLuint x, y, w, h;
+ GLuint pitch, format;
+
+ w = color[0]->mesa.Width;
+ h = color[0]->mesa.Height;
+ x = nmesa->drawX;
+ y = nmesa->drawY;
+
+ if (num_color != 1)
+ return GL_FALSE;
+
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 6);
+ OUT_RING_CACHE((w << 16) | x);
+ OUT_RING_CACHE((h << 16) | y);
+ pitch = color[0]->pitch;
+ if (depth) {
+ pitch |= (depth->pitch << 16);
+ }
+ format = 0x108;
+ if (color[0]->mesa._ActualFormat != GL_RGBA8) {
+ format = 0x103; /* R5G6B5 color buffer */
+ }
+ OUT_RING(format);
+ OUT_RING(pitch);
+ OUT_RING(color[0]->offset);
+ OUT_RING(depth ? depth->offset : color[0]->offset);
+
+ return GL_TRUE;
+}
+
+void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func)
+{
+ 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/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c
new file mode 100644
index 0000000000..12b277de45
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c
@@ -0,0 +1,569 @@
+/*
+ * 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, G70 */
+
+#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);
+ }
+ 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 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 = NULL;
+ tnl->Driver.Render.ClippedPolygon = NULL;
+}
+
+
+
+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
+ };
+
+ 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_40) {
+ /* Ensure passthrough shader is being used, and mvp matrix
+ * is up to date
+ */
+ nvsUpdateShader(ctx, nmesa->passthrough_vp);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_IN_REG, 2);
+ OUT_RING_CACHE (0xff09); /*IN : POS, COL, TC0-7 */
+ OUT_RING_CACHE (0x3fc001); /*OUT: COL, TC0-7, POS implied */
+
+ /* Update texenv shader / user fragprog */
+ nvsUpdateShader(ctx, (nouveauShader*)ctx->FragmentProgram._Current);
+ }
+}
+
+
+/**********************************************************************/
+/* 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/src/mesa/drivers/dri/nouveau/nv10_swtcl.h b/src/mesa/drivers/dri/nouveau/nv10_swtcl.h
new file mode 100644
index 0000000000..7c854addd2
--- /dev/null
+++ b/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/src/mesa/drivers/dri/nouveau/nv20_shader.h b/src/mesa/drivers/dri/nouveau/nv20_shader.h
new file mode 100644
index 0000000000..7d2e29db66
--- /dev/null
+++ b/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/src/mesa/drivers/dri/nouveau/nv20_state.c b/src/mesa/drivers/dri/nouveau/nv20_state.c
new file mode 100644
index 0000000000..8e38d6eba0
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nv20_state.c
@@ -0,0 +1,662 @@
+/**************************************************************************
+
+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); /* NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC */
+ OUT_RING_CACHE(ubRef); /* NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF */
+}
+
+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 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:
+// 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 */
+void (*PolygonOffset)(GLcontext *ctx, GLfloat factor, GLfloat units);
+/** Set the polygon stippling pattern */
+void (*PolygonStipple)(GLcontext *ctx, const GLubyte *mask );
+/* 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)
+{
+}
+
+/** 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);
+void (*TextureMatrix)(GLcontext *ctx, GLuint unit, const GLmatrix *mat);
+
+/** Set the viewport */
+static void nv20Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+{
+ /* TODO: Where do the VIEWPORT_XFRM_* regs come in? */
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2);
+ OUT_RING_CACHE((w << 16) | x);
+ OUT_RING_CACHE((h << 16) | y);
+}
+
+/* Initialise any card-specific non-GL related state */
+static GLboolean nv20InitCard(nouveauContextPtr nmesa)
+{
+ return GL_TRUE;
+}
+
+/* Update buffer offset/pitch/format */
+static GLboolean nv20BindBuffers(nouveauContextPtr nmesa, int num_color,
+ nouveau_renderbuffer **color,
+ nouveau_renderbuffer *depth)
+{
+ return GL_TRUE;
+}
+
+/* Update anything that depends on the window position/size */
+static void nv20WindowMoved(nouveauContextPtr nmesa)
+{
+}
+
+void nv20InitStateFuncs(GLcontext *ctx, struct dd_function_table *func)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ nmesa->hw_func.InitCard = nv20InitCard;
+ nmesa->hw_func.BindBuffers = nv20BindBuffers;
+ nmesa->hw_func.WindowMoved = nv20WindowMoved;
+
+ func->AlphaFunc = nv20AlphaFunc;
+ func->BlendColor = nv20BlendColor;
+ func->BlendEquationSeparate = nv20BlendEquationSeparate;
+ func->BlendFuncSeparate = nv20BlendFuncSeparate;
+ func->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;
+#if 0
+ func->PolygonOffset = nv20PolygonOffset;
+ func->PolygonStipple = nv20PolygonStipple;
+ func->ReadBuffer = nv20ReadBuffer;
+ func->RenderMode = nv20RenderMode;
+#endif
+ func->Scissor = nv20Scissor;
+ func->ShadeModel = nv20ShadeModel;
+ func->StencilFuncSeparate = nv20StencilFuncSeparate;
+ func->StencilMaskSeparate = nv20StencilMaskSeparate;
+ func->StencilOpSeparate = nv20StencilOpSeparate;
+#if 0
+ func->TexGen = nv20TexGen;
+ func->TexParameter = nv20TexParameter;
+ func->TextureMatrix = nv20TextureMatrix;
+#endif
+ func->Viewport = nv20Viewport;
+}
+
diff --git a/src/mesa/drivers/dri/nouveau/nv20_vertprog.c b/src/mesa/drivers/dri/nouveau/nv20_vertprog.c
new file mode 100644
index 0000000000..60cfcd7056
--- /dev/null
+++ b/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/src/mesa/drivers/dri/nouveau/nv30_fragprog.c b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c
new file mode 100644
index 0000000000..cd7c955c9e
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c
@@ -0,0 +1,716 @@
+#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);
+ 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 */
+ ctx->Driver.BufferData(ctx, GL_ARRAY_BUFFER_ARB,
+ nvs->program_size * sizeof(uint32_t),
+ (const GLvoid *)nvs->program,
+ GL_DYNAMIC_DRAW_ARB,
+ nvs->program_buffer);
+
+ offset = nouveau_bufferobj_gpu_ref(ctx, GL_READ_ONLY_ARB,
+ nvs->program_buffer);
+
+ /* 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);
+}
+
+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)
+{
+ 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
+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;
+ }
+ 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);
+ 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/src/mesa/drivers/dri/nouveau/nv30_shader.h b/src/mesa/drivers/dri/nouveau/nv30_shader.h
new file mode 100644
index 0000000000..7a027dd427
--- /dev/null
+++ b/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/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c
new file mode 100644
index 0000000000..4d79bb6127
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nv30_state.c
@@ -0,0 +1,901 @@
+/**************************************************************************
+
+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);
+ 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:
+ 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:
+ 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;
+
+ CLAMPED_FLOAT_TO_UBYTE(ubWidth, width);
+
+ 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);
+ 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)
+{
+ /* Need some love.. */
+ return GL_FALSE;
+}
+
+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);
+
+ BEGIN_RING_SIZE(NvSub3D, 0x1d60, 1);
+ OUT_RING(0x03008000);
+
+ 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);
+ OUT_RING (color[0]->pitch);
+ OUT_RING (color[0]->offset);
+
+ if (depth) {
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_OFFSET, 1);
+ OUT_RING (depth->offset);
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH, 1);
+ OUT_RING (depth->pitch);
+ }
+
+ return GL_TRUE;
+}
+
+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->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/src/mesa/drivers/dri/nouveau/nv30_vertprog.c b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c
new file mode 100644
index 0000000000..6ba8e35d55
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c
@@ -0,0 +1,353 @@
+#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);
+}
+
+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
+ */
+
+/*****************************************************************************
+ * 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;
+}
+
diff --git a/src/mesa/drivers/dri/nouveau/nv40_fragprog.c b/src/mesa/drivers/dri/nouveau/nv40_fragprog.c
new file mode 100644
index 0000000000..3d58d6b666
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nv40_fragprog.c
@@ -0,0 +1,152 @@
+#include "nouveau_shader.h"
+#include "nv40_shader.h"
+
+/* branching ops */
+unsigned int NVFP_TX_BOP_COUNT = 5;
+struct _op_xlat NVFP_TX_BOP[64];
+
+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);
+
+ /* 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;
+}
diff --git a/src/mesa/drivers/dri/nouveau/nv40_shader.h b/src/mesa/drivers/dri/nouveau/nv40_shader.h
new file mode 100644
index 0000000000..2a2b5639b6
--- /dev/null
+++ b/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_SRC_SCALE_SHIFT 28
+#define NV40_FP_OP_SRC_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/src/mesa/drivers/dri/nouveau/nv40_vertprog.c b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c
new file mode 100644
index 0000000000..0493e18403
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c
@@ -0,0 +1,685 @@
+#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);
+}
+
+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) {
+ int hwidx;
+
+ switch (dest->index) {
+ case NVS_FR_POSITION : hwidx = NV40_VP_INST_DEST_POS; break;
+ case NVS_FR_COL0 : hwidx = NV40_VP_INST_DEST_COL0; break;
+ case NVS_FR_COL1 : hwidx = NV40_VP_INST_DEST_COL1; break;
+ case NVS_FR_BFC0 : hwidx = NV40_VP_INST_DEST_BFC0; break;
+ case NVS_FR_BFC1 : hwidx = NV40_VP_INST_DEST_BFC1; break;
+ case NVS_FR_FOGCOORD : hwidx = NV40_VP_INST_DEST_FOGC; break;
+ case NVS_FR_POINTSZ : hwidx = NV40_VP_INST_DEST_PSZ; break;
+ case NVS_FR_TEXCOORD0: hwidx = NV40_VP_INST_DEST_TC(0); break;
+ case NVS_FR_TEXCOORD1: hwidx = NV40_VP_INST_DEST_TC(1); break;
+ case NVS_FR_TEXCOORD2: hwidx = NV40_VP_INST_DEST_TC(2); break;
+ case NVS_FR_TEXCOORD3: hwidx = NV40_VP_INST_DEST_TC(3); break;
+ case NVS_FR_TEXCOORD4: hwidx = NV40_VP_INST_DEST_TC(4); break;
+ case NVS_FR_TEXCOORD5: hwidx = NV40_VP_INST_DEST_TC(5); break;
+ case NVS_FR_TEXCOORD6: hwidx = NV40_VP_INST_DEST_TC(6); break;
+ case NVS_FR_TEXCOORD7: hwidx = NV40_VP_INST_DEST_TC(7); break;
+ default:
+ WARN_ONCE("unknown vtxprog output %d\n", dest->index);
+ hwidx = 0;
+ break;
+ }
+ 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);
+ 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
+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->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/src/mesa/drivers/dri/r128/r128_span.c b/src/mesa/drivers/dri/r128/r128_span.c
index 25e57133cc..85798c1601 100644
--- a/src/mesa/drivers/dri/r128/r128_span.c
+++ b/src/mesa/drivers/dri/r128/r128_span.c
@@ -209,7 +209,7 @@ do { \
*/
#define WRITE_DEPTH_SPAN() \
do { \
- GLint buf[n]; \
+ GLuint buf[n]; \
GLint i; \
GLuint *readbuf = (GLuint *)((GLubyte *)sPriv->pFB + \
r128scrn->spanOffset); \
@@ -228,7 +228,7 @@ do { \
#define WRITE_DEPTH_PIXELS() \
do { \
- GLint buf[n]; \
+ GLuint buf[n]; \
GLint ox[MAX_WIDTH]; \
GLint oy[MAX_WIDTH]; \
GLuint *readbuf = (GLuint *)((GLubyte *)sPriv->pFB + \
@@ -309,7 +309,7 @@ do { \
*/
#define WRITE_STENCIL_SPAN() \
do { \
- GLint buf[n]; \
+ GLuint buf[n]; \
GLint i; \
GLuint *readbuf = (GLuint *)((GLubyte *)sPriv->pFB + \
r128scrn->spanOffset); \
@@ -328,7 +328,7 @@ do { \
#define WRITE_STENCIL_PIXELS() \
do { \
- GLint buf[n]; \
+ GLuint buf[n]; \
GLint ox[MAX_WIDTH]; \
GLint oy[MAX_WIDTH]; \
GLuint *readbuf = (GLuint *)((GLubyte *)sPriv->pFB + \
diff --git a/src/mesa/drivers/dri/r200/.gitignore b/src/mesa/drivers/dri/r200/.gitignore
new file mode 100644
index 0000000000..3773d8ea73
--- /dev/null
+++ b/src/mesa/drivers/dri/r200/.gitignore
@@ -0,0 +1,3 @@
+radeon_chipset.h
+radeon_screen.*
+server
diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c
index a1533d7f3e..fc6eb93daa 100644
--- a/src/mesa/drivers/dri/r200/r200_context.c
+++ b/src/mesa/drivers/dri/r200/r200_context.c
@@ -86,21 +86,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
int R200_DEBUG = (0);
#endif
-
-/* Return the width and height of the given buffer.
- */
-static void r200GetBufferSize( GLframebuffer *buffer,
- GLuint *width, GLuint *height )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
- LOCK_HARDWARE( rmesa );
- *width = rmesa->dri.drawable->w;
- *height = rmesa->dri.drawable->h;
- UNLOCK_HARDWARE( rmesa );
-}
-
/* Return various strings for glGetString().
*/
static const GLubyte *r200GetString( GLcontext *ctx, GLenum name )
@@ -232,12 +217,8 @@ static const struct tnl_pipeline_stage *r200_pipeline[] = {
*/
static void r200InitDriverFuncs( struct dd_function_table *functions )
{
- functions->GetBufferSize = r200GetBufferSize;
+ functions->GetBufferSize = NULL; /* OBSOLETE */
functions->GetString = r200GetString;
-
- functions->Error = NULL;
- functions->DrawPixels = NULL;
- functions->Bitmap = NULL;
}
static const struct dri_debug_control debug_control[] =
@@ -690,7 +671,13 @@ r200MakeCurrent( __DRIcontextPrivate *driContextPriv,
if ( newCtx->dri.drawable != driDrawPriv ) {
driDrawableInitVBlank( driDrawPriv, newCtx->vblank_flags,
&newCtx->vbl_seq );
+ }
+
+ if ( newCtx->dri.drawable != driDrawPriv ||
+ newCtx->dri.readable != driReadPriv ) {
newCtx->dri.drawable = driDrawPriv;
+ newCtx->dri.readable = driReadPriv;
+
r200UpdateWindow( newCtx->glCtx );
r200UpdateViewportOffset( newCtx->glCtx );
}
diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h
index 07b6d6e12d..44c67b68cb 100644
--- a/src/mesa/drivers/dri/r200/r200_context.h
+++ b/src/mesa/drivers/dri/r200/r200_context.h
@@ -107,6 +107,8 @@ struct r200_vertex_program {
VERTEX_SHADER_INSTRUCTION instr[R200_VSF_MAX_INST + 6];
int pos_end;
int inputs[VERT_ATTRIB_MAX];
+ int rev_inputs[16];
+ int gen_inputs_mapped;
int native;
int fogpidx;
int fogmode;
@@ -699,6 +701,7 @@ struct r200_dri_mirror {
__DRIcontextPrivate *context; /* DRI context */
__DRIscreenPrivate *screen; /* DRI screen */
__DRIdrawablePrivate *drawable; /* DRI drawable bound to this ctx */
+ __DRIdrawablePrivate *readable; /* DRI readable bound to this ctx */
drm_context_t hwContext;
drm_hw_lock_t *hwLock;
@@ -725,19 +728,21 @@ struct r200_tcl_info {
GLint last_offset;
GLuint hw_primitive;
-/* FIXME: what's the maximum number of components? */
- struct r200_dma_region *aos_components[11];
+/* hw can handle 12 components max */
+ struct r200_dma_region *aos_components[12];
GLuint nr_aos_components;
GLuint *Elts;
struct r200_dma_region indexed_verts;
+ struct r200_dma_region weight;
struct r200_dma_region obj;
struct r200_dma_region rgba;
struct r200_dma_region spec;
struct r200_dma_region fog;
struct r200_dma_region tex[R200_MAX_TEXTURE_UNITS];
struct r200_dma_region norm;
+ struct r200_dma_region generic[16];
};
diff --git a/src/mesa/drivers/dri/r200/r200_fragshader.c b/src/mesa/drivers/dri/r200/r200_fragshader.c
index 7993e3015a..5dd3adaef6 100644
--- a/src/mesa/drivers/dri/r200/r200_fragshader.c
+++ b/src/mesa/drivers/dri/r200/r200_fragshader.c
@@ -132,10 +132,10 @@ static void r200UpdateFSArith( GLcontext *ctx )
R200_STATECHANGE( rmesa, afs[1] );
if (shader->NumPasses < 2) {
- afs_cmd = rmesa->hw.afs[1].cmd;
+ afs_cmd = (GLuint *) rmesa->hw.afs[1].cmd;
}
else {
- afs_cmd = rmesa->hw.afs[0].cmd;
+ afs_cmd = (GLuint *) rmesa->hw.afs[0].cmd;
}
for (pass = 0; pass < shader->NumPasses; pass++) {
GLuint opnum = 0;
@@ -317,7 +317,7 @@ static void r200UpdateFSArith( GLcontext *ctx )
SET_INST(opnum, 1), SET_INST_2(opnum, 1));*/
opnum++;
}
- afs_cmd = rmesa->hw.afs[1].cmd;
+ afs_cmd = (GLuint *) rmesa->hw.afs[1].cmd;
}
rmesa->afs_loaded = ctx->ATIFragmentShader.Current;
}
@@ -362,7 +362,7 @@ static void r200UpdateFSRouting( GLcontext *ctx ) {
if (shader->NumPasses < 2) {
for (reg = 0; reg < R200_MAX_TEXTURE_UNITS; reg++) {
- struct gl_texture_object *texObj = ctx->Texture.Unit[reg]._Current;
+ GLbitfield targetbit = ctx->Texture.Unit[reg]._ReallyEnabled;
R200_STATECHANGE( rmesa, tex[reg] );
rmesa->hw.tex[reg].cmd[TEX_PP_TXMULTI_CTL] = 0;
if (shader->SetupInst[0][reg].Opcode) {
@@ -385,15 +385,16 @@ static void r200UpdateFSRouting( GLcontext *ctx ) {
else {
txformat_x |= R200_TEXCOORD_PROJ;
}
+ rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg;
}
- else if (texObj->Target == GL_TEXTURE_3D) {
+ else if (targetbit == TEXTURE_3D_BIT) {
txformat_x |= R200_TEXCOORD_VOLUME;
}
- else if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
+ else if (targetbit == TEXTURE_CUBE_BIT) {
txformat_x |= R200_TEXCOORD_CUBIC_ENV;
}
else if (shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STR_ATI ||
- shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
+ shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
txformat_x |= R200_TEXCOORD_NONPROJ;
}
else {
@@ -401,16 +402,16 @@ static void r200UpdateFSRouting( GLcontext *ctx ) {
}
rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT] = txformat;
rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT_X] = txformat_x;
- /* is this a good idea? Could potentially sample from not enabled unit.
- results are probably undefined anyway (?) but I hope it doesn't lock up... */
- rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg;
+ /* enabling texturing when unit isn't correctly configured may not be safe */
+ if (targetbit)
+ rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg;
}
}
} else {
/* setup 1st pass */
for (reg = 0; reg < R200_MAX_TEXTURE_UNITS; reg++) {
- struct gl_texture_object *texObj = ctx->Texture.Unit[reg]._Current;
+ GLbitfield targetbit = ctx->Texture.Unit[reg]._ReallyEnabled;
R200_STATECHANGE( rmesa, tex[reg] );
GLuint txformat_multi = 0;
if (shader->SetupInst[0][reg].Opcode) {
@@ -425,11 +426,12 @@ static void r200UpdateFSRouting( GLcontext *ctx ) {
else {
txformat_multi |= R200_PASS1_TEXCOORD_PROJ;
}
+ rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= R200_PPX_TEX_0_ENABLE << reg;
}
- else if (texObj->Target == GL_TEXTURE_3D) {
+ else if (targetbit == TEXTURE_3D_BIT) {
txformat_multi |= R200_PASS1_TEXCOORD_VOLUME;
}
- else if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
+ else if (targetbit == TEXTURE_CUBE_BIT) {
txformat_multi |= R200_PASS1_TEXCOORD_CUBIC_ENV;
}
else if (shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STR_ATI ||
@@ -439,14 +441,15 @@ static void r200UpdateFSRouting( GLcontext *ctx ) {
else {
txformat_multi |= R200_PASS1_TEXCOORD_PROJ;
}
- rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= R200_PPX_TEX_0_ENABLE << reg;
+ if (targetbit)
+ rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= R200_PPX_TEX_0_ENABLE << reg;
}
rmesa->hw.tex[reg].cmd[TEX_PP_TXMULTI_CTL] = txformat_multi;
}
/* setup 2nd pass */
for (reg=0; reg < R200_MAX_TEXTURE_UNITS; reg++) {
- struct gl_texture_object *texObj = ctx->Texture.Unit[reg]._Current;
+ GLbitfield targetbit = ctx->Texture.Unit[reg]._ReallyEnabled;
if (shader->SetupInst[1][reg].Opcode) {
GLuint coord = shader->SetupInst[1][reg].src;
GLuint txformat = rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT]
@@ -463,15 +466,16 @@ static void r200UpdateFSRouting( GLcontext *ctx ) {
else {
txformat_x |= R200_TEXCOORD_PROJ;
}
+ rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg;
}
- else if (texObj->Target == GL_TEXTURE_3D) {
+ else if (targetbit == TEXTURE_3D_BIT) {
txformat_x |= R200_TEXCOORD_VOLUME;
}
- else if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
+ else if (targetbit == TEXTURE_CUBE_BIT) {
txformat_x |= R200_TEXCOORD_CUBIC_ENV;
}
else if (shader->SetupInst[1][reg].swizzle == GL_SWIZZLE_STR_ATI ||
- shader->SetupInst[1][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
+ shader->SetupInst[1][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
txformat_x |= R200_TEXCOORD_NONPROJ;
}
else {
@@ -488,7 +492,8 @@ static void r200UpdateFSRouting( GLcontext *ctx ) {
}
rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT_X] = txformat_x;
rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT] = txformat;
- rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg;
+ if (targetbit)
+ rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg;
}
}
}
diff --git a/src/mesa/drivers/dri/r200/r200_lock.c b/src/mesa/drivers/dri/r200/r200_lock.c
index 66bb075864..bcc0c91639 100644
--- a/src/mesa/drivers/dri/r200/r200_lock.c
+++ b/src/mesa/drivers/dri/r200/r200_lock.c
@@ -69,7 +69,8 @@ r200UpdatePageFlipping( r200ContextPtr rmesa )
*/
void r200GetLock( r200ContextPtr rmesa, GLuint flags )
{
- __DRIdrawablePrivate *dPriv = rmesa->dri.drawable;
+ __DRIdrawablePrivate *drawable = rmesa->dri.drawable;
+ __DRIdrawablePrivate *readable = rmesa->dri.readable;
__DRIscreenPrivate *sPriv = rmesa->dri.screen;
drm_radeon_sarea_t *sarea = rmesa->sarea;
int i;
@@ -84,17 +85,20 @@ void r200GetLock( r200ContextPtr rmesa, GLuint flags )
* Since the hardware state depends on having the latest drawable
* clip rects, all state checking must be done _after_ this call.
*/
- DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv );
+ DRI_VALIDATE_DRAWABLE_INFO( sPriv, drawable );
+ if (drawable != readable) {
+ DRI_VALIDATE_DRAWABLE_INFO( sPriv, readable );
+ }
- if ( rmesa->lastStamp != dPriv->lastStamp ) {
+ if ( rmesa->lastStamp != drawable->lastStamp ) {
r200UpdatePageFlipping( rmesa );
if (rmesa->glCtx->DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_BACK_LEFT)
r200SetCliprects( rmesa, GL_BACK_LEFT );
else
r200SetCliprects( rmesa, GL_FRONT_LEFT );
r200UpdateViewportOffset( rmesa->glCtx );
- driUpdateFramebufferSize(rmesa->glCtx, dPriv);
- rmesa->lastStamp = dPriv->lastStamp;
+ driUpdateFramebufferSize(rmesa->glCtx, drawable);
+ rmesa->lastStamp = drawable->lastStamp;
}
R200_STATECHANGE( rmesa, ctx );
diff --git a/src/mesa/drivers/dri/r200/r200_maos_arrays.c b/src/mesa/drivers/dri/r200/r200_maos_arrays.c
index 92348c90ca..270dc35a46 100644
--- a/src/mesa/drivers/dri/r200/r200_maos_arrays.c
+++ b/src/mesa/drivers/dri/r200/r200_maos_arrays.c
@@ -385,8 +385,16 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs )
GLuint vfmt0 = 0, vfmt1 = 0;
GLuint count = VB->Count;
GLuint i;
-
- if (1) {
+ GLuint generic_in_mapped = 0;
+ struct r200_vertex_program *vp = NULL;
+
+ /* this looks way more complicated than necessary... */
+ if (ctx->VertexProgram._Enabled) {
+ vp = rmesa->curr_vp_hw;
+ generic_in_mapped = vp->gen_inputs_mapped;
+ }
+
+ if (inputs & VERT_BIT_POS) {
if (!rmesa->tcl.obj.buf)
emit_vector( ctx,
&rmesa->tcl.obj,
@@ -404,7 +412,33 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs )
}
component[nr++] = &rmesa->tcl.obj;
}
-
+ else if (generic_in_mapped & (1 << 0)) {
+ int geninput = vp->rev_inputs[0] - VERT_ATTRIB_GENERIC0;
+ if (!rmesa->tcl.generic[geninput].buf) {
+ emit_vector( ctx,
+ &(rmesa->tcl.generic[geninput]),
+ (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data,
+ 4,
+ VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride,
+ count );
+ }
+ component[nr++] = &rmesa->tcl.generic[geninput];
+ vfmt0 |= R200_VTX_W0 | R200_VTX_Z0;
+ }
+
+ if (inputs & VERT_BIT_WEIGHT) {
+ if (!rmesa->tcl.weight.buf)
+ emit_vector( ctx,
+ &rmesa->tcl.weight,
+ (char *)VB->AttribPtr[VERT_ATTRIB_WEIGHT]->data,
+ VB->AttribPtr[VERT_ATTRIB_WEIGHT]->size,
+ VB->AttribPtr[VERT_ATTRIB_WEIGHT]->stride,
+ count);
+
+ assert(VB->AttribPtr[VERT_ATTRIB_WEIGHT]->size <= 4);
+ vfmt0 |= VB->AttribPtr[VERT_ATTRIB_WEIGHT]->size << R200_VTX_WEIGHT_COUNT_SHIFT;
+ component[nr++] = &rmesa->tcl.weight;
+ }
if (inputs & VERT_BIT_NORMAL) {
if (!rmesa->tcl.norm.buf)
@@ -464,6 +498,23 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs )
component[nr++] = &rmesa->tcl.rgba;
}
+/* vfmt0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT;
+ emit_ubyte_rgba( ctx, &rmesa->tcl.rgba,
+ (char *)VB->ColorPtr[0]->data, 4,
+ VB->ColorPtr[0]->stride, count);*/
+ else if (generic_in_mapped & (1 << 2)) {
+ int geninput = vp->rev_inputs[2] - VERT_ATTRIB_GENERIC0;
+ if (!rmesa->tcl.generic[geninput].buf) {
+ emit_vector( ctx,
+ &(rmesa->tcl.generic[geninput]),
+ (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data,
+ 4,
+ VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride,
+ count );
+ }
+ component[nr++] = &rmesa->tcl.generic[geninput];
+ vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT;
+ }
if (inputs & VERT_BIT_COLOR1) {
@@ -481,8 +532,49 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs )
vfmt0 |= R200_VTX_FP_RGB << R200_VTX_COLOR_1_SHIFT;
component[nr++] = &rmesa->tcl.spec;
}
-
- for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) {
+ else if (generic_in_mapped & (1 << 3)) {
+ int geninput = vp->rev_inputs[3] - VERT_ATTRIB_GENERIC0;
+ if (!rmesa->tcl.generic[geninput].buf) {
+ emit_vector( ctx,
+ &(rmesa->tcl.generic[geninput]),
+ (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data,
+ 4,
+ VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride,
+ count );
+ }
+ component[nr++] = &rmesa->tcl.generic[geninput];
+ vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT;
+ }
+
+ if (generic_in_mapped & (1 << 4)) {
+ int geninput = vp->rev_inputs[4] - VERT_ATTRIB_GENERIC0;
+ if (!rmesa->tcl.generic[geninput].buf) {
+ emit_vector( ctx,
+ &(rmesa->tcl.generic[geninput]),
+ (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data,
+ 4,
+ VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride,
+ count );
+ }
+ component[nr++] = &rmesa->tcl.generic[geninput];
+ vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_2_SHIFT;
+ }
+
+ if (generic_in_mapped & (1 << 5)) {
+ int geninput = vp->rev_inputs[5] - VERT_ATTRIB_GENERIC0;
+ if (!rmesa->tcl.generic[geninput].buf) {
+ emit_vector( ctx,
+ &(rmesa->tcl.generic[geninput]),
+ (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data,
+ 4,
+ VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride,
+ count );
+ }
+ component[nr++] = &rmesa->tcl.generic[geninput];
+ vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_3_SHIFT;
+ }
+
+ for ( i = 0 ; i < 6 ; i++ ) {
if (inputs & (VERT_BIT_TEX0 << i)) {
if (!rmesa->tcl.tex[i].buf)
emit_vector( ctx,
@@ -495,8 +587,82 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs )
vfmt1 |= VB->TexCoordPtr[i]->size << (i * 3);
component[nr++] = &rmesa->tcl.tex[i];
}
+ else if (generic_in_mapped & (1 << (i + 6))) {
+ int geninput = vp->rev_inputs[i + 6] - VERT_ATTRIB_GENERIC0;
+ if (!rmesa->tcl.generic[geninput].buf) {
+ emit_vector( ctx,
+ &(rmesa->tcl.generic[geninput]),
+ (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data,
+ 4,
+ VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride,
+ count );
+ }
+ component[nr++] = &rmesa->tcl.generic[geninput];
+ vfmt1 |= 4 << (R200_VTX_TEX0_COMP_CNT_SHIFT + (i * 3));
+ }
}
+ if (generic_in_mapped & (1 << 13)) {
+ int geninput = vp->rev_inputs[13] - VERT_ATTRIB_GENERIC0;
+ if (!rmesa->tcl.generic[geninput].buf) {
+ emit_vector( ctx,
+ &(rmesa->tcl.generic[geninput]),
+ (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data,
+ 4,
+ VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride,
+ count );
+ }
+ component[nr++] = &rmesa->tcl.generic[geninput];
+ vfmt0 |= R200_VTX_XY1 | R200_VTX_Z1 | R200_VTX_W1;
+ }
+
+/* doesn't work. Wrong order with mixed generic & conventional! */
+/*
+ if (ctx->VertexProgram._Enabled) {
+ int *vp_inputs = rmesa->curr_vp_hw->inputs;
+ for ( i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++ ) {
+ if (inputs & (1 << i)) {
+ int geninput = i - VERT_ATTRIB_GENERIC0;
+ if (!rmesa->tcl.generic[geninput].buf) {
+ emit_vector( ctx,
+ &(rmesa->tcl.generic[geninput]),
+ (char *)VB->AttribPtr[i]->data,
+ 4,
+ VB->AttribPtr[i]->stride,
+ count );
+ }
+ component[nr++] = &rmesa->tcl.generic[geninput];
+ switch (vp_inputs[i]) {
+ case 0:
+ vfmt0 |= R200_VTX_W0 | R200_VTX_Z0;
+ break;
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ vfmt0 |= R200_VTX_FP_RGBA << (R200_VTX_COLOR_0_SHIFT + (vp_inputs[i] - 2) * 2);
+ break;
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ vfmt1 |= 4 << (R200_VTX_TEX0_COMP_CNT_SHIFT + (vp_inputs[i] - 6) * 3);
+ break;
+ case 13:
+ vfmt0 |= R200_VTX_XY1 | R200_VTX_Z1 | R200_VTX_W1;
+ break;
+ case 1:
+ case 12:
+ default:
+ assert(0);
+ }
+ }
+ }
+ }
+*/
+
if (vfmt0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] ||
vfmt1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) {
R200_STATECHANGE( rmesa, vtx );
@@ -520,9 +686,12 @@ void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs )
if (newinputs & VERT_BIT_POS)
r200ReleaseDmaRegion( rmesa, &rmesa->tcl.obj, __FUNCTION__ );
+ if (newinputs & VERT_BIT_WEIGHT)
+ r200ReleaseDmaRegion( rmesa, &rmesa->tcl.weight, __FUNCTION__ );
+
if (newinputs & VERT_BIT_NORMAL)
r200ReleaseDmaRegion( rmesa, &rmesa->tcl.norm, __FUNCTION__ );
-
+
if (newinputs & VERT_BIT_FOG)
r200ReleaseDmaRegion( rmesa, &rmesa->tcl.fog, __FUNCTION__ );
@@ -536,4 +705,14 @@ void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs )
if (newinputs & VERT_BIT_TEX(unit))
r200ReleaseDmaRegion( rmesa, &rmesa->tcl.tex[unit], __FUNCTION__ );
}
+
+ if (ctx->VertexProgram._Enabled) {
+ int i;
+ for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) {
+ if (newinputs & (1 << i))
+ r200ReleaseDmaRegion( rmesa,
+ &rmesa->tcl.generic[i - VERT_ATTRIB_GENERIC0], __FUNCTION__ );
+ }
+ }
+
}
diff --git a/src/mesa/drivers/dri/r200/r200_sanity.c b/src/mesa/drivers/dri/r200/r200_sanity.c
index ca5b926a94..3f2a866530 100644
--- a/src/mesa/drivers/dri/r200/r200_sanity.c
+++ b/src/mesa/drivers/dri/r200/r200_sanity.c
@@ -978,7 +978,7 @@ static int radeon_emit_veclinear(
}
}
else if ((start >= 0x180) && (start < 0x1c0)) {
- for (i = start ; (i < start + sz) ; i += 4) {
+ for (i = 0 ; i < sz ; i += 4) {
fprintf(stderr, "R200_VS_PROG %d OPDST %08x\n", (i >> 2) + start - 0x180 + 0x40, data[i]);
fprintf(stderr, "R200_VS_PROG %d SRC1 %08x\n", (i >> 2) + start - 0x180 + 0x40, data[i+1]);
fprintf(stderr, "R200_VS_PROG %d SRC2 %08x\n", (i >> 2) + start - 0x180 + 0x40, data[i+2]);
diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c
index e68f1e30f3..bab767838d 100644
--- a/src/mesa/drivers/dri/r200/r200_state.c
+++ b/src/mesa/drivers/dri/r200/r200_state.c
@@ -40,6 +40,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "enums.h"
#include "colormac.h"
#include "light.h"
+#include "framebuffer.h"
#include "swrast/swrast.h"
#include "vbo/vbo.h"
@@ -1844,23 +1845,26 @@ static void r200LogicOpCode( GLcontext *ctx, GLenum opcode )
void r200SetCliprects( r200ContextPtr rmesa, GLenum mode )
{
- __DRIdrawablePrivate *dPriv = rmesa->dri.drawable;
+ __DRIdrawablePrivate *const drawable = rmesa->dri.drawable;
+ __DRIdrawablePrivate *const readable = rmesa->dri.readable;
+ GLframebuffer *const draw_fb = (GLframebuffer*) drawable->driverPrivate;
+ GLframebuffer *const read_fb = (GLframebuffer*) readable->driverPrivate;
switch ( mode ) {
case GL_FRONT_LEFT:
- rmesa->numClipRects = dPriv->numClipRects;
- rmesa->pClipRects = dPriv->pClipRects;
+ rmesa->numClipRects = drawable->numClipRects;
+ rmesa->pClipRects = drawable->pClipRects;
break;
case GL_BACK_LEFT:
/* Can't ignore 2d windows if we are page flipping.
*/
- if ( dPriv->numBackClipRects == 0 || rmesa->doPageFlip ) {
- rmesa->numClipRects = dPriv->numClipRects;
- rmesa->pClipRects = dPriv->pClipRects;
+ if ( drawable->numBackClipRects == 0 || rmesa->doPageFlip ) {
+ rmesa->numClipRects = drawable->numClipRects;
+ rmesa->pClipRects = drawable->pClipRects;
}
else {
- rmesa->numClipRects = dPriv->numBackClipRects;
- rmesa->pClipRects = dPriv->pBackClipRects;
+ rmesa->numClipRects = drawable->numBackClipRects;
+ rmesa->pClipRects = drawable->pBackClipRects;
}
break;
default:
@@ -1868,6 +1872,21 @@ void r200SetCliprects( r200ContextPtr rmesa, GLenum mode )
return;
}
+ if ((draw_fb->Width != drawable->w) || (draw_fb->Height != drawable->h)) {
+ _mesa_resize_framebuffer(rmesa->glCtx, draw_fb,
+ drawable->w, drawable->h);
+ draw_fb->Initialized = GL_TRUE;
+ }
+
+ if (drawable != readable) {
+ if ((read_fb->Width != readable->w) ||
+ (read_fb->Height != readable->h)) {
+ _mesa_resize_framebuffer(rmesa->glCtx, read_fb,
+ readable->w, readable->h);
+ read_fb->Initialized = GL_TRUE;
+ }
+ }
+
if (rmesa->state.scissor.enabled)
r200RecalcScissorRects( rmesa );
}
diff --git a/src/mesa/drivers/dri/r200/r200_tcl.c b/src/mesa/drivers/dri/r200/r200_tcl.c
index 0b3bb281e0..62c335a707 100644
--- a/src/mesa/drivers/dri/r200/r200_tcl.c
+++ b/src/mesa/drivers/dri/r200/r200_tcl.c
@@ -384,7 +384,7 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx,
r200ContextPtr rmesa = R200_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
- GLuint inputs = VERT_BIT_POS | VERT_BIT_COLOR0;
+ GLuint inputs = 0;
GLuint i;
/* TODO: separate this from the swtnl pipeline
@@ -404,6 +404,7 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx,
r200ValidateState( ctx );
if (!ctx->VertexProgram._Enabled) {
+ inputs = VERT_BIT_POS | VERT_BIT_COLOR0;
/* NOTE: inputs != tnl->render_inputs - these are the untransformed
* inputs.
*/
@@ -436,11 +437,13 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx,
We only need to change compsel. */
GLuint out_compsel = 0;
GLuint vp_out = rmesa->curr_vp_hw->mesa_program.Base.OutputsWritten;
+#if 0
/* can't handle other inputs, generic attribs etc. currently - should never arrive here */
assert ((rmesa->curr_vp_hw->mesa_program.Base.InputsRead &
~(VERT_BIT_POS | VERT_BIT_NORMAL | VERT_BIT_COLOR0 | VERT_BIT_COLOR1 |
VERT_BIT_FOG | VERT_BIT_TEX0 | VERT_BIT_TEX1 | VERT_BIT_TEX2 |
VERT_BIT_TEX3 | VERT_BIT_TEX4 | VERT_BIT_TEX5)) == 0);
+#endif
inputs |= rmesa->curr_vp_hw->mesa_program.Base.InputsRead;
assert(vp_out & (1 << VERT_RESULT_HPOS));
out_compsel = R200_OUTPUT_XYZW;
@@ -577,7 +580,7 @@ static void transition_to_hwtnl( GLcontext *ctx )
rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~R200_FOG_USE_MASK;
rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |= R200_FOG_USE_VTX_FOG;
}
-
+
R200_STATECHANGE( rmesa, vte );
rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] &= ~(R200_VTX_XY_FMT|R200_VTX_Z_FMT);
rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] |= R200_VTX_W0_FMT;
diff --git a/src/mesa/drivers/dri/r200/r200_texstate.c b/src/mesa/drivers/dri/r200/r200_texstate.c
index 397b27ae52..875d3bab73 100644
--- a/src/mesa/drivers/dri/r200/r200_texstate.c
+++ b/src/mesa/drivers/dri/r200/r200_texstate.c
@@ -1178,7 +1178,7 @@ static void import_tex_obj_state( r200ContextPtr rmesa,
r200TexObjPtr texobj )
{
/* do not use RADEON_DB_STATE to avoid stale texture caches */
- GLuint *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0];
+ int *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0];
R200_STATECHANGE( rmesa, tex[unit] );
@@ -1199,7 +1199,7 @@ static void import_tex_obj_state( r200ContextPtr rmesa,
}
if (texobj->base.tObj->Target == GL_TEXTURE_CUBE_MAP) {
- GLuint *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0];
+ int *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0];
GLuint bytesPerFace = texobj->base.totalSize / 6;
ASSERT(texobj->base.totalSize % 6 == 0);
diff --git a/src/mesa/drivers/dri/r200/r200_vertprog.c b/src/mesa/drivers/dri/r200/r200_vertprog.c
index 9ac7a96827..491701b796 100644
--- a/src/mesa/drivers/dri/r200/r200_vertprog.c
+++ b/src/mesa/drivers/dri/r200/r200_vertprog.c
@@ -404,6 +404,9 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte
unsigned long hw_op;
int dofogfix = 0;
int fog_temp_i = 0;
+ int free_inputs;
+ int free_inputs_conv;
+ int array_count = 0;
vp->native = GL_FALSE;
vp->translated = GL_TRUE;
@@ -412,6 +415,7 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte
if (mesa_vp->Base.NumInstructions == 0)
return GL_FALSE;
+#if 0
if ((mesa_vp->Base.InputsRead &
~(VERT_BIT_POS | VERT_BIT_NORMAL | VERT_BIT_COLOR0 | VERT_BIT_COLOR1 |
VERT_BIT_FOG | VERT_BIT_TEX0 | VERT_BIT_TEX1 | VERT_BIT_TEX2 |
@@ -422,6 +426,7 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte
}
return GL_FALSE;
}
+#endif
if ((mesa_vp->Base.OutputsWritten &
~((1 << VERT_RESULT_HPOS) | (1 << VERT_RESULT_COL0) | (1 << VERT_RESULT_COL1) |
@@ -470,35 +475,87 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte
else
mesa_vp->Base.NumNativeParameters = 0;
- for(i=0; i < VERT_ATTRIB_MAX; i++)
+ for(i = 0; i < VERT_ATTRIB_MAX; i++)
vp->inputs[i] = -1;
+ free_inputs = 0x2ffd;
+
/* fglrx uses fixed inputs as follows for conventional attribs.
- generic attribs use non-fixed assignment, fglrx will always use the lowest attrib values available.
- There are 12 generic attribs possible, corresponding to attrib 0, 2-11 and 13 in a hw vertex prog.
- attr 1 and 12 are not available for generic attribs as those cannot be made vec4 (correspond to
- vertex normal/weight)
+ generic attribs use non-fixed assignment, fglrx will always use the
+ lowest attrib values available. We'll just do the same.
+ There are 12 generic attribs possible, corresponding to attrib 0, 2-11
+ and 13 in a hw vertex prog.
+ attr 1 and 12 aren't used for generic attribs as those cannot be made vec4
+ (correspond to vertex normal/weight - maybe weight actually could be made vec4).
+ Additionally, not more than 12 arrays in total are possible I think.
attr 0 is pos, R200_VTX_XY1|R200_VTX_Z1|R200_VTX_W1 in R200_SE_VTX_FMT_0
attr 2-5 use colors 0-3 (R200_VTX_FP_RGBA << R200_VTX_COLOR_0/1/2/3_SHIFT in R200_SE_VTX_FMT_0)
attr 6-11 use tex 0-5 (4 << R200_VTX_TEX0/1/2/3/4/5_COMP_CNT_SHIFT in R200_SE_VTX_FMT_1)
attr 13 uses vtx1 pos (R200_VTX_XY1|R200_VTX_Z1|R200_VTX_W1 in R200_SE_VTX_FMT_0)
- generic attribs would require some more work (dma regions, renaming). */
+*/
-/* may look different when using idx buf / input_route instead of se_vtx_fmt? */
- vp->inputs[VERT_ATTRIB_POS] = 0;
- vp->inputs[VERT_ATTRIB_WEIGHT] = 12;
- vp->inputs[VERT_ATTRIB_NORMAL] = 1;
- vp->inputs[VERT_ATTRIB_COLOR0] = 2;
- vp->inputs[VERT_ATTRIB_COLOR1] = 3;
- vp->inputs[VERT_ATTRIB_FOG] = 15;
- vp->inputs[VERT_ATTRIB_TEX0] = 6;
- vp->inputs[VERT_ATTRIB_TEX1] = 7;
- vp->inputs[VERT_ATTRIB_TEX2] = 8;
- vp->inputs[VERT_ATTRIB_TEX3] = 9;
- vp->inputs[VERT_ATTRIB_TEX4] = 10;
- vp->inputs[VERT_ATTRIB_TEX5] = 11;
/* attr 4,5 and 13 are only used with generic attribs.
Haven't seen attr 14 used, maybe that's for the hw pointsize vec1 (which is
not possibe to use with vertex progs as it is lacking in vert prog specification) */
+/* may look different when using idx buf / input_route instead of se_vtx_fmt? */
+ if (mesa_vp->Base.InputsRead & VERT_BIT_POS) {
+ vp->inputs[VERT_ATTRIB_POS] = 0;
+ free_inputs &= ~(1 << 0);
+ array_count++;
+ }
+ if (mesa_vp->Base.InputsRead & VERT_BIT_WEIGHT) {
+ vp->inputs[VERT_ATTRIB_WEIGHT] = 12;
+ array_count++;
+ }
+ if (mesa_vp->Base.InputsRead & VERT_BIT_NORMAL) {
+ vp->inputs[VERT_ATTRIB_NORMAL] = 1;
+ array_count++;
+ }
+ if (mesa_vp->Base.InputsRead & VERT_BIT_COLOR0) {
+ vp->inputs[VERT_ATTRIB_COLOR0] = 2;
+ free_inputs &= ~(1 << 2);
+ array_count++;
+ }
+ if (mesa_vp->Base.InputsRead & VERT_BIT_COLOR1) {
+ vp->inputs[VERT_ATTRIB_COLOR1] = 3;
+ free_inputs &= ~(1 << 3);
+ array_count++;
+ }
+ if (mesa_vp->Base.InputsRead & VERT_BIT_FOG) {
+ vp->inputs[VERT_ATTRIB_FOG] = 15; array_count++;
+ }
+ for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX5; i++) {
+ if (mesa_vp->Base.InputsRead & (1 << i)) {
+ vp->inputs[i] = i - VERT_ATTRIB_TEX0 + 6;
+ free_inputs &= ~(1 << (i - VERT_ATTRIB_TEX0 + 6));
+ array_count++;
+ }
+ }
+ free_inputs_conv = free_inputs;
+ /* using VERT_ATTRIB_TEX6/7 would be illegal */
+ /* completely ignore aliasing? */
+ for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) {
+ int j;
+ /* completely ignore aliasing? */
+ if (mesa_vp->Base.InputsRead & (1 << i)) {
+ array_count++;
+ if (array_count > 12) {
+ if (R200_DEBUG & DEBUG_FALLBACKS) {
+ fprintf(stderr, "more than 12 attribs used in vert prog\n");
+ }
+ return GL_FALSE;
+ }
+ for (j = 0; j < 14; j++) {
+ /* will always find one due to limited array_count */
+ if (free_inputs & (1 << j)) {
+ free_inputs &= ~(1 << j);
+ vp->inputs[i] = j;
+ vp->rev_inputs[j] = i;
+ break;
+ }
+ }
+ }
+ }
+ vp->gen_inputs_mapped = free_inputs ^ free_inputs_conv;
if (!(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS))) {
if (R200_DEBUG & DEBUG_FALLBACKS) {
@@ -506,6 +563,12 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte
}
return GL_FALSE;
}
+ if (free_inputs & 1) {
+ if (R200_DEBUG & DEBUG_FALLBACKS) {
+ fprintf(stderr, "can't handle vert prog without position input\n");
+ }
+ return GL_FALSE;
+ }
o_inst = vp->instr;
for (vpi = mesa_vp->Base.Instructions; vpi->Opcode != OPCODE_END; vpi++, o_inst++){
@@ -1145,6 +1208,9 @@ r200ProgramStringNotify(GLcontext *ctx, GLenum target, struct gl_program *prog)
r200_translate_vertex_program(ctx, vp);
rmesa->curr_vp_hw = NULL;
break;
+ case GL_FRAGMENT_SHADER_ATI:
+ rmesa->afs_loaded = NULL;
+ break;
}
/* need this for tcl fallbacks */
_tnl_program_string(ctx, target, prog);
diff --git a/src/mesa/drivers/dri/r300/.gitignore b/src/mesa/drivers/dri/r300/.gitignore
new file mode 100644
index 0000000000..3773d8ea73
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/.gitignore
@@ -0,0 +1,3 @@
+radeon_chipset.h
+radeon_screen.*
+server
diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h
index 02ffbfcbef..02f8e9107d 100644
--- a/src/mesa/drivers/dri/r300/r300_context.h
+++ b/src/mesa/drivers/dri/r300/r300_context.h
@@ -552,6 +552,7 @@ struct r300_stencilbuffer_state {
/* Can be tested with colormat currently. */
#define VSF_MAX_FRAGMENT_TEMPS (14)
+#define STATE_R300_WINDOW_DIMENSION (STATE_INTERNAL_DRIVER+0)
struct r300_vertex_shader_fragment {
int length;
@@ -595,7 +596,8 @@ struct r300_vertex_shader_state {
extern int hw_tcl_on;
-#define CURRENT_VERTEX_SHADER(ctx) (ctx->VertexProgram._Current)
+//#define CURRENT_VERTEX_SHADER(ctx) (ctx->VertexProgram._Current)
+#define CURRENT_VERTEX_SHADER(ctx) (R300_CONTEXT(ctx)->selected_vp)
/* Should but doesnt work */
//#define CURRENT_VERTEX_SHADER(ctx) (R300_CONTEXT(ctx)->curr_vp)
@@ -610,15 +612,22 @@ extern int hw_tcl_on;
/* r300_vertex_shader_state and r300_vertex_program should probably be merged together someday.
* Keeping them them seperate for now should ensure fixed pipeline keeps functioning properly.
*/
+
+struct r300_vertex_program_key {
+ GLuint InputsRead;
+ GLuint OutputsWritten;
+};
+
struct r300_vertex_program {
- struct gl_vertex_program mesa_program; /* Must be first */
+ struct r300_vertex_program *next;
+ struct r300_vertex_program_key key;
int translated;
struct r300_vertex_shader_fragment program;
- struct r300_vertex_shader_fragment params;
int pos_end;
int num_temporaries; /* Number of temp vars used by program */
+ int wpos_idx;
int inputs[VERT_ATTRIB_MAX];
int outputs[VERT_RESULT_MAX];
int native;
@@ -626,6 +635,12 @@ struct r300_vertex_program {
int use_ref_count;
};
+struct r300_vertex_program_cont {
+ struct gl_vertex_program mesa_program; /* Must be first */
+ struct r300_vertex_shader_fragment params;
+ struct r300_vertex_program *progs;
+};
+
#define PFS_MAX_ALU_INST 64
#define PFS_MAX_TEX_INST 64
#define PFS_MAX_TEX_INDIRECT 4
@@ -800,6 +815,7 @@ struct r300_context {
struct r300_cmdbuf cmdbuf;
struct r300_state state;
struct gl_vertex_program *curr_vp;
+ struct r300_vertex_program *selected_vp;
/* Vertex buffers
*/
@@ -857,9 +873,9 @@ extern GLboolean r300CreateContext(const __GLcontextModes * glVisual,
extern int r300_get_num_verts(r300ContextPtr rmesa, int num_verts, int prim);
-void r300_translate_vertex_shader(struct r300_vertex_program *vp);
+extern void r300_select_vertex_shader(r300ContextPtr r300);
extern void r300InitShaderFuncs(struct dd_function_table *functions);
-extern int r300VertexProgUpdateParams(GLcontext *ctx, struct r300_vertex_program *vp, float *dst);
+extern int r300VertexProgUpdateParams(GLcontext *ctx, struct r300_vertex_program_cont *vp, float *dst);
extern int r300Fallback(GLcontext *ctx);
extern void radeon_vb_to_rvb(r300ContextPtr rmesa, struct radeon_vertex_buffer *rvb, struct vertex_buffer *vb);
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c
index 91ec4f855c..6e85f0b5dd 100644
--- a/src/mesa/drivers/dri/r300/r300_fragprog.c
+++ b/src/mesa/drivers/dri/r300/r300_fragprog.c
@@ -28,14 +28,14 @@
/*
* Authors:
* Ben Skeggs <darktama@iinet.net.au>
+ * Jerome Glisse <j.glisse@gmail.com>
*/
/*TODO'S
*
- * - COS/SIN/SCS/LIT instructions
+ * - COS/SIN/SCS instructions
* - Depth write, WPOS/FOGC inputs
* - FogOption
- * - Negate on individual components (implement in swizzle code?)
* - Verify results of opcodes for accuracy, I've only checked them
* in specific cases.
* - and more...
@@ -51,18 +51,110 @@
#include "r300_fragprog.h"
#include "r300_reg.h"
+/*
+ * Usefull macros and values
+ */
+#define ERROR(fmt, args...) do { \
+ fprintf(stderr, "%s::%s(): " fmt "\n", \
+ __FILE__, __func__, ##args); \
+ rp->error = GL_TRUE; \
+ } while(0)
+
#define PFS_INVAL 0xFFFFFFFF
#define COMPILE_STATE struct r300_pfs_compile_state *cs = rp->cs
-static void dump_program(struct r300_fragment_program *rp);
-static void emit_arith(struct r300_fragment_program *rp, int op,
- pfs_reg_t dest, int mask,
- pfs_reg_t src0, pfs_reg_t src1, pfs_reg_t src2,
- int flags);
+#define SWIZZLE_XYZ 0
+#define SWIZZLE_XXX 1
+#define SWIZZLE_YYY 2
+#define SWIZZLE_ZZZ 3
+#define SWIZZLE_WWW 4
+#define SWIZZLE_YZX 5
+#define SWIZZLE_ZXY 6
+#define SWIZZLE_WZY 7
+#define SWIZZLE_111 8
+#define SWIZZLE_000 9
+#define SWIZZLE_HHH 10
+
+#define swizzle(r, x, y, z, w) do_swizzle(rp, r, \
+ ((SWIZZLE_##x<<0)| \
+ (SWIZZLE_##y<<3)| \
+ (SWIZZLE_##z<<6)| \
+ (SWIZZLE_##w<<9)), \
+ 0)
-/***************************************
- * begin: useful data structions for fragment program generation
- ***************************************/
+#define REG_TYPE_INPUT 0
+#define REG_TYPE_OUTPUT 1
+#define REG_TYPE_TEMP 2
+#define REG_TYPE_CONST 3
+
+#define REG_TYPE_SHIFT 0
+#define REG_INDEX_SHIFT 2
+#define REG_VSWZ_SHIFT 8
+#define REG_SSWZ_SHIFT 13
+#define REG_NEGV_SHIFT 18
+#define REG_NEGS_SHIFT 19
+#define REG_ABS_SHIFT 20
+#define REG_NO_USE_SHIFT 21
+#define REG_VALID_SHIFT 22
+
+#define REG_TYPE_MASK (0x03 << REG_TYPE_SHIFT)
+#define REG_INDEX_MASK (0x3F << REG_INDEX_SHIFT)
+#define REG_VSWZ_MASK (0x1F << REG_VSWZ_SHIFT)
+#define REG_SSWZ_MASK (0x1F << REG_SSWZ_SHIFT)
+#define REG_NEGV_MASK (0x01 << REG_NEGV_SHIFT)
+#define REG_NEGS_MASK (0x01 << REG_NEGS_SHIFT)
+#define REG_ABS_MASK (0x01 << REG_ABS_SHIFT)
+#define REG_NO_USE_MASK (0x01 << REG_NO_USE_SHIFT)
+#define REG_VALID_MASK (0x01 << REG_VALID_SHIFT)
+
+#define REG(type, index, vswz, sswz, nouse, valid) \
+ (((type << REG_TYPE_SHIFT) & REG_TYPE_MASK) | \
+ ((index << REG_INDEX_SHIFT) & REG_INDEX_MASK) | \
+ ((nouse << REG_NO_USE_SHIFT) & REG_NO_USE_MASK) | \
+ ((valid << REG_VALID_SHIFT) & REG_VALID_MASK) | \
+ ((vswz << REG_VSWZ_SHIFT) & REG_VSWZ_MASK) | \
+ ((sswz << REG_SSWZ_SHIFT) & REG_SSWZ_MASK))
+#define REG_GET_TYPE(reg) \
+ ((reg & REG_TYPE_MASK) >> REG_TYPE_SHIFT)
+#define REG_GET_INDEX(reg) \
+ ((reg & REG_INDEX_MASK) >> REG_INDEX_SHIFT)
+#define REG_GET_VSWZ(reg) \
+ ((reg & REG_VSWZ_MASK) >> REG_VSWZ_SHIFT)
+#define REG_GET_SSWZ(reg) \
+ ((reg & REG_SSWZ_MASK) >> REG_SSWZ_SHIFT)
+#define REG_GET_NO_USE(reg) \
+ ((reg & REG_NO_USE_MASK) >> REG_NO_USE_SHIFT)
+#define REG_GET_VALID(reg) \
+ ((reg & REG_VALID_MASK) >> REG_VALID_SHIFT)
+#define REG_SET_TYPE(reg, type) \
+ reg = ((reg & ~REG_TYPE_MASK) | \
+ ((type << REG_TYPE_SHIFT) & REG_TYPE_MASK))
+#define REG_SET_INDEX(reg, index) \
+ reg = ((reg & ~REG_INDEX_MASK) | \
+ ((index << REG_INDEX_SHIFT) & REG_INDEX_MASK))
+#define REG_SET_VSWZ(reg, vswz) \
+ reg = ((reg & ~REG_VSWZ_MASK) | \
+ ((vswz << REG_VSWZ_SHIFT) & REG_VSWZ_MASK))
+#define REG_SET_SSWZ(reg, sswz) \
+ reg = ((reg & ~REG_SSWZ_MASK) | \
+ ((sswz << REG_SSWZ_SHIFT) & REG_SSWZ_MASK))
+#define REG_SET_NO_USE(reg, nouse) \
+ reg = ((reg & ~REG_NO_USE_MASK) | \
+ ((nouse << REG_NO_USE_SHIFT) & REG_NO_USE_MASK))
+#define REG_SET_VALID(reg, valid) \
+ reg = ((reg & ~REG_VALID_MASK) | \
+ ((valid << REG_VALID_SHIFT) & REG_VALID_MASK))
+#define REG_ABS(reg) \
+ reg = (reg | REG_ABS_MASK)
+#define REG_NEGV(reg) \
+ reg = (reg | REG_NEGV_MASK)
+#define REG_NEGS(reg) \
+ reg = (reg | REG_NEGS_MASK)
+
+
+/*
+ * Datas structures for fragment program generation
+ */
/* description of r300 native hw instructions */
static const struct {
@@ -86,20 +178,19 @@ static const struct {
{ "CMPH", 3, R300_FPI0_OUTC_CMPH, PFS_INVAL },
};
-#define MAKE_SWZ3(x, y, z) (MAKE_SWIZZLE4(SWIZZLE_##x, \
- SWIZZLE_##y, \
- SWIZZLE_##z, \
- SWIZZLE_ZERO))
-
-#define SLOT_VECTOR (1<<0)
-#define SLOT_SCALAR (1<<3)
-#define SLOT_BOTH (SLOT_VECTOR|SLOT_SCALAR)
/* vector swizzles r300 can support natively, with a couple of
* cases we handle specially
*
- * pfs_reg_t.v_swz/pfs_reg_t.s_swz is an index into this table
- **/
+ * REG_VSWZ/REG_SSWZ is an index into this table
+ */
+#define SLOT_VECTOR (1<<0)
+#define SLOT_SCALAR (1<<3)
+#define SLOT_BOTH (SLOT_VECTOR | SLOT_SCALAR)
+#define MAKE_SWZ3(x, y, z) (MAKE_SWIZZLE4(SWIZZLE_##x, \
+ SWIZZLE_##y, \
+ SWIZZLE_##z, \
+ SWIZZLE_ZERO))
static const struct r300_pfs_swizzle {
GLuint hash; /* swizzle value this matches */
GLuint base; /* base value for hw swizzle */
@@ -120,39 +211,29 @@ static const struct r300_pfs_swizzle {
{ PFS_INVAL, R300_FPI0_ARGC_HALF, 0, 0},
{ PFS_INVAL, 0, 0, 0},
};
-#define SWIZZLE_XYZ 0
-#define SWIZZLE_XXX 1
-#define SWIZZLE_YYY 2
-#define SWIZZLE_ZZZ 3
-#define SWIZZLE_WWW 4
-#define SWIZZLE_YZX 5
-#define SWIZZLE_ZXY 6
-#define SWIZZLE_WZY 7
-#define SWIZZLE_111 8
-#define SWIZZLE_000 9
-#define SWIZZLE_HHH 10
+/* used during matching of non-native swizzles */
#define SWZ_X_MASK (7 << 0)
#define SWZ_Y_MASK (7 << 3)
#define SWZ_Z_MASK (7 << 6)
#define SWZ_W_MASK (7 << 9)
-/* used during matching of non-native swizzles */
static const struct {
- GLuint hash; /* used to mask matching swizzle components */
+ GLuint hash; /* used to mask matching swizzle components */
int mask; /* actual outmask */
int count; /* count of components matched */
} s_mask[] = {
- { SWZ_X_MASK|SWZ_Y_MASK|SWZ_Z_MASK, 1|2|4, 3},
- { SWZ_X_MASK|SWZ_Y_MASK, 1|2, 2},
- { SWZ_X_MASK|SWZ_Z_MASK, 1|4, 2},
- { SWZ_Y_MASK|SWZ_Z_MASK, 2|4, 2},
- { SWZ_X_MASK, 1, 1},
- { SWZ_Y_MASK, 2, 1},
- { SWZ_Z_MASK, 4, 1},
- { PFS_INVAL, PFS_INVAL, PFS_INVAL}
+ { SWZ_X_MASK|SWZ_Y_MASK|SWZ_Z_MASK, 1|2|4, 3},
+ { SWZ_X_MASK|SWZ_Y_MASK, 1|2, 2},
+ { SWZ_X_MASK|SWZ_Z_MASK, 1|4, 2},
+ { SWZ_Y_MASK|SWZ_Z_MASK, 2|4, 2},
+ { SWZ_X_MASK, 1, 1},
+ { SWZ_Y_MASK, 2, 1},
+ { SWZ_Z_MASK, 4, 1},
+ { PFS_INVAL, PFS_INVAL, PFS_INVAL}
};
/* mapping from SWIZZLE_* to r300 native values for scalar insns */
+#define SWIZZLE_HALF 6
static const struct {
int base; /* hw value of swizzle */
int stride; /* difference between SRC0/1/2 */
@@ -166,58 +247,51 @@ static const struct {
{ R300_FPI2_ARGA_ONE , 0, 0 },
{ R300_FPI2_ARGA_HALF , 0, 0 }
};
-#define SWIZZLE_HALF 6
/* boiler-plate reg, for convenience */
-static const pfs_reg_t undef = {
- type: REG_TYPE_TEMP,
- index: 0,
- v_swz: SWIZZLE_XYZ,
- s_swz: SWIZZLE_W,
- negate_v: 0,
- negate_s: 0,
- absolute: 0,
- no_use: GL_FALSE,
- valid: GL_FALSE
-};
+static const GLuint undef = REG(REG_TYPE_TEMP,
+ 0,
+ SWIZZLE_XYZ,
+ SWIZZLE_W,
+ GL_FALSE,
+ GL_FALSE);
/* constant one source */
-static const pfs_reg_t pfs_one = {
- type: REG_TYPE_CONST,
- index: 0,
- v_swz: SWIZZLE_111,
- s_swz: SWIZZLE_ONE,
- valid: GL_TRUE
-};
+static const GLuint pfs_one = REG(REG_TYPE_CONST,
+ 0,
+ SWIZZLE_111,
+ SWIZZLE_ONE,
+ GL_FALSE,
+ GL_TRUE);
/* constant half source */
-static const pfs_reg_t pfs_half = {
- type: REG_TYPE_CONST,
- index: 0,
- v_swz: SWIZZLE_HHH,
- s_swz: SWIZZLE_HALF,
- valid: GL_TRUE
-};
+static const GLuint pfs_half = REG(REG_TYPE_CONST,
+ 0,
+ SWIZZLE_HHH,
+ SWIZZLE_HALF,
+ GL_FALSE,
+ GL_TRUE);
/* constant zero source */
-static const pfs_reg_t pfs_zero = {
- type: REG_TYPE_CONST,
- index: 0,
- v_swz: SWIZZLE_000,
- s_swz: SWIZZLE_ZERO,
- valid: GL_TRUE
-};
-
-/***************************************
- * end: data structures
- ***************************************/
+static const GLuint pfs_zero = REG(REG_TYPE_CONST,
+ 0,
+ SWIZZLE_000,
+ SWIZZLE_ZERO,
+ GL_FALSE,
+ GL_TRUE);
-#define ERROR(fmt, args...) do { \
- fprintf(stderr, "%s::%s(): " fmt "\n",\
- __FILE__, __func__, ##args); \
- rp->error = GL_TRUE; \
-} while(0)
+/*
+ * Common functions prototypes
+ */
+static void dump_program(struct r300_fragment_program *rp);
+static void emit_arith(struct r300_fragment_program *rp, int op,
+ GLuint dest, int mask,
+ GLuint src0, GLuint src1, GLuint src2,
+ int flags);
+/*
+ * Helper functions prototypes
+ */
static int get_hw_temp(struct r300_fragment_program *rp)
{
COMPILE_STATE;
@@ -256,266 +330,339 @@ static void free_hw_temp(struct r300_fragment_program *rp, int idx)
cs->hwreg_in_use &= ~(1<<idx);
}
-static pfs_reg_t get_temp_reg(struct r300_fragment_program *rp)
+static GLuint get_temp_reg(struct r300_fragment_program *rp)
{
COMPILE_STATE;
- pfs_reg_t r = undef;
+ GLuint r = undef;
+ GLuint index;
- r.index = ffs(~cs->temp_in_use);
- if (!r.index) {
+ index = ffs(~cs->temp_in_use);
+ if (!index) {
ERROR("Out of program temps\n");
return r;
}
- cs->temp_in_use |= (1 << --r.index);
-
- cs->temps[r.index].refcount = 0xFFFFFFFF;
- cs->temps[r.index].reg = -1;
- r.valid = GL_TRUE;
+
+ cs->temp_in_use |= (1 << --index);
+ cs->temps[index].refcount = 0xFFFFFFFF;
+ cs->temps[index].reg = -1;
+
+ REG_SET_TYPE(r, REG_TYPE_TEMP);
+ REG_SET_INDEX(r, index);
+ REG_SET_VALID(r, GL_TRUE);
return r;
}
-static pfs_reg_t get_temp_reg_tex(struct r300_fragment_program *rp)
+static GLuint get_temp_reg_tex(struct r300_fragment_program *rp)
{
COMPILE_STATE;
- pfs_reg_t r = undef;
+ GLuint r = undef;
+ GLuint index;
- r.index = ffs(~cs->temp_in_use);
- if (!r.index) {
+ index = ffs(~cs->temp_in_use);
+ if (!index) {
ERROR("Out of program temps\n");
return r;
}
- cs->temp_in_use |= (1 << --r.index);
-
- cs->temps[r.index].refcount = 0xFFFFFFFF;
- cs->temps[r.index].reg = get_hw_temp_tex(rp);
- r.valid = GL_TRUE;
+
+ cs->temp_in_use |= (1 << --index);
+ cs->temps[index].refcount = 0xFFFFFFFF;
+ cs->temps[index].reg = get_hw_temp_tex(rp);
+
+ REG_SET_TYPE(r, REG_TYPE_TEMP);
+ REG_SET_INDEX(r, index);
+ REG_SET_VALID(r, GL_TRUE);
return r;
}
-static void free_temp(struct r300_fragment_program *rp, pfs_reg_t r)
+static void free_temp(struct r300_fragment_program *rp, GLuint r)
{
COMPILE_STATE;
- if (!(cs->temp_in_use & (1<<r.index))) return;
+ GLuint index = REG_GET_INDEX(r);
+
+ if (!(cs->temp_in_use & (1 << index)))
+ return;
- if (r.type == REG_TYPE_TEMP) {
- free_hw_temp(rp, cs->temps[r.index].reg);
- cs->temps[r.index].reg = -1;
- cs->temp_in_use &= ~(1<<r.index);
- } else if (r.type == REG_TYPE_INPUT) {
- free_hw_temp(rp, cs->inputs[r.index].reg);
- cs->inputs[r.index].reg = -1;
+ if (REG_GET_TYPE(r) == REG_TYPE_TEMP) {
+ free_hw_temp(rp, cs->temps[index].reg);
+ cs->temps[index].reg = -1;
+ cs->temp_in_use &= ~(1 << index);
+ } else if (REG_GET_TYPE(r) == REG_TYPE_INPUT) {
+ free_hw_temp(rp, cs->inputs[index].reg);
+ cs->inputs[index].reg = -1;
}
}
-static pfs_reg_t emit_param4fv(struct r300_fragment_program *rp,
- GLfloat *values)
+static GLuint emit_param4fv(struct r300_fragment_program *rp,
+ GLfloat *values)
{
- pfs_reg_t r = undef;
- r.type = REG_TYPE_CONST;
+ GLuint r = undef;
+ GLuint index;
int pidx;
pidx = rp->param_nr++;
- r.index = rp->const_nr++;
- if (pidx >= PFS_NUM_CONST_REGS || r.index >= PFS_NUM_CONST_REGS) {
+ index = rp->const_nr++;
+ if (pidx >= PFS_NUM_CONST_REGS || index >= PFS_NUM_CONST_REGS) {
ERROR("Out of const/param slots!\n");
return r;
}
-
- rp->param[pidx].idx = r.index;
+
+ rp->param[pidx].idx = index;
rp->param[pidx].values = values;
rp->params_uptodate = GL_FALSE;
- r.valid = GL_TRUE;
+ REG_SET_TYPE(r, REG_TYPE_CONST);
+ REG_SET_INDEX(r, index);
+ REG_SET_VALID(r, GL_TRUE);
return r;
}
-static pfs_reg_t emit_const4fv(struct r300_fragment_program *rp, GLfloat *cp)
+static GLuint emit_const4fv(struct r300_fragment_program *rp, GLfloat *cp)
{
- pfs_reg_t r = undef;
- r.type = REG_TYPE_CONST;
+ GLuint r = undef;
+ GLuint index;
- r.index = rp->const_nr++;
- if (r.index >= PFS_NUM_CONST_REGS) {
+ index = rp->const_nr++;
+ if (index >= PFS_NUM_CONST_REGS) {
ERROR("Out of hw constants!\n");
return r;
}
- COPY_4V(rp->constant[r.index], cp);
- r.valid = GL_TRUE;
+ COPY_4V(rp->constant[index], cp);
+
+ REG_SET_TYPE(r, REG_TYPE_CONST);
+ REG_SET_INDEX(r, index);
+ REG_SET_VALID(r, GL_TRUE);
return r;
}
-static __inline pfs_reg_t negate(pfs_reg_t r)
+static inline GLuint negate(GLuint r)
{
- r.negate_v = 1;
- r.negate_s = 1;
+ REG_NEGS(r);
+ REG_NEGV(r);
return r;
}
/* Hack, to prevent clobbering sources used multiple times when
* emulating non-native instructions
*/
-static __inline pfs_reg_t keep(pfs_reg_t r)
+static inline GLuint keep(GLuint r)
{
- r.no_use = GL_TRUE;
+ REG_SET_NO_USE(r, GL_TRUE);
return r;
}
-static __inline pfs_reg_t absolute(pfs_reg_t r)
+static inline GLuint absolute(GLuint r)
{
- r.absolute = 1;
+ REG_ABS(r);
return r;
}
static int swz_native(struct r300_fragment_program *rp,
- pfs_reg_t src, pfs_reg_t *r, GLuint arbneg)
+ GLuint src,
+ GLuint *r,
+ GLuint arbneg)
{
- /* Native swizzle, nothing to see here */
- src.negate_s = (arbneg >> 3) & 1;
+ /* Native swizzle, handle negation */
+ src = (src & ~REG_NEGS_MASK) |
+ (((arbneg >> 3) & 1) << REG_NEGS_SHIFT);
if ((arbneg & 0x7) == 0x0) {
- src.negate_v = 0;
+ src = src & ~REG_NEGV_MASK;
*r = src;
} else if ((arbneg & 0x7) == 0x7) {
- src.negate_v = 1;
+ src |= REG_NEGV_MASK;
*r = src;
} else {
- if (!r->valid)
+ if (!REG_GET_VALID(*r))
*r = get_temp_reg(rp);
- src.negate_v = 1;
- emit_arith(rp, PFS_OP_MAD, *r, arbneg & 0x7,
- keep(src), pfs_one, pfs_zero, 0);
- src.negate_v = 0;
- emit_arith(rp, PFS_OP_MAD, *r,
+ src |= REG_NEGV_MASK;
+ emit_arith(rp,
+ PFS_OP_MAD,
+ *r,
+ arbneg & 0x7,
+ keep(src),
+ pfs_one,
+ pfs_zero,
+ 0);
+ src = src & ~REG_NEGV_MASK;
+ emit_arith(rp,
+ PFS_OP_MAD,
+ *r,
(arbneg ^ 0x7) | WRITEMASK_W,
- src, pfs_one, pfs_zero, 0);
+ src,
+ pfs_one,
+ pfs_zero,
+ 0);
}
return 3;
}
-static int swz_emit_partial(struct r300_fragment_program *rp, pfs_reg_t src,
- pfs_reg_t *r, int mask, int mc, GLuint arbneg)
+static int swz_emit_partial(struct r300_fragment_program *rp,
+ GLuint src,
+ GLuint *r,
+ int mask,
+ int mc,
+ GLuint arbneg)
{
GLuint tmp;
GLuint wmask = 0;
- if (!r->valid)
+ if (!REG_GET_VALID(*r))
*r = get_temp_reg(rp);
- /* A partial match, src.v_swz/mask define what parts of the
- * desired swizzle we match */
+ /* A partial match, VSWZ/mask define what parts of the
+ * desired swizzle we match
+ */
if (mc + s_mask[mask].count == 3) {
wmask = WRITEMASK_W;
- src.negate_s = (arbneg >> 3) & 1;
+ src |= ((arbneg >> 3) & 1) << REG_NEGS_SHIFT;
}
tmp = arbneg & s_mask[mask].mask;
if (tmp) {
tmp = tmp ^ s_mask[mask].mask;
if (tmp) {
- src.negate_v = 1;
- emit_arith(rp, PFS_OP_MAD, *r,
+ emit_arith(rp,
+ PFS_OP_MAD,
+ *r,
arbneg & s_mask[mask].mask,
- keep(src), pfs_one, pfs_zero, 0);
- src.negate_v = 0;
- if (!wmask) src.no_use = GL_TRUE;
- else src.no_use = GL_FALSE;
- emit_arith(rp, PFS_OP_MAD, *r, tmp | wmask,
- src, pfs_one, pfs_zero, 0);
+ keep(src) | REG_NEGV_MASK,
+ pfs_one,
+ pfs_zero,
+ 0);
+ if (!wmask) {
+ REG_SET_NO_USE(src, GL_TRUE);
+ } else {
+ REG_SET_NO_USE(src, GL_FALSE);
+ }
+ emit_arith(rp,
+ PFS_OP_MAD,
+ *r,
+ tmp | wmask,
+ src,
+ pfs_one,
+ pfs_zero,
+ 0);
} else {
- src.negate_v = 1;
- if (!wmask) src.no_use = GL_TRUE;
- else src.no_use = GL_FALSE;
- emit_arith(rp, PFS_OP_MAD, *r,
+ if (!wmask) {
+ REG_SET_NO_USE(src, GL_TRUE);
+ } else {
+ REG_SET_NO_USE(src, GL_FALSE);
+ }
+ emit_arith(rp,
+ PFS_OP_MAD,
+ *r,
(arbneg & s_mask[mask].mask) | wmask,
- src, pfs_one, pfs_zero, 0);
- src.negate_v = 0;
+ src | REG_NEGV_MASK,
+ pfs_one,
+ pfs_zero,
+ 0);
}
} else {
- if (!wmask) src.no_use = GL_TRUE;
- else src.no_use = GL_FALSE;
- emit_arith(rp, PFS_OP_MAD, *r,
+ if (!wmask) {
+ REG_SET_NO_USE(src, GL_TRUE);
+ } else {
+ REG_SET_NO_USE(src, GL_FALSE);
+ }
+ emit_arith(rp, PFS_OP_MAD,
+ *r,
s_mask[mask].mask | wmask,
- src, pfs_one, pfs_zero, 0);
+ src,
+ pfs_one,
+ pfs_zero,
+ 0);
}
return s_mask[mask].count;
}
-#define swizzle(r, x, y, z, w) do_swizzle(rp, r, \
- ((SWIZZLE_##x<<0)| \
- (SWIZZLE_##y<<3)| \
- (SWIZZLE_##z<<6)| \
- (SWIZZLE_##w<<9)), \
- 0)
-
-static pfs_reg_t do_swizzle(struct r300_fragment_program *rp,
- pfs_reg_t src, GLuint arbswz, GLuint arbneg)
+static GLuint do_swizzle(struct r300_fragment_program *rp,
+ GLuint src,
+ GLuint arbswz,
+ GLuint arbneg)
{
- pfs_reg_t r = undef;
-
+ GLuint r = undef;
+ GLuint vswz;
int c_mask = 0;
- int v_matched = 0;
+ int v_match = 0;
/* If swizzling from something without an XYZW native swizzle,
* emit result to a temp, and do new swizzle from the temp.
*/
- if (src.v_swz != SWIZZLE_XYZ || src.s_swz != SWIZZLE_W) {
- pfs_reg_t temp = get_temp_reg(rp);
- emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_XYZW, src, pfs_one,
- pfs_zero, 0);
+ if (REG_GET_VSWZ(src) != SWIZZLE_XYZ ||
+ REG_GET_SSWZ(src) != SWIZZLE_W) {
+ GLuint temp = get_temp_reg(rp);
+ emit_arith(rp,
+ PFS_OP_MAD,
+ temp,
+ WRITEMASK_XYZW,
+ src,
+ pfs_one,
+ pfs_zero,
+ 0);
src = temp;
}
- src.s_swz = GET_SWZ(arbswz, 3);
+
+ /* set scalar swizzling */
+ REG_SET_SSWZ(src, GET_SWZ(arbswz, 3));
do {
+ vswz = REG_GET_VSWZ(src);
do {
-#define CUR_HASH (v_swiz[src.v_swz].hash & s_mask[c_mask].hash)
- if (CUR_HASH == (arbswz & s_mask[c_mask].hash)) {
- if (s_mask[c_mask].count == 3)
- v_matched += swz_native(rp, src, &r,
+ int chash;
+
+ REG_SET_VSWZ(src, vswz);
+ chash = v_swiz[REG_GET_VSWZ(src)].hash &
+ s_mask[c_mask].hash;
+
+ if (chash == (arbswz & s_mask[c_mask].hash)) {
+ if (s_mask[c_mask].count == 3) {
+ v_match += swz_native(rp,
+ src,
+ &r,
arbneg);
- else
- v_matched += swz_emit_partial(rp, src,
- &r,
- c_mask,
- v_matched,
- arbneg);
-
- if (v_matched == 3)
+ } else {
+ v_match += swz_emit_partial(rp,
+ src,
+ &r,
+ c_mask,
+ v_match,
+ arbneg);
+ }
+
+ if (v_match == 3)
return r;
/* Fill with something invalid.. all 0's was
* wrong before, matched SWIZZLE_X. So all
- * 1's will be okay for now */
+ * 1's will be okay for now
+ */
arbswz |= (PFS_INVAL & s_mask[c_mask].hash);
}
- } while(v_swiz[++src.v_swz].hash != PFS_INVAL);
- src.v_swz = SWIZZLE_XYZ;
+ } while(v_swiz[++vswz].hash != PFS_INVAL);
+ REG_SET_VSWZ(src, SWIZZLE_XYZ);
} while (s_mask[++c_mask].hash != PFS_INVAL);
ERROR("should NEVER get here\n");
return r;
}
-
-static pfs_reg_t t_src(struct r300_fragment_program *rp,
- struct prog_src_register fpsrc)
+
+static GLuint t_src(struct r300_fragment_program *rp,
+ struct prog_src_register fpsrc)
{
- pfs_reg_t r = undef;
-#if 0
- pfs_reg_t n = undef;
-#endif
+ GLuint r = undef;
switch (fpsrc.File) {
case PROGRAM_TEMPORARY:
- r.index = fpsrc.Index;
- r.valid = GL_TRUE;
+ REG_SET_INDEX(r, fpsrc.Index);
+ REG_SET_VALID(r, GL_TRUE);
+ REG_SET_TYPE(r, REG_TYPE_TEMP);
break;
case PROGRAM_INPUT:
- r.index = fpsrc.Index;
- r.type = REG_TYPE_INPUT;
- r.valid = GL_TRUE;
+ REG_SET_INDEX(r, fpsrc.Index);
+ REG_SET_VALID(r, GL_TRUE);
+ REG_SET_TYPE(r, REG_TYPE_INPUT);
break;
case PROGRAM_LOCAL_PARAM:
r = emit_param4fv(rp,
@@ -536,72 +683,40 @@ static pfs_reg_t t_src(struct r300_fragment_program *rp,
}
/* no point swizzling ONE/ZERO/HALF constants... */
- if (r.v_swz < SWIZZLE_111 || r.s_swz < SWIZZLE_ZERO)
+ if (REG_GET_VSWZ(r) < SWIZZLE_111 || REG_GET_SSWZ(r) < SWIZZLE_ZERO)
r = do_swizzle(rp, r, fpsrc.Swizzle, fpsrc.NegateBase);
-#if 0
- /* WRONG! Need to be able to do individual component negation,
- * should probably handle this in the swizzling code unless
- * all components are negated, then we can do this natively */
- if ((fpsrc.NegateBase & 0xf) == 0xf)
- r.negate = GL_TRUE;
-
- r.negate_s = (fpsrc.NegateBase >> 3) & 1;
-
- if ((fpsrc.NegateBase & 0x7) == 0x0) {
- r.negate_v = 0;
- } else if ((fpsrc.NegateBase & 0x7) == 0x7) {
- r.negate_v = 1;
- } else {
- if (r.type != REG_TYPE_TEMP) {
- n = get_temp_reg(rp);
- emit_arith(rp, PFS_OP_MAD, n, 0x7 ^ fpsrc.NegateBase,
- keep(r), pfs_one, pfs_zero, 0);
- r.negate_v = 1;
- emit_arith(rp, PFS_OP_MAD, n,
- fpsrc.NegateBase & 0x7 | WRITEMASK_W,
- r, pfs_one, pfs_zero, 0);
- r.negate_v = 0;
- r = n;
- } else {
- r.negate_v = 1;
- emit_arith(rp, PFS_OP_MAD, r,
- fpsrc.NegateBase & 0x7 | WRITEMASK_W,
- r, pfs_one, pfs_zero, 0);
- r.negate_v = 0;
- }
- }
-#endif
-
return r;
}
-static pfs_reg_t t_scalar_src(struct r300_fragment_program *rp,
- struct prog_src_register fpsrc)
+static GLuint t_scalar_src(struct r300_fragment_program *rp,
+ struct prog_src_register fpsrc)
{
struct prog_src_register src = fpsrc;
int sc = GET_SWZ(fpsrc.Swizzle, 0); /* X */
-
+
src.Swizzle = ((sc<<0)|(sc<<3)|(sc<<6)|(sc<<9));
return t_src(rp, src);
}
-static pfs_reg_t t_dst(struct r300_fragment_program *rp,
- struct prog_dst_register dest) {
- pfs_reg_t r = undef;
+static GLuint t_dst(struct r300_fragment_program *rp,
+ struct prog_dst_register dest)
+{
+ GLuint r = undef;
switch (dest.File) {
case PROGRAM_TEMPORARY:
- r.index = dest.Index;
- r.valid = GL_TRUE;
+ REG_SET_INDEX(r, dest.Index);
+ REG_SET_VALID(r, GL_TRUE);
+ REG_SET_TYPE(r, REG_TYPE_TEMP);
return r;
case PROGRAM_OUTPUT:
- r.type = REG_TYPE_OUTPUT;
+ REG_SET_TYPE(r, REG_TYPE_OUTPUT);
switch (dest.Index) {
case FRAG_RESULT_COLR:
case FRAG_RESULT_DEPR:
- r.index = dest.Index;
- r.valid = GL_TRUE;
+ REG_SET_INDEX(r, dest.Index);
+ REG_SET_VALID(r, GL_TRUE);
return r;
default:
ERROR("Bad DstReg->Index 0x%x\n", dest.Index);
@@ -613,66 +728,77 @@ static pfs_reg_t t_dst(struct r300_fragment_program *rp,
}
}
-static int t_hw_src(struct r300_fragment_program *rp, pfs_reg_t src,
+static int t_hw_src(struct r300_fragment_program *rp,
+ GLuint src,
GLboolean tex)
{
COMPILE_STATE;
int idx;
+ int index = REG_GET_INDEX(src);
- switch (src.type) {
+ switch(REG_GET_TYPE(src)) {
case REG_TYPE_TEMP:
/* NOTE: if reg==-1 here, a source is being read that
- * hasn't been written to. Undefined results */
- if (cs->temps[src.index].reg == -1)
- cs->temps[src.index].reg = get_hw_temp(rp);
- idx = cs->temps[src.index].reg;
+ * hasn't been written to. Undefined results
+ */
+ if (cs->temps[index].reg == -1)
+ cs->temps[index].reg = get_hw_temp(rp);
+
+ idx = cs->temps[index].reg;
- if (!src.no_use && (--cs->temps[src.index].refcount == 0))
+ if (!REG_GET_NO_USE(src) &&
+ (--cs->temps[index].refcount == 0))
free_temp(rp, src);
break;
case REG_TYPE_INPUT:
- idx = cs->inputs[src.index].reg;
+ idx = cs->inputs[index].reg;
- if (!src.no_use && (--cs->inputs[src.index].refcount == 0))
- free_hw_temp(rp, cs->inputs[src.index].reg);
+ if (!REG_GET_NO_USE(src) &&
+ (--cs->inputs[index].refcount == 0))
+ free_hw_temp(rp, cs->inputs[index].reg);
break;
case REG_TYPE_CONST:
- return (src.index | SRC_CONST);
+ return (index | SRC_CONST);
default:
ERROR("Invalid type for source reg\n");
return (0 | SRC_CONST);
}
- if (!tex) cs->used_in_node |= (1 << idx);
+ if (!tex)
+ cs->used_in_node |= (1 << idx);
return idx;
}
-static int t_hw_dst(struct r300_fragment_program *rp, pfs_reg_t dest,
+static int t_hw_dst(struct r300_fragment_program *rp,
+ GLuint dest,
GLboolean tex)
{
COMPILE_STATE;
int idx;
- assert(dest.valid);
+ GLuint index = REG_GET_INDEX(dest);
+ assert(REG_GET_VALID(dest));
- switch (dest.type) {
+ switch(REG_GET_TYPE(dest)) {
case REG_TYPE_TEMP:
- if (cs->temps[dest.index].reg == -1) {
- if (!tex)
- cs->temps[dest.index].reg = get_hw_temp(rp);
- else
- cs->temps[dest.index].reg = get_hw_temp_tex(rp);
+ if (cs->temps[REG_GET_INDEX(dest)].reg == -1) {
+ if (!tex) {
+ cs->temps[index].reg = get_hw_temp(rp);
+ } else {
+ cs->temps[index].reg = get_hw_temp_tex(rp);
+ }
}
- idx = cs->temps[dest.index].reg;
+ idx = cs->temps[index].reg;
- if (!dest.no_use && (--cs->temps[dest.index].refcount == 0))
+ if (!REG_GET_NO_USE(dest) &&
+ (--cs->temps[index].refcount == 0))
free_temp(rp, dest);
cs->dest_in_node |= (1 << idx);
cs->used_in_node |= (1 << idx);
break;
case REG_TYPE_OUTPUT:
- switch (dest.index) {
+ switch(index) {
case FRAG_RESULT_COLR:
rp->node[rp->cur_node].flags |= R300_PFS_NODE_OUTPUT_COLOR;
break;
@@ -680,17 +806,18 @@ static int t_hw_dst(struct r300_fragment_program *rp, pfs_reg_t dest,
rp->node[rp->cur_node].flags |= R300_PFS_NODE_OUTPUT_DEPTH;
break;
}
- return dest.index;
+ return index;
break;
default:
- ERROR("invalid dest reg type %d\n", dest.type);
+ ERROR("invalid dest reg type %d\n", REG_GET_TYPE(dest));
return 0;
}
return idx;
}
-static void emit_nop(struct r300_fragment_program *rp, GLuint mask,
+static void emit_nop(struct r300_fragment_program *rp,
+ GLuint mask,
GLboolean sync)
{
COMPILE_STATE;
@@ -716,8 +843,8 @@ static void emit_tex(struct r300_fragment_program *rp,
int opcode)
{
COMPILE_STATE;
- pfs_reg_t coord = t_src(rp, fpi->SrcReg[0]);
- pfs_reg_t dest = undef, rdest = undef;
+ GLuint coord = t_src(rp, fpi->SrcReg[0]);
+ GLuint dest = undef, rdest = undef;
GLuint din = cs->dest_in_node, uin = cs->used_in_node;
int unit = fpi->TexSrcUnit;
int hwsrc, hwdest;
@@ -728,7 +855,7 @@ static void emit_tex(struct r300_fragment_program *rp,
dest = t_dst(rp, fpi->DstReg);
/* r300 doesn't seem to be able to do TEX->output reg */
- if (dest.type == REG_TYPE_OUTPUT) {
+ if (REG_GET_TYPE(dest) == REG_TYPE_OUTPUT) {
rdest = dest;
dest = get_temp_reg_tex(rp);
}
@@ -740,7 +867,7 @@ static void emit_tex(struct r300_fragment_program *rp,
if (uin & (1 << hwdest)) {
free_hw_temp(rp, hwdest);
hwdest = get_hw_temp_tex(rp);
- cs->temps[dest.index].reg = hwdest;
+ cs->temps[REG_GET_INDEX(dest)].reg = hwdest;
}
} else {
hwdest = 0;
@@ -750,8 +877,8 @@ static void emit_tex(struct r300_fragment_program *rp,
/* Indirection if source has been written in this node, or if the
* dest has been read/written in this node
*/
- if ((coord.type != REG_TYPE_CONST && (din & (1<<hwsrc))) ||
- (uin & (1<<hwdest))) {
+ if ((REG_GET_TYPE(coord) != REG_TYPE_CONST &&
+ (din & (1<<hwsrc))) || (uin & (1<<hwdest))) {
/* Finish off current node */
cs->v_pos = cs->s_pos = MAX2(cs->v_pos, cs->s_pos);
@@ -791,13 +918,13 @@ static void emit_tex(struct r300_fragment_program *rp,
| (opcode << R300_FPITX_OPCODE_SHIFT);
cs->dest_in_node |= (1 << hwdest);
- if (coord.type != REG_TYPE_CONST)
+ if (REG_GET_TYPE(coord) != REG_TYPE_CONST)
cs->used_in_node |= (1 << hwsrc);
rp->node[rp->cur_node].tex_end++;
/* Copy from temp to output if needed */
- if (rdest.valid) {
+ if (REG_GET_VALID(rdest)) {
emit_arith(rp, PFS_OP_MAD, rdest, WRITEMASK_XYZW, dest,
pfs_one, pfs_zero, 0);
free_temp(rp, dest);
@@ -807,7 +934,9 @@ static void emit_tex(struct r300_fragment_program *rp,
/* Add sources to FPI1/FPI3 lists. If source is already on list,
* reuse the index instead of wasting a source.
*/
-static int add_src(struct r300_fragment_program *rp, int reg, int pos,
+static int add_src(struct r300_fragment_program *rp,
+ int reg,
+ int pos,
int srcmask)
{
COMPILE_STATE;
@@ -856,9 +985,12 @@ static int add_src(struct r300_fragment_program *rp, int reg, int pos,
* It's not necessary to force the first case, but it makes disassembled
* shaders easier to read.
*/
-static GLboolean force_same_slot(int vop, int sop,
- GLboolean emit_vop, GLboolean emit_sop,
- int argc, pfs_reg_t *src)
+static GLboolean force_same_slot(int vop,
+ int sop,
+ GLboolean emit_vop,
+ GLboolean emit_sop,
+ int argc,
+ GLuint *src)
{
int i;
@@ -870,20 +1002,24 @@ static GLboolean force_same_slot(int vop, int sop,
if (emit_vop) {
for (i=0;i<argc;i++)
- if (src[i].v_swz == SWIZZLE_WZY)
+ if (REG_GET_VSWZ(src[i]) == SWIZZLE_WZY)
return GL_TRUE;
}
return GL_FALSE;
}
-static void emit_arith(struct r300_fragment_program *rp, int op,
- pfs_reg_t dest, int mask,
- pfs_reg_t src0, pfs_reg_t src1, pfs_reg_t src2,
+static void emit_arith(struct r300_fragment_program *rp,
+ int op,
+ GLuint dest,
+ int mask,
+ GLuint src0,
+ GLuint src1,
+ GLuint src2,
int flags)
{
COMPILE_STATE;
- pfs_reg_t src[3] = { src0, src1, src2 };
+ GLuint src[3] = { src0, src1, src2 };
int hwsrc[3], sswz[3], vswz[3];
int hwdest;
GLboolean emit_vop = GL_FALSE, emit_sop = GL_FALSE;
@@ -900,7 +1036,8 @@ static void emit_arith(struct r300_fragment_program *rp, int op,
if ((mask & WRITEMASK_W) || vop == R300_FPI0_OUTC_REPL_ALPHA)
emit_sop = GL_TRUE;
- if (dest.type == REG_TYPE_OUTPUT && dest.index == FRAG_RESULT_DEPR)
+ if (REG_GET_TYPE(dest) == REG_TYPE_OUTPUT &&
+ REG_GET_INDEX(dest) == FRAG_RESULT_DEPR)
emit_vop = GL_FALSE;
if (force_same_slot(vop, sop, emit_vop, emit_sop, argc, src)) {
@@ -916,12 +1053,12 @@ static void emit_arith(struct r300_fragment_program *rp, int op,
*/
for (i=0;i<3;i++) {
if (emit_vop &&
- (v_swiz[src[i].v_swz].flags & SLOT_SCALAR)) {
+ (v_swiz[REG_GET_VSWZ(src[i])].flags & SLOT_SCALAR)) {
vpos = spos = MAX2(vpos, spos);
break;
}
if (emit_sop &&
- (s_swiz[src[i].s_swz].flags & SLOT_VECTOR)) {
+ (s_swiz[REG_GET_VSWZ(src[i])].flags & SLOT_VECTOR)) {
vpos = spos = MAX2(vpos, spos);
break;
}
@@ -945,20 +1082,22 @@ static void emit_arith(struct r300_fragment_program *rp, int op,
if (emit_vop && vop != R300_FPI0_OUTC_REPL_ALPHA) {
srcpos = add_src(rp, hwsrc[i], vpos,
- v_swiz[src[i].v_swz].flags);
- vswz[i] = (v_swiz[src[i].v_swz].base +
- (srcpos * v_swiz[src[i].v_swz].stride)) |
- (src[i].negate_v ? ARG_NEG : 0) |
- (src[i].absolute ? ARG_ABS : 0);
+ v_swiz[REG_GET_VSWZ(src[i])].flags);
+ vswz[i] = (v_swiz[REG_GET_VSWZ(src[i])].base +
+ (srcpos *
+ v_swiz[REG_GET_VSWZ(src[i])].stride)) |
+ ((src[i] & REG_NEGV_MASK) ? ARG_NEG : 0) |
+ ((src[i] & REG_ABS_MASK) ? ARG_ABS : 0);
} else vswz[i] = R300_FPI0_ARGC_ZERO;
if (emit_sop) {
srcpos = add_src(rp, hwsrc[i], spos,
- s_swiz[src[i].s_swz].flags);
- sswz[i] = (s_swiz[src[i].s_swz].base +
- (srcpos * s_swiz[src[i].s_swz].stride)) |
- (src[i].negate_s ? ARG_NEG : 0) |
- (src[i].absolute ? ARG_ABS : 0);
+ s_swiz[REG_GET_SSWZ(src[i])].flags);
+ sswz[i] = (s_swiz[REG_GET_SSWZ(src[i])].base +
+ (srcpos *
+ s_swiz[REG_GET_SSWZ(src[i])].stride)) |
+ ((src[i] & REG_NEGS_MASK) ? ARG_NEG : 0) |
+ ((src[i] & REG_ABS_MASK) ? ARG_ABS : 0);
} else sswz[i] = R300_FPI2_ARGA_ZERO;
}
hwdest = t_hw_dst(rp, dest, GL_FALSE);
@@ -980,8 +1119,8 @@ static void emit_arith(struct r300_fragment_program *rp, int op,
(vswz[2] << R300_FPI0_ARG2C_SHIFT);
rp->alu.inst[vpos].inst1 |= hwdest << R300_FPI1_DSTC_SHIFT;
- if (dest.type == REG_TYPE_OUTPUT) {
- if (dest.index == FRAG_RESULT_COLR) {
+ if (REG_GET_TYPE(dest) == REG_TYPE_OUTPUT) {
+ if (REG_GET_INDEX(dest) == FRAG_RESULT_COLR) {
rp->alu.inst[vpos].inst1 |=
(mask & WRITEMASK_XYZ) << R300_FPI1_DSTC_OUTPUT_MASK_SHIFT;
} else assert(0);
@@ -1005,11 +1144,11 @@ static void emit_arith(struct r300_fragment_program *rp, int op,
sswz[2] << R300_FPI2_ARG2A_SHIFT;
if (mask & WRITEMASK_W) {
- if (dest.type == REG_TYPE_OUTPUT) {
- if (dest.index == FRAG_RESULT_COLR) {
+ if (REG_GET_TYPE(dest) == REG_TYPE_OUTPUT) {
+ if (REG_GET_INDEX(dest) == FRAG_RESULT_COLR) {
rp->alu.inst[spos].inst3 |=
(hwdest << R300_FPI3_DSTA_SHIFT) | R300_FPI3_DSTA_OUTPUT;
- } else if (dest.index == FRAG_RESULT_DEPR) {
+ } else if (REG_GET_INDEX(dest) == FRAG_RESULT_DEPR) {
rp->alu.inst[spos].inst3 |= R300_FPI3_DSTA_DEPTH;
} else assert(0);
} else {
@@ -1022,22 +1161,22 @@ static void emit_arith(struct r300_fragment_program *rp, int op,
rp->alu.inst[vpos].inst2 = NOP_INST2;
return;
-};
+}
#if 0
-static pfs_reg_t get_attrib(struct r300_fragment_program *rp, GLuint attr)
+static GLuint get_attrib(struct r300_fragment_program *rp, GLuint attr)
{
struct gl_fragment_program *mp = &rp->mesa_program;
- pfs_reg_t r = undef;
+ GLuint r = undef;
if (!(mp->Base.InputsRead & (1<<attr))) {
ERROR("Attribute %d was not provided!\n", attr);
return undef;
}
- r.type = REG_TYPE_INPUT;
- r.index = attr;
- r.valid = GL_TRUE;
+ REG_SET_TYPE(r, REG_TYPE_INPUT);
+ REG_SET_INDEX(r, attr);
+ REG_SET_VALID(r, GL_TRUE);
return r;
}
#endif
@@ -1047,8 +1186,8 @@ static GLboolean parse_program(struct r300_fragment_program *rp)
struct gl_fragment_program *mp = &rp->mesa_program;
const struct prog_instruction *inst = mp->Base.Instructions;
struct prog_instruction *fpi;
- pfs_reg_t src[3], dest, temp;
- pfs_reg_t cnst;
+ GLuint src[3], dest, temp;
+ GLuint cnst;
int flags, mask = 0;
GLfloat cnstv[4] = {0.0, 0.0, 0.0, 0.0};
@@ -1094,7 +1233,64 @@ static GLboolean parse_program(struct r300_fragment_program *rp)
flags);
break;
case OPCODE_COS:
- ERROR("COS not implemented\n");
+ /*
+ * cos using taylor serie:
+ * cos(x) = 1 - x^2/2! + x^4/4! - x^6/6!
+ */
+ temp = get_temp_reg(rp);
+ cnstv[0] = 0.5;
+ cnstv[1] = 0.041666667;
+ cnstv[2] = 0.001388889;
+ cnstv[4] = 0.0;
+ cnst = emit_const4fv(rp, cnstv);
+ src[0] = t_scalar_src(rp, fpi->SrcReg[0]);
+
+ emit_arith(rp, PFS_OP_MAD, temp,
+ WRITEMASK_XYZ,
+ src[0],
+ src[0],
+ pfs_zero,
+ flags);
+ emit_arith(rp, PFS_OP_MAD, temp,
+ WRITEMASK_Y | WRITEMASK_Z,
+ temp, temp,
+ pfs_zero,
+ flags);
+ emit_arith(rp, PFS_OP_MAD, temp,
+ WRITEMASK_Z,
+ temp,
+ swizzle(temp, X, X, X, W),
+ pfs_zero,
+ flags);
+ emit_arith(rp, PFS_OP_MAD, temp,
+ WRITEMASK_XYZ,
+ temp, cnst,
+ pfs_zero,
+ flags);
+ emit_arith(rp, PFS_OP_MAD, temp,
+ WRITEMASK_X,
+ pfs_one,
+ pfs_one,
+ negate(temp),
+ flags);
+ emit_arith(rp, PFS_OP_MAD, temp,
+ WRITEMASK_X,
+ temp,
+ pfs_one,
+ swizzle(temp, Y, Y, Y, W),
+ flags);
+ emit_arith(rp, PFS_OP_MAD, temp,
+ WRITEMASK_X,
+ temp,
+ pfs_one,
+ negate(swizzle(temp, Z, Z, Z, W)),
+ flags);
+ emit_arith(rp, PFS_OP_MAD, dest, mask,
+ swizzle(temp, X, X, X, X),
+ pfs_one,
+ pfs_zero,
+ flags);
+ free_temp(rp, temp);
break;
case OPCODE_DP3:
src[0] = t_src(rp, fpi->SrcReg[0]);
@@ -1147,7 +1343,7 @@ static GLboolean parse_program(struct r300_fragment_program *rp)
/* result.x = 1.0
* result.w = src1.w */
if (mask & WRITEMASK_XW) {
- src[1].v_swz = SWIZZLE_111; /* Cheat.. */
+ REG_SET_VSWZ(src[1], SWIZZLE_111); /*Cheat*/
emit_arith(rp, PFS_OP_MAD, dest,
mask & WRITEMASK_XW,
src[1], pfs_one, pfs_zero,
@@ -1351,7 +1547,70 @@ static GLboolean parse_program(struct r300_fragment_program *rp)
free_temp(rp, temp);
break;
case OPCODE_SIN:
- ERROR("SIN not implemented\n");
+ /*
+ * sin using taylor serie:
+ * sin(x) = x - x^3/3! + x^5/5! - x^7/7!
+ */
+ temp = get_temp_reg(rp);
+ cnstv[0] = 0.333333333;
+ cnstv[1] = 0.008333333;
+ cnstv[2] = 0.000198413;
+ cnstv[4] = 0.0;
+ cnst = emit_const4fv(rp, cnstv);
+ src[0] = t_scalar_src(rp, fpi->SrcReg[0]);
+
+ emit_arith(rp, PFS_OP_MAD, temp,
+ WRITEMASK_XYZ,
+ src[0],
+ src[0],
+ pfs_zero,
+ flags);
+ emit_arith(rp, PFS_OP_MAD, temp,
+ WRITEMASK_Y | WRITEMASK_Z,
+ temp, temp,
+ pfs_zero,
+ flags);
+ emit_arith(rp, PFS_OP_MAD, temp,
+ WRITEMASK_Z,
+ temp,
+ swizzle(temp, X, X, X, W),
+ pfs_zero,
+ flags);
+ emit_arith(rp, PFS_OP_MAD, temp,
+ WRITEMASK_XYZ,
+ src[0],
+ temp,
+ pfs_zero,
+ flags);
+ emit_arith(rp, PFS_OP_MAD, temp,
+ WRITEMASK_XYZ,
+ temp, cnst,
+ pfs_zero,
+ flags);
+ emit_arith(rp, PFS_OP_MAD, temp,
+ WRITEMASK_X,
+ src[0],
+ pfs_one,
+ negate(temp),
+ flags);
+ emit_arith(rp, PFS_OP_MAD, temp,
+ WRITEMASK_X,
+ temp,
+ pfs_one,
+ swizzle(temp, Y, Y, Y, W),
+ flags);
+ emit_arith(rp, PFS_OP_MAD, temp,
+ WRITEMASK_X,
+ temp,
+ pfs_one,
+ negate(swizzle(temp, Z, Z, Z, W)),
+ flags);
+ emit_arith(rp, PFS_OP_MAD, dest, mask,
+ swizzle(temp, X, X, X, X),
+ pfs_one,
+ pfs_zero,
+ flags);
+ free_temp(rp, temp);
break;
case OPCODE_SLT:
src[0] = t_src(rp, fpi->SrcReg[0]);
@@ -1470,6 +1729,13 @@ static void init_program(struct r300_fragment_program *rp)
}
InputsRead &= ~FRAG_BITS_TEX_ANY;
+ /* fragment position treated as a texcoord */
+ if (InputsRead & FRAG_BIT_WPOS) {
+ cs->inputs[FRAG_ATTRIB_WPOS].refcount = 0;
+ cs->inputs[FRAG_ATTRIB_WPOS].reg = get_hw_temp(rp);
+ }
+ InputsRead &= ~FRAG_BIT_WPOS;
+
/* Then primary colour */
if (InputsRead & FRAG_BIT_COL0) {
cs->inputs[FRAG_ATTRIB_COL0].refcount = 0;
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.h b/src/mesa/drivers/dri/r300/r300_fragprog.h
index 4bbaa07e01..b0cebe60bb 100644
--- a/src/mesa/drivers/dri/r300/r300_fragprog.h
+++ b/src/mesa/drivers/dri/r300/r300_fragprog.h
@@ -41,6 +41,7 @@
#include "r300_context.h"
#include "program_instruction.h"
+#if 0
/* representation of a register for emit_arith/swizzle */
typedef struct _pfs_reg_t {
enum {
@@ -58,7 +59,7 @@ typedef struct _pfs_reg_t {
GLboolean no_use:1;
GLboolean valid:1;
} pfs_reg_t;
-
+#endif
typedef struct r300_fragment_program_swizzle {
GLuint length;
GLuint src[4];
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_swz.c b/src/mesa/drivers/dri/r300/r300_fragprog_swz.c
deleted file mode 100644
index b29331d7bd..0000000000
--- a/src/mesa/drivers/dri/r300/r300_fragprog_swz.c
+++ /dev/null
@@ -1,1328 +0,0 @@
-/*
- * Copyright (C) 2005 Jerome Glisse. 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 "r300_fragprog.h"
-#include "r300_reg.h"
-
-
-#define I0_000 ( (R300_FPI0_OUTC_MAD) | \
- (R300_FPI0_ARGC_ZERO) | \
- (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG1C_SHIFT) | \
- (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG2C_SHIFT) )
-#define I0_111 ( (R300_FPI0_OUTC_MAD) | \
- (R300_FPI0_ARGC_ZERO) | \
- (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG1C_SHIFT) | \
- (R300_FPI0_ARGC_ONE << R300_FPI0_ARG2C_SHIFT) )
-#define I0_XXX ( (R300_FPI0_OUTC_MAD) | \
- (R300_FPI0_ARGC_SRC0C_XXX) | \
- (R300_FPI0_ARGC_ONE << R300_FPI0_ARG1C_SHIFT) | \
- (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG2C_SHIFT) )
-#define I0_YYY ( (R300_FPI0_OUTC_MAD) | \
- (R300_FPI0_ARGC_SRC0C_YYY) | \
- (R300_FPI0_ARGC_ONE << R300_FPI0_ARG1C_SHIFT) | \
- (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG2C_SHIFT) )
-#define I0_ZZZ ( (R300_FPI0_OUTC_MAD) | \
- (R300_FPI0_ARGC_SRC0C_ZZZ) | \
- (R300_FPI0_ARGC_ONE << R300_FPI0_ARG1C_SHIFT) | \
- (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG2C_SHIFT) )
-#define I0_XYZ ( (R300_FPI0_OUTC_MAD) | \
- (R300_FPI0_ARGC_SRC0C_XYZ) | \
- (R300_FPI0_ARGC_ONE << R300_FPI0_ARG1C_SHIFT) | \
- (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG2C_SHIFT) )
-#define I0_YZX ( (R300_FPI0_OUTC_MAD) | \
- (R300_FPI0_ARGC_SRC0C_YZX) | \
- (R300_FPI0_ARGC_ONE << R300_FPI0_ARG1C_SHIFT) | \
- (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG2C_SHIFT) )
-#define I0_ZXY ( (R300_FPI0_OUTC_MAD) | \
- (R300_FPI0_ARGC_SRC0C_ZXY) | \
- (R300_FPI0_ARGC_ONE << R300_FPI0_ARG1C_SHIFT) | \
- (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG2C_SHIFT) )
-#define I0_WZY ( (R300_FPI0_OUTC_MAD) | \
- (R300_FPI0_ARGC_SRC0CA_WZY) | \
- (R300_FPI0_ARGC_ONE << R300_FPI0_ARG1C_SHIFT) | \
- (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG2C_SHIFT) )
-#define I0_WWW ( (R300_FPI0_OUTC_MAD) | \
- (R300_FPI0_ARGC_SRC0A) | \
- (R300_FPI0_ARGC_ONE << R300_FPI0_ARG1C_SHIFT) | \
- (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG2C_SHIFT) )
-
-#define IEMPTY 0
-
-#define I1_XYZ ( R300_FPI1_SRC1C_CONST | \
- R300_FPI1_SRC2C_CONST | \
- R300_FPI1_DSTC_REG_X | \
- R300_FPI1_DSTC_REG_Y | \
- R300_FPI1_DSTC_REG_Z )
-#define I1_XY_ ( R300_FPI1_SRC1C_CONST | \
- R300_FPI1_SRC2C_CONST | \
- R300_FPI1_DSTC_REG_X | \
- R300_FPI1_DSTC_REG_Y )
-#define I1_X_Z ( R300_FPI1_SRC1C_CONST | \
- R300_FPI1_SRC2C_CONST | \
- R300_FPI1_DSTC_REG_X | \
- R300_FPI1_DSTC_REG_Z )
-#define I1__YZ ( R300_FPI1_SRC1C_CONST | \
- R300_FPI1_SRC2C_CONST | \
- R300_FPI1_DSTC_REG_Y | \
- R300_FPI1_DSTC_REG_Z )
-#define I1_X__ ( R300_FPI1_SRC1C_CONST | \
- R300_FPI1_SRC2C_CONST | \
- R300_FPI1_DSTC_REG_X )
-#define I1__Y_ ( R300_FPI1_SRC1C_CONST | \
- R300_FPI1_SRC2C_CONST | \
- R300_FPI1_DSTC_REG_Y )
-#define I1___Z ( R300_FPI1_SRC1C_CONST | \
- R300_FPI1_SRC2C_CONST | \
- R300_FPI1_DSTC_REG_Z )
-
-#define SEMPTY {0,{0,0,0,0},{0,0,0,0,0,0,0,0}}
-
-struct r300_fragment_program_swizzle r300_swizzle [512] = {
- /* XXX */
- {1,{0,0,0,0},{ I0_XXX, I1_XYZ,
- 0, 0, 0, 0, 0, 0 } },
- /* YXX */
- {2,{0,0,0,0},{ I0_YZX, I1_X_Z,
- I0_XXX, I1__Y_,
- 0,0,
- 0,0 } },
- /* ZXX */
- {2,{0,0,0,0},{ I0_ZZZ, I1_X__,
- I0_XXX, I1__YZ,
- 0,0,
- 0,0 } },
- /* WXX */
- {2,{0,0,0,0},{ I0_WZY, I1_X__,
- I0_XXX, I1__YZ,
- 0,0,
- 0,0} },
- /* 0XX */
- {2,{0,2,0,0},{ I0_XXX, I1__YZ,
- I0_000, I1_X__,
- 0,0,
- 0,0 } },
- /* 1XX */
- {2,{0,2,0,0},{ I0_XXX, I1__YZ,
- I0_111, I1_X__,
- 0,0,0,0}},
- SEMPTY,SEMPTY,
- /* XYX */
- {2,{0,0,0,0},{ I0_YYY, I1__Y_,
- I0_XXX, I1_X_Z,
- 0,0,0,0}},
- /* YYX */
- {2,{0,0,0,0},{ I0_YYY, I1_XY_,
- I0_XXX, I1___Z,
- 0,0,0,0}},
- /* ZYX */
- {3,{0,0,0,0},{ I0_ZZZ, I1_X__,
- I0_YYY, I1__Y_,
- I0_XXX, I1___Z,
- 0,0}},
- /* WYX */
- {3,{0,0,0,0},{ I0_WZY, I1_X__,
- I0_YYY, I1__Y_,
- I0_XXX, I1___Z,
- 0,0}},
- /* 0YX */
- {3,{0,0,2,0},{ I0_YYY, I1__Y_,
- I0_XXX, I1___Z,
- I0_000, I1_X__,
- 0,0}},
- /* 1YX */
- {3,{0,0,2,0},{ I0_YYY, I1__Y_,
- I0_XXX, I1___Z,
- I0_111, I1_X__,
- 0,0}},
- SEMPTY,SEMPTY,
- /* XZX */
- {2,{0,0,0,0},{ I0_YZX, I1__YZ,
- I0_XXX, I1_X__,
- 0,0,0,0}},
- /* YZX */
- {1,{0,0,0,0},{ I0_YZX, I1_XYZ,
- 0, 0, 0, 0, 0, 0 } },
- /* ZZX */
- {2,{0,0,0,0},{ I0_YZX, I1__YZ,
- I0_ZZZ, I1_X__,0,0,0,0}},
- /* WZX */
- {2,{0,0,0,0},{ I0_WZY, I1_XY_,
- I0_XXX, I1___Z,0,0,0,0}},
- /* 0ZX */
- {2,{0,2,0,0},{ I0_YZX, I1__YZ,
- I0_000, I1_X__,
- 0,0,0,0}},
- /* 1ZX */
- {2,{0,2,0,0},{ I0_YZX, I1__YZ,
- I0_111, I1_X__,
- 0,0,0,0}},
- SEMPTY,SEMPTY,
- /* XWX */
- {2,{0,0,0,0},{ I0_WWW, I1__Y_,
- I0_XXX, I1_X_Z,
- 0,0,0,0}},
- /* YWX */
- {2,{0,0,0,0},{ I0_WWW, I1__Y_,
- I0_YZX, I1_X_Z,
- 0,0,0,0}},
- /* ZWX */
- {3,{0,0,0,0},{ I0_WWW, I1__Y_,
- I0_ZZZ, I1_X__,
- I0_XXX, I1___Z,
- 0,0}},
- /* WWX */
- {2,{0,0,0,0},{ I0_WWW, I1_XY_,
- I0_YZX, I1___Z,
- 0,0,0,0}},
- /* 0WX */
- {3,{0,0,2,0},{ I0_WWW, I1__Y_,
- I0_XXX, I1___Z,
- I0_000, I1_X__,
- 0,0}},
- /* 1WX */
- {3,{0,0,2,0},{ I0_WWW, I1__Y_,
- I0_XXX, I1___Z,
- I0_111, I1_X__,
- 0,0}},
- SEMPTY,SEMPTY,
- /* X0X */
- {2,{0,2,0,0},{ I0_XXX, I1_X_Z,
- I0_000, I1__Y_,
- 0,0,0,0}},
- /* Y0X */
- {2,{0,2,0,0},{ I0_YZX, I1_X_Z,
- I0_000, I1__Y_,
- 0,0,0,0}},
- /* Z0X */
- {3,{0,2,0,0},{ I0_XXX, I1___Z,
- I0_000, I1__Y_,
- I0_ZZZ, I1_X__,
- 0,0}},
- /* W0X */
- {3,{0,0,2,0},{ I0_WZY, I1_XYZ,
- I0_XXX, I1___Z,
- I0_000, I1__Y_,
- 0,0}},
- /* 00X */
- {2,{0,2,0,0},{ I0_XXX, I1___Z,
- I0_000, I1_XY_,
- 0,0,0,0}},
- /* 10X */
- {3,{0,2,0,0},{ I0_XXX, I1___Z,
- I0_000, I1__Y_,
- I0_111, I1_X__,
- 0,0}},
- SEMPTY,SEMPTY,
- /* X1X */
- {2,{0,2,0,0},{ I0_XXX, I1_X_Z,
- I0_111, I1__Y_,
- 0,0,0,0}},
- /* Y1X */
- {2,{0,2,0,0},{ I0_YZX, I1_X_Z,
- I0_111, I1__Y_,
- 0,0,0,0}},
- /* Z1X */
- {3,{0,2,0,0},{ I0_XXX, I1___Z,
- I0_111, I1__Y_,
- I0_ZZZ, I1_X__,
- 0,0}},
- /* W1X */
- {3,{0,0,2,0},{ I0_WZY, I1_XYZ,
- I0_XXX, I1___Z,
- I0_111, I1__Y_,
- 0,0}},
- /* 01X */
- {3,{0,2,0,0},{ I0_XXX, I1___Z,
- I0_111, I1__Y_,
- I0_000, I1_X__,
- 0,0}},
- /* 11X */
- {2,{0,2,0,0},{ I0_XXX, I1___Z,
- I0_111, I1_XY_,
- 0,0,0,0}},
- SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,
- SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,
- /* XXY */
- {2,{0,0,0,0},{ I0_YYY, I1___Z,
- I0_XXX, I1_XY_,
- 0,0,0,0}},
- /* YXY */
- {2,{0,0,0,0},{ I0_YYY, I1_X_Z,
- I0_XXX, I1__Y_,
- 0,0,0,0}},
- /* ZXY */
- {1,{0,0,0,0},{ I0_ZXY, I1_XYZ,
- 0, 0, 0, 0, 0, 0 } },
- /* WXY */
- {2,{0,0,0,0},{ I0_WZY, I1_X__,
- I0_ZXY, I1__YZ,
- 0,0,0,0}},
- /* 0XY */
- {2,{0,0,0,0},{ I0_ZXY, I1__YZ,
- I0_000, I1_X__,
- 0,0,0,0}},
- /* 1XY */
- {2,{0,0,0,0},{ I0_ZXY, I1__YZ,
- I0_111, I1_X__,
- 0,0,0,0}},
- SEMPTY,SEMPTY,
- /* XYY */
- {2,{0,0,0,0},{ I0_YYY, I1__YZ,
- I0_XXX, I1_X__,
- 0,0,0,0}},
- /* YYY */
- {1,{0,0,0,0},{ I0_YYY, I1_XYZ,
- 0, 0, 0, 0, 0, 0 } },
- /* ZYY */
- {2,{0,0,0,0},{ I0_YYY, I1__YZ,
- I0_ZZZ, I1_X__,
- 0,0,0,0}},
- /* WYY */
- {2,{0,0,0,0},{ I0_WZY, I1_XYZ,
- I0_YYY, I1__YZ,
- 0,0,0,0}},
- /* 0YY */
- {2,{0,0,0,0},{ I0_YYY, I1__YZ,
- I0_000, I1_X__,
- 0,0,0,0}},
- /* 1YY */
- {2,{0,0,0,0},{ I0_YYY, I1__YZ,
- I0_111, I1_X__,
- 0,0,0,0}},
- SEMPTY,SEMPTY,
- /* XZY */
- {2,{0,0,0,0},{ I0_WZY, I1__YZ,
- I0_XXX, I1_X__,
- 0,0,0,0}},
- /* YZY */
- {2,{0,0,0,0},{ I0_WZY, I1__YZ,
- I0_YYY, I1_X__,
- 0,0,0,0}},
- /* ZZY */
- {2,{0,0,0,0},{ I0_WZY, I1__YZ,
- I0_ZZZ, I1_X__,
- 0,0,0,0}},
- /* WZY */
- {1,{0,0,0,0},{ I0_WZY, I1_XYZ,
- 0, 0, 0, 0, 0, 0 } },
- /* 0ZY */
- {2,{0,0,0,0},{ I0_WZY, I1__YZ,
- I0_000, I1_X__,
- 0,0,0,0}},
- /* 1ZY */
- {2,{0,0,0,0},{ I0_WZY, I1__YZ,
- I0_111, I1_X__,
- 0,0,0,0}},
- SEMPTY,SEMPTY,
- /* XWY */
- {3,{0,0,0,0},{ I0_WWW, I1__Y_,
- I0_XXX, I1_X__,
- I0_YYY, I1___Z,
- 0,0}},
- /* YWY */
- {2,{0,0,0,0},{ I0_WWW, I1__Y_,
- I0_YYY, I1_X_Z,
- 0,0,0,0}},
- /* ZWY */
- {2,{0,0,0,0},{ I0_WWW, I1__Y_,
- I0_ZXY, I1_X_Z,
- 0,0,0,0}},
- /* WWY */
- {2,{0,0,0,0},{ I0_WWW, I1_XY_,
- I0_ZXY, I1___Z,
- 0,0,0,0}},
- /* 0WY */
- {3,{0,0,2,0},{ I0_WWW, I1__Y_,
- I0_ZXY, I1___Z,
- I0_000, I1_X__,
- 0,0}},
- /* 1WY */
- {3,{0,0,0,0},{ I0_WWW, I1__Y_,
- I0_ZXY, I1___Z,
- I0_111, I1_X__,
- 0,0}},
- SEMPTY,SEMPTY,
- /* X0Y */
- {3,{0,2,0,0},{ I0_XXX, I1_X__,
- I0_000, I1__Y_,
- I0_YYY, I1___Z,
- 0,0}},
- /* Y0Y */
- {2,{0,2,0,0},{ I0_YYY, I1_X_Z,
- I0_000, I1__Y_,
- 0,0,0,0}},
- /* Z0Y */
- {2,{0,2,0,0},{ I0_ZXY, I1_X_Z,
- I0_000, I1__Y_,
- 0,0,0,0}},
- /* W0Y */
- {2,{0,2,0,0},{ I0_WZY, I1_X_Z,
- I0_000, I1__Y_,
- 0,0,0,0}},
- /* 00Y */
- {2,{0,2,0,0},{ I0_YYY, I1___Z,
- I0_000, I1_XY_,
- 0,0,0,0}},
- /* 10Y */
- {3,{0,2,0,0},{ I0_YYY, I1___Z,
- I0_000, I1__Y_,
- I0_111, I1_X__,
- 0,0}},
- SEMPTY,SEMPTY,
- /* X1Y */
- {3,{0,2,0,0},{ I0_XXX, I1_X__,
- I0_111, I1__Y_,
- I0_YYY, I1___Z,
- 0,0}},
- /* Y1Y */
- {2,{0,2,0,0},{ I0_YYY, I1_X_Z,
- I0_111, I1__Y_,
- 0,0,0,0}},
- /* Z1Y */
- {2,{0,2,0,0},{ I0_ZXY, I1_X_Z,
- I0_111, I1__Y_,
- 0,0,0,0}},
- /* W1Y */
- {3,{0,2,0,0},{ I0_WZY, I1_X_Z,
- I0_111, I1__Y_,
- 0,0,0,0}},
- /* 01Y */
- {3,{0,2,0,0},{ I0_YYY, I1___Z,
- I0_111, I1__Y_,
- I0_000, I1_X__,
- 0,0}},
- /* 11Y */
- {2,{0,2,0,0},{ I0_YYY, I1___Z,
- I0_111, I1_XY_,
- 0,0,0,0}},
- SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,
- SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,
- /* XXZ */
- {2,{0,0,0,0},{ I0_XXX, I1_XY_,
- I0_ZZZ, I1___Z,
- 0,0,0,0}},
- /* YXZ */
- {3,{0,0,0,0},{ I0_XXX, I1__Y_,
- I0_YYY, I1_X__,
- I0_ZZZ, I1___Z,
- 0,0}},
- /* ZXZ */
- {2,{0,0,0,0},{ I0_XXX, I1__Y_,
- I0_ZZZ, I1_X_Z,
- 0,0,0,0}},
- /* WXZ */
- {3,{0,0,0,0},{ I0_WZY, I1_XYZ,
- I0_XXX, I1__Y_,
- I0_ZZZ, I1___Z,
- 0,0}},
- /* 0XZ */
- {3,{0,0,2,0},{ I0_XXX, I1__Y_,
- I0_ZZZ, I1___Z,
- I0_000, I1_X__,
- 0,0}},
- /* 1XZ */
- {3,{0,0,2,0},{ I0_XXX, I1__Y_,
- I0_ZZZ, I1___Z,
- I0_111, I1_X__,
- 0,0}},
- SEMPTY,SEMPTY,
- /* XYZ */
- {1,{0,0,0,0},{ I0_XYZ, I1_XYZ,
- 0, 0, 0, 0, 0, 0 } },
- /* YYZ */
- {2,{0,0,0,0},{ I0_ZZZ, I1___Z,
- I0_YYY, I1_XY_,
- 0,0,0,0}},
- /* ZYZ */
- {2,{0,0,0,0},{ I0_ZZZ, I1_X_Z,
- I0_YYY, I1__Y_,
- 0,0,0,0}},
- /* WYZ */
- {2,{0,0,0,0},{ I0_WZY, I1_XYZ,
- I0_XYZ, I1__YZ,
- 0,0,0,0}},
- /* 0YZ */
- {2,{0,2,0,0},{ I0_XYZ, I1__YZ,
- I0_000, I1_X__,
- 0,0,0,0}},
- /* 1YZ */
- {2,{0,2,0,0},{ I0_XYZ, I1__YZ,
- I0_111, I1_X__,
- 0,0,0,0}},
- SEMPTY,SEMPTY,
- /* XZZ */
- {2,{0,0,0,0},{ I0_ZZZ, I1__YZ,
- I0_XXX, I1_X__,
- 0,0,0,0}},
- /* YZZ */
- {2,{0,0,0,0},{ I0_ZZZ, I1__YZ,
- I0_YYY, I1_X__,
- 0,0,0,0}},
- /* ZZZ */
- {1,{0,0,0,0},{ I0_ZZZ, I1_XYZ,
- 0, 0, 0, 0, 0, 0 } },
- /* WZZ */
- {2,{0,0,0,0},{ I0_WZY, I1_XYZ,
- I0_ZZZ, I1__YZ,
- 0,0,0,0}},
- /* 0ZZ */
- {2,{0,2,0,0},{ I0_ZZZ, I1__YZ,
- I0_000, I1_X__,
- 0,0,0,0}},
- /* 1ZZ */
- {2,{0,2,0,0},{ I0_ZZZ, I1__YZ,
- I0_111, I1_X__,
- 0,0,0,0}},
- SEMPTY,SEMPTY,
- /* XWZ */
- {2,{0,0,0,0},{ I0_WWW, I1__Y_,
- I0_XYZ, I1_X_Z,
- 0,0,0,0}},
- /* YWZ */
- {3,{0,0,0,0},{ I0_WWW, I1__Y_,
- I0_YYY, I1_X__,
- I0_XYZ, I1___Z,
- 0,0}},
- /* ZWZ */
- {2,{0,0,0,0},{ I0_WWW, I1__Y_,
- I0_ZZZ, I1_X_Z,
- 0,0,0,0}},
- /* WWZ */
- {2,{0,0,0,0},{ I0_WWW, I1_XY_,
- I0_XYZ, I1___Z,
- 0,0,0,0}},
- /* 0WZ */
- {3,{0,0,2,0},{ I0_WWW, I1__Y_,
- I0_XYZ, I1___Z,
- I0_000, I1_X__,
- 0,0}},
- /* 1WZ */
- {3,{0,0,2,0},{ I0_WWW, I1__Y_,
- I0_XYZ, I1___Z,
- I0_111, I1_X__,
- 0,0}},
- SEMPTY,SEMPTY,
- /* X0Z */
- {2,{0,2,0,0},{ I0_XYZ, I1_X_Z,
- I0_000, I1__Y_,
- 0,0,0,0}},
- /* Y0Z */
- {3,{0,2,0,0},{ I0_ZZZ, I1___Z,
- I0_000, I1__Y_,
- I0_YYY, I1_X__,
- 0,0}},
- /* Z0Z */
- {2,{0,2,0,0},{ I0_ZZZ, I1_X_Z,
- I0_000, I1__Y_,
- 0,0,0,0}},
- /* W0Z */
- {3,{0,0,2,0},{ I0_WZY, I1_X_Z,
- I0_ZZZ, I1___Z,
- I0_000, I1__Y_,
- 0,0}},
- /* 00Z */
- {2,{0,2,0,0},{ I0_ZZZ, I1___Z,
- I0_000, I1_XY_,
- 0,0,0,0}},
- /* 10Z */
- {3,{0,2,2,0},{ I0_ZZZ, I1___Z,
- I0_000, I1__Y_,
- I0_111, I1_X__,
- 0,0}},
- SEMPTY,SEMPTY,
- /* X1Z */
- {2,{0,2,0,0},{ I0_XYZ, I1_X_Z,
- I0_111, I1__Y_,
- 0,0,0,0}},
- /* Y1Z */
- {3,{0,2,0,0},{ I0_ZZZ, I1___Z,
- I0_111, I1__Y_,
- I0_YYY, I1_X__,
- 0,0}},
- /* Z1Z */
- {2,{0,2,0,0},{ I0_ZZZ, I1_X_Z,
- I0_111, I1__Y_,
- 0,0,0,0}},
- /* W1Z */
- {3,{0,0,2,0},{ I0_WZY, I1_XYZ,
- I0_ZZZ, I1___Z,
- I0_111, I1__Y_,
- 0,0}},
- /* 01Z */
- {3,{0,2,2,0},{ I0_ZZZ, I1___Z,
- I0_111, I1__Y_,
- I0_000, I1_X__,
- 0,0}},
- /* 11Z */
- {2,{0,2,0,0},{ I0_ZZZ, I1___Z,
- I0_111, I1_XY_,
- 0,0,0,0}},
- SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,
- SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,
- /* XXW */
- {2,{0,0,0,0},{ I0_WWW, I1___Z,
- I0_XXX, I1_XY_,
- 0,0,0,0}},
- /* YXW */
- {3,{0,0,0,0},{ I0_WWW, I1___Z,
- I0_XXX, I1__Y_,
- I0_YYY, I1_X__,
- 0,0}},
- /* ZXW */
- {2,{0,0,0,0},{ I0_WWW, I1___Z,
- I0_ZXY, I1_XY_,
- 0,0,0,0}},
- /* WXW */
- {2,{0,0,0,0},{ I0_WWW, I1_X_Z,
- I0_XXX, I1__Y_,
- 0,0,0,0}},
- /* 0XW */
- {3,{0,0,2,0},{ I0_WWW, I1___Z,
- I0_XXX, I1__Y_,
- I0_000, I1_X__,
- 0,0}},
- /* 1XW */
- {3,{0,0,2,0},{ I0_WWW, I1___Z,
- I0_XXX, I1__Y_,
- I0_111, I1_X__,
- 0,0}},
- SEMPTY,SEMPTY,
- /* XYW */
- {2,{0,0,0,0},{ I0_WWW, I1___Z,
- I0_XYZ, I1_XY_,
- 0,0,0,0}},
- /* YYW */
- {2,{0,0,0,0},{ I0_WWW, I1___Z,
- I0_YYY, I1_XY_,
- 0,0}},
- /* ZYW */
- {3,{0,0,0,0},{ I0_WWW, I1___Z,
- I0_XYZ, I1__Y_,
- I0_ZZZ, I1_X__,
- 0,0}},
- /* WYW */
- {2,{0,0,0,0},{ I0_WWW, I1_X_Z,
- I0_YYY, I1__Y_,
- 0,0,0,0}},
- /* 0YW */
- {3,{0,0,2,0},{ I0_WWW, I1___Z,
- I0_YYY, I1__Y_,
- I0_000, I1_X__,
- 0,0}},
- /* 1YW */
- {3,{0,0,2,0},{ I0_WWW, I1___Z,
- I0_YYY, I1__Y_,
- I0_111, I1_X__,
- 0,0}},
-
- SEMPTY,SEMPTY,
- /* XZW */
- {3,{0,0,0,0},{ I0_WWW, I1___Z,
- I0_XYZ, I1_X__,
- I0_ZZZ, I1__Y_,
- 0,0}},
- /* YZW */
- {2,{0,0,0,0},{ I0_WWW, I1___Z,
- I0_YZX, I1_XY_,
- 0,0,0,0}},
- /* ZZW */
- {2,{0,0,0,0},{ I0_WWW, I1___Z,
- I0_ZZZ, I1_XY_,
- 0,0,0,0}},
- /* WZW */
- {2,{0,0,0,0},{ I0_WWW, I1_X_Z,
- I0_ZZZ, I1__Y_,
- 0,0,0,0}},
- /* 0ZW */
- {3,{0,0,2,0},{ I0_WWW, I1___Z,
- I0_ZZZ, I1__Y_,
- I0_000, I1_X__,
- 0,0}},
- /* 1ZW */
- {3,{0,0,2,0},{ I0_WWW, I1___Z,
- I0_ZZZ, I1__Y_,
- I0_111, I1_X__,
- 0,0}},
-
- SEMPTY,SEMPTY,
- /* XWW */
- {2,{0,0,0,0},{ I0_WWW, I1__YZ,
- I0_XYZ, I1_X__,
- 0,0,0,0}},
- /* YWW */
- {2,{0,0,0,0},{ I0_WWW, I1__YZ,
- I0_YYY, I1_X__,
- 0,0,0,0}},
- /* ZWW */
- {2,{0,0,0,0},{ I0_WWW, I1__YZ,
- I0_ZZZ, I1_X__,
- 0,0,0,0}},
- /* WWW */
- {1,{0,0,0,0},{ I0_WWW, I1_XYZ,
- 0,0,0,0,0,0}},
- /* 0WW */
- {2,{0,2,0,0},{ I0_WWW, I1__YZ,
- I0_000, I1_X__,
- 0,0,0,0}},
- /* 1WW */
- {2,{0,2,0,0},{ I0_WWW, I1__YZ,
- I0_111, I1_X__,
- 0,0}},
- SEMPTY,SEMPTY,
- /* X0W */
- {3,{0,0,2,0},{ I0_WWW, I1___Z,
- I0_XYZ, I1_X__,
- I0_000, I1__Y_,
- 0,0}},
- /* Y0W */
- {3,{0,0,2,0},{ I0_WWW, I1___Z,
- I0_YYY, I1_X__,
- I0_000, I1__Y_,
- 0,0}},
- /* Z0W */
- {3,{0,0,2,0},{ I0_WWW, I1___Z,
- I0_ZZZ, I1_X__,
- I0_000, I1__Y_,
- 0,0}},
- /* W0W */
- {2,{0,2,0,0},{ I0_WWW, I1_X_Z,
- I0_000, I1__Y_,
- 0,0,0,0}},
- /* 00W */
- {2,{0,2,0,0},{ I0_WWW, I1___Z,
- I0_000, I1_XY_,
- 0,0,0,0}},
- /* 10W */
- {3,{0,2,2,0},{ I0_WWW, I1___Z,
- I0_111, I1_X__,
- I0_000, I1__Y_,
- 0,0}},
- SEMPTY,SEMPTY,
- /* X1W */
- {3,{0,0,2,0},{ I0_WWW, I1___Z,
- I0_XYZ, I1_X__,
- I0_111, I1__Y_,
- 0,0}},
- /* Y1W */
- {3,{0,0,2,0},{ I0_WWW, I1___Z,
- I0_YYY, I1_X__,
- I0_111, I1__Y_,
- 0,0}},
- /* Z1W */
- {3,{0,0,2,0},{ I0_WWW, I1___Z,
- I0_ZZZ, I1_X__,
- I0_111, I1__Y_,
- 0,0}},
- /* W1W */
- {2,{0,2,0,0},{ I0_WWW, I1_XYZ,
- I0_111, I1__Y_,
- 0,0,0,0}},
- /* 01W */
- {3,{0,2,2,0},{ I0_WWW, I1___Z,
- I0_000, I1_X__,
- I0_111, I1__Y_,
- 0,0}},
- /* 11W */
- {2,{0,2,0,0},{ I0_WWW, I1___Z,
- I0_111, I1_XY_,
- 0,0,0,0}},
- SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,
- SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,
- /* XX0 */
- {2,{0,2,0,0},{ I0_XXX, I1_XY_,
- I0_000, I1___Z,
- 0,0,0,0}},
- /* YX0 */
- {3,{0,0,2,0},{ I0_YYY, I1_X__,
- I0_XXX, I1__Y_,
- I0_000, I1___Z,
- 0,0}},
- /* ZX0 */
- {2,{0,2,0,0},{ I0_ZXY, I1_XY_,
- I0_000, I1___Z,
- 0,0,0,0}},
- /* WX0 */
- {3,{0,0,2,0},{ I0_WZY, I1_X__,
- I0_XXX, I1__Y_,
- I0_000, I1___Z,
- 0,0}},
- /* 0X0 */
- {2,{0,2,0,0},{ I0_XXX, I1__Y_,
- I0_000, I1_X_Z,
- 0,0,0,0}},
- /* 1X0 */
- {3,{0,2,2,0},{ I0_XXX, I1__Y_,
- I0_000, I1___Z,
- I0_111, I1_X__,
- 0,0}},
- SEMPTY,SEMPTY,
- /* XY0 */
- {2,{0,2,0,0},{ I0_XYZ, I1_XY_,
- I0_000, I1___Z,
- 0,0,0,0}},
- /* YY0 */
- {2,{0,2,0,0},{ I0_YYY, I1_XY_,
- I0_000, I1___Z,
- 0,0,0,0}},
- /* ZY0 */
- {3,{0,0,2,0},{ I0_YYY, I1__Y_,
- I0_ZZZ, I1_X__,
- I0_000, I1___Z,
- 0,0}},
- /* WY0 */
- {3,{0,0,2,0},{ I0_WZY, I1_X__,
- I0_XYZ, I1__Y_,
- I0_000, I1___Z,
- 0,0}},
- /* 0Y0 */
- {2,{0,2,0,0},{ I0_XYZ, I1__Y_,
- I0_000, I1_X_Z,
- 0,0,0,0}},
- /* 1Y0 */
- {3,{0,2,2,0},{ I0_XYZ, I1__Y_,
- I0_000, I1___Z,
- I0_111, I1_X__,
- 0,0}},
- SEMPTY,SEMPTY,
- /* XZ0 */
- {3,{0,0,2,0},{ I0_ZZZ, I1__Y_,
- I0_XYZ, I1_X__,
- I0_000, I1___Z,
- 0,0}},
- /* YZ0 */
- {2,{0,2,0,0},{ I0_YZX, I1_XY_,
- I0_000, I1___Z,
- 0,0,0,0}},
- /* ZZ0 */
- {2,{0,2,0,0},{ I0_ZZZ, I1_XY_,
- I0_000, I1___Z,
- 0,0,0,0}},
- /* WZ0 */
- {3,{0,0,2,0},{ I0_XYZ, I1_XYZ,
- I0_WZY, I1_XY_,
- I0_000, I1___Z,
- 0,0}},
- /* 0Z0 */
- {2,{0,2,0,0},{ I0_ZZZ, I1__Y_,
- I0_000, I1_X_Z,
- 0,0,0,0}},
- /* 1Z0 */
- {3,{0,2,2,0},{ I0_ZZZ, I1__Y_,
- I0_000, I1___Z,
- I0_111, I1_X__,
- 0,0}},
- SEMPTY,SEMPTY,
- /* XW0 */
- {3,{0,0,2,0},{ I0_WWW, I1__Y_,
- I0_XYZ, I1_X__,
- I0_000, I1___Z,
- 0,0}},
- /* YW0 */
- {3,{0,2,0,0},{ I0_WWW, I1__Y_,
- I0_000, I1___Z,
- I0_YYY, I1_X__,
- 0,0}},
- /* ZW0 */
- {3,{0,2,0,0},{ I0_WWW, I1__Y_,
- I0_000, I1___Z,
- I0_ZZZ, I1_X__,
- 0,0}},
- /* WW0 */
- {2,{0,2,0,0},{ I0_WWW, I1_XY_,
- I0_000, I1___Z,
- 0,0,0,0}},
- /* 0W0 */
- {2,{0,2,0,0},{ I0_WWW, I1__Y_,
- I0_000, I1_X_Z,
- 0,0,0,0}},
- /* 1W0 */
- {3,{0,2,2,0},{ I0_WWW, I1__Y_,
- I0_000, I1___Z,
- I0_111, I1_X__,
- 0,0}},
- SEMPTY,SEMPTY,
- /* X00 */
- {2,{0,2,0,0},{ I0_XYZ, I1_X__,
- I0_000, I1__YZ,
- 0,0,0,0}},
- /* Y00 */
- {2,{0,2,0,0},{ I0_YYY, I1_X__,
- I0_000, I1__YZ,
- 0,0,0,0}},
- /* Z00 */
- {2,{0,2,0,0},{ I0_ZZZ, I1_X__,
- I0_000, I1__YZ,
- 0,0,0,0}},
- /* W00 */
- {2,{2,0,0,0},{ I0_WZY, I1_X__,
- I0_000, I1__YZ,
- 0,0,0,0}},
- /* 000 */
- {1,{2,0,0,0},{ I0_000, I1_XYZ,
- 0, 0, 0, 0, 0, 0 } },
- /* 100 */
- {2,{2,2,0,0},{ I0_000, I1__YZ,
- I0_111, I1_X__,
- 0,0,0,0}},
- SEMPTY,SEMPTY,
- /* X10 */
- {3,{0,2,2,0},{ I0_XYZ, I1_XYZ,
- I0_000, I1___Z,
- I0_111, I1__Y_,
- 0,0}},
- /* Y10 */
- {3,{0,2,2,0},{ I0_YYY, I1_XYZ,
- I0_000, I1___Z,
- I0_111, I1__Y_,
- 0,0}},
- /* Z10 */
- {3,{0,2,2,0},{ I0_ZZZ, I1_XYZ,
- I0_000, I1___Z,
- I0_111, I1__Y_,
- 0,0}},
- /* W10 */
- {3,{0,2,2,0},{ I0_WZY, I1_XYZ,
- I0_000, I1___Z,
- I0_111, I1__Y_,
- 0,0}},
- /* 010 */
- {2,{2,2,0,0},{ I0_000, I1_X_Z,
- I0_111, I1__Y_,
- 0, 0, 0, 0 } },
- /* 110 */
- {2,{2,2,0,0},{ I0_000, I1___Z,
- I0_111, I1_XY_,
- 0,0,0,0}},
- SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,
- SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,
-
-
-
- /* XX1 */
- {2,{0,2,0,0},{ I0_XXX, I1_XY_,
- I0_111, I1___Z,
- 0,0,0,0}},
- /* YX1 */
- {3,{0,0,2,0},{ I0_YYY, I1_X__,
- I0_XXX, I1__Y_,
- I0_111, I1___Z,
- 0,0}},
- /* ZX1 */
- {2,{0,2,0,0},{ I0_ZXY, I1_XY_,
- I0_111, I1___Z,
- 0,0,0,0}},
- /* WX1 */
- {3,{0,0,2,0},{ I0_WZY, I1_XYZ,
- I0_XXX, I1__Y_,
- I0_111, I1___Z,
- 0,0}},
- /* 0X1 */
- {3,{0,2,2,0},{ I0_XXX, I1__Y_,
- I0_111, I1___Z,
- I0_000, I1_X__,
- 0,0}},
- /* 1X1 */
- {2,{0,2,0,0},{ I0_XXX, I1__Y_,
- I0_111, I1_X_Z,
- 0,0,0,0}},
- SEMPTY,SEMPTY,
- /* XY1 */
- {2,{0,2,0,0},{ I0_XYZ, I1_XY_,
- I0_111, I1___Z,
- 0,0,0,0}},
- /* YY1 */
- {2,{0,2,0,0},{ I0_YYY, I1_XY_,
- I0_111, I1___Z,
- 0,0,0,0}},
- /* ZY1 */
- {3,{0,0,2,0},{ I0_YYY, I1__Y_,
- I0_ZZZ, I1_X__,
- I0_111, I1___Z,
- 0,0}},
- /* WY1 */
- {3,{0,0,2,0},{ I0_WZY, I1_XYZ,
- I0_XYZ, I1__Y_,
- I0_111, I1___Z,
- 0,0}},
- /* 0Y1 */
- {3,{0,2,2,0},{ I0_XYZ, I1__Y_,
- I0_111, I1___Z,
- I0_000, I1_X__,
- 0,0}},
- /* 1Y1 */
- {2,{0,2,0,0},{ I0_XYZ, I1__Y_,
- I0_111, I1_X_Z,
- 0,0,0,0}},
- SEMPTY,SEMPTY,
- /* XZ1 */
- {3,{0,0,2,0},{ I0_ZZZ, I1__Y_,
- I0_XYZ, I1_X__,
- I0_111, I1___Z,
- 0,0}},
- /* YZ1 */
- {2,{0,2,0,0},{ I0_YZX, I1_XY_,
- I0_111, I1___Z,
- 0,0,0,0}},
- /* ZZ1 */
- {2,{0,2,0,0},{ I0_ZZZ, I1_XYZ,
- I0_111, I1___Z,
- 0,0,0,0}},
- /* WZ1 */
- {2,{0,2,0,0},{ I0_WZY, I1_XY_,
- I0_111, I1___Z,
- 0,0,0,0}},
- /* 0Z1 */
- {3,{0,2,2,0},{ I0_ZZZ, I1_XYZ,
- I0_111, I1___Z,
- I0_000, I1_X__,
- 0,0}},
- /* 1Z1 */
- {2,{0,2,0,0},{ I0_ZZZ, I1__Y_,
- I0_111, I1_X_Z,
- 0,0,0,0}},
- SEMPTY,SEMPTY,
- /* XW1 */
- {3,{0,0,2,0},{ I0_WWW, I1__Y_,
- I0_XYZ, I1_X__,
- I0_111, I1___Z,
- 0,0}},
- /* YW1 */
- {3,{0,2,0,0},{ I0_WWW, I1__Y_,
- I0_111, I1___Z,
- I0_YYY, I1_X__,
- 0,0}},
- /* ZW1 */
- {3,{0,2,0,0},{ I0_WWW, I1__Y_,
- I0_111, I1___Z,
- I0_ZZZ, I1_X__,
- 0,0}},
- /* WW1 */
- {2,{0,2,0,0},{ I0_WWW, I1_XY_,
- I0_111, I1___Z,
- 0,0,0,0}},
- /* 0W1 */
- {3,{0,2,2,0},{ I0_WWW, I1__Y_,
- I0_111, I1___Z,
- I0_000, I1_X__,
- 0,0}},
- /* 1W1 */
- {2,{0,2,0,0},{ I0_WWW, I1__Y_,
- I0_111, I1_X_Z,
- 0,0,0,0}},
- SEMPTY,SEMPTY,
- /* X01 */
- {3,{0,2,2,0},{ I0_XYZ, I1_X__,
- I0_111, I1___Z,
- I0_000, I1__Y_,
- 0,0}},
- /* Y01 */
- {3,{0,2,2,0},{ I0_YYY, I1_X__,
- I0_111, I1___Z,
- I0_000, I1__Y_,
- 0,0}},
- /* Z01 */
- {3,{0,2,2,0},{ I0_ZZZ, I1_X__,
- I0_111, I1___Z,
- I0_000, I1__Y_,
- 0,0}},
- /* W01 */
- {3,{0,2,2,0},{ I0_WZY, I1_XYZ,
- I0_111, I1___Z,
- I0_000, I1__Y_,
- 0,0}},
- /* 001 */
- {2,{2,2,0,0},{ I0_111, I1___Z,
- I0_000, I1_XY_,
- 0,0,0,0}},
- /* 101 */
- {2,{2,2,0,0},{ I0_111, I1_X_Z,
- I0_000, I1__Y_,
- 0, 0, 0, 0 } },
- SEMPTY,SEMPTY,
- /* X11 */
- {2,{0,2,0,0},{ I0_XYZ, I1_X__,
- I0_111, I1__YZ,
- 0,0,0,0}},
- /* Y11 */
- {2,{0,2,0,0},{ I0_YYY, I1_X__,
- I0_111, I1__YZ,
- 0,0,0,0}},
- /* Z11 */
- {2,{0,2,0,0},{ I0_ZZZ, I1_X__,
- I0_111, I1__YZ,
- 0,0,0,0}},
- /* W11 */
- {2,{0,2,0,0},{ I0_WZY, I1_XYZ,
- I0_111, I1__YZ,
- 0,0,0,0}},
- /* 011 */
- {2,{2,2,0,0},{ I0_111, I1__YZ,
- I0_000, I1_X__,
- 0,0,0,0}},
- /* 111 */
- {1,{2,0,0,0},{ I0_111, I1_XYZ,
- 0, 0, 0, 0, 0, 0 } },
- SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,
- SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,
- SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,
- SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,
- SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,
- SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,
- SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,
- SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,
- SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,
- SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,
- SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,
- SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,
- SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,
- SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,
- SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY
-};
-
-/******************************************************************************
-* Color source mask table
-******************************************************************************/
-
-#define S_111 R300_FPI0_ARGC_ONE
-#define S_000 R300_FPI0_ARGC_ZERO
-
-#define S0XXX R300_FPI0_ARGC_SRC0C_XXX
-#define S0YYY R300_FPI0_ARGC_SRC0C_YYY
-#define S0ZZZ R300_FPI0_ARGC_SRC0C_ZZZ
-#define S0WWW R300_FPI0_ARGC_SRC0A
-#define S0XYZ R300_FPI0_ARGC_SRC0C_XYZ
-#define S0ZXY R300_FPI0_ARGC_SRC0C_ZXY
-#define S0YZX R300_FPI0_ARGC_SRC0C_YZX
-#define S0WZY R300_FPI0_ARGC_SRC0CA_WZY
-#define S0WZY R300_FPI0_ARGC_SRC0CA_WZY
-
-#define S1XXX R300_FPI0_ARGC_SRC1C_XXX
-#define S1YYY R300_FPI0_ARGC_SRC1C_YYY
-#define S1ZZZ R300_FPI0_ARGC_SRC1C_ZZZ
-#define S1WWW R300_FPI0_ARGC_SRC1A
-#define S1XYZ R300_FPI0_ARGC_SRC1C_XYZ
-#define S1ZXY R300_FPI0_ARGC_SRC1C_ZXY
-#define S1YZX R300_FPI0_ARGC_SRC1C_YZX
-#define S1WZY R300_FPI0_ARGC_SRC1CA_WZY
-
-#define S2XXX R300_FPI0_ARGC_SRC2C_XXX
-#define S2YYY R300_FPI0_ARGC_SRC2C_YYY
-#define S2ZZZ R300_FPI0_ARGC_SRC2C_ZZZ
-#define S2WWW R300_FPI0_ARGC_SRC2A
-#define S2XYZ R300_FPI0_ARGC_SRC2C_XYZ
-#define S2ZXY R300_FPI0_ARGC_SRC2C_ZXY
-#define S2YZX R300_FPI0_ARGC_SRC2C_YZX
-#define S2WZY R300_FPI0_ARGC_SRC2CA_WZY
-
-#define ntnat 32
-
-const GLuint r300_swz_srcc_mask[3][512] = {
- {
- S0XXX,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S0YZX,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S0ZXY,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,S0YYY,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,S0WZY,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S0XYZ,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S0ZZZ,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S0WWW,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,S_000,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,S_111,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat
- },
- {
- S1XXX,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S1YZX,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S1ZXY,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,S1YYY,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,S1WZY,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S1XYZ,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S1ZZZ,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S1WWW,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,S_000,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,S_111,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat
- },
- {
- S2XXX,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S2YZX,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S2ZXY,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,S2YYY,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,S2WZY,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S2XYZ,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S2ZZZ,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S2WWW,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,S_000,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,S_111,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,
- ntnat,ntnat
- }
-};
-
-/******************************************************************************
-* Alpha source mask table
-******************************************************************************/
-
-GLuint r300_swz_srca_mask[3][6] = {
- { R300_FPI2_ARGA_SRC0C_X,
- R300_FPI2_ARGA_SRC0C_Y,
- R300_FPI2_ARGA_SRC0C_Z,
- R300_FPI2_ARGA_SRC0A,
- R300_FPI2_ARGA_ZERO,
- R300_FPI2_ARGA_ONE },
- { R300_FPI2_ARGA_SRC1C_X,
- R300_FPI2_ARGA_SRC1C_Y,
- R300_FPI2_ARGA_SRC1C_Z,
- R300_FPI2_ARGA_SRC1A,
- R300_FPI2_ARGA_ZERO,
- R300_FPI2_ARGA_ONE },
- { R300_FPI2_ARGA_SRC2C_X,
- R300_FPI2_ARGA_SRC2C_Y,
- R300_FPI2_ARGA_SRC2C_Z,
- R300_FPI2_ARGA_SRC2A,
- R300_FPI2_ARGA_ZERO,
- R300_FPI2_ARGA_ONE },
-};
diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c
index 87276a11ae..0774a2af6b 100644
--- a/src/mesa/drivers/dri/r300/r300_ioctl.c
+++ b/src/mesa/drivers/dri/r300/r300_ioctl.c
@@ -570,9 +570,10 @@ void r300Flush(GLcontext * ctx)
#ifdef USER_BUFFERS
#include "radeon_mm.h"
-void r300RefillCurrentDmaRegion(r300ContextPtr rmesa)
+void r300RefillCurrentDmaRegion(r300ContextPtr rmesa, int size)
{
struct r300_dma_buffer *dmabuf;
+ size = MAX2(size, RADEON_BUFFER_SIZE*16);
if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
fprintf(stderr, "%s\n", __FUNCTION__);
@@ -591,20 +592,20 @@ void r300RefillCurrentDmaRegion(r300ContextPtr rmesa)
dmabuf->buf = (void *)1; /* hack */
dmabuf->refcount = 1;
- dmabuf->id = radeon_mm_alloc(rmesa, 4, RADEON_BUFFER_SIZE*16);
+ dmabuf->id = radeon_mm_alloc(rmesa, 4, size);
if (dmabuf->id == 0) {
LOCK_HARDWARE(&rmesa->radeon); /* no need to validate */
r300FlushCmdBufLocked(rmesa, __FUNCTION__);
radeonWaitForIdleLocked(&rmesa->radeon);
- dmabuf->id = radeon_mm_alloc(rmesa, 4, RADEON_BUFFER_SIZE*16);
+ dmabuf->id = radeon_mm_alloc(rmesa, 4, size);
#ifdef HW_VBOS
if (dmabuf->id == 0) {
/* Just kick all */
r300_evict_vbos(rmesa->radeon.glCtx, /*RADEON_BUFFER_SIZE*16*/1<<30);
- dmabuf->id = radeon_mm_alloc(rmesa, 4, RADEON_BUFFER_SIZE*16);
+ dmabuf->id = radeon_mm_alloc(rmesa, 4, size);
}
#endif
UNLOCK_HARDWARE(&rmesa->radeon);
@@ -617,7 +618,7 @@ void r300RefillCurrentDmaRegion(r300ContextPtr rmesa)
rmesa->dma.current.buf = dmabuf;
rmesa->dma.current.address = radeon_mm_ptr(rmesa, dmabuf->id);
- rmesa->dma.current.end = RADEON_BUFFER_SIZE*16;
+ rmesa->dma.current.end = size;
rmesa->dma.current.start = 0;
rmesa->dma.current.ptr = 0;
}
@@ -665,7 +666,8 @@ void r300AllocDmaRegion(r300ContextPtr rmesa,
(rmesa->dma.current.ptr + alignment) & ~alignment;
if (rmesa->dma.current.ptr + bytes > rmesa->dma.current.end)
- r300RefillCurrentDmaRegion(rmesa);
+ r300RefillCurrentDmaRegion(rmesa,
+ (bytes + 0x7) & ~0x7);
region->start = rmesa->dma.current.start;
region->ptr = rmesa->dma.current.start;
diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.h b/src/mesa/drivers/dri/r300/r300_ioctl.h
index 5514214cc6..52325646e9 100644
--- a/src/mesa/drivers/dri/r300/r300_ioctl.h
+++ b/src/mesa/drivers/dri/r300/r300_ioctl.h
@@ -50,7 +50,6 @@ extern GLuint r300GartOffsetFromVirtual(r300ContextPtr rmesa,
extern void r300Flush(GLcontext * ctx);
-extern void r300RefillCurrentDmaRegion(r300ContextPtr rmesa);
extern void r300ReleaseDmaRegion(r300ContextPtr rmesa,
struct r300_dma_region *region, const char *caller);
extern void r300AllocDmaRegion(r300ContextPtr rmesa,
diff --git a/src/mesa/drivers/dri/r300/r300_maos.c b/src/mesa/drivers/dri/r300/r300_maos.c
index 2fdad519fd..fcb87cbbb5 100644
--- a/src/mesa/drivers/dri/r300/r300_maos.c
+++ b/src/mesa/drivers/dri/r300/r300_maos.c
@@ -407,8 +407,8 @@ int r300EmitArrays(GLcontext *ctx)
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)->Base.InputsRead;
- OutputsWritten = CURRENT_VERTEX_SHADER(ctx)->Base.OutputsWritten;
+ 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;
diff --git a/src/mesa/drivers/dri/r300/r300_shader.c b/src/mesa/drivers/dri/r300/r300_shader.c
index 576b18953f..26721e8dfd 100644
--- a/src/mesa/drivers/dri/r300/r300_shader.c
+++ b/src/mesa/drivers/dri/r300/r300_shader.c
@@ -12,13 +12,13 @@ r300BindProgram(GLcontext *ctx, GLenum target, struct gl_program *prog)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
- struct r300_vertex_program *vp=(void *)prog;
+ struct r300_vertex_program_cont *vp=(void *)prog;
switch(target){
case GL_VERTEX_PROGRAM_ARB:
- rmesa->curr_vp = (struct gl_vertex_program *)vp;
- vp->ref_count++;
+ //rmesa->curr_vp = (struct gl_vertex_program *)vp;
+ //vp->ref_count++;
#if 0
if((vp->ref_count % 1500) == 0) {
fprintf(stderr, "id %p, ref_count %d\n", vp, vp->ref_count);
@@ -37,13 +37,13 @@ r300BindProgram(GLcontext *ctx, GLenum target, struct gl_program *prog)
static struct gl_program *
r300NewProgram(GLcontext *ctx, GLenum target, GLuint id)
{
- struct r300_vertex_program *vp;
+ struct r300_vertex_program_cont *vp;
struct r300_fragment_program *fp;
switch(target){
case GL_VERTEX_STATE_PROGRAM_NV:
case GL_VERTEX_PROGRAM_ARB:
- vp=CALLOC_STRUCT(r300_vertex_program);
+ vp=CALLOC_STRUCT(r300_vertex_program_cont);
return _mesa_init_vertex_program(ctx, &vp->mesa_program, target, id);
case GL_FRAGMENT_PROGRAM_ARB:
fp=CALLOC_STRUCT(r300_fragment_program);
@@ -77,13 +77,14 @@ r300DeleteProgram(GLcontext *ctx, struct gl_program *prog)
static void
r300ProgramStringNotify(GLcontext *ctx, GLenum target, struct gl_program *prog)
{
- struct r300_vertex_program *vp=(void *)prog;
+ struct r300_vertex_program_cont *vp=(void *)prog;
struct r300_fragment_program *fp = (struct r300_fragment_program *) prog;
switch(target) {
case GL_VERTEX_PROGRAM_ARB:
- vp->translated = GL_FALSE;
- memset(&vp->translated, 0, sizeof(struct r300_vertex_program) - sizeof(struct gl_vertex_program));
+ vp->progs = NULL;
+ /*vp->translated = GL_FALSE;
+ memset(&vp->translated, 0, sizeof(struct r300_vertex_program) - sizeof(struct gl_vertex_program));*/
/*r300_translate_vertex_shader(vp);*/
break;
case GL_FRAGMENT_PROGRAM_ARB:
diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
index 6aff04fd27..1930a683f1 100644
--- a/src/mesa/drivers/dri/r300/r300_state.c
+++ b/src/mesa/drivers/dri/r300/r300_state.c
@@ -206,7 +206,7 @@ static void r300_set_blend_state(GLcontext * ctx)
(R300_BLEND_GL_ZERO << R300_DST_BLEND_SHIFT);
int eqnA = R300_COMB_FCN_ADD_CLAMP;
- if (ctx->Color._LogicOpEnabled || !ctx->Color.BlendEnabled) {
+ if (RGBA_LOGICOP_ENABLED(ctx) || !ctx->Color.BlendEnabled) {
r300_set_blend_cntl(r300,
func, eqn, 0,
func, eqn);
@@ -1044,6 +1044,59 @@ r300UpdateDrawBuffer(GLcontext *ctx)
#endif
}
+static void r300FetchStateParameter(GLcontext *ctx, const enum state_index state[],
+ GLfloat *value)
+{
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
+
+ switch(state[0])
+ {
+ case STATE_INTERNAL:
+ switch(state[1])
+ {
+ case STATE_R300_WINDOW_DIMENSION:
+ value[0] = r300->radeon.dri.drawable->w; /* width */
+ value[1] = r300->radeon.dri.drawable->h; /* height */
+ value[2] = 0.5F; /* for moving range [-1 1] -> [0 1] */
+ value[3] = 1.0F; /* not used */
+ break;
+ default:;
+ }
+ default:;
+ }
+}
+
+/**
+ * Update R300's own internal state parameters.
+ * For now just STATE_R300_WINDOW_DIMENSION
+ */
+static void r300UpdateStateParameters(GLcontext * ctx, GLuint new_state)
+{
+ struct r300_vertex_program_cont *vpc;
+ struct gl_program_parameter_list *paramList;
+ GLuint i;
+
+ if(!(new_state & (_NEW_BUFFERS|_NEW_PROGRAM)))
+ return;
+
+ vpc = (struct r300_vertex_program_cont *)ctx->VertexProgram._Current;
+ if (!vpc)
+ return;
+
+ paramList = vpc->mesa_program.Base.Parameters;
+
+ if (!paramList)
+ return;
+
+ for (i = 0; i < paramList->NumParameters; i++) {
+ if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR){
+ r300FetchStateParameter(ctx,
+ paramList->Parameters[i].StateIndexes,
+ paramList->ParameterValues[i]);
+ }
+ }
+}
+
/* =============================================================
* Polygon state
*/
@@ -1285,7 +1338,7 @@ void r300_setup_rs_unit(GLcontext *ctx)
int i;
if(hw_tcl_on)
- OutputsWritten.vp_outputs = CURRENT_VERTEX_SHADER(ctx)->Base.OutputsWritten;
+ OutputsWritten.vp_outputs = CURRENT_VERTEX_SHADER(ctx)->key.OutputsWritten;
else
RENDERINPUTS_COPY( OutputsWritten.index_bitset, r300->state.render_inputs_bitset );
@@ -1304,6 +1357,20 @@ void r300_setup_rs_unit(GLcontext *ctx)
r300->hw.rr.cmd[R300_RR_ROUTE_1] = 0;
+ 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");
+ exit(0);
+ }
+
+ InputsRead |= (FRAG_BIT_TEX0 << i);
+ InputsRead &= ~FRAG_BIT_WPOS;
+ }
+
for (i=0;i<ctx->Const.MaxTextureUnits;i++) {
r300->hw.ri.cmd[R300_RI_INTERP_0+i] = 0
| R300_RS_INTERP_USED
@@ -1610,7 +1677,7 @@ void r300SetupVertexProgram(r300ContextPtr rmesa)
((drm_r300_cmd_header_t*)rmesa->hw.vpp.cmd)->vpu.count = 0;
R300_STATECHANGE(rmesa, vpp);
- param_count = r300VertexProgUpdateParams(ctx, prog, (float *)&rmesa->hw.vpp.cmd[R300_VPP_PARAM_0]);
+ param_count = r300VertexProgUpdateParams(ctx, (struct r300_vertex_program_cont *)ctx->VertexProgram._Current/*prog*/, (float *)&rmesa->hw.vpp.cmd[R300_VPP_PARAM_0]);
bump_vpu_count(rmesa->hw.vpp.cmd, param_count);
param_count /= 4;
@@ -1669,9 +1736,10 @@ void r300UpdateShaders(r300ContextPtr rmesa)
TNL_CONTEXT(ctx)->vb.AttribPtr[i] = rmesa->temp_attrib[i];
}
+ r300_select_vertex_shader(rmesa);
vp = (struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);
- if (vp->translated == GL_FALSE)
- r300_translate_vertex_shader(vp);
+ /*if (vp->translated == GL_FALSE)
+ r300_translate_vertex_shader(vp);*/
if (vp->translated == GL_FALSE) {
fprintf(stderr, "Failing back to sw-tcl\n");
hw_tcl_on = future_hw_tcl_on = 0;
@@ -1679,6 +1747,7 @@ void r300UpdateShaders(r300ContextPtr rmesa)
return ;
}
+ r300UpdateStateParameters(ctx, _NEW_PROGRAM);
}
}
@@ -1812,6 +1881,9 @@ static void r300InvalidateState(GLcontext * ctx, GLuint new_state)
if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) {
r300UpdateDrawBuffer(ctx);
}
+
+ r300UpdateStateParameters(ctx, new_state);
+
#ifndef CB_DPATH
/* Go inefficiency! */
r300ResetHwState(r300);
diff --git a/src/mesa/drivers/dri/r300/r300_vertexprog.c b/src/mesa/drivers/dri/r300/r300_vertexprog.c
index cc932b86d9..c08c98767e 100644
--- a/src/mesa/drivers/dri/r300/r300_vertexprog.c
+++ b/src/mesa/drivers/dri/r300/r300_vertexprog.c
@@ -95,7 +95,7 @@ static struct{
};
#undef OPN
-int r300VertexProgUpdateParams(GLcontext *ctx, struct r300_vertex_program *vp, float *dst)
+int r300VertexProgUpdateParams(GLcontext *ctx, struct r300_vertex_program_cont *vp, float *dst)
{
int pi;
struct gl_vertex_program *mesa_vp = &vp->mesa_program;
@@ -177,17 +177,9 @@ static unsigned long t_dst_class(enum register_file file)
static unsigned long t_dst_index(struct r300_vertex_program *vp, struct prog_dst_register *dst)
{
- if(dst->File == PROGRAM_OUTPUT) {
- if (vp->outputs[dst->Index] != -1)
- return vp->outputs[dst->Index];
- else {
- WARN_ONCE("Unknown output %d\n", dst->Index);
- return 10;
- }
- }else if(dst->File == PROGRAM_ADDRESS) {
- assert(dst->Index == 0);
- }
-
+ if(dst->File == PROGRAM_OUTPUT)
+ return vp->outputs[dst->Index];
+
return dst->Index;
}
@@ -335,6 +327,18 @@ static unsigned long op_operands(enum prog_opcode opcode)
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){
+ WARN_ONCE("Output %d not used by fragment program\n", dst->Index);
+ 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 && \
@@ -384,10 +388,8 @@ static unsigned long op_operands(enum prog_opcode opcode)
u_temp_i=VSF_MAX_FRAGMENT_TEMPS-1; \
} while (0)
-void r300_translate_vertex_shader(struct r300_vertex_program *vp)
+static void r300_translate_vertex_shader(struct r300_vertex_program *vp, struct prog_instruction *vpi)
{
- struct gl_vertex_program *mesa_vp= &vp->mesa_program;
- struct prog_instruction *vpi;
int i, cur_reg=0;
VERTEX_SHADER_INSTRUCTION *o_inst;
unsigned long operands;
@@ -399,131 +401,9 @@ void r300_translate_vertex_shader(struct r300_vertex_program *vp)
int u_temp_i=VSF_MAX_FRAGMENT_TEMPS-1;
struct prog_src_register src[3];
- if (mesa_vp->Base.NumInstructions == 0)
- return;
-
- if (getenv("R300_VP_SAFETY")) {
- WARN_ONCE("R300_VP_SAFETY enabled.\n");
-
- vpi = malloc((mesa_vp->Base.NumInstructions + VSF_MAX_FRAGMENT_TEMPS) * sizeof(struct prog_instruction));
- memset(vpi, 0, VSF_MAX_FRAGMENT_TEMPS * sizeof(struct prog_instruction));
-
- for (i=0; i < VSF_MAX_FRAGMENT_TEMPS; i++) {
- vpi[i].Opcode = OPCODE_MOV;
- vpi[i].StringPos = 0;
- vpi[i].Data = 0;
-
- vpi[i].DstReg.File = PROGRAM_TEMPORARY;
- vpi[i].DstReg.Index = i;
- vpi[i].DstReg.WriteMask = WRITEMASK_XYZW;
- vpi[i].DstReg.CondMask = COND_TR;
-
- vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR;
- vpi[i].SrcReg[0].Index = 0;
- vpi[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE);
- }
-
- memcpy(&vpi[i], mesa_vp->Base.Instructions, mesa_vp->Base.NumInstructions * sizeof(struct prog_instruction));
-
- free(mesa_vp->Base.Instructions);
-
- mesa_vp->Base.Instructions = vpi;
-
- mesa_vp->Base.NumInstructions += VSF_MAX_FRAGMENT_TEMPS;
- vpi = &mesa_vp->Base.Instructions[mesa_vp->Base.NumInstructions-1];
-
- assert(vpi->Opcode == OPCODE_END);
- }
-
- if (mesa_vp->IsPositionInvariant) {
- struct gl_program_parameter_list *paramList;
- GLint tokens[6] = { STATE_MATRIX, STATE_MVP, 0, 0, 0, STATE_MATRIX };
-
-#ifdef PREFER_DP4
- tokens[5] = STATE_MATRIX;
-#else
- tokens[5] = STATE_MATRIX_TRANSPOSE;
-#endif
- paramList = mesa_vp->Base.Parameters;
-
- vpi = malloc((mesa_vp->Base.NumInstructions + 4) * sizeof(struct prog_instruction));
- memset(vpi, 0, 4 * sizeof(struct prog_instruction));
-
- for (i=0; i < 4; i++) {
- GLint idx;
- tokens[3] = tokens[4] = 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 = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
-
- vpi[i].SrcReg[1].File = PROGRAM_INPUT;
- vpi[i].SrcReg[1].Index = VERT_ATTRIB_POS;
- vpi[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
-#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 = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
-
- 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 = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
- }
-#endif
- }
-
- memcpy(&vpi[i], mesa_vp->Base.Instructions, mesa_vp->Base.NumInstructions * sizeof(struct prog_instruction));
-
- free(mesa_vp->Base.Instructions);
-
- mesa_vp->Base.Instructions = vpi;
-
- mesa_vp->Base.NumInstructions += 4;
- vpi = &mesa_vp->Base.Instructions[mesa_vp->Base.NumInstructions-1];
-
- assert(vpi->Opcode == OPCODE_END);
-
- mesa_vp->Base.InputsRead |= (1 << VERT_ATTRIB_POS);
- mesa_vp->Base.OutputsWritten |= (1 << VERT_RESULT_HPOS);
-
- //fprintf(stderr, "IsPositionInvariant is set!\n");
- //_mesa_print_program(&mesa_vp->Base);
- }
-
vp->pos_end=0; /* Not supported yet */
vp->program.length=0;
- vp->num_temporaries=mesa_vp->Base.NumTemporaries;
+ /*vp->num_temporaries=mesa_vp->Base.NumTemporaries;*/
for(i=0; i < VERT_ATTRIB_MAX; i++)
vp->inputs[i] = -1;
@@ -531,42 +411,49 @@ void r300_translate_vertex_shader(struct r300_vertex_program *vp)
for(i=0; i < VERT_RESULT_MAX; i++)
vp->outputs[i] = -1;
- assert(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS));
+ assert(vp->key.OutputsWritten & (1 << VERT_RESULT_HPOS));
/* Assign outputs */
- if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS))
+ if(vp->key.OutputsWritten & (1 << VERT_RESULT_HPOS))
vp->outputs[VERT_RESULT_HPOS] = cur_reg++;
- if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_PSIZ))
+ if(vp->key.OutputsWritten & (1 << VERT_RESULT_PSIZ))
vp->outputs[VERT_RESULT_PSIZ] = cur_reg++;
- if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_COL0))
+ if(vp->key.OutputsWritten & (1 << VERT_RESULT_COL0))
vp->outputs[VERT_RESULT_COL0] = cur_reg++;
- if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_COL1))
+ if(vp->key.OutputsWritten & (1 << VERT_RESULT_COL1))
vp->outputs[VERT_RESULT_COL1] = cur_reg++;
#if 0 /* Not supported yet */
- if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_BFC0))
+ if(vp->key.OutputsWritten & (1 << VERT_RESULT_BFC0))
vp->outputs[VERT_RESULT_BFC0] = cur_reg++;
- if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_BFC1))
+ if(vp->key.OutputsWritten & (1 << VERT_RESULT_BFC1))
vp->outputs[VERT_RESULT_BFC1] = cur_reg++;
- if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_FOGC))
+ 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(mesa_vp->Base.OutputsWritten & (1 << 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=mesa_vp->Base.Instructions; vpi->Opcode != OPCODE_END; vpi++, o_inst++){
+ 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;
@@ -987,3 +874,308 @@ void r300_translate_vertex_shader(struct r300_vertex_program *vp)
#endif
}
+static void position_invariant(struct gl_program *prog)
+{
+ struct prog_instruction *vpi;
+ struct gl_program_parameter_list *paramList;
+ int i;
+
+ GLint tokens[6] = { STATE_MATRIX, STATE_MVP, 0, 0, 0, STATE_MATRIX };
+
+#ifdef PREFER_DP4
+ tokens[5] = STATE_MATRIX;
+#else
+ tokens[5] = STATE_MATRIX_TRANSPOSE;
+#endif
+ paramList = prog->Parameters;
+
+ vpi = malloc((prog->NumInstructions + 4) * sizeof(struct prog_instruction));
+ memset(vpi, 0, 4 * sizeof(struct prog_instruction));
+
+ for (i=0; i < 4; i++) {
+ GLint idx;
+ tokens[3] = tokens[4] = 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 = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
+
+ vpi[i].SrcReg[1].File = PROGRAM_INPUT;
+ vpi[i].SrcReg[1].Index = VERT_ATTRIB_POS;
+ vpi[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
+#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 = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
+
+ 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 = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
+ }
+#endif
+ }
+
+ memcpy(&vpi[i], prog->Instructions, prog->NumInstructions * sizeof(struct prog_instruction));
+
+ 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,
+ GLint pos)
+{
+
+ GLint tokens[6] = { STATE_INTERNAL, STATE_R300_WINDOW_DIMENSION, 0, 0, 0, 0 };
+ struct prog_instruction *vpi;
+ struct prog_instruction *vpi_insert;
+ GLuint temp_index;
+ GLuint window_index;
+ int i = 0;
+
+ vpi = malloc((prog->NumInstructions + 5) * sizeof(struct prog_instruction));
+ memcpy(vpi, prog->Instructions, (pos+1) * sizeof(struct prog_instruction));
+
+ vpi_insert = &vpi[pos];
+
+ /* make a copy before outputting VERT_RESULT_HPOS */
+ vpi_insert->DstReg.File = vpi_insert->SrcReg[2].File;
+ vpi_insert->DstReg.Index = temp_index = vpi_insert->SrcReg[2].Index;
+
+ vpi_insert++;
+ memset(vpi_insert, 0, 5 * sizeof(struct prog_instruction));
+
+ 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 = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
+ i++;
+
+ /* perspective divide */
+ vpi_insert[i].Opcode = OPCODE_RCP;
+
+ vpi_insert[i].DstReg.File = PROGRAM_TEMPORARY;
+ vpi_insert[i].DstReg.Index = temp_index;
+ vpi_insert[i].DstReg.WriteMask = WRITEMASK_W;
+ 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 = MAKE_SWIZZLE4(SWIZZLE_W, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO);
+ i++;
+
+ vpi_insert[i].Opcode = OPCODE_MUL;
+
+ vpi_insert[i].DstReg.File = PROGRAM_TEMPORARY;
+ vpi_insert[i].DstReg.Index = temp_index;
+ vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZ;
+ 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 = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);
+
+ vpi_insert[i].SrcReg[1].File = PROGRAM_TEMPORARY;
+ vpi_insert[i].SrcReg[1].Index = temp_index;
+ vpi_insert[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_ZERO);
+ i++;
+
+ /* viewport transformation */
+ window_index = _mesa_add_state_reference(prog->Parameters, tokens);
+
+ vpi_insert[i].Opcode = OPCODE_MAD;
+
+ vpi_insert[i].DstReg.File = PROGRAM_TEMPORARY;
+ vpi_insert[i].DstReg.Index = temp_index;
+ vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZ;
+ 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 = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);
+
+ vpi_insert[i].SrcReg[1].File = PROGRAM_STATE_VAR;
+ vpi_insert[i].SrcReg[1].Index = window_index;
+ vpi_insert[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_ZERO);
+
+ vpi_insert[i].SrcReg[2].File = PROGRAM_STATE_VAR;
+ vpi_insert[i].SrcReg[2].Index = window_index;
+ vpi_insert[i].SrcReg[2].Swizzle = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_ZERO);
+ i++;
+
+ vpi_insert[i].Opcode = OPCODE_MUL;
+
+ 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 = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
+
+ vpi_insert[i].SrcReg[1].File = PROGRAM_STATE_VAR;
+ vpi_insert[i].SrcReg[1].Index = window_index;
+ vpi_insert[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ONE, SWIZZLE_ONE);
+ i++;
+
+ memcpy(&vpi_insert[i], &prog->Instructions[pos+1], (prog->NumInstructions-(pos+1)) * sizeof(struct prog_instruction));
+
+ free(prog->Instructions);
+
+ prog->Instructions = vpi;
+
+ prog->NumInstructions += i;
+ vpi = &prog->Instructions[prog->NumInstructions-1];
+
+ assert(vpi->Opcode == OPCODE_END);
+ /* we need position, don't we ? :) */
+ prog->InputsRead |= (1 << VERT_ATTRIB_POS);
+}
+
+static void pos_as_texcoord(struct r300_vertex_program *vp,
+ struct gl_program *prog)
+{
+ struct prog_instruction *vpi;
+ int pos = 0;
+
+ for(vpi = prog->Instructions; vpi->Opcode != OPCODE_END; vpi++, pos++){
+ if( vpi->DstReg.File == PROGRAM_OUTPUT &&
+ vpi->DstReg.Index == VERT_RESULT_HPOS ){
+ insert_wpos(vp, prog, pos);
+ break;
+ }
+ }
+
+}
+
+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;
+
+ r300_translate_vertex_shader(vp, mesa_vp->Base.Instructions);
+
+ return vp;
+}
+
+void r300_select_vertex_shader(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");
+ exit(0);
+ }
+
+ 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/src/mesa/drivers/dri/r300/radeon_context.c b/src/mesa/drivers/dri/r300/radeon_context.c
index 62a6e1e5f7..3a6bde8fc3 100644
--- a/src/mesa/drivers/dri/r300/radeon_context.c
+++ b/src/mesa/drivers/dri/r300/radeon_context.c
@@ -102,7 +102,6 @@ static const GLubyte *radeonGetString(GLcontext * ctx, GLenum name)
*/
static void radeonInitDriverFuncs(struct dd_function_table *functions)
{
- functions->GetBufferSize = NULL;
functions->GetString = radeonGetString;
}
@@ -267,12 +266,14 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
fprintf(stderr, "%s ctx %p\n", __FUNCTION__,
radeon->glCtx);
- if ( (radeon->dri.drawable != driDrawPriv)
- || (radeon->dri.readable != driReadPriv) ) {
-
+ if (radeon->dri.drawable != driDrawPriv) {
driDrawableInitVBlank(driDrawPriv,
radeon->vblank_flags,
&radeon->vbl_seq);
+ }
+
+ if (radeon->dri.drawable != driDrawPriv ||
+ radeon->dri.readable != driReadPriv) {
radeon->dri.drawable = driDrawPriv;
radeon->dri.readable = driReadPriv;
diff --git a/src/mesa/drivers/dri/r300/radeon_mm.c b/src/mesa/drivers/dri/r300/radeon_mm.c
index 7595d2144f..f86a1b4e72 100644
--- a/src/mesa/drivers/dri/r300/radeon_mm.c
+++ b/src/mesa/drivers/dri/r300/radeon_mm.c
@@ -213,7 +213,7 @@ int radeon_mm_alloc(r300ContextPtr rmesa, int alignment, int size)
}
goto again;
#else
- WARN_ONCE("Ran out of GART memory!\nPlease consider adjusting GARTSize option.\n");
+ WARN_ONCE("Ran out of GART memory (for %d)!\nPlease consider adjusting GARTSize option.\n", size);
return 0;
#endif
}
diff --git a/src/mesa/drivers/dri/r300/radeon_state.c b/src/mesa/drivers/dri/r300/radeon_state.c
index 1b1ec3df3c..ddadf83a00 100644
--- a/src/mesa/drivers/dri/r300/radeon_state.c
+++ b/src/mesa/drivers/dri/r300/radeon_state.c
@@ -169,10 +169,6 @@ void radeonSetCliprects(radeonContextPtr radeon)
if ((draw_fb->Width != drawable->w) ||
(draw_fb->Height != drawable->h)) {
- printf("w,h %d %d\n",
- radeon->glCtx->DrawBuffer->Width,
- radeon->glCtx->DrawBuffer->Height);
-
_mesa_resize_framebuffer(radeon->glCtx, draw_fb,
drawable->w, drawable->h);
draw_fb->Initialized = GL_TRUE;
diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c
index 8845881e3f..6bc2c4aa5c 100644
--- a/src/mesa/drivers/dri/radeon/radeon_context.c
+++ b/src/mesa/drivers/dri/radeon/radeon_context.c
@@ -170,7 +170,6 @@ static const struct tnl_pipeline_stage *radeon_pipeline[] = {
*/
static void radeonInitDriverFuncs( struct dd_function_table *functions )
{
- functions->GetBufferSize = NULL; /* OBSOLETE */
functions->GetString = radeonGetString;
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_texstate.c b/src/mesa/drivers/dri/radeon/radeon_texstate.c
index cfa8d4c9fa..37bb749223 100644
--- a/src/mesa/drivers/dri/radeon/radeon_texstate.c
+++ b/src/mesa/drivers/dri/radeon/radeon_texstate.c
@@ -865,7 +865,7 @@ static void import_tex_obj_state( radeonContextPtr rmesa,
radeonTexObjPtr texobj )
{
/* do not use RADEON_DB_STATE to avoid stale texture caches */
- GLuint *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0];
+ int *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0];
GLuint se_coord_fmt = rmesa->hw.set.cmd[SET_SE_COORDFMT];
RADEON_STATECHANGE( rmesa, tex[unit] );
@@ -888,7 +888,7 @@ static void import_tex_obj_state( radeonContextPtr rmesa,
se_coord_fmt &= ~(RADEON_VTX_ST0_NONPARAMETRIC << unit);
if (texobj->base.tObj->Target == GL_TEXTURE_CUBE_MAP) {
- GLuint *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0];
+ int *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0];
GLuint bytesPerFace = texobj->base.totalSize / 6;
ASSERT(texobj->base.totalSize % 6 == 0);
diff --git a/src/mesa/drivers/dri/savage/savage_init.h b/src/mesa/drivers/dri/savage/savage_init.h
index 0dec397b7b..43fb969c69 100644
--- a/src/mesa/drivers/dri/savage/savage_init.h
+++ b/src/mesa/drivers/dri/savage/savage_init.h
@@ -80,21 +80,10 @@ typedef struct {
} savageScreenPrivate;
-/**
- * savageRenderbuffer, derived from Mesa's gl_renderbuffer
- */
-typedef struct {
- struct gl_renderbuffer Base;
- /* XXX per-window info should go here */
- int foo, bar;
-} savageRenderbuffer;
-
-
#include "savagecontext.h"
extern void savageGetLock( savageContextPtr imesa, GLuint flags );
-extern void savageXMesaSetBackClipRects( savageContextPtr imesa );
-extern void savageXMesaSetFrontClipRects( savageContextPtr imesa );
+extern void savageXMesaSetClipRects(savageContextPtr imesa);
#define GET_DISPATCH_AGE( imesa ) imesa->sarea->last_dispatch
diff --git a/src/mesa/drivers/dri/savage/savage_xmesa.c b/src/mesa/drivers/dri/savage/savage_xmesa.c
index 3557ce0118..ad79b9235c 100644
--- a/src/mesa/drivers/dri/savage/savage_xmesa.c
+++ b/src/mesa/drivers/dri/savage/savage_xmesa.c
@@ -173,6 +173,9 @@ savageInitDriver(__DRIscreenPrivate *sPriv)
{
savageScreenPrivate *savageScreen;
SAVAGEDRIPtr gDRIPriv = (SAVAGEDRIPtr)sPriv->pDevPriv;
+ PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
+ (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension"));
+
if (sPriv->devPrivSize != sizeof(SAVAGEDRIRec)) {
fprintf(stderr,"\nERROR! sizeof(SAVAGEDRIRec) does not match passed size from device driver\n");
@@ -260,6 +263,11 @@ savageInitDriver(__DRIscreenPrivate *sPriv)
driParseOptionInfo (&savageScreen->optionCache,
__driConfigOptions, __driNConfigOptions);
+ if (glx_enable_extension != NULL) {
+ (*glx_enable_extension)(sPriv->psc->screenConfigs,
+ "GLX_SGI_make_current_read");
+ }
+
#if 0
savageDDFastPathInit();
savageDDTrifuncInit();
@@ -716,34 +724,18 @@ void XMesaSwapBuffers(__DRIdrawablePrivate *driDrawPriv)
}
#endif
-void savageXMesaSetFrontClipRects( savageContextPtr imesa )
-{
- __DRIdrawablePrivate *dPriv = imesa->driDrawable;
-
- imesa->numClipRects = dPriv->numClipRects;
- imesa->pClipRects = dPriv->pClipRects;
- imesa->drawX = dPriv->x;
- imesa->drawY = dPriv->y;
- savageCalcViewport( imesa->glCtx );
-}
-
-
-void savageXMesaSetBackClipRects( savageContextPtr imesa )
+void savageXMesaSetClipRects(savageContextPtr imesa)
{
__DRIdrawablePrivate *dPriv = imesa->driDrawable;
- if (dPriv->numBackClipRects == 0)
- {
-
-
+ if ((dPriv->numBackClipRects == 0)
+ || (imesa->glCtx->DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT)) {
imesa->numClipRects = dPriv->numClipRects;
imesa->pClipRects = dPriv->pClipRects;
imesa->drawX = dPriv->x;
imesa->drawY = dPriv->y;
} else {
-
-
imesa->numClipRects = dPriv->numBackClipRects;
imesa->pClipRects = dPriv->pBackClipRects;
imesa->drawX = dPriv->backX;
@@ -756,18 +748,17 @@ void savageXMesaSetBackClipRects( savageContextPtr imesa )
static void savageXMesaWindowMoved( savageContextPtr imesa )
{
+ __DRIdrawablePrivate *const drawable = imesa->driDrawable;
+ __DRIdrawablePrivate *const readable = imesa->driReadable;
+
if (0)
fprintf(stderr, "savageXMesaWindowMoved\n\n");
- switch (imesa->glCtx->DrawBuffer->_ColorDrawBufferMask[0]) {
- case BUFFER_BIT_FRONT_LEFT:
- savageXMesaSetFrontClipRects( imesa );
- break;
- case BUFFER_BIT_BACK_LEFT:
- savageXMesaSetBackClipRects( imesa );
- break;
- default:
- break;
+ savageXMesaSetClipRects(imesa);
+
+ driUpdateFramebufferSize(imesa->glCtx, drawable);
+ if (drawable != readable) {
+ driUpdateFramebufferSize(imesa->glCtx, readable);
}
}
@@ -858,11 +849,12 @@ savageMakeCurrent(__DRIcontextPrivate *driContextPriv,
void savageGetLock( savageContextPtr imesa, GLuint flags )
{
- __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+ __DRIdrawablePrivate *const drawable = imesa->driDrawable;
+ __DRIdrawablePrivate *const readable = imesa->driReadable;
__DRIscreenPrivate *sPriv = imesa->driScreen;
drm_savage_sarea_t *sarea = imesa->sarea;
int me = imesa->hHWContext;
- int stamp = dPriv->lastStamp;
+ int stamp = drawable->lastStamp;
int heap;
unsigned int timestamp = 0;
@@ -882,10 +874,11 @@ void savageGetLock( savageContextPtr imesa, GLuint flags )
* NOTE: This releases and regains the hw lock, so all state
* checking must be done *after* this call:
*/
- DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
-
+ DRI_VALIDATE_DRAWABLE_INFO(sPriv, drawable);
+ if (drawable != readable) {
+ DRI_VALIDATE_DRAWABLE_INFO(sPriv, readable);
+ }
-
/* If we lost context, need to dump all registers to hardware.
* Note that we don't care about 2d contexts, even if they perform
@@ -916,8 +909,8 @@ void savageGetLock( savageContextPtr imesa, GLuint flags )
DRI_AGE_TEXTURES( imesa->textureHeaps[heap] );
}
- if (dPriv->lastStamp != stamp) {
- driUpdateFramebufferSize(imesa->glCtx, dPriv);
+ if (drawable->lastStamp != stamp) {
+ driUpdateFramebufferSize(imesa->glCtx, drawable);
savageXMesaWindowMoved( imesa );
}
}
diff --git a/src/mesa/drivers/dri/savage/savagedd.c b/src/mesa/drivers/dri/savage/savagedd.c
index ae19481f03..a5c5310e28 100644
--- a/src/mesa/drivers/dri/savage/savagedd.c
+++ b/src/mesa/drivers/dri/savage/savagedd.c
@@ -42,7 +42,7 @@
#include "utils.h"
-#define DRIVER_DATE "20050829"
+#define DRIVER_DATE "20061110"
/***************************************
* Mesa's Driver Functions
@@ -95,24 +95,7 @@ static GLint savageGetParameteri(const GLcontext *ctx, GLint param)
#endif
-static void savageBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height)
-{
- GET_CURRENT_CONTEXT(ctx);
- savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
-
- /* Need to lock to make sure the driDrawable is uptodate. This
- * information is used to resize Mesa's software buffers, so it has
- * to be correct.
- */
- LOCK_HARDWARE(imesa);
- *width = imesa->driDrawable->w;
- *height = imesa->driDrawable->h;
- UNLOCK_HARDWARE(imesa);
-}
-
-
void savageDDInitDriverFuncs( GLcontext *ctx )
{
- ctx->Driver.GetBufferSize = savageBufferSize;
ctx->Driver.GetString = savageDDGetString;
}
diff --git a/src/mesa/drivers/dri/savage/savagespan.c b/src/mesa/drivers/dri/savage/savagespan.c
index 5d6246797f..61ab9e6d64 100644
--- a/src/mesa/drivers/dri/savage/savagespan.c
+++ b/src/mesa/drivers/dri/savage/savagespan.c
@@ -33,9 +33,8 @@
#define DBG 0
#define LOCAL_VARS \
- savageContextPtr imesa = SAVAGE_CONTEXT(ctx); \
- __DRIdrawablePrivate *dPriv = imesa->driDrawable; \
driRenderbuffer *drb = (driRenderbuffer *) rb; \
+ __DRIdrawablePrivate *const dPriv = drb->dPriv; \
GLuint cpp = drb->cpp; \
GLuint pitch = drb->pitch; \
GLuint height = dPriv->h; \
@@ -44,9 +43,8 @@
(void) p
#define LOCAL_DEPTH_VARS \
- savageContextPtr imesa = SAVAGE_CONTEXT(ctx); \
- __DRIdrawablePrivate *dPriv = imesa->driDrawable; \
driRenderbuffer *drb = (driRenderbuffer *) rb; \
+ __DRIdrawablePrivate *const dPriv = drb->dPriv; \
GLuint zpp = drb->cpp; \
GLuint pitch = drb->pitch; \
GLuint height = dPriv->h; \
diff --git a/src/mesa/drivers/dri/savage/savagestate.c b/src/mesa/drivers/dri/savage/savagestate.c
index 5c2b397bde..741a9dda4f 100644
--- a/src/mesa/drivers/dri/savage/savagestate.c
+++ b/src/mesa/drivers/dri/savage/savagestate.c
@@ -647,23 +647,20 @@ static void savageDDDrawBuffer(GLcontext *ctx, GLenum mode )
case BUFFER_BIT_FRONT_LEFT:
imesa->IsDouble = GL_FALSE;
imesa->regs.s4.destCtrl.ni.offset = imesa->savageScreen->frontOffset>>11;
-
- imesa->NotFirstFrame = GL_FALSE;
- savageXMesaSetFrontClipRects( imesa );
- FALLBACK( ctx, SAVAGE_FALLBACK_DRAW_BUFFER, GL_FALSE );
break;
case BUFFER_BIT_BACK_LEFT:
imesa->IsDouble = GL_TRUE;
imesa->regs.s4.destCtrl.ni.offset = imesa->savageScreen->backOffset>>11;
- imesa->NotFirstFrame = GL_FALSE;
- savageXMesaSetBackClipRects( imesa );
- FALLBACK( ctx, SAVAGE_FALLBACK_DRAW_BUFFER, GL_FALSE );
break;
default:
FALLBACK( ctx, SAVAGE_FALLBACK_DRAW_BUFFER, GL_TRUE );
return;
}
+ imesa->NotFirstFrame = GL_FALSE;
+ savageXMesaSetClipRects(imesa);
+ FALLBACK(ctx, SAVAGE_FALLBACK_DRAW_BUFFER, GL_FALSE);
+
if (destCtrl != imesa->regs.s4.destCtrl.ui)
imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
}
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_context.c b/src/mesa/drivers/dri/tdfx/tdfx_context.c
index 07d2cb1db5..a9163f49a8 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_context.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_context.c
@@ -23,19 +23,14 @@
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.c,v 1.12 2003/05/08 09:25:35 herrb Exp $ */
-/*
- * New fixes:
- * Daniel Borca <dborca@users.sourceforge.net>, 19 Jul 2004
- *
- * Original rewrite:
- * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000
- *
- * Authors:
- * Gareth Hughes <gareth@valinux.com>
- * Brian Paul <brianp@valinux.com>
+/**
+ * \file tdfx_context.c
+ * Context management functions for 3Dfx hardware.
*
+ * \author Gareth Hughes <gareth@valinux.com> (original rewrite 29 Sep - 1 Oct 2000)
+ * \author Brian Paul <brianp@valinux.com>
+ * \author Daniel Borca <dborca@users.sourceforge.net> (new fixes 19 Jul 2004)
*/
#include <dlfcn.h>
@@ -65,6 +60,7 @@
#define need_GL_ARB_multisample
/* #define need_GL_ARB_point_parameters */
+#define need_GL_ARB_occlusion_query
#define need_GL_ARB_texture_compression
#define need_GL_ARB_vertex_buffer_object
/* #define need_GL_ARB_vertex_program */
@@ -87,6 +83,7 @@
const struct dri_extension card_extensions[] =
{
{ "GL_ARB_multisample", GL_ARB_multisample_functions },
+ { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions },
{ "GL_ARB_texture_mirrored_repeat", NULL },
{ "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions },
@@ -660,8 +657,10 @@ tdfxMakeCurrent( __DRIcontextPrivate *driContextPriv,
GLcontext *newCtx = newFx->glCtx;
GET_CURRENT_CONTEXT(curCtx);
- if ( newFx->driDrawable != driDrawPriv ) {
+ if ((newFx->driDrawable != driDrawPriv)
+ || (newFx->driReadable != driReadPriv)) {
newFx->driDrawable = driDrawPriv;
+ newFx->driReadable = driReadPriv;
newFx->dirty = ~0;
}
else {
@@ -679,6 +678,11 @@ tdfxMakeCurrent( __DRIcontextPrivate *driContextPriv,
newFx->dirty = ~0;
}
+ driUpdateFramebufferSize(newCtx, driDrawPriv);
+ if (driDrawPriv != driReadPriv) {
+ driUpdateFramebufferSize(newCtx, driReadPriv);
+ }
+
if ( !newFx->Glide.Initialized ) {
if ( !tdfxInitContext( driDrawPriv, newFx ) )
return GL_FALSE;
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_context.h b/src/mesa/drivers/dri/tdfx/tdfx_context.h
index b8349fec73..89a7a9d6c4 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_context.h
+++ b/src/mesa/drivers/dri/tdfx/tdfx_context.h
@@ -895,7 +895,17 @@ struct tdfx_context {
/* stuff added for DRI */
__DRIscreenPrivate *driScreen;
__DRIcontextPrivate *driContext;
- __DRIdrawablePrivate *driDrawable;
+
+ /**
+ * DRI drawable bound to this context for drawing.
+ */
+ __DRIdrawablePrivate *driDrawable;
+
+ /**
+ * DRI drawable bound to this context for reading.
+ */
+ __DRIdrawablePrivate *driReadable;
+
drm_context_t hHWContext;
drm_hw_lock_t *driHwLock;
int driFd;
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_dd.c b/src/mesa/drivers/dri/tdfx/tdfx_dd.c
index c2f3185dc4..adbe0c0f33 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_dd.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_dd.c
@@ -23,16 +23,13 @@
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_dd.c,v 1.10 2002/10/30 12:52:00 alanh Exp $ */
-/*
- * Original rewrite:
- * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000
- *
- * Authors:
- * Gareth Hughes <gareth@valinux.com>
- * Brian Paul <brianp@valinux.com>
- *
+/**
+ * \file tdfx_dd.c
+ * Device driver interface functions for 3Dfx based cards.
+ *
+ * \author Gareth Hughes <gareth@valinux.com> (Original rewrite 29 Sep - 1 Oct 2000)
+ * \author Brian Paul <brianp@valinux.com>
*/
#include "tdfx_context.h"
@@ -41,6 +38,7 @@
#include "tdfx_vb.h"
#include "tdfx_pixels.h"
+#include "utils.h"
#include "context.h"
#include "enums.h"
#include "framebuffer.h"
@@ -50,7 +48,7 @@
#endif
-#define TDFX_DATE "20040719"
+#define DRIVER_DATE "20061113"
/* These are used in calls to FX_grColorMaskv() */
@@ -67,67 +65,40 @@ static const GLubyte *tdfxDDGetString( GLcontext *ctx, GLenum name )
{
tdfxContextPtr fxMesa = (tdfxContextPtr) ctx->DriverCtx;
- switch ( name ) {
+ switch (name) {
case GL_RENDERER:
{
/* The renderer string must be per-context state to handle
* multihead correctly.
*/
- char *buffer = fxMesa->rendererString;
- char hardware[100];
+ char *const buffer = fxMesa->rendererString;
+ char hardware[64];
LOCK_HARDWARE(fxMesa);
- strcpy( hardware, fxMesa->Glide.grGetString(GR_HARDWARE) );
+ strncpy(hardware, fxMesa->Glide.grGetString(GR_HARDWARE),
+ sizeof(hardware));
+ hardware[sizeof(hardware) - 1] = '\0';
UNLOCK_HARDWARE(fxMesa);
- strcpy( buffer, "Mesa DRI " );
- strcat( buffer, TDFX_DATE );
- strcat( buffer, " " );
-
- if ( strcmp( hardware, "Voodoo3 (tm)" ) == 0 ) {
- strcat( buffer, "Voodoo3" );
- }
- else if ( strcmp( hardware, "Voodoo Banshee (tm)" ) == 0 ) {
- strcat( buffer, "VoodooBanshee" );
+ if ((strncmp(hardware, "Voodoo3", 7) == 0)
+ || (strncmp(hardware, "Voodoo4", 7) == 0)
+ || (strncmp(hardware, "Voodoo5", 7) == 0)) {
+ hardware[7] = '\0';
}
- else if ( strcmp( hardware, "Voodoo4 (tm)" ) == 0 ) {
- strcat( buffer, "Voodoo4" );
- }
- else if ( strcmp( hardware, "Voodoo5 (tm)" ) == 0 ) {
- strcat( buffer, "Voodoo5" );
+ else if (strncmp(hardware, "Voodoo Banshee", 14) == 0) {
+ strcpy(&hardware[6], "Banshee");
}
else {
/* unexpected result: replace spaces with hyphens */
int i;
- for ( i = 0 ; hardware[i] && i < 60 ; i++ ) {
- if ( hardware[i] == ' ' || hardware[i] == '\t' )
+ for (i = 0; hardware[i] && (i < sizeof(hardware)); i++) {
+ if (hardware[i] == ' ' || hardware[i] == '\t') {
hardware[i] = '-';
+ }
}
- strcat( buffer, hardware );
}
- /* Append any CPU-specific information.
- */
-#ifdef USE_X86_ASM
- if ( _mesa_x86_cpu_features ) {
- strncat( buffer, " x86", 4 );
- }
-#endif
-#ifdef USE_MMX_ASM
- if ( cpu_has_mmx ) {
- strncat( buffer, "/MMX", 4 );
- }
-#endif
-#ifdef USE_3DNOW_ASM
- if ( cpu_has_3dnow ) {
- strncat( buffer, "/3DNow!", 7 );
- }
-#endif
-#ifdef USE_SSE_ASM
- if ( cpu_has_xmm ) {
- strncat( buffer, "/SSE", 4 );
- }
-#endif
+ (void) driGetRendererString(buffer, hardware, DRIVER_DATE, 0);
return (const GLubyte *) buffer;
}
case GL_VENDOR:
@@ -138,18 +109,52 @@ static const GLubyte *tdfxDDGetString( GLcontext *ctx, GLenum name )
}
-/* Return uptodate buffer size information.
- */
-static void tdfxDDGetBufferSize( GLframebuffer *buffer,
- GLuint *width, GLuint *height )
+static void
+tdfxBeginQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q)
+{
+ tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
+
+ (void) q;
+
+ if (target == GL_SAMPLES_PASSED_ARB) {
+ LOCK_HARDWARE(fxMesa);
+ fxMesa->Glide.grFinish();
+ fxMesa->Glide.grReset(GR_STATS_PIXELS);
+ UNLOCK_HARDWARE(fxMesa);
+ }
+}
+
+
+static void
+tdfxEndQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q)
{
- GET_CURRENT_CONTEXT(ctx);
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
+ FxI32 total_pixels;
+ FxI32 z_fail_pixels;
+
- LOCK_HARDWARE( fxMesa );
- *width = fxMesa->width;
- *height = fxMesa->height;
- UNLOCK_HARDWARE( fxMesa );
+ if (target == GL_SAMPLES_PASSED_ARB) {
+ LOCK_HARDWARE(fxMesa);
+ fxMesa->Glide.grFinish();
+
+ fxMesa->Glide.grGet(GR_STATS_PIXELS_DEPTHFUNC_FAIL, sizeof(FxI32),
+ &z_fail_pixels);
+ fxMesa->Glide.grGet(GR_STATS_PIXELS_IN, sizeof(FxI32), &total_pixels);
+
+ q->Result = total_pixels - z_fail_pixels;
+
+ /* Apparently, people have seen z_fail_pixels > total_pixels under
+ * some conditions on some 3Dfx hardware. The occlusion query spec
+ * requires that we clamp to 0.
+ */
+ if (q->Result < 0) {
+ q->Result = 0;
+ }
+
+ q->Ready = GL_TRUE;
+
+ UNLOCK_HARDWARE(fxMesa);
+ }
}
@@ -166,8 +171,9 @@ void tdfxDDInitDriverFuncs( const __GLcontextModes *visual,
fprintf( stderr, "tdfx: %s()\n", __FUNCTION__ );
}
- functions->GetString = tdfxDDGetString;
- functions->GetBufferSize = tdfxDDGetBufferSize;
+ functions->GetString = tdfxDDGetString;
+ functions->BeginQuery = tdfxBeginQuery;
+ functions->EndQuery = tdfxEndQuery;
/* Accelerated paths
*/
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_lock.c b/src/mesa/drivers/dri/tdfx/tdfx_lock.c
index ae3ba1a832..a20c91d030 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_lock.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_lock.c
@@ -47,16 +47,20 @@
void tdfxGetLock( tdfxContextPtr fxMesa )
{
__DRIcontextPrivate *cPriv = fxMesa->driContext;
- __DRIdrawablePrivate *dPriv = cPriv->driDrawablePriv;
- __DRIscreenPrivate *sPriv = dPriv->driScreenPriv;
+ __DRIdrawablePrivate *const drawable = cPriv->driDrawablePriv;
+ __DRIdrawablePrivate *const readable = cPriv->driReadablePriv;
+ __DRIscreenPrivate *sPriv = drawable->driScreenPriv;
TDFXSAREAPriv *saPriv = (TDFXSAREAPriv *) (((char *) sPriv->pSAREA) +
fxMesa->fxScreen->sarea_priv_offset);
- unsigned int stamp = dPriv->lastStamp;
+ unsigned int stamp = drawable->lastStamp;
drmGetLock( fxMesa->driFd, fxMesa->hHWContext, 0 );
- /* This macro will update dPriv's cliprects if needed */
- DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv );
+ /* This macro will update drawable's cliprects if needed */
+ DRI_VALIDATE_DRAWABLE_INFO(sPriv, drawable);
+ if (drawable != readable) {
+ DRI_VALIDATE_DRAWABLE_INFO(sPriv, readable);
+ }
if ( saPriv->fifoOwner != fxMesa->hHWContext ) {
fxMesa->Glide.grDRIImportFifo( saPriv->fifoPtr, saPriv->fifoRead );
@@ -83,10 +87,15 @@ void tdfxGetLock( tdfxContextPtr fxMesa )
}
#endif
- if ( *dPriv->pStamp != stamp || saPriv->ctxOwner != fxMesa->hHWContext ) {
+ if ((*drawable->pStamp != stamp)
+ || (saPriv->ctxOwner != fxMesa->hHWContext)) {
+ driUpdateFramebufferSize(fxMesa->glCtx, drawable);
+ if (drawable != readable) {
+ driUpdateFramebufferSize(fxMesa->glCtx, readable);
+ }
+
tdfxUpdateClipping(fxMesa->glCtx);
tdfxUploadClipping(fxMesa);
- driUpdateFramebufferSize(fxMesa->glCtx, dPriv);
}
DEBUG_LOCK();
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_pixels.c b/src/mesa/drivers/dri/tdfx/tdfx_pixels.c
index 1a5a2b1109..732270b2bd 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_pixels.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_pixels.c
@@ -496,9 +496,9 @@ tdfx_readpixels_R5G6B5(GLcontext * ctx, GLint x, GLint y,
{
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
GrLfbInfo_t info;
-
- const GLint winX = fxMesa->x_offset;
- const GLint winY = fxMesa->y_offset + fxMesa->height - 1;
+ __DRIdrawablePrivate *const readable = fxMesa->driReadable;
+ const GLint winX = readable->x;
+ const GLint winY = readable->y + readable->h - 1;
const GLint scrX = winX + x;
const GLint scrY = winY - y;
@@ -554,9 +554,9 @@ tdfx_readpixels_R8G8B8A8(GLcontext * ctx, GLint x, GLint y,
{
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
GrLfbInfo_t info;
-
- const GLint winX = fxMesa->x_offset;
- const GLint winY = fxMesa->y_offset + fxMesa->height - 1;
+ __DRIdrawablePrivate *const readable = fxMesa->driReadable;
+ const GLint winX = readable->x;
+ const GLint winY = readable->y + readable->h - 1;
const GLint scrX = winX + x;
const GLint scrY = winY - y;
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_screen.c b/src/mesa/drivers/dri/tdfx/tdfx_screen.c
index 0a4499cfae..646f5126eb 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_screen.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_screen.c
@@ -73,6 +73,9 @@ tdfxCreateScreen( __DRIscreenPrivate *sPriv )
{
tdfxScreenPrivate *fxScreen;
TDFXDRIPtr fxDRIPriv = (TDFXDRIPtr) sPriv->pDevPriv;
+ PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
+ (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension"));
+ void *const psc = sPriv->psc->screenConfigs;
if (sPriv->devPrivSize != sizeof(TDFXDRIRec)) {
fprintf(stderr,"\nERROR! sizeof(TDFXDRIRec) does not match passed size from device driver\n");
@@ -113,6 +116,10 @@ tdfxCreateScreen( __DRIscreenPrivate *sPriv )
return GL_FALSE;
}
+ if (glx_enable_extension != NULL) {
+ (*glx_enable_extension)(psc, "GLX_SGI_make_current_read");
+ }
+
return GL_TRUE;
}
@@ -180,6 +187,7 @@ tdfxCreateBuffer( __DRIscreenPrivate *driScrnPriv,
driDrawPriv);
tdfxSetSpanFunctions(backRb, mesaVis);
_mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base);
+ backRb->backBuffer = GL_TRUE;
}
if (mesaVis->depthBits == 16) {
@@ -265,7 +273,9 @@ tdfxSwapBuffers( __DRIdrawablePrivate *driDrawPriv )
return;
LOCK_HARDWARE( fxMesa );
fxMesa->Glide.grSstSelect( fxMesa->Glide.Board );
+#ifdef DEBUG
printf("SwapBuf SetState 1\n");
+#endif
fxMesa->Glide.grGlideSetState(fxMesa->Glide.State );
}
}
@@ -325,7 +335,9 @@ tdfxSwapBuffers( __DRIdrawablePrivate *driDrawPriv )
if (ctx->DriverCtx != fxMesa) {
fxMesa = TDFX_CONTEXT(ctx);
fxMesa->Glide.grSstSelect( fxMesa->Glide.Board );
+#ifdef DEBUG
printf("SwapBuf SetState 2\n");
+#endif
fxMesa->Glide.grGlideSetState(fxMesa->Glide.State );
}
UNLOCK_HARDWARE( fxMesa );
@@ -393,7 +405,7 @@ static __GLcontextModes *tdfxFillInModes(unsigned pixel_bits,
m->accumRedBits = accum ? 16 : 0;
m->accumGreenBits = accum ? 16 : 0;
m->accumBlueBits = accum ? 16 : 0;
- m->accumAlphaBits = accum ? 16 : 0;
+ m->accumAlphaBits = (accum && deep) ? 16 : 0;
m->stencilBits = stencil ? 8 : 0;
m->depthBits = deep
? (depth ? 24 : 0)
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_span.c b/src/mesa/drivers/dri/tdfx/tdfx_span.c
index ce895f8254..d9d52d2b6f 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_span.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_span.c
@@ -47,21 +47,19 @@
#define LOCAL_VARS \
- __DRIdrawablePrivate *dPriv = fxMesa->driDrawable; \
- tdfxScreenPrivate *fxPriv = fxMesa->fxScreen; \
- GLboolean isFront = (ctx->DrawBuffer->_ColorDrawBufferMask[0] \
- == BUFFER_BIT_FRONT_LEFT); \
- GLuint pitch = isFront ? (fxMesa->screen_width * BYTESPERPIXEL) \
- : info.strideInBytes; \
- GLuint height = fxMesa->height; \
+ driRenderbuffer *drb = (driRenderbuffer *) rb; \
+ __DRIdrawablePrivate *const dPriv = drb->dPriv; \
+ GLuint pitch = drb->backBuffer ? info.strideInBytes \
+ : (drb->pitch * drb->cpp); \
+ const GLuint bottom = dPriv->h - 1; \
char *buf = (char *)((char *)info.lfbPtr + \
- dPriv->x * fxPriv->cpp + \
- dPriv->y * pitch); \
+ (dPriv->x * drb->cpp) + \
+ (dPriv->y * pitch)); \
GLuint p; \
(void) buf; (void) p;
-#define Y_FLIP(_y) (height - _y - 1)
+#define Y_FLIP(_y) (bottom - _y)
#define HW_WRITE_LOCK() \
@@ -71,10 +69,9 @@
UNLOCK_HARDWARE( fxMesa ); \
LOCK_HARDWARE( fxMesa ); \
info.size = sizeof(GrLfbInfo_t); \
- if ( fxMesa->Glide.grLfbLock( GR_LFB_WRITE_ONLY, \
- fxMesa->DrawBuffer, LFB_MODE, \
- GR_ORIGIN_UPPER_LEFT, FXFALSE, &info ) ) \
- {
+ if (fxMesa->Glide.grLfbLock(GR_LFB_WRITE_ONLY, fxMesa->DrawBuffer, \
+ LFB_MODE, GR_ORIGIN_UPPER_LEFT, FXFALSE, \
+ &info)) {
#define HW_WRITE_UNLOCK() \
fxMesa->Glide.grLfbUnlock( GR_LFB_WRITE_ONLY, fxMesa->DrawBuffer );\
@@ -976,7 +973,7 @@ tdfxDDWriteDepthPixels(GLcontext * ctx, struct gl_renderbuffer *rb,
GetFbParams(fxMesa, &info, &backBufferInfo,
&ReadParams, sizeof(GLushort));
for (i = 0; i < n; i++) {
- if (mask[i] && visible_pixel(fxMesa, x[i], y[i])) {
+ if ((!mask || mask[i]) && visible_pixel(fxMesa, x[i], y[i])) {
xpos = x[i] + fxMesa->x_offset;
ypos = bottom - y[i];
d16 = depth[i];
@@ -1000,7 +997,7 @@ tdfxDDWriteDepthPixels(GLcontext * ctx, struct gl_renderbuffer *rb,
GetFbParams(fxMesa, &info, &backBufferInfo,
&ReadParams, sizeof(GLuint));
for (i = 0; i < n; i++) {
- if (mask[i]) {
+ if (!mask || mask[i]) {
if (visible_pixel(fxMesa, x[i], y[i])) {
xpos = x[i] + fxMesa->x_offset;
ypos = bottom - y[i];
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_tex.c b/src/mesa/drivers/dri/tdfx/tdfx_tex.c
index c3fe7bebd3..89865d9637 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_tex.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_tex.c
@@ -1755,7 +1755,7 @@ tdfxCompressedTexSubImage2D( GLcontext *ctx, GLenum target,
for (i = 0; i < rows; i++) {
MEMCPY(dest, data, srcRowStride);
dest += destRowStride;
- data = (GLvoid *)((GLuint)data + (GLuint)srcRowStride);
+ data = (GLvoid *)((intptr_t)data + (intptr_t)srcRowStride);
}
/* [dBorca] Hack alert:
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_texstate.c b/src/mesa/drivers/dri/tdfx/tdfx_texstate.c
index f5f385fad7..fda9ce5684 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_texstate.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_texstate.c
@@ -1015,9 +1015,12 @@ SetupSingleTexEnvVoodoo3(GLcontext *ctx, int unit,
}
break;
- default:
+ default: {
+ (void) memcpy(&colorComb, &fxMesa->ColorCombine, sizeof(colorComb));
+ (void) memcpy(&alphaComb, &fxMesa->AlphaCombine, sizeof(alphaComb));
_mesa_problem(ctx, "bad texture env mode in %s", __FUNCTION__);
}
+ }
if (colorComb.Function != fxMesa->ColorCombine.Function ||
colorComb.Factor != fxMesa->ColorCombine.Factor ||
diff --git a/src/mesa/drivers/dri/trident/trident_context.c b/src/mesa/drivers/dri/trident/trident_context.c
index a07b40fd5d..dbbd1ac0c6 100644
--- a/src/mesa/drivers/dri/trident/trident_context.c
+++ b/src/mesa/drivers/dri/trident/trident_context.c
@@ -50,6 +50,7 @@
#include "drivers/common/driverfuncs.h"
#include "dri_util.h"
+#include "utils.h"
static const struct tnl_pipeline_stage *trident_pipeline[] = {
&_tnl_vertex_transform_stage,
diff --git a/src/mesa/drivers/dri/unichrome/via_context.c b/src/mesa/drivers/dri/unichrome/via_context.c
index 38dcf458db..bc5a414df6 100644
--- a/src/mesa/drivers/dri/unichrome/via_context.c
+++ b/src/mesa/drivers/dri/unichrome/via_context.c
@@ -147,10 +147,13 @@ viaRenderbufferStorage(GLcontext *ctx, struct gl_renderbuffer *rb,
static void
-viaInitRenderbuffer(struct gl_renderbuffer *rb, GLenum format)
+viaInitRenderbuffer(struct via_renderbuffer *vrb, GLenum format,
+ __DRIdrawablePrivate *dPriv)
{
const GLuint name = 0;
+ struct gl_renderbuffer *rb = & vrb->Base;
+ vrb->dPriv = dPriv;
_mesa_init_renderbuffer(rb, name);
/* Make sure we're using a null-valued GetPointer routine */
@@ -198,8 +201,9 @@ viaInitRenderbuffer(struct gl_renderbuffer *rb, GLenum format)
* \sa AllocateBuffer
*/
static GLboolean
-calculate_buffer_parameters( struct via_context *vmesa,
- struct gl_framebuffer *fb )
+calculate_buffer_parameters(struct via_context *vmesa,
+ struct gl_framebuffer *fb,
+ __DRIdrawablePrivate *dPriv)
{
const unsigned shift = vmesa->viaScreen->bitsPerPixel / 16;
const unsigned extra = 32;
@@ -215,26 +219,28 @@ calculate_buffer_parameters( struct via_context *vmesa,
if (!vmesa->front.Base.InternalFormat) {
/* do one-time init for the renderbuffers */
- viaInitRenderbuffer(&vmesa->front.Base, GL_RGBA);
+ viaInitRenderbuffer(&vmesa->front, GL_RGBA, dPriv);
viaSetSpanFunctions(&vmesa->front, &fb->Visual);
_mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &vmesa->front.Base);
if (fb->Visual.doubleBufferMode) {
- viaInitRenderbuffer(&vmesa->back.Base, GL_RGBA);
+ viaInitRenderbuffer(&vmesa->back, GL_RGBA, dPriv);
viaSetSpanFunctions(&vmesa->back, &fb->Visual);
_mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &vmesa->back.Base);
}
if (vmesa->glCtx->Visual.depthBits > 0) {
- viaInitRenderbuffer(&vmesa->depth.Base,
+ viaInitRenderbuffer(&vmesa->depth,
(vmesa->glCtx->Visual.depthBits == 16
- ? GL_DEPTH_COMPONENT16 : GL_DEPTH_COMPONENT24));
+ ? GL_DEPTH_COMPONENT16 : GL_DEPTH_COMPONENT24),
+ dPriv);
viaSetSpanFunctions(&vmesa->depth, &fb->Visual);
_mesa_add_renderbuffer(fb, BUFFER_DEPTH, &vmesa->depth.Base);
}
if (vmesa->glCtx->Visual.stencilBits > 0) {
- viaInitRenderbuffer(&vmesa->stencil.Base, GL_STENCIL_INDEX8_EXT);
+ viaInitRenderbuffer(&vmesa->stencil, GL_STENCIL_INDEX8_EXT,
+ dPriv);
viaSetSpanFunctions(&vmesa->stencil, &fb->Visual);
_mesa_add_renderbuffer(fb, BUFFER_STENCIL, &vmesa->stencil.Base);
}
@@ -243,11 +249,9 @@ calculate_buffer_parameters( struct via_context *vmesa,
assert(vmesa->front.Base.InternalFormat);
assert(vmesa->front.Base.AllocStorage);
if (fb->Visual.doubleBufferMode) {
- assert(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
- assert(vmesa->front.Base.AllocStorage);
+ assert(vmesa->back.Base.AllocStorage);
}
if (fb->Visual.depthBits) {
- assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer);
assert(vmesa->depth.Base.AllocStorage);
}
@@ -352,19 +356,11 @@ void viaReAllocateBuffers(GLcontext *ctx, GLframebuffer *drawbuffer,
{
struct via_context *vmesa = VIA_CONTEXT(ctx);
- calculate_buffer_parameters( vmesa, drawbuffer );
+ calculate_buffer_parameters(vmesa, drawbuffer, vmesa->driDrawable);
_mesa_resize_framebuffer(ctx, drawbuffer, width, height);
}
-static void viaBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height)
-{
- GET_CURRENT_CONTEXT(ctx);
- struct via_context *vmesa = VIA_CONTEXT(ctx);
- *width = vmesa->driDrawable->w;
- *height = vmesa->driDrawable->h;
-}
-
/* Extension strings exported by the Unichrome driver.
*/
const struct dri_extension card_extensions[] =
@@ -579,7 +575,6 @@ viaCreateContext(const __GLcontextModes *visual,
ctx->Const.MaxPointSizeAA = 1.0;
ctx->Const.PointSizeGranularity = 1.0;
- ctx->Driver.GetBufferSize = viaBufferSize;
ctx->Driver.GetString = viaGetString;
ctx->DriverCtx = (void *)vmesa;
@@ -734,50 +729,72 @@ viaDestroyContext(__DRIcontextPrivate *driContextPriv)
void viaXMesaWindowMoved(struct via_context *vmesa)
{
- __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+ __DRIdrawablePrivate *const drawable = vmesa->driDrawable;
+ __DRIdrawablePrivate *const readable = vmesa->driReadable;
+ struct via_renderbuffer *const draw_buffer =
+ (struct via_renderbuffer *) drawable->driverPrivate;
+ struct via_renderbuffer *const read_buffer =
+ (struct via_renderbuffer *) readable->driverPrivate;
GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
- if (!dPriv)
+ if (!drawable)
return;
switch (vmesa->glCtx->DrawBuffer->_ColorDrawBufferMask[0]) {
case BUFFER_BIT_BACK_LEFT:
- if (dPriv->numBackClipRects == 0) {
- vmesa->numClipRects = dPriv->numClipRects;
- vmesa->pClipRects = dPriv->pClipRects;
+ if (drawable->numBackClipRects == 0) {
+ vmesa->numClipRects = drawable->numClipRects;
+ vmesa->pClipRects = drawable->pClipRects;
}
else {
- vmesa->numClipRects = dPriv->numBackClipRects;
- vmesa->pClipRects = dPriv->pBackClipRects;
+ vmesa->numClipRects = drawable->numBackClipRects;
+ vmesa->pClipRects = drawable->pBackClipRects;
}
break;
case BUFFER_BIT_FRONT_LEFT:
- vmesa->numClipRects = dPriv->numClipRects;
- vmesa->pClipRects = dPriv->pClipRects;
+ vmesa->numClipRects = drawable->numClipRects;
+ vmesa->pClipRects = drawable->pClipRects;
break;
default:
vmesa->numClipRects = 0;
break;
}
- if (vmesa->drawW != dPriv->w ||
- vmesa->drawH != dPriv->h)
- calculate_buffer_parameters( vmesa, vmesa->glCtx->DrawBuffer );
+ if ((draw_buffer->drawW != drawable->w)
+ || (draw_buffer->drawH != drawable->h)) {
+ calculate_buffer_parameters(vmesa, vmesa->glCtx->DrawBuffer,
+ drawable);
+ }
- vmesa->drawXoff = (GLuint)(((dPriv->x * bytePerPixel) & 0x1f) /
+ draw_buffer->drawXoff = (GLuint)(((drawable->x * bytePerPixel) & 0x1f) /
bytePerPixel);
- vmesa->drawX = dPriv->x - vmesa->drawXoff;
- vmesa->drawY = dPriv->y;
- vmesa->drawW = dPriv->w;
- vmesa->drawH = dPriv->h;
+ draw_buffer->drawX = drawable->x - draw_buffer->drawXoff;
+ draw_buffer->drawY = drawable->y;
+ draw_buffer->drawW = drawable->w;
+ draw_buffer->drawH = drawable->h;
+
+ if (drawable != readable) {
+ if ((read_buffer->drawW != readable->w)
+ || (read_buffer->drawH != readable->h)) {
+ calculate_buffer_parameters(vmesa, vmesa->glCtx->ReadBuffer,
+ readable);
+ }
+
+ read_buffer->drawXoff = (GLuint)(((readable->x * bytePerPixel) & 0x1f) /
+ bytePerPixel);
+ read_buffer->drawX = readable->x - read_buffer->drawXoff;
+ read_buffer->drawY = readable->y;
+ read_buffer->drawW = readable->w;
+ read_buffer->drawH = readable->h;
+ }
vmesa->front.orig = (vmesa->front.offset +
- vmesa->drawY * vmesa->front.pitch +
- vmesa->drawX * bytePerPixel);
+ draw_buffer->drawY * vmesa->front.pitch +
+ draw_buffer->drawX * bytePerPixel);
vmesa->front.origMap = (vmesa->front.map +
- vmesa->drawY * vmesa->front.pitch +
- vmesa->drawX * bytePerPixel);
+ draw_buffer->drawY * vmesa->front.pitch +
+ draw_buffer->drawX * bytePerPixel);
vmesa->back.orig = vmesa->back.offset;
vmesa->depth.orig = vmesa->depth.offset;
@@ -813,15 +830,41 @@ viaMakeCurrent(__DRIcontextPrivate *driContextPriv,
drawBuffer = (GLframebuffer *)driDrawPriv->driverPrivate;
readBuffer = (GLframebuffer *)driReadPriv->driverPrivate;
- if ( vmesa->driDrawable != driDrawPriv ) {
- driDrawableInitVBlank( driDrawPriv, vmesa->vblank_flags,
- &vmesa->vbl_seq );
- vmesa->driDrawable = driDrawPriv;
- if ( ! calculate_buffer_parameters( vmesa, drawBuffer ) ) {
- return GL_FALSE;
- }
+ if (vmesa->driDrawable != driDrawPriv) {
+ driDrawableInitVBlank(driDrawPriv, vmesa->vblank_flags,
+ &vmesa->vbl_seq);
}
+ if ((vmesa->driDrawable != driDrawPriv)
+ || (vmesa->driReadable != driReadPriv)) {
+ vmesa->driDrawable = driDrawPriv;
+ vmesa->driReadable = driReadPriv;
+
+ if ((drawBuffer->Width != driDrawPriv->w)
+ || (drawBuffer->Height != driDrawPriv->h)) {
+ _mesa_resize_framebuffer(ctx, drawBuffer,
+ driDrawPriv->w, driDrawPriv->h);
+ drawBuffer->Initialized = GL_TRUE;
+ }
+
+ if (!calculate_buffer_parameters(vmesa, drawBuffer, driDrawPriv)) {
+ return GL_FALSE;
+ }
+
+ if (driDrawPriv != driReadPriv) {
+ if ((readBuffer->Width != driReadPriv->w)
+ || (readBuffer->Height != driReadPriv->h)) {
+ _mesa_resize_framebuffer(ctx, readBuffer,
+ driReadPriv->w, driReadPriv->h);
+ readBuffer->Initialized = GL_TRUE;
+ }
+
+ if (!calculate_buffer_parameters(vmesa, readBuffer, driReadPriv)) {
+ return GL_FALSE;
+ }
+ }
+ }
+
_mesa_make_current(vmesa->glCtx, drawBuffer, readBuffer);
ctx->Driver.DrawBuffer( ctx, ctx->Color.DrawBuffer[0] );
@@ -847,7 +890,10 @@ void viaGetLock(struct via_context *vmesa, GLuint flags)
drmGetLock(vmesa->driFd, vmesa->hHWContext, flags);
- DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv );
+ DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
+ if (dPriv != vmesa->driReadable) {
+ DRI_VALIDATE_DRAWABLE_INFO(sPriv, vmesa->driReadable);
+ }
if (vmesa->sarea->ctxOwner != vmesa->hHWContext) {
vmesa->sarea->ctxOwner = vmesa->hHWContext;
diff --git a/src/mesa/drivers/dri/unichrome/via_context.h b/src/mesa/drivers/dri/unichrome/via_context.h
index 9d7a0e6cb6..77161a8d5d 100644
--- a/src/mesa/drivers/dri/unichrome/via_context.h
+++ b/src/mesa/drivers/dri/unichrome/via_context.h
@@ -98,6 +98,18 @@ struct via_renderbuffer {
* at (drawX,drawY) in screen space.
*/
char *origMap;
+
+ int drawX; /* origin of drawable in draw buffer */
+ int drawY;
+ int drawW;
+ int drawH;
+
+ int drawXoff; /* drawX is 32byte aligned - this is
+ * the delta to the real origin, in
+ * pixel units.
+ */
+
+ __DRIdrawablePrivate *dPriv;
};
@@ -272,16 +284,6 @@ struct via_context {
struct via_renderbuffer *drawBuffer;
- int drawX; /* origin of drawable in draw buffer */
- int drawY;
- int drawW;
- int drawH;
-
- int drawXoff; /* drawX is 32byte aligned - this is
- * the delta to the real origin, in
- * pixel units.
- */
-
GLuint numClipRects; /* cliprects for that buffer */
drm_clip_rect_t *pClipRects;
@@ -294,7 +296,16 @@ struct via_context {
int driFd;
__DRInativeDisplay *display;
- __DRIdrawablePrivate *driDrawable;
+ /**
+ * DRI drawable bound to this context for drawing.
+ */
+ __DRIdrawablePrivate *driDrawable;
+
+ /**
+ * DRI drawable bound to this context for reading.
+ */
+ __DRIdrawablePrivate *driReadable;
+
__DRIscreenPrivate *driScreen;
viaScreenPrivate *viaScreen;
drm_via_sarea_t *sarea;
diff --git a/src/mesa/drivers/dri/unichrome/via_ioctl.c b/src/mesa/drivers/dri/unichrome/via_ioctl.c
index dd2e93b286..5d102de93e 100644
--- a/src/mesa/drivers/dri/unichrome/via_ioctl.c
+++ b/src/mesa/drivers/dri/unichrome/via_ioctl.c
@@ -182,8 +182,8 @@ static void viaFillBuffer(struct via_context *vmesa,
GLuint i;
for (i = 0; i < nboxes ; i++) {
- int x = pbox[i].x1 - vmesa->drawX;
- int y = pbox[i].y1 - vmesa->drawY;
+ int x = pbox[i].x1 - buffer->drawX;
+ int y = pbox[i].y1 - buffer->drawY;
int w = pbox[i].x2 - pbox[i].x1;
int h = pbox[i].y2 - pbox[i].y1;
@@ -206,6 +206,8 @@ static void viaClear(GLcontext *ctx, GLbitfield mask)
{
struct via_context *vmesa = VIA_CONTEXT(ctx);
__DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+ struct via_renderbuffer *const vrb =
+ (struct via_renderbuffer *) dPriv->driverPrivate;
int flag = 0;
GLuint i = 0;
GLuint clear_depth_mask = 0xf << 28;
@@ -274,8 +276,8 @@ static void viaClear(GLcontext *ctx, GLbitfield mask)
/* flip top to bottom */
cy = dPriv->h - cy - ch;
- cx += vmesa->drawX + vmesa->drawXoff;
- cy += vmesa->drawY;
+ cx += vrb->drawX + vrb->drawXoff;
+ cy += vrb->drawY;
if (!all) {
drm_clip_rect_t *b = vmesa->pClipRects;
@@ -352,8 +354,8 @@ static void viaDoSwapBuffers(struct via_context *vmesa,
GLuint i;
for (i = 0; i < nbox; i++, b++) {
- GLint x = b->x1 - vmesa->drawX;
- GLint y = b->y1 - vmesa->drawY;
+ GLint x = b->x1 - back->drawX;
+ GLint y = b->y1 - back->drawY;
GLint w = b->x2 - b->x1;
GLint h = b->y2 - b->y1;
@@ -766,7 +768,7 @@ static void via_emit_cliprect(struct via_context *vmesa,
vb[4] = (HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF);
vb[5] = (HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000) >> 24);
- vb[6] = (HC_SubA_HSPXYOS << 24) | ((31-vmesa->drawXoff) << HC_HSPXOS_SHIFT);
+ vb[6] = (HC_SubA_HSPXYOS << 24) | ((31 - buffer->drawXoff) << HC_HSPXOS_SHIFT);
vb[7] = (HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch;
}
@@ -881,21 +883,25 @@ void viaFlushDmaLocked(struct via_context *vmesa, GLuint flags)
}
else if (vmesa->numClipRects) {
drm_clip_rect_t *pbox = vmesa->pClipRects;
-
+ __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+ struct via_renderbuffer *const vrb =
+ (struct via_renderbuffer *) dPriv->driverPrivate;
+
+
for (i = 0; i < vmesa->numClipRects; i++) {
drm_clip_rect_t b;
- b.x1 = pbox[i].x1 - (vmesa->drawX + vmesa->drawXoff);
- b.x2 = pbox[i].x2 - (vmesa->drawX + vmesa->drawXoff);
- b.y1 = pbox[i].y1 - vmesa->drawY;
- b.y2 = pbox[i].y2 - vmesa->drawY;
+ b.x1 = pbox[i].x1 - (vrb->drawX + vrb->drawXoff);
+ b.x2 = pbox[i].x2 - (vrb->drawX + vrb->drawXoff);
+ b.y1 = pbox[i].y1 - vrb->drawY;
+ b.y2 = pbox[i].y2 - vrb->drawY;
if (vmesa->scissor &&
!intersect_rect(&b, &b, &vmesa->scissorRect))
continue;
- b.x1 += vmesa->drawXoff;
- b.x2 += vmesa->drawXoff;
+ b.x1 += vrb->drawXoff;
+ b.x2 += vrb->drawXoff;
via_emit_cliprect(vmesa, &b);
diff --git a/src/mesa/drivers/dri/unichrome/via_screen.c b/src/mesa/drivers/dri/unichrome/via_screen.c
index 98a742c720..28e1f9451e 100644
--- a/src/mesa/drivers/dri/unichrome/via_screen.c
+++ b/src/mesa/drivers/dri/unichrome/via_screen.c
@@ -182,6 +182,7 @@ viaInitDriver(__DRIscreenPrivate *sPriv)
(*glx_enable_extension)( psc, "GLX_MESA_swap_control" );
}
+ (*glx_enable_extension)( psc, "GLX_SGI_make_current_read" );
(*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
}
diff --git a/src/mesa/drivers/dri/unichrome/via_span.c b/src/mesa/drivers/dri/unichrome/via_span.c
index 6ff95cc444..f1ed98036b 100644
--- a/src/mesa/drivers/dri/unichrome/via_span.c
+++ b/src/mesa/drivers/dri/unichrome/via_span.c
@@ -41,13 +41,12 @@
#undef LOCAL_VARS
#define LOCAL_VARS \
- struct via_context *vmesa = VIA_CONTEXT(ctx); \
- __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
struct via_renderbuffer *vrb = (struct via_renderbuffer *) rb; \
+ __DRIdrawablePrivate *dPriv = vrb->dPriv; \
GLuint pitch = vrb->pitch; \
GLuint height = dPriv->h; \
GLint p = 0; \
- char *buf = (char *)(vrb->origMap + vmesa->drawXoff * vrb->bpp); \
+ char *buf = (char *)(vrb->origMap + vrb->drawXoff * vrb->bpp); \
(void) p;
/* ================================================================
@@ -79,12 +78,11 @@
/* 16 bit depthbuffer functions.
*/
#define LOCAL_DEPTH_VARS \
- struct via_context *vmesa = VIA_CONTEXT(ctx); \
- __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
struct via_renderbuffer *vrb = (struct via_renderbuffer *) rb; \
+ __DRIdrawablePrivate *dPriv = vrb->dPriv; \
GLuint depth_pitch = vrb->pitch; \
GLuint height = dPriv->h; \
- char *buf = (char *)(vrb->map + (vmesa->drawXoff * vrb->bpp/8))
+ char *buf = (char *)(vrb->map + (vrb->drawXoff * vrb->bpp/8))
#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
diff --git a/src/mesa/drivers/dri/unichrome/via_state.c b/src/mesa/drivers/dri/unichrome/via_state.c
index 102a333068..30b9dc289a 100644
--- a/src/mesa/drivers/dri/unichrome/via_state.c
+++ b/src/mesa/drivers/dri/unichrome/via_state.c
@@ -476,6 +476,9 @@ void viaEmitState(struct via_context *vmesa)
*/
if (ctx->Polygon.StippleFlag) {
GLuint *stipple = &ctx->PolygonStipple[0];
+ __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+ struct via_renderbuffer *const vrb =
+ (struct via_renderbuffer *) dPriv->driverPrivate;
GLint i;
BEGIN_RING(38);
@@ -498,9 +501,9 @@ void viaEmitState(struct via_context *vmesa)
OUT_RING( HC_HEADER2 );
OUT_RING( (HC_ParaType_NotTex << 16) );
OUT_RING( (HC_SubA_HSPXYOS << 24) |
- (((32- vmesa->drawXoff) & 0x1f) << HC_HSPXOS_SHIFT));
+ (((32- vrb->drawXoff) & 0x1f) << HC_HSPXOS_SHIFT));
OUT_RING( (HC_SubA_HSPXYOS << 24) |
- (((32 - vmesa->drawXoff) & 0x1f) << HC_HSPXOS_SHIFT));
+ (((32 - vrb->drawXoff) & 0x1f) << HC_HSPXOS_SHIFT));
ADVANCE_RING();
}
@@ -720,15 +723,18 @@ static void viaColorMask(GLcontext *ctx,
void viaCalcViewport(GLcontext *ctx)
{
struct via_context *vmesa = VIA_CONTEXT(ctx);
+ __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+ struct via_renderbuffer *const vrb =
+ (struct via_renderbuffer *) dPriv->driverPrivate;
const GLfloat *v = ctx->Viewport._WindowMap.m;
GLfloat *m = vmesa->ViewportMatrix.m;
/* See also via_translate_vertex.
*/
m[MAT_SX] = v[MAT_SX];
- m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X + vmesa->drawXoff;
+ m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X + vrb->drawXoff;
m[MAT_SY] = - v[MAT_SY];
- m[MAT_TY] = - v[MAT_TY] + vmesa->driDrawable->h + SUBPIXEL_Y;
+ m[MAT_TY] = - v[MAT_TY] + dPriv->h + SUBPIXEL_Y;
m[MAT_SZ] = v[MAT_SZ] * (1.0 / vmesa->depth_max);
m[MAT_TZ] = v[MAT_TZ] * (1.0 / vmesa->depth_max);
}