summaryrefslogtreecommitdiffstats
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.c21
-rw-r--r--src/mesa/drivers/dri/common/extension_helper.h22
-rw-r--r--src/mesa/drivers/dri/fb/fb_dri.c8
-rw-r--r--src/mesa/drivers/dri/fb/fb_egl.c6
-rw-r--r--src/mesa/drivers/dri/ffb/ffb_state.c4
-rw-r--r--src/mesa/drivers/dri/ffb/ffb_xmesa.c6
-rw-r--r--src/mesa/drivers/dri/gamma/gamma_context.c4
-rw-r--r--src/mesa/drivers/dri/gamma/gamma_state.c4
-rw-r--r--src/mesa/drivers/dri/gamma/gamma_xmesa.c4
-rw-r--r--src/mesa/drivers/dri/i810/i810context.c6
-rw-r--r--src/mesa/drivers/dri/i810/i810state.c4
-rw-r--r--src/mesa/drivers/dri/i915/i915_context.c5
-rw-r--r--src/mesa/drivers/dri/i915/i915_state.c10
-rw-r--r--src/mesa/drivers/dri/i915/intel_context.c8
-rw-r--r--src/mesa/drivers/dri/i915tex/Makefile5
-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_state.c11
-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/intel_batchbuffer.c18
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_batchbuffer.h2
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_buffer_objects.c5
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_context.c40
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_context.h9
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_screen.c3
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.c19
-rw-r--r--src/mesa/drivers/dri/i965/Makefile14
-rw-r--r--src/mesa/drivers/dri/i965/brw_attrib.h114
-rw-r--r--src/mesa/drivers/dri/i965/brw_attrib_tmp.h485
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip.h2
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.c8
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.h27
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw.c173
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw.h57
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw_current.c103
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw_upload.c130
-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_exec.c125
-rw-r--r--src/mesa/drivers/dri/i965/brw_exec.h150
-rw-r--r--src/mesa/drivers/dri/i965/brw_exec_api.c716
-rw-r--r--src/mesa/drivers/dri/i965/brw_exec_array.c283
-rw-r--r--src/mesa/drivers/dri/i965/brw_exec_draw.c227
-rw-r--r--src/mesa/drivers/dri/i965/brw_exec_eval.c255
-rw-r--r--src/mesa/drivers/dri/i965/brw_fallback.c349
-rw-r--r--src/mesa/drivers/dri/i965/brw_fallback.h4
-rw-r--r--src/mesa/drivers/dri/i965/brw_gs.c9
-rw-r--r--src/mesa/drivers/dri/i965/brw_gs.h1
-rw-r--r--src/mesa/drivers/dri/i965/brw_gs_emit.c10
-rw-r--r--src/mesa/drivers/dri/i965/brw_metaops.c73
-rw-r--r--src/mesa/drivers/dri/i965/brw_save.c126
-rw-r--r--src/mesa/drivers/dri/i965/brw_save.h171
-rw-r--r--src/mesa/drivers/dri/i965/brw_save_api.c1170
-rw-r--r--src/mesa/drivers/dri/i965/brw_save_draw.c221
-rw-r--r--src/mesa/drivers/dri/i965/brw_structs.h22
-rw-r--r--src/mesa/drivers/dri/i965/brw_tex_layout.c55
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs.c5
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_constval.c7
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_emit.c6
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_tnl.c47
-rw-r--r--src/mesa/drivers/dri/i965/brw_vtbl.c10
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_state.c4
-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.c4
-rw-r--r--src/mesa/drivers/dri/i965/intel_context.c81
-rw-r--r--src/mesa/drivers/dri/i965/intel_context.h3
-rw-r--r--src/mesa/drivers/dri/i965/intel_ioctl.c35
-rw-r--r--src/mesa/drivers/dri/i965/intel_regions.c2
-rw-r--r--src/mesa/drivers/dri/i965/intel_regions.h1
-rw-r--r--src/mesa/drivers/dri/i965/intel_screen.c12
-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/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.c6
-rw-r--r--src/mesa/drivers/dri/mach64/mach64_state.c4
-rw-r--r--src/mesa/drivers/dri/mga/mga_xmesa.c6
-rw-r--r--src/mesa/drivers/dri/mga/mgastate.c4
-rw-r--r--src/mesa/drivers/dri/nouveau/Makefile53
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c616
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h77
-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.h232
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_context.c371
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_context.h233
-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.h179
-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.c101
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_object.h44
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_query.c198
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_query.h38
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_reg.h1505
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_screen.c380
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_screen.h61
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_shader.c818
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_shader.h441
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_shader_0.c1006
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_shader_1.c14
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_shader_2.c261
-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.c345
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_state.h50
-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.c195
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_sync.h67
-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_state.c538
-rw-r--r--src/mesa/drivers/dri/nouveau/nv04_swtcl.c618
-rw-r--r--src/mesa/drivers/dri/nouveau/nv04_swtcl.h12
-rw-r--r--src/mesa/drivers/dri/nouveau/nv10_state.c798
-rw-r--r--src/mesa/drivers/dri/nouveau/nv10_swtcl.c647
-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.c811
-rw-r--r--src/mesa/drivers/dri/nouveau/nv20_vertprog.c447
-rw-r--r--src/mesa/drivers/dri/nouveau/nv30_fragprog.c742
-rw-r--r--src/mesa/drivers/dri/nouveau/nv30_shader.h379
-rw-r--r--src/mesa/drivers/dri/nouveau/nv30_state.c980
-rw-r--r--src/mesa/drivers/dri/nouveau/nv30_vertprog.c367
-rw-r--r--src/mesa/drivers/dri/nouveau/nv40_fragprog.c224
-rw-r--r--src/mesa/drivers/dri/nouveau/nv40_shader.h467
-rw-r--r--src/mesa/drivers/dri/nouveau/nv40_vertprog.c778
-rw-r--r--src/mesa/drivers/dri/nouveau/nv50_state.c641
-rw-r--r--src/mesa/drivers/dri/r128/r128_context.c6
-rw-r--r--src/mesa/drivers/dri/r128/r128_state.c4
-rw-r--r--src/mesa/drivers/dri/r200/Makefile6
-rw-r--r--src/mesa/drivers/dri/r200/r200_context.c26
-rw-r--r--src/mesa/drivers/dri/r200/r200_context.h135
-rw-r--r--src/mesa/drivers/dri/r200/r200_maos.h2
-rw-r--r--src/mesa/drivers/dri/r200/r200_maos_arrays.c392
-rw-r--r--src/mesa/drivers/dri/r200/r200_state.c18
-rw-r--r--src/mesa/drivers/dri/r200/r200_state_init.c3
-rw-r--r--src/mesa/drivers/dri/r200/r200_swtcl.c8
-rw-r--r--src/mesa/drivers/dri/r200/r200_swtcl.h1
-rw-r--r--src/mesa/drivers/dri/r200/r200_tcl.c44
-rw-r--r--src/mesa/drivers/dri/r200/r200_vertprog.c20
-rw-r--r--src/mesa/drivers/dri/r200/r200_vtxfmt.c1234
-rw-r--r--src/mesa/drivers/dri/r200/r200_vtxfmt.h123
-rw-r--r--src/mesa/drivers/dri/r200/r200_vtxfmt_c.c1002
-rw-r--r--src/mesa/drivers/dri/r200/r200_vtxfmt_sse.c234
-rw-r--r--src/mesa/drivers/dri/r200/r200_vtxfmt_x86.c440
-rw-r--r--src/mesa/drivers/dri/r200/r200_vtxtmp_x86.S499
-rw-r--r--src/mesa/drivers/dri/r300/Makefile6
-rw-r--r--src/mesa/drivers/dri/r300/r200_context.h822
-rw-r--r--src/mesa/drivers/dri/r300/r200_ioctl.h204
-rw-r--r--src/mesa/drivers/dri/r300/r200_reg.h1423
-rw-r--r--src/mesa/drivers/dri/r300/r200_state.h58
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.c18
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.h12
-rw-r--r--src/mesa/drivers/dri/r300/r300_fragprog.c1111
-rw-r--r--src/mesa/drivers/dri/r300/r300_fragprog.h8
-rw-r--r--src/mesa/drivers/dri/r300/r300_fragprog_swz.c1328
-rw-r--r--src/mesa/drivers/dri/r300/r300_render.c18
-rw-r--r--src/mesa/drivers/dri/r300/r300_state.c35
-rw-r--r--src/mesa/drivers/dri/r300/r300_vertexprog.c41
-rw-r--r--src/mesa/drivers/dri/r300/radeon_state.c2
-rw-r--r--src/mesa/drivers/dri/r300/radeon_vtxfmt_a.c304
-rw-r--r--src/mesa/drivers/dri/radeon/Makefile9
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_context.c26
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_context.h111
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_ioctl.c8
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_maos_verts.c2
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_screen.c17
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_state.c6
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_state_init.c3
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_swtcl.c9
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_swtcl.h1
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_tcl.c2
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_vtxfmt.c1086
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_vtxfmt.h120
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_vtxfmt_c.c924
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_vtxfmt_sse.c236
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_vtxfmt_x86.c440
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_vtxtmp_x86.S498
-rw-r--r--src/mesa/drivers/dri/s3v/s3v_context.c4
-rw-r--r--src/mesa/drivers/dri/s3v/s3v_state.c4
-rw-r--r--src/mesa/drivers/dri/s3v/s3v_xmesa.c4
-rw-r--r--src/mesa/drivers/dri/savage/savage_xmesa.c6
-rw-r--r--src/mesa/drivers/dri/savage/savagestate.c4
-rw-r--r--src/mesa/drivers/dri/sis/sis6326_state.c4
-rw-r--r--src/mesa/drivers/dri/sis/sis_context.c6
-rw-r--r--src/mesa/drivers/dri/sis/sis_state.c4
-rw-r--r--src/mesa/drivers/dri/tdfx/tdfx_context.c6
-rw-r--r--src/mesa/drivers/dri/tdfx/tdfx_state.c4
-rw-r--r--src/mesa/drivers/dri/trident/trident_context.c6
-rw-r--r--src/mesa/drivers/dri/trident/trident_state.c4
-rw-r--r--src/mesa/drivers/dri/unichrome/server/via_dri.c1
-rw-r--r--src/mesa/drivers/dri/unichrome/server/via_regs.h1
-rw-r--r--src/mesa/drivers/dri/unichrome/via_context.c6
-rw-r--r--src/mesa/drivers/dri/unichrome/via_state.c4
211 files changed, 19534 insertions, 17189 deletions
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index ba251a81430..cc3dcf9d8db 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -482,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/extension_helper.h b/src/mesa/drivers/dri/common/extension_helper.h
index d6d51cdd165..c7984964255 100644
--- a/src/mesa/drivers/dri/common/extension_helper.h
+++ b/src/mesa/drivers/dri/common/extension_helper.h
@@ -2466,10 +2466,10 @@ static const char MultiTexCoord4ivARB_names[] =
"";
#endif
-#if defined(need_GL_VERSION_2_0)
-static const char GetVertexAttribPointervARB_names[] =
- "iip\0" /* Parameter signature */
- "glGetVertexAttribPointerv\0"
+#if defined(need_GL_EXT_gpu_program_parameters)
+static const char ProgramLocalParameters4fvEXT_names[] =
+ "iiip\0" /* Parameter signature */
+ "glProgramLocalParameters4fvEXT\0"
"";
#endif
@@ -3152,13 +3152,6 @@ static const char VertexAttribPointerNV_names[] =
"";
#endif
-#if defined(need_GL_EXT_gpu_program_parameters)
-static const char ProgramLocalParameters4fvEXT_names[] =
- "iiip\0" /* Parameter signature */
- "glProgramLocalParameters4fvEXT\0"
- "";
-#endif
-
#if defined(need_GL_EXT_framebuffer_object)
static const char GetFramebufferAttachmentParameterivEXT_names[] =
"iiip\0" /* Parameter signature */
@@ -3781,9 +3774,10 @@ static const char ReplacementCodeuiColor3fVertex3fSUN_names[] =
"";
#endif
-#if defined(need_GL_ARB_vertex_program) || defined(need_GL_NV_vertex_program)
+#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) || defined(need_GL_NV_vertex_program)
static const char GetVertexAttribPointervNV_names[] =
"iip\0" /* Parameter signature */
+ "glGetVertexAttribPointerv\0"
"glGetVertexAttribPointervARB\0"
"glGetVertexAttribPointervNV\0"
"";
@@ -5343,8 +5337,8 @@ static const struct dri_extension_function GL_EXT_framebuffer_object_functions[]
#if defined(need_GL_EXT_gpu_program_parameters)
static const struct dri_extension_function GL_EXT_gpu_program_parameters_functions[] = {
- { ProgramEnvParameters4fvEXT_names, ProgramEnvParameters4fvEXT_remap_index, -1 },
{ ProgramLocalParameters4fvEXT_names, ProgramLocalParameters4fvEXT_remap_index, -1 },
+ { ProgramEnvParameters4fvEXT_names, ProgramEnvParameters4fvEXT_remap_index, -1 },
{ NULL, 0, 0 }
};
#endif
@@ -6263,7 +6257,6 @@ static const struct dri_extension_function GL_VERSION_2_0_functions[] = {
{ GetVertexAttribfvARB_names, GetVertexAttribfvARB_remap_index, -1 },
{ GetAttribLocationARB_names, GetAttribLocationARB_remap_index, -1 },
{ Uniform3ivARB_names, Uniform3ivARB_remap_index, -1 },
- { GetVertexAttribPointervARB_names, GetVertexAttribPointervARB_remap_index, -1 },
{ VertexAttrib4sARB_names, VertexAttrib4sARB_remap_index, -1 },
{ VertexAttrib2dvARB_names, VertexAttrib2dvARB_remap_index, -1 },
{ VertexAttrib2fvARB_names, VertexAttrib2fvARB_remap_index, -1 },
@@ -6295,6 +6288,7 @@ static const struct dri_extension_function GL_VERSION_2_0_functions[] = {
{ Uniform4iARB_names, Uniform4iARB_remap_index, -1 },
{ UseProgramObjectARB_names, UseProgramObjectARB_remap_index, -1 },
{ DeleteProgram_names, DeleteProgram_remap_index, -1 },
+ { GetVertexAttribPointervNV_names, GetVertexAttribPointervNV_remap_index, -1 },
{ Uniform2iARB_names, Uniform2iARB_remap_index, -1 },
{ VertexAttrib4dARB_names, VertexAttrib4dARB_remap_index, -1 },
{ GetUniformLocationARB_names, GetUniformLocationARB_remap_index, -1 },
diff --git a/src/mesa/drivers/dri/fb/fb_dri.c b/src/mesa/drivers/dri/fb/fb_dri.c
index d6ba23bc6e6..08b52b4d8f7 100644
--- a/src/mesa/drivers/dri/fb/fb_dri.c
+++ b/src/mesa/drivers/dri/fb/fb_dri.c
@@ -50,7 +50,7 @@
#include "extensions.h"
#include "framebuffer.h"
#include "renderbuffer.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
@@ -93,7 +93,7 @@ update_state( GLcontext *ctx, GLuint new_state )
/* not much to do here - pass it on */
_swrast_InvalidateState( ctx, new_state );
_swsetup_InvalidateState( ctx, new_state );
- _ac_InvalidateState( ctx, new_state );
+ _vbo_InvalidateState( ctx, new_state );
_tnl_InvalidateState( ctx, new_state );
}
@@ -365,7 +365,7 @@ fbCreateContext( const __GLcontextModes *glVisual,
/* Create module contexts */
_swrast_CreateContext( ctx );
- _ac_CreateContext( ctx );
+ _vbo_CreateContext( ctx );
_tnl_CreateContext( ctx );
_swsetup_CreateContext( ctx );
_swsetup_Wakeup( ctx );
@@ -399,7 +399,7 @@ fbDestroyContext( __DRIcontextPrivate *driContextPriv )
if ( fbmesa ) {
_swsetup_DestroyContext( fbmesa->glCtx );
_tnl_DestroyContext( fbmesa->glCtx );
- _ac_DestroyContext( fbmesa->glCtx );
+ _vbo_DestroyContext( fbmesa->glCtx );
_swrast_DestroyContext( fbmesa->glCtx );
/* free the Mesa context */
diff --git a/src/mesa/drivers/dri/fb/fb_egl.c b/src/mesa/drivers/dri/fb/fb_egl.c
index 5c74b0b0f47..517e71f8880 100644
--- a/src/mesa/drivers/dri/fb/fb_egl.c
+++ b/src/mesa/drivers/dri/fb/fb_egl.c
@@ -17,7 +17,7 @@
#include "extensions.h"
#include "framebuffer.h"
#include "renderbuffer.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
@@ -388,7 +388,7 @@ update_state( GLcontext *ctx, GLuint new_state )
/* not much to do here - pass it on */
_swrast_InvalidateState( ctx, new_state );
_swsetup_InvalidateState( ctx, new_state );
- _ac_InvalidateState( ctx, new_state );
+ _vbo_InvalidateState( ctx, new_state );
_tnl_InvalidateState( ctx, new_state );
}
@@ -491,7 +491,7 @@ fbCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext sh
/* Create module contexts */
_swrast_CreateContext( ctx );
- _ac_CreateContext( ctx );
+ _vbo_CreateContext( ctx );
_tnl_CreateContext( ctx );
_swsetup_CreateContext( ctx );
_swsetup_Wakeup( ctx );
diff --git a/src/mesa/drivers/dri/ffb/ffb_state.c b/src/mesa/drivers/dri/ffb/ffb_state.c
index b81d94de252..eb13478166a 100644
--- a/src/mesa/drivers/dri/ffb/ffb_state.c
+++ b/src/mesa/drivers/dri/ffb/ffb_state.c
@@ -40,7 +40,7 @@
#include "enums.h"
#include "swrast/swrast.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "swrast_setup/swrast_setup.h"
@@ -1034,7 +1034,7 @@ static void ffbDDUpdateState(GLcontext *ctx, GLuint newstate)
_swrast_InvalidateState( ctx, newstate );
_swsetup_InvalidateState( ctx, newstate );
- _ac_InvalidateState( ctx, newstate );
+ _vbo_InvalidateState( ctx, newstate );
_tnl_InvalidateState( ctx, newstate );
if (newstate & _NEW_TEXTURE)
diff --git a/src/mesa/drivers/dri/ffb/ffb_xmesa.c b/src/mesa/drivers/dri/ffb/ffb_xmesa.c
index 99256d76b6e..215aaf8ffba 100644
--- a/src/mesa/drivers/dri/ffb/ffb_xmesa.c
+++ b/src/mesa/drivers/dri/ffb/ffb_xmesa.c
@@ -38,7 +38,7 @@
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "drivers/common/driverfuncs.h"
#include "ffb_context.h"
@@ -277,7 +277,7 @@ ffbCreateContext(const __GLcontextModes *mesaVis,
/* Initialize the software rasterizer and helper modules. */
_swrast_CreateContext( ctx );
- _ac_CreateContext( ctx );
+ _vbo_CreateContext( ctx );
_tnl_CreateContext( ctx );
_swsetup_CreateContext( ctx );
@@ -313,7 +313,7 @@ ffbDestroyContext(__DRIcontextPrivate *driContextPriv)
_swsetup_DestroyContext( fmesa->glCtx );
_tnl_DestroyContext( fmesa->glCtx );
- _ac_DestroyContext( fmesa->glCtx );
+ _vbo_DestroyContext( fmesa->glCtx );
_swrast_DestroyContext( fmesa->glCtx );
/* free the Mesa context */
diff --git a/src/mesa/drivers/dri/gamma/gamma_context.c b/src/mesa/drivers/dri/gamma/gamma_context.c
index ffaf45459bc..b1dcbfcdcfa 100644
--- a/src/mesa/drivers/dri/gamma/gamma_context.c
+++ b/src/mesa/drivers/dri/gamma/gamma_context.c
@@ -28,7 +28,7 @@
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
@@ -147,7 +147,7 @@ GLboolean gammaCreateContext( const __GLcontextModes *glVisual,
/* Initialize the software rasterizer and helper modules.
*/
_swrast_CreateContext( ctx );
- _ac_CreateContext( ctx );
+ _vbo_CreateContext( ctx );
_tnl_CreateContext( ctx );
_swsetup_CreateContext( ctx );
diff --git a/src/mesa/drivers/dri/gamma/gamma_state.c b/src/mesa/drivers/dri/gamma/gamma_state.c
index 08749bf5d39..8dbe0a97caa 100644
--- a/src/mesa/drivers/dri/gamma/gamma_state.c
+++ b/src/mesa/drivers/dri/gamma/gamma_state.c
@@ -33,7 +33,7 @@
#include "colormac.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#define ENABLELIGHTING 0
@@ -1663,7 +1663,7 @@ static void gammaDDUpdateState( GLcontext *ctx, GLuint new_state )
{
_swrast_InvalidateState( ctx, new_state );
_swsetup_InvalidateState( ctx, new_state );
- _ac_InvalidateState( ctx, new_state );
+ _vbo_InvalidateState( ctx, new_state );
_tnl_InvalidateState( ctx, new_state );
GAMMA_CONTEXT(ctx)->new_gl_state |= new_state;
}
diff --git a/src/mesa/drivers/dri/gamma/gamma_xmesa.c b/src/mesa/drivers/dri/gamma/gamma_xmesa.c
index 00f6aa32aeb..e8922b15036 100644
--- a/src/mesa/drivers/dri/gamma/gamma_xmesa.c
+++ b/src/mesa/drivers/dri/gamma/gamma_xmesa.c
@@ -34,7 +34,7 @@
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
static GLboolean
gammaInitDriver(__DRIscreenPrivate *sPriv)
@@ -57,7 +57,7 @@ gammaDestroyContext(__DRIcontextPrivate *driContextPriv)
if (gmesa) {
_swsetup_DestroyContext( gmesa->glCtx );
_tnl_DestroyContext( gmesa->glCtx );
- _ac_DestroyContext( gmesa->glCtx );
+ _vbo_DestroyContext( gmesa->glCtx );
_swrast_DestroyContext( gmesa->glCtx );
gammaFreeVB( gmesa->glCtx );
diff --git a/src/mesa/drivers/dri/i810/i810context.c b/src/mesa/drivers/dri/i810/i810context.c
index c0f4efd7a31..db8f7a19a23 100644
--- a/src/mesa/drivers/dri/i810/i810context.c
+++ b/src/mesa/drivers/dri/i810/i810context.c
@@ -44,7 +44,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/t_pipeline.h"
@@ -287,7 +287,7 @@ i810CreateContext( const __GLcontextModes *mesaVis,
/* Initialize the software rasterizer and helper modules.
*/
_swrast_CreateContext( ctx );
- _ac_CreateContext( ctx );
+ _vbo_CreateContext( ctx );
_tnl_CreateContext( ctx );
_swsetup_CreateContext( ctx );
@@ -350,7 +350,7 @@ i810DestroyContext(__DRIcontextPrivate *driContextPriv)
release_texture_heaps = (imesa->glCtx->Shared->RefCount == 1);
_swsetup_DestroyContext( imesa->glCtx );
_tnl_DestroyContext( imesa->glCtx );
- _ac_DestroyContext( imesa->glCtx );
+ _vbo_DestroyContext( imesa->glCtx );
_swrast_DestroyContext( imesa->glCtx );
i810FreeVB( imesa->glCtx );
diff --git a/src/mesa/drivers/dri/i810/i810state.c b/src/mesa/drivers/dri/i810/i810state.c
index 6f9d4b5bd47..3ad25282d90 100644
--- a/src/mesa/drivers/dri/i810/i810state.c
+++ b/src/mesa/drivers/dri/i810/i810state.c
@@ -21,8 +21,8 @@
#include "i810ioctl.h"
#include "swrast/swrast.h"
-#include "array_cache/acache.h"
#include "tnl/tnl.h"
+#include "vbo/vbo.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/t_pipeline.h"
@@ -953,7 +953,7 @@ static void i810InvalidateState( GLcontext *ctx, GLuint new_state )
{
_swrast_InvalidateState( ctx, new_state );
_swsetup_InvalidateState( ctx, new_state );
- _ac_InvalidateState( ctx, new_state );
+ _vbo_InvalidateState( ctx, new_state );
_tnl_InvalidateState( ctx, new_state );
I810_CONTEXT(ctx)->new_state |= new_state;
}
diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c
index b2e9ba31874..e58c9498ce0 100644
--- a/src/mesa/drivers/dri/i915/i915_context.c
+++ b/src/mesa/drivers/dri/i915/i915_context.c
@@ -36,7 +36,8 @@
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
+
#include "utils.h"
#include "i915_reg.h"
@@ -63,7 +64,7 @@ static void i915InvalidateState( GLcontext *ctx, GLuint new_state )
{
_swrast_InvalidateState( ctx, new_state );
_swsetup_InvalidateState( ctx, new_state );
- _ac_InvalidateState( ctx, new_state );
+ _vbo_InvalidateState( ctx, new_state );
_tnl_InvalidateState( ctx, new_state );
_tnl_invalidate_vertex_state( ctx, new_state );
INTEL_CONTEXT(ctx)->NewGLState |= new_state;
diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c
index 3cec6a2ddfc..fd11e10652e 100644
--- a/src/mesa/drivers/dri/i915/i915_state.c
+++ b/src/mesa/drivers/dri/i915/i915_state.c
@@ -611,10 +611,12 @@ void i915_update_fog( GLcontext *ctx )
i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_FOG_ENABLE;
}
- if (enabled) {
- _tnl_allow_vertex_fog( ctx, (i915->vertex_fog == I915_FOG_VERTEX) );
- _tnl_allow_pixel_fog( ctx, (i915->vertex_fog != I915_FOG_VERTEX) );
- }
+ /* always enbale pixel fog
+ * vertex fog use precaculted fog coord will conflict with appended
+ * fog program
+ */
+ _tnl_allow_vertex_fog( ctx, 0 );
+ _tnl_allow_pixel_fog( ctx, 1 );
}
static void i915Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c
index 0a2e33ffd53..7bb00d98339 100644
--- a/src/mesa/drivers/dri/i915/intel_context.c
+++ b/src/mesa/drivers/dri/i915/intel_context.c
@@ -37,7 +37,7 @@
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/t_pipeline.h"
#include "tnl/t_vertex.h"
@@ -228,7 +228,7 @@ static void intelInvalidateState( GLcontext *ctx, GLuint new_state )
{
_swrast_InvalidateState( ctx, new_state );
_swsetup_InvalidateState( ctx, new_state );
- _ac_InvalidateState( ctx, new_state );
+ _vbo_InvalidateState( ctx, new_state );
_tnl_InvalidateState( ctx, new_state );
_tnl_invalidate_vertex_state( ctx, new_state );
INTEL_CONTEXT(ctx)->NewGLState |= new_state;
@@ -304,7 +304,7 @@ GLboolean intelInitContext( intelContextPtr intel,
/* Initialize the software rasterizer and helper modules. */
_swrast_CreateContext( ctx );
- _ac_CreateContext( ctx );
+ _vbo_CreateContext( ctx );
_tnl_CreateContext( ctx );
_swsetup_CreateContext( ctx );
@@ -423,7 +423,7 @@ void intelDestroyContext(__DRIcontextPrivate *driContextPriv)
release_texture_heaps = (intel->ctx.Shared->RefCount == 1);
_swsetup_DestroyContext (&intel->ctx);
_tnl_DestroyContext (&intel->ctx);
- _ac_DestroyContext (&intel->ctx);
+ _vbo_DestroyContext (&intel->ctx);
_swrast_DestroyContext (&intel->ctx);
intel->Fallback = 0; /* don't call _swrast_Flush later */
diff --git a/src/mesa/drivers/dri/i915tex/Makefile b/src/mesa/drivers/dri/i915tex/Makefile
index 94879d209f7..3b3f3f5a3f7 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/i915_context.c b/src/mesa/drivers/dri/i915tex/i915_context.c
index 4cbe29d79d6..9b4d72eab3e 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 5ae76fcd185..d2713e88f96 100644
--- a/src/mesa/drivers/dri/i915tex/i915_context.h
+++ b/src/mesa/drivers/dri/i915tex/i915_context.h
@@ -243,7 +243,6 @@ struct i915_context
GLuint lodbias_ss2[MAX_TEXTURE_UNITS];
- struct i915_fragment_program tex_program;
struct i915_fragment_program *current_program;
struct i915_hw_state meta, initial, state, *current;
diff --git a/src/mesa/drivers/dri/i915tex/i915_state.c b/src/mesa/drivers/dri/i915tex/i915_state.c
index 2f5a30787ee..78ae4bdb5fc 100644
--- a/src/mesa/drivers/dri/i915tex/i915_state.c
+++ b/src/mesa/drivers/dri/i915tex/i915_state.c
@@ -520,7 +520,6 @@ update_specular(GLcontext * ctx)
/* A hack to trigger the rebuild of the fragment program.
*/
intel_context(ctx)->NewGLState |= _NEW_TEXTURE;
- I915_CONTEXT(ctx)->tex_program.translated = 0;
}
static void
@@ -646,10 +645,12 @@ i915_update_fog(GLcontext * ctx)
i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_FOG_ENABLE;
}
- if (enabled) {
- _tnl_allow_vertex_fog(ctx, (i915->vertex_fog == I915_FOG_VERTEX));
- _tnl_allow_pixel_fog(ctx, (i915->vertex_fog != I915_FOG_VERTEX));
- }
+ /* always enbale pixel fog
+ * vertex fog use precaculted fog coord will conflict with appended
+ * fog program
+ */
+ _tnl_allow_vertex_fog( ctx, 0 );
+ _tnl_allow_pixel_fog( ctx, 1 );
}
static void
diff --git a/src/mesa/drivers/dri/i915tex/i915_tex.c b/src/mesa/drivers/dri/i915tex/i915_tex.c
index a53abe9a92f..59e148ca04e 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 e9360ecea83..333fefef859 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/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c
index b4e0b74f161..c92b83bcb3a 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:
*/
@@ -313,7 +311,7 @@ intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch,
struct _DriBufferObject *buffer,
GLuint flags, GLuint mask, GLuint delta)
{
- assert(batch->nr_relocs <= MAX_RELOCS);
+ assert(batch->nr_relocs < MAX_RELOCS);
driBOAddListItem(&batch->list, buffer, flags, mask);
diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h
index a83dbf423df..59261f72741 100644
--- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h
+++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h
@@ -9,7 +9,7 @@ struct intel_context;
#define BATCH_SZ 16384
#define BATCH_RESERVED 16
-#define MAX_RELOCS 100
+#define MAX_RELOCS 400
#define INTEL_BATCH_NO_CLIPRECTS 0x1
#define INTEL_BATCH_CLIPRECTS 0x2
diff --git a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c
index 31c41d86857..ba3c7f0c1f7 100644
--- a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c
+++ b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c
@@ -50,7 +50,10 @@ intel_bufferobj_alloc(GLcontext * ctx, GLuint name, GLenum target)
_mesa_initialize_buffer_object(&obj->Base, name, target);
driGenBuffers(intel->intelScreen->regionPool,
- "bufferobj", 1, &obj->buffer, 64, 0, 0);
+ "bufferobj", 1, &obj->buffer, 64,
+ DRM_BO_FLAG_MEM_LOCAL |
+ DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE,
+ 0);
return &obj->Base;
}
diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c b/src/mesa/drivers/dri/i915tex/intel_context.c
index c77d365360d..a5ce08b1701 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"
@@ -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;
@@ -357,6 +356,10 @@ intelInitContext(struct intel_context *intel,
intel->driScreen = sPriv;
intel->sarea = saPriv;
+ intel->width = intelScreen->width;
+ intel->height = intelScreen->height;
+ intel->current_rotation = intelScreen->current_rotation;
+
if (!lockMutexInit) {
lockMutexInit = GL_TRUE;
_glthread_INIT_MUTEX(lockMutex);
@@ -390,7 +393,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 +503,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 */
@@ -635,14 +638,35 @@ intelContendedLock(struct intel_context *intel, GLuint flags)
sarea->rotation != intelScreen->current_rotation) {
intelUpdateScreenRotation(sPriv, sarea);
+ }
- /*
+ if (sarea->width != intel->width ||
+ sarea->height != intel->height ||
+ sarea->rotation != intel->current_rotation) {
+
+ void *batchMap = intel->batch->map;
+
+ /*
+ * FIXME: Really only need to do this when drawing to a
+ * common back- or front buffer.
+ */
+
+ /*
* This will drop the outstanding batchbuffer on the floor
- * FIXME: This should be done for all contexts?
*/
+ if (batchMap != NULL) {
+ driBOUnmap(intel->batch->buffer);
+ intel->batch->map = NULL;
+ }
+
intel_batchbuffer_reset(intel->batch);
+ if (batchMap == NULL) {
+ driBOUnmap(intel->batch->buffer);
+ intel->batch->map = NULL;
+ }
+
/* lose all primitives */
intel->prim.primitive = ~0;
intel->prim.start_ptr = 0;
@@ -653,6 +677,10 @@ intelContendedLock(struct intel_context *intel, GLuint flags)
/* force window update */
intel->lastStamp = 0;
+
+ intel->width = sarea->width;
+ intel->height = sarea->height;
+ intel->current_rotation = sarea->rotation;
}
diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h b/src/mesa/drivers/dri/i915tex/intel_context.h
index 7654e4ecd51..96b911501f3 100644
--- a/src/mesa/drivers/dri/i915tex/intel_context.h
+++ b/src/mesa/drivers/dri/i915tex/intel_context.h
@@ -286,6 +286,15 @@ struct intel_context
GLuint swap_missed_count;
GLuint swap_scheduled;
+
+ /* Rotation. Need to match that of the
+ * current screen.
+ */
+
+ int width;
+ int height;
+ int current_rotation;
+
};
/* These are functions now:
diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c
index 9bbfabbb8c3..efa1b014a61 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_layout.c b/src/mesa/drivers/dri/i915tex/intel_tex_layout.c
new file mode 120000
index 00000000000..fe61b441945
--- /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 25a2dca6857..3935787806b 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 5f82dfa19e6..79d587a1744 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);
}
@@ -194,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/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile
index 213eac895cb..9e4ff112dc3 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 \
@@ -34,17 +35,11 @@ DRIVER_SOURCES = \
brw_context.c \
brw_curbe.c \
brw_draw.c \
- brw_draw_current.c \
brw_draw_upload.c \
brw_eu.c \
brw_eu_debug.c \
brw_eu_emit.c \
brw_eu_util.c \
- brw_exec.c \
- brw_exec_api.c \
- brw_exec_array.c \
- brw_exec_draw.c \
- brw_exec_eval.c \
brw_fallback.c \
brw_gs.c \
brw_gs_emit.c \
@@ -53,9 +48,6 @@ DRIVER_SOURCES = \
brw_metaops.c \
brw_misc_state.c \
brw_program.c \
- brw_save.c \
- brw_save_api.c \
- brw_save_draw.c \
brw_sf.c \
brw_sf_emit.c \
brw_sf_state.c \
@@ -92,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_attrib.h b/src/mesa/drivers/dri/i965/brw_attrib.h
deleted file mode 100644
index 12659bd1cf0..00000000000
--- a/src/mesa/drivers/dri/i965/brw_attrib.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- Copyright (C) Intel Corp. 2006. All Rights Reserved.
- Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
- develop this 3D driver.
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice (including the
- next paragraph) shall be included in all copies or substantial
- portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- **********************************************************************/
- /*
- * Authors:
- * Keith Whitwell <[email protected]>
- */
-
-#ifndef BRW_ATTRIB_H
-#define BRW_ATTRIB_H
-
-
-/*
- * Note: The first attributes match the VERT_ATTRIB_* definitions
- * in mtypes.h. However, the tnl module has additional attributes
- * for materials, color indexes, edge flags, etc.
- */
-/* Although it's nice to use these as bit indexes in a DWORD flag, we
- * could manage without if necessary. Another limit currently is the
- * number of bits allocated for these numbers in places like vertex
- * program instruction formats and register layouts.
- */
-enum {
- BRW_ATTRIB_POS = 0,
- BRW_ATTRIB_WEIGHT = 1,
- BRW_ATTRIB_NORMAL = 2,
- BRW_ATTRIB_COLOR0 = 3,
- BRW_ATTRIB_COLOR1 = 4,
- BRW_ATTRIB_FOG = 5,
- BRW_ATTRIB_INDEX = 6,
- BRW_ATTRIB_EDGEFLAG = 7,
- BRW_ATTRIB_TEX0 = 8,
- BRW_ATTRIB_TEX1 = 9,
- BRW_ATTRIB_TEX2 = 10,
- BRW_ATTRIB_TEX3 = 11,
- BRW_ATTRIB_TEX4 = 12,
- BRW_ATTRIB_TEX5 = 13,
- BRW_ATTRIB_TEX6 = 14,
- BRW_ATTRIB_TEX7 = 15,
-
- BRW_ATTRIB_GENERIC0 = 16, /* Not used? */
- BRW_ATTRIB_GENERIC1 = 17,
- BRW_ATTRIB_GENERIC2 = 18,
- BRW_ATTRIB_GENERIC3 = 19,
- BRW_ATTRIB_GENERIC4 = 20,
- BRW_ATTRIB_GENERIC5 = 21,
- BRW_ATTRIB_GENERIC6 = 22,
- BRW_ATTRIB_GENERIC7 = 23,
- BRW_ATTRIB_GENERIC8 = 24,
- BRW_ATTRIB_GENERIC9 = 25,
- BRW_ATTRIB_GENERIC10 = 26,
- BRW_ATTRIB_GENERIC11 = 27,
- BRW_ATTRIB_GENERIC12 = 28,
- BRW_ATTRIB_GENERIC13 = 29,
- BRW_ATTRIB_GENERIC14 = 30,
- BRW_ATTRIB_GENERIC15 = 31,
-
- BRW_ATTRIB_MAT_FRONT_AMBIENT = 32,
- BRW_ATTRIB_MAT_BACK_AMBIENT = 33,
- BRW_ATTRIB_MAT_FRONT_DIFFUSE = 34,
- BRW_ATTRIB_MAT_BACK_DIFFUSE = 35,
- BRW_ATTRIB_MAT_FRONT_SPECULAR = 36,
- BRW_ATTRIB_MAT_BACK_SPECULAR = 37,
- BRW_ATTRIB_MAT_FRONT_EMISSION = 38,
- BRW_ATTRIB_MAT_BACK_EMISSION = 39,
- BRW_ATTRIB_MAT_FRONT_SHININESS = 40,
- BRW_ATTRIB_MAT_BACK_SHININESS = 41,
- BRW_ATTRIB_MAT_FRONT_INDEXES = 42,
- BRW_ATTRIB_MAT_BACK_INDEXES = 43,
-
- BRW_ATTRIB_MAX = 44
-} ;
-
-#define BRW_ATTRIB_FIRST_MATERIAL BRW_ATTRIB_MAT_FRONT_AMBIENT
-#define BRW_ATTRIB_LAST_MATERIAL BRW_ATTRIB_MAT_BACK_INDEXES
-
-#define BRW_MAX_COPIED_VERTS 3
-
-
-static inline GLuint64EXT brw_translate_inputs( GLboolean vp_enabled,
- GLuint mesa_inputs )
-{
- GLuint64EXT inputs = mesa_inputs;
- if (vp_enabled)
- return inputs;
- else
- return (inputs & 0xffff) | ((inputs & 0xffff0000) << 16);
-}
-
-
-#endif
diff --git a/src/mesa/drivers/dri/i965/brw_attrib_tmp.h b/src/mesa/drivers/dri/i965/brw_attrib_tmp.h
deleted file mode 100644
index 3089bd6cac2..00000000000
--- a/src/mesa/drivers/dri/i965/brw_attrib_tmp.h
+++ /dev/null
@@ -1,485 +0,0 @@
-/**************************************************************************
-
-Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas.
-
-All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-on the rights to use, copy, modify, merge, publish, distribute, sub
-license, and/or sell copies of the Software, and to permit persons to whom
-the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice (including the next
-paragraph) shall be included in all copies or substantial portions of the
-Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
-TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-#define ATTR1FV( A, V ) ATTR( A, 1, (V)[0], 0, 0, 1 )
-#define ATTR2FV( A, V ) ATTR( A, 2, (V)[0], (V)[1], 0, 1 )
-#define ATTR3FV( A, V ) ATTR( A, 3, (V)[0], (V)[1], (V)[2], 1 )
-#define ATTR4FV( A, V ) ATTR( A, 4, (V)[0], (V)[1], (V)[2], (V)[3] )
-
-#define ATTR1F( A, X ) ATTR( A, 1, X, 0, 0, 1 )
-#define ATTR2F( A, X, Y ) ATTR( A, 2, X, Y, 0, 1 )
-#define ATTR3F( A, X, Y, Z ) ATTR( A, 3, X, Y, Z, 1 )
-#define ATTR4F( A, X, Y, Z, W ) ATTR( A, 4, X, Y, Z, W )
-
-#define MAT_ATTR( A, N, V ) ATTR( A, N, (V)[0], (V)[1], (V)[2], (V)[3] )
-
-static void GLAPIENTRY TAG(Vertex2f)( GLfloat x, GLfloat y )
-{
- GET_CURRENT_CONTEXT( ctx );
- ATTR2F( BRW_ATTRIB_POS, x, y );
-}
-
-static void GLAPIENTRY TAG(Vertex2fv)( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT( ctx );
- ATTR2FV( BRW_ATTRIB_POS, v );
-}
-
-static void GLAPIENTRY TAG(Vertex3f)( GLfloat x, GLfloat y, GLfloat z )
-{
- GET_CURRENT_CONTEXT( ctx );
- ATTR3F( BRW_ATTRIB_POS, x, y, z );
-}
-
-static void GLAPIENTRY TAG(Vertex3fv)( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT( ctx );
- ATTR3FV( BRW_ATTRIB_POS, v );
-}
-
-static void GLAPIENTRY TAG(Vertex4f)( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
-{
- GET_CURRENT_CONTEXT( ctx );
- ATTR4F( BRW_ATTRIB_POS, x, y, z, w );
-}
-
-static void GLAPIENTRY TAG(Vertex4fv)( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT( ctx );
- ATTR4FV( BRW_ATTRIB_POS, v );
-}
-
-static void GLAPIENTRY TAG(TexCoord1f)( GLfloat x )
-{
- GET_CURRENT_CONTEXT( ctx );
- ATTR1F( BRW_ATTRIB_TEX0, x );
-}
-
-static void GLAPIENTRY TAG(TexCoord1fv)( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT( ctx );
- ATTR1FV( BRW_ATTRIB_TEX0, v );
-}
-
-static void GLAPIENTRY TAG(TexCoord2f)( GLfloat x, GLfloat y )
-{
- GET_CURRENT_CONTEXT( ctx );
- ATTR2F( BRW_ATTRIB_TEX0, x, y );
-}
-
-static void GLAPIENTRY TAG(TexCoord2fv)( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT( ctx );
- ATTR2FV( BRW_ATTRIB_TEX0, v );
-}
-
-static void GLAPIENTRY TAG(TexCoord3f)( GLfloat x, GLfloat y, GLfloat z )
-{
- GET_CURRENT_CONTEXT( ctx );
- ATTR3F( BRW_ATTRIB_TEX0, x, y, z );
-}
-
-static void GLAPIENTRY TAG(TexCoord3fv)( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT( ctx );
- ATTR3FV( BRW_ATTRIB_TEX0, v );
-}
-
-static void GLAPIENTRY TAG(TexCoord4f)( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
-{
- GET_CURRENT_CONTEXT( ctx );
- ATTR4F( BRW_ATTRIB_TEX0, x, y, z, w );
-}
-
-static void GLAPIENTRY TAG(TexCoord4fv)( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT( ctx );
- ATTR4FV( BRW_ATTRIB_TEX0, v );
-}
-
-static void GLAPIENTRY TAG(Normal3f)( GLfloat x, GLfloat y, GLfloat z )
-{
- GET_CURRENT_CONTEXT( ctx );
- ATTR3F( BRW_ATTRIB_NORMAL, x, y, z );
-}
-
-static void GLAPIENTRY TAG(Normal3fv)( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT( ctx );
- ATTR3FV( BRW_ATTRIB_NORMAL, v );
-}
-
-static void GLAPIENTRY TAG(FogCoordfEXT)( GLfloat x )
-{
- GET_CURRENT_CONTEXT( ctx );
- ATTR1F( BRW_ATTRIB_FOG, x );
-}
-
-static void GLAPIENTRY TAG(FogCoordfvEXT)( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT( ctx );
- ATTR1FV( BRW_ATTRIB_FOG, v );
-}
-
-static void GLAPIENTRY TAG(Color3f)( GLfloat x, GLfloat y, GLfloat z )
-{
- GET_CURRENT_CONTEXT( ctx );
- ATTR3F( BRW_ATTRIB_COLOR0, x, y, z );
-}
-
-static void GLAPIENTRY TAG(Color3fv)( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT( ctx );
- ATTR3FV( BRW_ATTRIB_COLOR0, v );
-}
-
-static void GLAPIENTRY TAG(Color4f)( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
-{
- GET_CURRENT_CONTEXT( ctx );
- ATTR4F( BRW_ATTRIB_COLOR0, x, y, z, w );
-}
-
-static void GLAPIENTRY TAG(Color4fv)( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT( ctx );
- ATTR4FV( BRW_ATTRIB_COLOR0, v );
-}
-
-static void GLAPIENTRY TAG(SecondaryColor3fEXT)( GLfloat x, GLfloat y, GLfloat z )
-{
- GET_CURRENT_CONTEXT( ctx );
- ATTR3F( BRW_ATTRIB_COLOR1, x, y, z );
-}
-
-static void GLAPIENTRY TAG(SecondaryColor3fvEXT)( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT( ctx );
- ATTR3FV( BRW_ATTRIB_COLOR1, v );
-}
-
-
-static void GLAPIENTRY TAG(EdgeFlag)( GLboolean b )
-{
- GET_CURRENT_CONTEXT( ctx );
- ATTR1F( BRW_ATTRIB_EDGEFLAG, (GLfloat)b );
-}
-
-static void GLAPIENTRY TAG(Indexf)( GLfloat f )
-{
- GET_CURRENT_CONTEXT( ctx );
- ATTR1F( BRW_ATTRIB_INDEX, f );
-}
-
-static void GLAPIENTRY TAG(Indexfv)( const GLfloat *f )
-{
- GET_CURRENT_CONTEXT( ctx );
- ATTR1FV( BRW_ATTRIB_INDEX, f );
-}
-
-
-static void GLAPIENTRY TAG(MultiTexCoord1f)( GLenum target, GLfloat x )
-{
- GET_CURRENT_CONTEXT( ctx );
- GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0;
- ATTR1F( attr, x );
-}
-
-static void GLAPIENTRY TAG(MultiTexCoord1fv)( GLenum target, const GLfloat *v )
-{
- GET_CURRENT_CONTEXT( ctx );
- GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0;
- ATTR1FV( attr, v );
-}
-
-static void GLAPIENTRY TAG(MultiTexCoord2f)( GLenum target, GLfloat x, GLfloat y )
-{
- GET_CURRENT_CONTEXT( ctx );
- GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0;
- ATTR2F( attr, x, y );
-}
-
-static void GLAPIENTRY TAG(MultiTexCoord2fv)( GLenum target, const GLfloat *v )
-{
- GET_CURRENT_CONTEXT( ctx );
- GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0;
- ATTR2FV( attr, v );
-}
-
-static void GLAPIENTRY TAG(MultiTexCoord3f)( GLenum target, GLfloat x, GLfloat y,
- GLfloat z)
-{
- GET_CURRENT_CONTEXT( ctx );
- GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0;
- ATTR3F( attr, x, y, z );
-}
-
-static void GLAPIENTRY TAG(MultiTexCoord3fv)( GLenum target, const GLfloat *v )
-{
- GET_CURRENT_CONTEXT( ctx );
- GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0;
- ATTR3FV( attr, v );
-}
-
-static void GLAPIENTRY TAG(MultiTexCoord4f)( GLenum target, GLfloat x, GLfloat y,
- GLfloat z, GLfloat w )
-{
- GET_CURRENT_CONTEXT( ctx );
- GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0;
- ATTR4F( attr, x, y, z, w );
-}
-
-static void GLAPIENTRY TAG(MultiTexCoord4fv)( GLenum target, const GLfloat *v )
-{
- GET_CURRENT_CONTEXT( ctx );
- GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0;
- ATTR4FV( attr, v );
-}
-
-
-static void GLAPIENTRY TAG(VertexAttrib1fARB)( GLuint index, GLfloat x )
-{
- GET_CURRENT_CONTEXT( ctx );
- if (index == 0)
- ATTR1F(0, x);
- else if (index < MAX_VERTEX_ATTRIBS)
- ATTR1F(BRW_ATTRIB_GENERIC0 + index, x);
- else
- ERROR();
-}
-
-static void GLAPIENTRY TAG(VertexAttrib1fvARB)( GLuint index,
- const GLfloat *v )
-{
- GET_CURRENT_CONTEXT( ctx );
- if (index == 0)
- ATTR1FV(0, v);
- else if (index < MAX_VERTEX_ATTRIBS)
- ATTR1FV(BRW_ATTRIB_GENERIC0 + index, v);
- else
- ERROR();
-}
-
-static void GLAPIENTRY TAG(VertexAttrib2fARB)( GLuint index, GLfloat x,
- GLfloat y )
-{
- GET_CURRENT_CONTEXT( ctx );
- if (index == 0)
- ATTR2F(0, x, y);
- else if (index < MAX_VERTEX_ATTRIBS)
- ATTR2F(BRW_ATTRIB_GENERIC0 + index, x, y);
- else
- ERROR();
-}
-
-static void GLAPIENTRY TAG(VertexAttrib2fvARB)( GLuint index,
- const GLfloat *v )
-{
- GET_CURRENT_CONTEXT( ctx );
- if (index == 0)
- ATTR2FV(0, v);
- else if (index < MAX_VERTEX_ATTRIBS)
- ATTR2FV(BRW_ATTRIB_GENERIC0 + index, v);
- else
- ERROR();
-}
-
-static void GLAPIENTRY TAG(VertexAttrib3fARB)( GLuint index, GLfloat x,
- GLfloat y, GLfloat z )
-{
- GET_CURRENT_CONTEXT( ctx );
- if (index == 0)
- ATTR3F(0, x, y, z);
- else if (index < MAX_VERTEX_ATTRIBS)
- ATTR3F(BRW_ATTRIB_GENERIC0 + index, x, y, z);
- else
- ERROR();
-}
-
-static void GLAPIENTRY TAG(VertexAttrib3fvARB)( GLuint index,
- const GLfloat *v )
-{
- GET_CURRENT_CONTEXT( ctx );
- if (index == 0)
- ATTR3FV(0, v);
- else if (index < MAX_VERTEX_ATTRIBS)
- ATTR3FV(BRW_ATTRIB_GENERIC0 + index, v);
- else
- ERROR();
-}
-
-static void GLAPIENTRY TAG(VertexAttrib4fARB)( GLuint index, GLfloat x,
- GLfloat y, GLfloat z,
- GLfloat w )
-{
- GET_CURRENT_CONTEXT( ctx );
- if (index == 0)
- ATTR4F(0, x, y, z, w);
- else if (index < MAX_VERTEX_ATTRIBS)
- ATTR4F(BRW_ATTRIB_GENERIC0 + index, x, y, z, w);
- else
- ERROR();
-}
-
-static void GLAPIENTRY TAG(VertexAttrib4fvARB)( GLuint index,
- const GLfloat *v )
-{
- GET_CURRENT_CONTEXT( ctx );
- if (index == 0)
- ATTR4FV(0, v);
- else if (index < MAX_VERTEX_ATTRIBS)
- ATTR4FV(BRW_ATTRIB_GENERIC0 + index, v);
- else
- ERROR();
-}
-
-
-/* Although we don't export NV_vertex_program, these entrypoints are
- * used by the display list and other code specifically because of
- * their property of aliasing with other attributes.
- */
-static void GLAPIENTRY TAG(VertexAttrib1fNV)( GLuint index, GLfloat x )
-{
- GET_CURRENT_CONTEXT( ctx );
- if (index < BRW_ATTRIB_MAX)
- ATTR1F(index, x);
-}
-
-static void GLAPIENTRY TAG(VertexAttrib1fvNV)( GLuint index,
- const GLfloat *v )
-{
- GET_CURRENT_CONTEXT( ctx );
- if (index < BRW_ATTRIB_MAX)
- ATTR1FV(index, v);
-}
-
-static void GLAPIENTRY TAG(VertexAttrib2fNV)( GLuint index, GLfloat x,
- GLfloat y )
-{
- GET_CURRENT_CONTEXT( ctx );
- if (index < BRW_ATTRIB_MAX)
- ATTR2F(index, x, y);
-}
-
-static void GLAPIENTRY TAG(VertexAttrib2fvNV)( GLuint index,
- const GLfloat *v )
-{
- GET_CURRENT_CONTEXT( ctx );
- if (index < BRW_ATTRIB_MAX)
- ATTR2FV(index, v);
-}
-
-static void GLAPIENTRY TAG(VertexAttrib3fNV)( GLuint index, GLfloat x,
- GLfloat y, GLfloat z )
-{
- GET_CURRENT_CONTEXT( ctx );
- if (index < BRW_ATTRIB_MAX)
- ATTR3F(index, x, y, z);
-}
-
-static void GLAPIENTRY TAG(VertexAttrib3fvNV)( GLuint index,
- const GLfloat *v )
-{
- GET_CURRENT_CONTEXT( ctx );
- if (index < BRW_ATTRIB_MAX)
- ATTR3FV(index, v);
-}
-
-static void GLAPIENTRY TAG(VertexAttrib4fNV)( GLuint index, GLfloat x,
- GLfloat y, GLfloat z,
- GLfloat w )
-{
- GET_CURRENT_CONTEXT( ctx );
- if (index < BRW_ATTRIB_MAX)
- ATTR4F(index, x, y, z, w);
-}
-
-static void GLAPIENTRY TAG(VertexAttrib4fvNV)( GLuint index,
- const GLfloat *v )
-{
- GET_CURRENT_CONTEXT( ctx );
- if (index < BRW_ATTRIB_MAX)
- ATTR4FV(index, v);
-}
-
-
-#define MAT( ATTR, N, face, params ) \
-do { \
- if (face != GL_BACK) \
- MAT_ATTR( ATTR, N, params ); /* front */ \
- if (face != GL_FRONT) \
- MAT_ATTR( ATTR + 1, N, params ); /* back */ \
-} while (0)
-
-
-/* Colormaterial conflicts are dealt with later.
- */
-static void GLAPIENTRY TAG(Materialfv)( GLenum face, GLenum pname,
- const GLfloat *params )
-{
- GET_CURRENT_CONTEXT( ctx );
- switch (pname) {
- case GL_EMISSION:
- MAT( BRW_ATTRIB_MAT_FRONT_EMISSION, 4, face, params );
- break;
- case GL_AMBIENT:
- MAT( BRW_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params );
- break;
- case GL_DIFFUSE:
- MAT( BRW_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params );
- break;
- case GL_SPECULAR:
- MAT( BRW_ATTRIB_MAT_FRONT_SPECULAR, 4, face, params );
- break;
- case GL_SHININESS:
- MAT( BRW_ATTRIB_MAT_FRONT_SHININESS, 1, face, params );
- break;
- case GL_COLOR_INDEXES:
- MAT( BRW_ATTRIB_MAT_FRONT_INDEXES, 3, face, params );
- break;
- case GL_AMBIENT_AND_DIFFUSE:
- MAT( BRW_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params );
- MAT( BRW_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params );
- break;
- default:
- ERROR();
- return;
- }
-}
-
-
-#undef ATTR1FV
-#undef ATTR2FV
-#undef ATTR3FV
-#undef ATTR4FV
-
-#undef ATTR1F
-#undef ATTR2F
-#undef ATTR3F
-#undef ATTR4F
-
-#undef MAT
-#undef MAT_ATTR
diff --git a/src/mesa/drivers/dri/i965/brw_clip.c b/src/mesa/drivers/dri/i965/brw_clip.c
index 0e8591aaa8d..3bec153075a 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_clip.h b/src/mesa/drivers/dri/i965/brw_clip.h
index c3967c8c614..49b2770a514 100644
--- a/src/mesa/drivers/dri/i965/brw_clip.h
+++ b/src/mesa/drivers/dri/i965/brw_clip.h
@@ -116,7 +116,7 @@ struct brw_clip_compile {
GLuint last_mrf;
GLuint header_position_offset;
- GLuint offset[BRW_ATTRIB_MAX];
+ GLuint offset[VERT_ATTRIB_MAX];
};
#define ATTR_SIZE (4*4)
diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index bc422c1a50b..6faee65542b 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -34,8 +34,6 @@
#include "brw_aub.h"
#include "brw_defines.h"
#include "brw_draw.h"
-#include "brw_exec.h"
-#include "brw_save.h"
#include "brw_vs.h"
#include "imports.h"
#include "intel_tex.h"
@@ -158,12 +156,6 @@ GLboolean brwCreateContext( const __GLcontextModes *mesaVis,
brw_FrameBufferTexInit( brw );
- /* Hook our functions into exec and compile dispatch tables. Only
- * fallback on out-of-memory situations.
- */
- brw_exec_init( ctx );
- brw_save_init( ctx );
-
{
const char *filename = getenv("INTEL_REPLAY");
if (filename) {
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index cac4d86d3ab..08fdc545205 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -36,7 +36,6 @@
#include "intel_context.h"
#include "brw_structs.h"
#include "imports.h"
-#include "brw_attrib.h"
/* Glossary:
@@ -215,7 +214,7 @@ struct brw_vs_prog_data {
GLuint total_grf;
GLuint outputs_written;
- GLuint64EXT inputs_read;
+ GLuint inputs_read;
/* Used for calculating urb partitions:
*/
@@ -382,10 +381,10 @@ struct brw_cached_batch_item {
-/* Protect against a future where BRW_ATTRIB_MAX > 32. Wouldn't life
+/* Protect against a future where VERT_ATTRIB_MAX > 32. Wouldn't life
* be easier if C allowed arrays of packed elements?
*/
-#define ATTRIB_BIT_DWORDS ((BRW_ATTRIB_MAX+31)/32)
+#define ATTRIB_BIT_DWORDS ((VERT_ATTRIB_MAX+31)/32)
struct brw_vertex_element {
const struct gl_client_array *glarray;
@@ -401,8 +400,8 @@ struct brw_vertex_element {
struct brw_vertex_info {
- GLuint64EXT varying; /* varying:1[BRW_ATTRIB_MAX] */
- GLuint sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[BRW_ATTRIB_MAX] */
+ GLuint varying; /* varying:1[VERT_ATTRIB_MAX] */
+ GLuint sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[VERT_ATTRIB_MAX] */
};
@@ -449,14 +448,13 @@ struct brw_context
struct brw_cached_batch_item *cached_batch_items;
struct {
- /* Fallback values for inputs not supplied:
- */
- struct gl_client_array current_values[BRW_ATTRIB_MAX];
/* Arrays with buffer objects to copy non-bufferobj arrays into
* for upload:
*/
- struct gl_client_array vbo_array[BRW_ATTRIB_MAX];
+ struct gl_client_array vbo_array[VERT_ATTRIB_MAX];
+
+ struct brw_vertex_element inputs[VERT_ATTRIB_MAX];
#define BRW_NR_UPLOAD_BUFS 17
#define BRW_UPLOAD_INIT_SIZE (128*1024)
@@ -469,11 +467,6 @@ struct brw_context
GLuint wrap;
} upload;
- /* Currenly bound arrays, including fallbacks to current_values
- * above:
- */
- struct brw_vertex_element inputs[BRW_ATTRIB_MAX];
-
/* Summary of size and varying of active arrays, so we can check
* for changes to this state:
*/
@@ -505,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:
diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c
index 471fda9f7ef..092c6bafc2d 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.c
+++ b/src/mesa/drivers/dri/i965/brw_draw.c
@@ -35,7 +35,6 @@
#include "brw_draw.h"
#include "brw_defines.h"
-#include "brw_attrib.h"
#include "brw_context.h"
#include "brw_aub.h"
#include "brw_state.h"
@@ -45,7 +44,8 @@
#include "intel_batchbuffer.h"
#include "intel_buffer_objects.h"
-
+#include "tnl/tnl.h"
+#include "vbo/vbo_context.h"
@@ -143,7 +143,7 @@ static void brw_emit_cliprect( struct brw_context *brw,
static void brw_emit_prim( struct brw_context *brw,
- const struct brw_draw_prim *prim )
+ const struct _mesa_prim *prim )
{
struct brw_3d_primitive prim_packet;
@@ -170,34 +170,9 @@ static void brw_emit_prim( struct brw_context *brw,
}
}
-
-
-static void update_current_size( struct gl_client_array *array)
-{
- const GLfloat *ptr = (const GLfloat *)array->Ptr;
-
- assert(array->StrideB == 0);
- assert(array->Type == GL_FLOAT || array->Type == GL_UNSIGNED_BYTE);
-
- if (ptr[3] != 1.0)
- array->Size = 4;
- else if (ptr[2] != 0.0)
- array->Size = 3;
- else if (ptr[1] != 0.0)
- array->Size = 2;
- else
- array->Size = 1;
-}
-
-
-
-/* Fill in any gaps in passed arrays with pointers to current
- * attributes:
- */
static void brw_merge_inputs( struct brw_context *brw,
const struct gl_client_array *arrays[])
{
- struct gl_client_array *current_values = brw->vb.current_values;
struct brw_vertex_element *inputs = brw->vb.inputs;
struct brw_vertex_info old = brw->vb.info;
GLuint i;
@@ -205,19 +180,16 @@ static void brw_merge_inputs( struct brw_context *brw,
memset(inputs, 0, sizeof(*inputs));
memset(&brw->vb.info, 0, sizeof(brw->vb.info));
- for (i = 0; i < BRW_ATTRIB_MAX; i++) {
- if (arrays[i] && arrays[i]->Enabled)
- {
- brw->vb.inputs[i].glarray = arrays[i];
- brw->vb.info.varying |= (GLuint64EXT) 1 << i;
- }
- else
- {
- brw->vb.inputs[i].glarray = &current_values[i];
- update_current_size(&current_values[i]);
- }
+ for (i = 0; i < VERT_ATTRIB_MAX; i++) {
+ brw->vb.inputs[i].glarray = arrays[i];
+
+ /* XXX: metaops passes null arrays */
+ if (arrays[i]) {
+ if (arrays[i]->StrideB != 0)
+ brw->vb.info.varying |= 1 << i;
- brw->vb.info.sizes[i/16] |= (inputs[i].glarray->Size - 1) << ((i%16) * 2);
+ brw->vb.info.sizes[i/16] |= (inputs[i].glarray->Size - 1) << ((i%16) * 2);
+ }
}
/* Raise statechanges if input sizes and varying have changed:
@@ -229,8 +201,11 @@ static void brw_merge_inputs( struct brw_context *brw,
brw->state.dirty.brw |= BRW_NEW_INPUT_VARYING;
}
+/* XXX: could split the primitive list to fallback only on the
+ * non-conformant primitives.
+ */
static GLboolean check_fallbacks( struct brw_context *brw,
- const struct brw_draw_prim *prim,
+ const struct _mesa_prim *prim,
GLuint nr_prims )
{
GLuint i;
@@ -281,15 +256,16 @@ static GLboolean check_fallbacks( struct brw_context *brw,
return GL_FALSE;
}
-
+/* May fail if out of video memory for texture or vbo upload, or on
+ * fallback conditions.
+ */
static GLboolean brw_try_draw_prims( GLcontext *ctx,
const struct gl_client_array *arrays[],
- const struct brw_draw_prim *prim,
+ const struct _mesa_prim *prim,
GLuint nr_prims,
- const struct brw_draw_index_buffer *ib,
+ const struct _mesa_index_buffer *ib,
GLuint min_index,
- GLuint max_index,
- GLuint flags )
+ GLuint max_index )
{
struct intel_context *intel = intel_context(ctx);
struct brw_context *brw = brw_context(ctx);
@@ -298,11 +274,11 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx,
if (ctx->NewState)
_mesa_update_state( ctx );
-
+
/* Bind all inputs, derive varying and size information:
*/
brw_merge_inputs( brw, arrays );
-
+
/* Have to validate state quite late. Will rebuild tnl_program,
* which depends on varying information.
*
@@ -319,10 +295,6 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx,
}
{
- assert(intel->locked);
-
-
-
/* Set the first primitive early, ahead of validate_state:
*/
brw_set_prim(brw, prim[0].mode);
@@ -411,44 +383,88 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx,
return retval;
}
+static GLboolean brw_need_rebase( GLcontext *ctx,
+ const struct gl_client_array *arrays[],
+ const struct _mesa_index_buffer *ib,
+ GLuint min_index )
+{
+ if (min_index == 0)
+ return GL_FALSE;
-GLboolean brw_draw_prims( GLcontext *ctx,
- const struct gl_client_array *arrays[],
- const struct brw_draw_prim *prim,
- GLuint nr_prims,
- const struct brw_draw_index_buffer *ib,
- GLuint min_index,
- GLuint max_index,
- GLuint flags )
+ if (ib) {
+ if (!vbo_all_varyings_in_vbos(arrays))
+ return GL_TRUE;
+ else
+ return GL_FALSE;
+ }
+ else {
+ /* Hmm. This isn't quite what I wanted. BRW can actually
+ * handle the mixed case well enough that we shouldn't need to
+ * rebase. However, it's probably not very common, nor hugely
+ * expensive to do it this way:
+ */
+ if (!vbo_all_varyings_in_vbos(arrays))
+ return GL_TRUE;
+ else
+ return GL_FALSE;
+ }
+}
+
+
+void brw_draw_prims( GLcontext *ctx,
+ const struct gl_client_array *arrays[],
+ const struct _mesa_prim *prim,
+ GLuint nr_prims,
+ const struct _mesa_index_buffer *ib,
+ GLuint min_index,
+ GLuint max_index )
{
struct intel_context *intel = intel_context(ctx);
GLboolean retval;
- retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index, flags);
+ /* Decide if we want to rebase. If so we end up recursing once
+ * only into this function.
+ */
+ if (brw_need_rebase( ctx, arrays, ib, min_index )) {
+ vbo_rebase_prims( ctx, arrays,
+ prim, nr_prims,
+ ib, min_index, max_index,
+ brw_draw_prims );
+
+ return;
+ }
-
- if (!retval && bmError(intel)) {
- DBG("retrying\n");
- /* This looks like out-of-memory but potentially we have
- * situation where there is enough memory but it has become
- * fragmented. Clear out all heaps and start from scratch by
- * faking a contended lock event: (done elsewhere)
- */
+ /* Make a first attempt at drawing:
+ */
+ retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
+
+ /* This looks like out-of-memory but potentially we have
+ * situation where there is enough memory but it has become
+ * fragmented. Clear out all heaps and start from scratch by
+ * faking a contended lock event: (done elsewhere)
+ */
+ if (!retval && !intel->Fallback && bmError(intel)) {
+ DBG("retrying\n");
/* Then try a second time only to upload textures and draw the
* primitives:
*/
- retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index, flags);
+ retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
+ }
+
+ /* Otherwise, we really are out of memory. Pass the drawing
+ * command to the software tnl module and which will in turn call
+ * swrast to do the drawing.
+ */
+ if (!retval) {
+ _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
}
if (intel->aub_file && (INTEL_DEBUG & DEBUG_SYNC)) {
intelFinish( &intel->ctx );
intel->aub_wrap = 1;
}
-
-
- return retval;
}
@@ -461,21 +477,25 @@ static void brw_invalidate_vbo_cb( struct intel_context *intel, void *ptr )
void brw_draw_init( struct brw_context *brw )
{
GLcontext *ctx = &brw->intel.ctx;
+ struct vbo_context *vbo = vbo_context(ctx);
GLuint i;
+ /* Register our drawing function:
+ */
+ vbo->draw_prims = brw_draw_prims;
+
brw->vb.upload.size = BRW_UPLOAD_INIT_SIZE;
for (i = 0; i < BRW_NR_UPLOAD_BUFS; i++) {
brw->vb.upload.vbo[i] = ctx->Driver.NewBufferObject(ctx, 1, GL_ARRAY_BUFFER_ARB);
- /* XXX: Set these to no-backing-store
+ /* NOTE: These are set to no-backing-store.
*/
bmBufferSetInvalidateCB(&brw->intel,
intel_bufferobj_buffer(intel_buffer_object(brw->vb.upload.vbo[i])),
brw_invalidate_vbo_cb,
&brw->intel,
GL_TRUE);
-
}
ctx->Driver.BufferData( ctx,
@@ -484,9 +504,6 @@ void brw_draw_init( struct brw_context *brw )
NULL,
GL_DYNAMIC_DRAW_ARB,
brw->vb.upload.vbo[0] );
-
-
- brw_init_current_values(ctx, brw->vb.current_values);
}
void brw_draw_destroy( struct brw_context *brw )
diff --git a/src/mesa/drivers/dri/i965/brw_draw.h b/src/mesa/drivers/dri/i965/brw_draw.h
index 92640bf725b..0f7b7383102 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.h
+++ b/src/mesa/drivers/dri/i965/brw_draw.h
@@ -29,44 +29,18 @@
#define BRW_DRAW_H
#include "mtypes.h" /* for GLcontext... */
-#include "brw_attrib.h"
+#include "vbo/vbo.h"
struct brw_context;
-struct brw_draw_prim {
- GLuint mode:8;
- GLuint indexed:1;
- GLuint begin:1;
- GLuint end:1;
- GLuint weak:1;
- GLuint pad:20;
- GLuint start;
- GLuint count;
-};
-
-struct brw_draw_index_buffer {
- GLuint count;
- GLenum type;
- struct gl_buffer_object *obj;
- const void *ptr;
- GLuint rebase;
-};
-
-
-#define BRW_DRAW_SORTED 0x1
-#define BRW_DRAW_ALL_INTERLEAVED 0x2
-#define BRW_DRAW_NON_INTERLEAVED 0x4
-#define BRW_DRAW_LOCKED 0x8
-
-GLboolean brw_draw_prims( GLcontext *ctx,
- const struct gl_client_array *arrays[],
- const struct brw_draw_prim *prims,
- GLuint nr_prims,
- const struct brw_draw_index_buffer *ib,
- GLuint min_index,
- GLuint max_index,
- GLuint flags );
+void brw_draw_prims( GLcontext *ctx,
+ const struct gl_client_array *arrays[],
+ const struct _mesa_prim *prims,
+ GLuint nr_prims,
+ const struct _mesa_index_buffer *ib,
+ GLuint min_index,
+ GLuint max_index );
void brw_draw_init( struct brw_context *brw );
void brw_draw_destroy( struct brw_context *brw );
@@ -80,25 +54,12 @@ void brw_init_current_values(GLcontext *ctx,
/* brw_draw_upload.c
*/
void brw_upload_indices( struct brw_context *brw,
- const struct brw_draw_index_buffer *index_buffer);
+ const struct _mesa_index_buffer *index_buffer);
GLboolean brw_upload_vertices( struct brw_context *brw,
GLuint min_index,
GLuint max_index );
-/* Helpers for save, exec. Should probably have their own file:
- */
-struct brw_exec_context;
-struct brw_save_context;
-
-struct brw_exec_save {
- struct brw_exec_context *exec;
- struct brw_save_context *save;
-};
-
-/* Doesn't really belong here:
- */
-#define IMM_CONTEXT(ctx) ((struct brw_exec_save *)((ctx)->swtnl_im))
#endif
diff --git a/src/mesa/drivers/dri/i965/brw_draw_current.c b/src/mesa/drivers/dri/i965/brw_draw_current.c
deleted file mode 100644
index 98d930738e5..00000000000
--- a/src/mesa/drivers/dri/i965/brw_draw_current.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-#include <stdlib.h>
-
-#include "glheader.h"
-#include "context.h"
-#include "state.h"
-#include "api_validate.h"
-#include "enums.h"
-
-#include "brw_context.h"
-#include "brw_draw.h"
-
-#include "bufmgr.h"
-#include "intel_buffer_objects.h"
-
-
-void brw_init_current_values(GLcontext *ctx,
- struct gl_client_array *arrays)
-{
- GLuint i;
-
- memset(arrays, 0, sizeof(*arrays) * BRW_ATTRIB_MAX);
-
- /* Set up a constant (StrideB == 0) array for each current
- * attribute:
- */
- for (i = 0; i < BRW_ATTRIB_MAX; i++) {
- struct gl_client_array *cl = &arrays[i];
-
- switch (i) {
- case BRW_ATTRIB_MAT_FRONT_SHININESS:
- case BRW_ATTRIB_MAT_BACK_SHININESS:
- case BRW_ATTRIB_INDEX:
- case BRW_ATTRIB_EDGEFLAG:
- cl->Size = 1;
- break;
- case BRW_ATTRIB_MAT_FRONT_INDEXES:
- case BRW_ATTRIB_MAT_BACK_INDEXES:
- cl->Size = 3;
- break;
- default:
- /* This is fixed for the material attributes, for others will
- * be determined at runtime:
- */
- if (i >= BRW_ATTRIB_MAT_FRONT_AMBIENT)
- cl->Size = 4;
- else
- cl->Size = 1;
- break;
- }
-
- switch (i) {
- case BRW_ATTRIB_EDGEFLAG:
- cl->Type = GL_UNSIGNED_BYTE;
- cl->Ptr = (const void *)&ctx->Current.EdgeFlag;
- break;
- case BRW_ATTRIB_INDEX:
- cl->Type = GL_FLOAT;
- cl->Ptr = (const void *)&ctx->Current.Index;
- break;
- default:
- cl->Type = GL_FLOAT;
- if (i < BRW_ATTRIB_FIRST_MATERIAL)
- cl->Ptr = (const void *)ctx->Current.Attrib[i];
- else
- cl->Ptr = (const void *)ctx->Light.Material.Attrib[i - BRW_ATTRIB_FIRST_MATERIAL];
- break;
- }
-
- cl->Stride = 0;
- cl->StrideB = 0;
- cl->Enabled = 1;
- cl->Flags = 0;
- cl->BufferObj = ctx->Array.NullBufferObj;
- }
-}
-
diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c
index 57ee294f0cf..6150cac4aa3 100644
--- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
@@ -35,7 +35,6 @@
#include "brw_draw.h"
#include "brw_defines.h"
-#include "brw_attrib.h"
#include "brw_context.h"
#include "brw_aub.h"
#include "brw_state.h"
@@ -310,7 +309,6 @@ copy_array_to_vbo_array( struct brw_context *brw,
GLuint i,
const struct gl_client_array *array,
GLuint element_size,
- GLuint min_index,
GLuint count)
{
GLcontext *ctx = &brw->intel.ctx;
@@ -337,7 +335,6 @@ copy_array_to_vbo_array( struct brw_context *brw,
vbo_array->Enabled = 1;
vbo_array->Normalized = array->Normalized;
vbo_array->_MaxElement = array->_MaxElement; /* ? */
- vbo_array->Flags = array->Flags; /* ? */
vbo_array->BufferObj = vbo;
{
@@ -349,7 +346,7 @@ copy_array_to_vbo_array( struct brw_context *brw,
map += offset;
copy_strided_array( map,
- array->Ptr + min_index * array->StrideB,
+ array->Ptr,
element_size,
array->StrideB,
count);
@@ -380,7 +377,6 @@ interleaved_vbo_array( struct brw_context *brw,
vbo_array->Enabled = 1;
vbo_array->Normalized = array->Normalized;
vbo_array->_MaxElement = array->_MaxElement;
- vbo_array->Flags = array->Flags; /* ? */
vbo_array->BufferObj = uploaded_array->BufferObj;
return vbo_array;
@@ -393,17 +389,17 @@ GLboolean brw_upload_vertices( struct brw_context *brw,
{
GLcontext *ctx = &brw->intel.ctx;
struct intel_context *intel = intel_context(ctx);
- GLuint64EXT tmp = brw->vs.prog_data->inputs_read;
+ GLuint tmp = brw->vs.prog_data->inputs_read;
struct brw_vertex_element_packet vep;
struct brw_array_state vbp;
GLuint i;
const void *ptr = NULL;
GLuint interleave = 0;
- struct brw_vertex_element *enabled[BRW_ATTRIB_MAX];
+ struct brw_vertex_element *enabled[VERT_ATTRIB_MAX];
GLuint nr_enabled = 0;
- struct brw_vertex_element *upload[BRW_ATTRIB_MAX];
+ struct brw_vertex_element *upload[VERT_ATTRIB_MAX];
GLuint nr_uploads = 0;
@@ -412,17 +408,19 @@ GLboolean brw_upload_vertices( struct brw_context *brw,
/* First build an array of pointers to ve's in vb.inputs_read
*/
+ if (0)
+ _mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);
while (tmp) {
- GLuint i = ffsll(tmp)-1;
+ GLuint i = _mesa_ffsll(tmp)-1;
struct brw_vertex_element *input = &brw->vb.inputs[i];
- tmp &= ~((GLuint64EXT)1<<i);
+ tmp &= ~(1<<i);
enabled[nr_enabled++] = input;
input->index = i;
input->element_size = get_size(input->glarray->Type) * input->glarray->Size;
- input->count = input->glarray->StrideB ? max_index - min_index : 1;
+ input->count = input->glarray->StrideB ? max_index + 1 - min_index : 1;
if (!input->glarray->BufferObj->Name) {
if (i == 0) {
@@ -441,10 +439,16 @@ GLboolean brw_upload_vertices( struct brw_context *brw,
}
upload[nr_uploads++] = input;
- input->vbo_rebase_offset = 0;
+
+ /* We rebase drawing to start at element zero only when
+ * varyings are not in vbos, which means we can end up
+ * uploading non-varying arrays (stride != 0) when min_index
+ * is zero. This doesn't matter as the amount to upload is
+ * the same for these arrays whether the draw call is rebased
+ * or not - we just have to upload the one element.
+ */
+ assert(min_index == 0 || input->glarray->StrideB == 0);
}
- else
- input->vbo_rebase_offset = min_index * input->glarray->StrideB;
}
/* Upload interleaved arrays if all uploads are interleaved
@@ -457,7 +461,6 @@ GLboolean brw_upload_vertices( struct brw_context *brw,
input0->glarray = copy_array_to_vbo_array(brw, 0,
input0->glarray,
interleave,
- min_index,
input0->count);
for (i = 1; i < nr_uploads; i++) {
@@ -475,7 +478,6 @@ GLboolean brw_upload_vertices( struct brw_context *brw,
input->glarray = copy_array_to_vbo_array(brw, i,
input->glarray,
input->element_size,
- min_index,
input->count);
}
@@ -523,9 +525,9 @@ GLboolean brw_upload_vertices( struct brw_context *brw,
vbp.vb[i].vb0.bits.pad = 0;
vbp.vb[i].vb0.bits.access_type = BRW_VERTEXBUFFER_ACCESS_VERTEXDATA;
vbp.vb[i].vb0.bits.vb_index = i;
- vbp.vb[i].offset = (GLuint)input->glarray->Ptr + input->vbo_rebase_offset;
+ vbp.vb[i].offset = (GLuint)input->glarray->Ptr;
vbp.vb[i].buffer = array_buffer(input->glarray);
- vbp.vb[i].max_index = max_index - min_index;
+ vbp.vb[i].max_index = max_index;
}
@@ -566,94 +568,32 @@ static GLuint element_size( GLenum type )
-
-static void rebase_indices_to_vbo_indices( struct brw_context *brw,
- const struct brw_draw_index_buffer *index_buffer,
- struct gl_buffer_object **vbo_return,
- GLuint *offset_return )
+void brw_upload_indices( struct brw_context *brw,
+ const struct _mesa_index_buffer *index_buffer )
{
GLcontext *ctx = &brw->intel.ctx;
- GLuint min_index = index_buffer->rebase;
- const void *indices = index_buffer->ptr;
- GLsizei count = index_buffer->count;
- GLenum type = index_buffer->type;
- GLuint size = element_size(type) * count;
- struct gl_buffer_object *bufferobj;
- GLuint offset;
- GLuint i;
-
- get_space(brw, size, &bufferobj, &offset);
+ struct intel_context *intel = &brw->intel;
+ GLuint ib_size = get_size(index_buffer->type) * index_buffer->count;
+ struct gl_buffer_object *bufferobj = index_buffer->obj;
+ GLuint offset = (GLuint)index_buffer->ptr;
- *vbo_return = bufferobj;
- *offset_return = offset;
+ /* Turn into a proper VBO:
+ */
+ if (!bufferobj->Name) {
+
+ /* Get new bufferobj, offset:
+ */
+ get_space(brw, ib_size, &bufferobj, &offset);
- if (min_index == 0) {
/* Straight upload
*/
ctx->Driver.BufferSubData( ctx,
GL_ELEMENT_ARRAY_BUFFER_ARB,
offset,
- size,
- indices,
+ ib_size,
+ index_buffer->ptr,
bufferobj);
}
- else {
- void *map = ctx->Driver.MapBuffer(ctx,
- GL_ELEMENT_ARRAY_BUFFER_ARB,
- GL_DYNAMIC_DRAW_ARB,
- bufferobj);
-
- map += offset;
-
- switch (type) {
- case GL_UNSIGNED_INT: {
- GLuint *ui_map = (GLuint *)map;
- const GLuint *ui_indices = (const GLuint *)indices;
-
- for (i = 0; i < count; i++)
- ui_map[i] = ui_indices[i] - min_index;
- break;
- }
- case GL_UNSIGNED_SHORT: {
- GLushort *us_map = (GLushort *)map;
- const GLushort *us_indices = (const GLushort *)indices;
-
- for (i = 0; i < count; i++)
- us_map[i] = us_indices[i] - min_index;
- break;
- }
- case GL_UNSIGNED_BYTE: {
- GLubyte *ub_map = (GLubyte *)map;
- const GLubyte *ub_indices = (const GLubyte *)indices;
-
- for (i = 0; i < count; i++)
- ub_map[i] = ub_indices[i] - min_index;
- break;
- }
- }
-
- ctx->Driver.UnmapBuffer(ctx,
- GL_ELEMENT_ARRAY_BUFFER_ARB,
- bufferobj);
-
- }
-}
-
-
-
-void brw_upload_indices( struct brw_context *brw,
- const struct brw_draw_index_buffer *index_buffer)
-{
- struct intel_context *intel = &brw->intel;
- GLuint ib_size = get_size(index_buffer->type) * index_buffer->count;
- struct gl_buffer_object *bufferobj = index_buffer->obj;
- GLuint offset = (GLuint)index_buffer->ptr;
-
- /* Already turned into a proper VBO:
- */
- if (!index_buffer->obj->Name) {
- rebase_indices_to_vbo_indices(brw, index_buffer, &bufferobj, &offset );
- }
/* Emit the indexbuffer packet:
*/
diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h
index 1afa0f816b8..d4dbcf38a7a 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 6425c91450c..9992b47d8ae 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_exec.c b/src/mesa/drivers/dri/i965/brw_exec.c
deleted file mode 100644
index fc06c3c3617..00000000000
--- a/src/mesa/drivers/dri/i965/brw_exec.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.3
- *
- * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Keith Whitwell <[email protected]>
- */
-
-
-#include "api_arrayelt.h"
-#include "glheader.h"
-#include "imports.h"
-#include "context.h"
-#include "macros.h"
-#include "mtypes.h"
-#include "dlist.h"
-#include "vtxfmt.h"
-
-#include "brw_exec.h"
-
-
-void brw_exec_init( GLcontext *ctx )
-{
- struct brw_exec_context *exec = CALLOC_STRUCT(brw_exec_context);
-
- if (ctx->swtnl_im == NULL) {
- ctx->swtnl_im = CALLOC_STRUCT(brw_exec_save);
- }
-
- exec->ctx = ctx;
- IMM_CONTEXT(ctx)->exec = exec;
-
- /* Initialize the arrayelt helper
- */
- if (!ctx->aelt_context &&
- !_ae_create_context( ctx ))
- return;
-
- brw_exec_vtx_init( exec );
- brw_exec_array_init( exec );
-
- ctx->Driver.NeedFlush = 0;
- ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
- ctx->Driver.FlushVertices = brw_exec_FlushVertices;
-
- exec->eval.recalculate_maps = 1;
-}
-
-
-void brw_exec_destroy( GLcontext *ctx )
-{
- struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec;
-
- if (ctx->aelt_context) {
- _ae_destroy_context( ctx );
- ctx->aelt_context = NULL;
- }
-
- brw_exec_vtx_destroy( exec );
- brw_exec_array_destroy( exec );
-
- if (exec) {
- FREE(exec);
- IMM_CONTEXT(ctx)->exec = NULL;
- }
-
- if (IMM_CONTEXT(ctx)->exec == NULL &&
- IMM_CONTEXT(ctx)->save == NULL) {
- FREE(IMM_CONTEXT(ctx));
- ctx->swtnl_im = NULL;
- }
-}
-
-/* Really want to install these callbacks to a central facility to be
- * invoked according to the state flags. That will have to wait for a
- * mesa rework:
- */
-void brw_exec_invalidate_state( GLcontext *ctx, GLuint new_state )
-{
- struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec;
-
- if (new_state & (_NEW_PROGRAM|_NEW_EVAL))
- exec->eval.recalculate_maps = 1;
-
- _ae_invalidate_state(ctx, new_state);
-}
-
-
-void brw_exec_wakeup( GLcontext *ctx )
-{
- struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec;
-
- ctx->Driver.FlushVertices = brw_exec_FlushVertices;
- ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT;
-
- /* Hook our functions into exec and compile dispatch tables.
- */
- _mesa_install_exec_vtxfmt( ctx, &exec->vtxfmt );
-
- /* Assume we haven't been getting state updates either:
- */
- brw_exec_invalidate_state( ctx, ~0 );
-}
-
-
-
diff --git a/src/mesa/drivers/dri/i965/brw_exec.h b/src/mesa/drivers/dri/i965/brw_exec.h
deleted file mode 100644
index f07b4485874..00000000000
--- a/src/mesa/drivers/dri/i965/brw_exec.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/**************************************************************************
-
-Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas.
-
-All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-on the rights to use, copy, modify, merge, publish, distribute, sub
-license, and/or sell copies of the Software, and to permit persons to whom
-the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice (including the next
-paragraph) shall be included in all copies or substantial portions of the
-Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
-TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Keith Whitwell <[email protected]>
- *
- */
-
-#ifndef __BRW_EXEC_H__
-#define __BRW_EXEC_H__
-
-#include "mtypes.h"
-#include "brw_attrib.h"
-#include "brw_draw.h"
-
-
-#define BRW_MAX_PRIM 64
-
-/* Wierd implementation stuff:
- */
-#define BRW_VERT_BUFFER_SIZE (1024*16) /* dwords == 64k */
-#define BRW_MAX_ATTR_CODEGEN 16
-#define ERROR_ATTRIB 16
-
-
-
-
-struct brw_exec_eval1_map {
- struct gl_1d_map *map;
- GLuint sz;
-};
-
-struct brw_exec_eval2_map {
- struct gl_2d_map *map;
- GLuint sz;
-};
-
-
-
-struct brw_exec_copied_vtx {
- GLfloat buffer[BRW_ATTRIB_MAX * 4 * BRW_MAX_COPIED_VERTS];
- GLuint nr;
-};
-
-
-typedef void (*brw_attrfv_func)( const GLfloat * );
-
-
-struct brw_exec_context
-{
- GLcontext *ctx;
- GLvertexformat vtxfmt;
-
- struct {
- struct gl_buffer_object *bufferobj;
- GLubyte *buffer_map;
-
- GLuint vertex_size;
-
- struct brw_draw_prim prim[BRW_MAX_PRIM];
- GLuint prim_count;
-
- GLfloat *vbptr; /* cursor, points into buffer */
- GLfloat vertex[BRW_ATTRIB_MAX*4]; /* current vertex */
-
- GLfloat *current[BRW_ATTRIB_MAX]; /* points into ctx->Current, ctx->Light.Material */
- GLfloat CurrentFloatEdgeFlag;
-
- GLuint vert_count;
- GLuint max_vert;
- struct brw_exec_copied_vtx copied;
-
- GLubyte attrsz[BRW_ATTRIB_MAX];
- GLubyte active_sz[BRW_ATTRIB_MAX];
-
- GLfloat *attrptr[BRW_ATTRIB_MAX];
- struct gl_client_array arrays[BRW_ATTRIB_MAX];
- const struct gl_client_array *inputs[BRW_ATTRIB_MAX];
- } vtx;
-
-
- struct {
- GLboolean recalculate_maps;
- struct brw_exec_eval1_map map1[BRW_ATTRIB_MAX];
- struct brw_exec_eval2_map map2[BRW_ATTRIB_MAX];
- } eval;
-
- struct {
- const struct gl_client_array *inputs[BRW_ATTRIB_MAX];
-
- struct gl_buffer_object *index_obj;
- } array;
-};
-
-
-
-/* External API:
- */
-void brw_exec_init( GLcontext *ctx );
-void brw_exec_destroy( GLcontext *ctx );
-void brw_exec_invalidate_state( GLcontext *ctx, GLuint new_state );
-void brw_exec_FlushVertices( GLcontext *ctx, GLuint flags );
-void brw_exec_wakeup( GLcontext *ctx );
-
-
-/* Internal functions:
- */
-void brw_exec_array_init( struct brw_exec_context *exec );
-void brw_exec_array_destroy( struct brw_exec_context *exec );
-
-
-void brw_exec_vtx_init( struct brw_exec_context *exec );
-void brw_exec_vtx_destroy( struct brw_exec_context *exec );
-void brw_exec_vtx_flush( struct brw_exec_context *exec );
-void brw_exec_vtx_wrap( struct brw_exec_context *exec );
-
-void brw_exec_eval_update( struct brw_exec_context *exec );
-
-void brw_exec_do_EvalCoord2f( struct brw_exec_context *exec,
- GLfloat u, GLfloat v );
-
-void brw_exec_do_EvalCoord1f( struct brw_exec_context *exec,
- GLfloat u);
-
-#endif
diff --git a/src/mesa/drivers/dri/i965/brw_exec_api.c b/src/mesa/drivers/dri/i965/brw_exec_api.c
deleted file mode 100644
index 470fa6f4177..00000000000
--- a/src/mesa/drivers/dri/i965/brw_exec_api.c
+++ /dev/null
@@ -1,716 +0,0 @@
-/**************************************************************************
-
-Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas.
-
-All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-on the rights to use, copy, modify, merge, publish, distribute, sub
-license, and/or sell copies of the Software, and to permit persons to whom
-the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice (including the next
-paragraph) shall be included in all copies or substantial portions of the
-Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
-TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Keith Whitwell <[email protected]>
- */
-
-#include "glheader.h"
-#include "context.h"
-#include "macros.h"
-#include "vtxfmt.h"
-#include "dlist.h"
-#include "state.h"
-#include "light.h"
-#include "api_arrayelt.h"
-#include "api_noop.h"
-#include "dispatch.h"
-
-#include "brw_exec.h"
-
-static void reset_attrfv( struct brw_exec_context *exec );
-
-
-/* Close off the last primitive, execute the buffer, restart the
- * primitive.
- */
-static void brw_exec_wrap_buffers( struct brw_exec_context *exec )
-{
- if (exec->vtx.prim_count == 0) {
- exec->vtx.copied.nr = 0;
- exec->vtx.vert_count = 0;
- exec->vtx.vbptr = (GLfloat *)exec->vtx.buffer_map;
- }
- else {
- GLuint last_begin = exec->vtx.prim[exec->vtx.prim_count-1].begin;
- GLuint last_count;
-
- if (exec->ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) {
- GLint i = exec->vtx.prim_count - 1;
- assert(i >= 0);
- exec->vtx.prim[i].count = (exec->vtx.vert_count -
- exec->vtx.prim[i].start);
- }
-
- last_count = exec->vtx.prim[exec->vtx.prim_count-1].count;
-
- /* Execute the buffer and save copied vertices.
- */
- if (exec->vtx.vert_count)
- brw_exec_vtx_flush( exec );
- else {
- exec->vtx.prim_count = 0;
- exec->vtx.copied.nr = 0;
- }
-
- /* Emit a glBegin to start the new list.
- */
- assert(exec->vtx.prim_count == 0);
-
- if (exec->ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) {
- exec->vtx.prim[0].mode = exec->ctx->Driver.CurrentExecPrimitive;
- exec->vtx.prim[0].start = 0;
- exec->vtx.prim[0].count = 0;
- exec->vtx.prim_count++;
-
- if (exec->vtx.copied.nr == last_count)
- exec->vtx.prim[0].begin = last_begin;
- }
- }
-}
-
-
-/* Deal with buffer wrapping where provoked by the vertex buffer
- * filling up, as opposed to upgrade_vertex().
- */
-void brw_exec_vtx_wrap( struct brw_exec_context *exec )
-{
- GLfloat *data = exec->vtx.copied.buffer;
- GLuint i;
-
- /* Run pipeline on current vertices, copy wrapped vertices
- * to exec->vtx.copied.
- */
- brw_exec_wrap_buffers( exec );
-
- /* Copy stored stored vertices to start of new list.
- */
- assert(exec->vtx.max_vert - exec->vtx.vert_count > exec->vtx.copied.nr);
-
- for (i = 0 ; i < exec->vtx.copied.nr ; i++) {
- _mesa_memcpy( exec->vtx.vbptr, data,
- exec->vtx.vertex_size * sizeof(GLfloat));
- exec->vtx.vbptr += exec->vtx.vertex_size;
- data += exec->vtx.vertex_size;
- exec->vtx.vert_count++;
- }
-
- exec->vtx.copied.nr = 0;
-}
-
-
-/*
- * Copy the active vertex's values to the ctx->Current fields.
- */
-static void brw_exec_copy_to_current( struct brw_exec_context *exec )
-{
- GLcontext *ctx = exec->ctx;
- GLuint i;
-
- for (i = BRW_ATTRIB_POS+1 ; i < BRW_ATTRIB_MAX ; i++) {
- if (exec->vtx.attrsz[i]) {
- /* Note: the exec->vtx.current[i] pointers point into the
- * ctx->Current.Attrib and ctx->Light.Material.Attrib arrays.
- */
- COPY_CLEAN_4V(exec->vtx.current[i],
- exec->vtx.attrsz[i],
- exec->vtx.attrptr[i]);
-
- /* This triggers rather too much recalculation of Mesa state
- * that doesn't get used (eg light positions).
- */
- if (i >= BRW_ATTRIB_MAT_FRONT_AMBIENT &&
- i <= BRW_ATTRIB_MAT_BACK_INDEXES)
- ctx->NewState |= _NEW_LIGHT;
- }
- }
-
- /* color index is special (it's not a float[4] so COPY_CLEAN_4V above
- * will trash adjacent memory!)
- */
- if (exec->vtx.attrsz[BRW_ATTRIB_INDEX]) {
- ctx->Current.Index = exec->vtx.attrptr[BRW_ATTRIB_INDEX][0];
- }
-
- /* Edgeflag requires additional treatment:
- */
- if (exec->vtx.attrsz[BRW_ATTRIB_EDGEFLAG]) {
- ctx->Current.EdgeFlag = (exec->vtx.CurrentFloatEdgeFlag == 1.0);
- }
-
- /* Colormaterial -- this kindof sucks.
- */
- if (ctx->Light.ColorMaterialEnabled &&
- exec->vtx.attrsz[BRW_ATTRIB_COLOR0]) {
- _mesa_update_color_material(ctx,
- ctx->Current.Attrib[BRW_ATTRIB_COLOR0]);
- }
-
- ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT;
-}
-
-
-static void brw_exec_copy_from_current( struct brw_exec_context *exec )
-{
- GLcontext *ctx = exec->ctx;
- GLint i;
-
- /* Edgeflag requires additional treatment:
- */
- exec->vtx.CurrentFloatEdgeFlag =
- (GLfloat)ctx->Current.EdgeFlag;
-
- for (i = BRW_ATTRIB_POS+1 ; i < BRW_ATTRIB_MAX ; i++)
- switch (exec->vtx.attrsz[i]) {
- case 4: exec->vtx.attrptr[i][3] = exec->vtx.current[i][3];
- case 3: exec->vtx.attrptr[i][2] = exec->vtx.current[i][2];
- case 2: exec->vtx.attrptr[i][1] = exec->vtx.current[i][1];
- case 1: exec->vtx.attrptr[i][0] = exec->vtx.current[i][0];
- break;
- }
-
- ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT;
-}
-
-
-/* Flush existing data, set new attrib size, replay copied vertices.
- */
-static void brw_exec_wrap_upgrade_vertex( struct brw_exec_context *exec,
- GLuint attr,
- GLuint newsz )
-{
- GLcontext *ctx = exec->ctx;
- GLint lastcount = exec->vtx.vert_count;
- GLfloat *tmp;
- GLuint oldsz;
- GLuint i;
-
- /* Run pipeline on current vertices, copy wrapped vertices
- * to exec->vtx.copied.
- */
- brw_exec_wrap_buffers( exec );
-
-
- /* Do a COPY_TO_CURRENT to ensure back-copying works for the case
- * when the attribute already exists in the vertex and is having
- * its size increased.
- */
- brw_exec_copy_to_current( exec );
-
-
- /* Heuristic: Attempt to isolate attributes received outside
- * begin/end so that they don't bloat the vertices.
- */
- if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END &&
- exec->vtx.attrsz[attr] == 0 &&
- lastcount > 8 &&
- exec->vtx.vertex_size) {
- reset_attrfv( exec );
- }
-
- /* Fix up sizes:
- */
- oldsz = exec->vtx.attrsz[attr];
- exec->vtx.attrsz[attr] = newsz;
-
- exec->vtx.vertex_size += newsz - oldsz;
- exec->vtx.max_vert = BRW_VERT_BUFFER_SIZE / exec->vtx.vertex_size;
- exec->vtx.vert_count = 0;
- exec->vtx.vbptr = (GLfloat *)exec->vtx.buffer_map;
-
-
- /* Recalculate all the attrptr[] values
- */
- for (i = 0, tmp = exec->vtx.vertex ; i < BRW_ATTRIB_MAX ; i++) {
- if (exec->vtx.attrsz[i]) {
- exec->vtx.attrptr[i] = tmp;
- tmp += exec->vtx.attrsz[i];
- }
- else
- exec->vtx.attrptr[i] = NULL; /* will not be dereferenced */
- }
-
- /* Copy from current to repopulate the vertex with correct values.
- */
- brw_exec_copy_from_current( exec );
-
- /* Replay stored vertices to translate them
- * to new format here.
- *
- * -- No need to replay - just copy piecewise
- */
- if (exec->vtx.copied.nr)
- {
- GLfloat *data = exec->vtx.copied.buffer;
- GLfloat *dest = exec->vtx.vbptr;
- GLuint j;
-
- assert(exec->vtx.vbptr == (GLfloat *)exec->vtx.buffer_map);
-
- for (i = 0 ; i < exec->vtx.copied.nr ; i++) {
- for (j = 0 ; j < BRW_ATTRIB_MAX ; j++) {
- if (exec->vtx.attrsz[j]) {
- if (j == attr) {
- if (oldsz) {
- COPY_CLEAN_4V( dest, oldsz, data );
- data += oldsz;
- dest += newsz;
- } else {
- COPY_SZ_4V( dest, newsz, exec->vtx.current[j] );
- dest += newsz;
- }
- }
- else {
- GLuint sz = exec->vtx.attrsz[j];
- COPY_SZ_4V( dest, sz, data );
- dest += sz;
- data += sz;
- }
- }
- }
- }
-
- exec->vtx.vbptr = dest;
- exec->vtx.vert_count += exec->vtx.copied.nr;
- exec->vtx.copied.nr = 0;
- }
-}
-
-
-static void brw_exec_fixup_vertex( GLcontext *ctx,
- GLuint attr, GLuint sz )
-{
- struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec;
- int i;
-
- if (sz > exec->vtx.attrsz[attr]) {
- /* New size is larger. Need to flush existing vertices and get
- * an enlarged vertex format.
- */
- brw_exec_wrap_upgrade_vertex( exec, attr, sz );
- }
- else if (sz < exec->vtx.active_sz[attr]) {
- static const GLfloat id[4] = { 0, 0, 0, 1 };
-
- /* New size is smaller - just need to fill in some
- * zeros. Don't need to flush or wrap.
- */
- for (i = sz ; i <= exec->vtx.attrsz[attr] ; i++)
- exec->vtx.attrptr[attr][i-1] = id[i-1];
- }
-
- exec->vtx.active_sz[attr] = sz;
-
- /* Does setting NeedFlush belong here? Necessitates resetting
- * vtxfmt on each flush (otherwise flags won't get reset
- * afterwards).
- */
- if (attr == 0)
- exec->ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
- else
- exec->ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT;
-}
-
-
-
-
-/*
- */
-#define ATTR( A, N, V0, V1, V2, V3 ) \
-do { \
- struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; \
- \
- if (exec->vtx.active_sz[A] != N) \
- brw_exec_fixup_vertex(ctx, A, N); \
- \
- { \
- GLfloat *dest = exec->vtx.attrptr[A]; \
- if (N>0) dest[0] = V0; \
- if (N>1) dest[1] = V1; \
- if (N>2) dest[2] = V2; \
- if (N>3) dest[3] = V3; \
- } \
- \
- if ((A) == 0) { \
- GLuint i; \
- \
- for (i = 0; i < exec->vtx.vertex_size; i++) \
- exec->vtx.vbptr[i] = exec->vtx.vertex[i]; \
- \
- exec->vtx.vbptr += exec->vtx.vertex_size; \
- exec->ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; \
- \
- if (++exec->vtx.vert_count >= exec->vtx.max_vert) \
- brw_exec_vtx_wrap( exec ); \
- } \
-} while (0)
-
-
-#define ERROR() _mesa_error( ctx, GL_INVALID_ENUM, __FUNCTION__ )
-#define TAG(x) brw_##x
-
-#include "brw_attrib_tmp.h"
-
-
-
-
-
-/* Eval
- */
-static void GLAPIENTRY brw_exec_EvalCoord1f( GLfloat u )
-{
- GET_CURRENT_CONTEXT( ctx );
- struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec;
-
- {
- GLint i;
- if (exec->eval.recalculate_maps)
- brw_exec_eval_update( exec );
-
- for (i = 0 ; i <= BRW_ATTRIB_INDEX ; i++) {
- if (exec->eval.map1[i].map)
- if (exec->vtx.active_sz[i] != exec->eval.map1[i].sz)
- brw_exec_fixup_vertex( ctx, i, exec->eval.map1[i].sz );
- }
- }
-
-
- _mesa_memcpy( exec->vtx.copied.buffer, exec->vtx.vertex,
- exec->vtx.vertex_size * sizeof(GLfloat));
-
- brw_exec_do_EvalCoord1f( exec, u );
-
- _mesa_memcpy( exec->vtx.vertex, exec->vtx.copied.buffer,
- exec->vtx.vertex_size * sizeof(GLfloat));
-}
-
-static void GLAPIENTRY brw_exec_EvalCoord2f( GLfloat u, GLfloat v )
-{
- GET_CURRENT_CONTEXT( ctx );
- struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec;
-
- {
- GLint i;
- if (exec->eval.recalculate_maps)
- brw_exec_eval_update( exec );
-
- for (i = 0 ; i <= BRW_ATTRIB_INDEX ; i++) {
- if (exec->eval.map2[i].map)
- if (exec->vtx.active_sz[i] != exec->eval.map2[i].sz)
- brw_exec_fixup_vertex( ctx, i, exec->eval.map2[i].sz );
- }
-
- if (ctx->Eval.AutoNormal)
- if (exec->vtx.active_sz[BRW_ATTRIB_NORMAL] != 3)
- brw_exec_fixup_vertex( ctx, BRW_ATTRIB_NORMAL, 3 );
- }
-
- _mesa_memcpy( exec->vtx.copied.buffer, exec->vtx.vertex,
- exec->vtx.vertex_size * sizeof(GLfloat));
-
- brw_exec_do_EvalCoord2f( exec, u, v );
-
- _mesa_memcpy( exec->vtx.vertex, exec->vtx.copied.buffer,
- exec->vtx.vertex_size * sizeof(GLfloat));
-}
-
-static void GLAPIENTRY brw_exec_EvalCoord1fv( const GLfloat *u )
-{
- brw_exec_EvalCoord1f( u[0] );
-}
-
-static void GLAPIENTRY brw_exec_EvalCoord2fv( const GLfloat *u )
-{
- brw_exec_EvalCoord2f( u[0], u[1] );
-}
-
-static void GLAPIENTRY brw_exec_EvalPoint1( GLint i )
-{
- GET_CURRENT_CONTEXT( ctx );
- GLfloat du = ((ctx->Eval.MapGrid1u2 - ctx->Eval.MapGrid1u1) /
- (GLfloat) ctx->Eval.MapGrid1un);
- GLfloat u = i * du + ctx->Eval.MapGrid1u1;
-
- brw_exec_EvalCoord1f( u );
-}
-
-
-static void GLAPIENTRY brw_exec_EvalPoint2( GLint i, GLint j )
-{
- GET_CURRENT_CONTEXT( ctx );
- GLfloat du = ((ctx->Eval.MapGrid2u2 - ctx->Eval.MapGrid2u1) /
- (GLfloat) ctx->Eval.MapGrid2un);
- GLfloat dv = ((ctx->Eval.MapGrid2v2 - ctx->Eval.MapGrid2v1) /
- (GLfloat) ctx->Eval.MapGrid2vn);
- GLfloat u = i * du + ctx->Eval.MapGrid2u1;
- GLfloat v = j * dv + ctx->Eval.MapGrid2v1;
-
- brw_exec_EvalCoord2f( u, v );
-}
-
-
-/* Build a list of primitives on the fly. Keep
- * ctx->Driver.CurrentExecPrimitive uptodate as well.
- */
-static void GLAPIENTRY brw_exec_Begin( GLenum mode )
-{
- GET_CURRENT_CONTEXT( ctx );
-
- if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) {
- struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec;
- int i;
-
- if (ctx->NewState) {
- _mesa_update_state( ctx );
-
- if ((ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) ||
- (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBegin (invalid vertex/fragment program)");
- return;
- }
-
- CALL_Begin(ctx->Exec, (mode));
- return;
- }
-
- /* Heuristic: attempt to isolate attributes occuring outside
- * begin/end pairs.
- */
- if (exec->vtx.vertex_size && !exec->vtx.attrsz[0])
- brw_exec_FlushVertices( ctx, ~0 );
-
- i = exec->vtx.prim_count++;
- exec->vtx.prim[i].mode = mode;
- exec->vtx.prim[i].begin = 1;
- exec->vtx.prim[i].end = 0;
- exec->vtx.prim[i].indexed = 0;
- exec->vtx.prim[i].weak = 0;
- exec->vtx.prim[i].pad = 0;
- exec->vtx.prim[i].start = exec->vtx.vert_count;
- exec->vtx.prim[i].count = 0;
-
- ctx->Driver.CurrentExecPrimitive = mode;
- }
- else
- _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" );
-
-}
-
-static void GLAPIENTRY brw_exec_End( void )
-{
- GET_CURRENT_CONTEXT( ctx );
-
- if (ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) {
- struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec;
- int idx = exec->vtx.vert_count;
- int i = exec->vtx.prim_count - 1;
-
- exec->vtx.prim[i].end = 1;
- exec->vtx.prim[i].count = idx - exec->vtx.prim[i].start;
-
- ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1;
-
- if (exec->vtx.prim_count == BRW_MAX_PRIM)
- brw_exec_vtx_flush( exec );
- }
- else
- _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" );
-}
-
-
-static void brw_exec_vtxfmt_init( struct brw_exec_context *exec )
-{
- GLvertexformat *vfmt = &exec->vtxfmt;
-
- vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */
- vfmt->Begin = brw_exec_Begin;
- vfmt->CallList = _mesa_CallList;
- vfmt->CallLists = _mesa_CallLists;
- vfmt->End = brw_exec_End;
- vfmt->EvalCoord1f = brw_exec_EvalCoord1f;
- vfmt->EvalCoord1fv = brw_exec_EvalCoord1fv;
- vfmt->EvalCoord2f = brw_exec_EvalCoord2f;
- vfmt->EvalCoord2fv = brw_exec_EvalCoord2fv;
- vfmt->EvalPoint1 = brw_exec_EvalPoint1;
- vfmt->EvalPoint2 = brw_exec_EvalPoint2;
-
- vfmt->Rectf = _mesa_noop_Rectf;
- vfmt->EvalMesh1 = _mesa_noop_EvalMesh1;
- vfmt->EvalMesh2 = _mesa_noop_EvalMesh2;
-
-
- /* from attrib_tmp.h:
- */
- vfmt->Color3f = brw_Color3f;
- vfmt->Color3fv = brw_Color3fv;
- vfmt->Color4f = brw_Color4f;
- vfmt->Color4fv = brw_Color4fv;
- vfmt->FogCoordfEXT = brw_FogCoordfEXT;
- vfmt->FogCoordfvEXT = brw_FogCoordfvEXT;
- vfmt->MultiTexCoord1fARB = brw_MultiTexCoord1f;
- vfmt->MultiTexCoord1fvARB = brw_MultiTexCoord1fv;
- vfmt->MultiTexCoord2fARB = brw_MultiTexCoord2f;
- vfmt->MultiTexCoord2fvARB = brw_MultiTexCoord2fv;
- vfmt->MultiTexCoord3fARB = brw_MultiTexCoord3f;
- vfmt->MultiTexCoord3fvARB = brw_MultiTexCoord3fv;
- vfmt->MultiTexCoord4fARB = brw_MultiTexCoord4f;
- vfmt->MultiTexCoord4fvARB = brw_MultiTexCoord4fv;
- vfmt->Normal3f = brw_Normal3f;
- vfmt->Normal3fv = brw_Normal3fv;
- vfmt->SecondaryColor3fEXT = brw_SecondaryColor3fEXT;
- vfmt->SecondaryColor3fvEXT = brw_SecondaryColor3fvEXT;
- vfmt->TexCoord1f = brw_TexCoord1f;
- vfmt->TexCoord1fv = brw_TexCoord1fv;
- vfmt->TexCoord2f = brw_TexCoord2f;
- vfmt->TexCoord2fv = brw_TexCoord2fv;
- vfmt->TexCoord3f = brw_TexCoord3f;
- vfmt->TexCoord3fv = brw_TexCoord3fv;
- vfmt->TexCoord4f = brw_TexCoord4f;
- vfmt->TexCoord4fv = brw_TexCoord4fv;
- vfmt->Vertex2f = brw_Vertex2f;
- vfmt->Vertex2fv = brw_Vertex2fv;
- vfmt->Vertex3f = brw_Vertex3f;
- vfmt->Vertex3fv = brw_Vertex3fv;
- vfmt->Vertex4f = brw_Vertex4f;
- vfmt->Vertex4fv = brw_Vertex4fv;
-
- vfmt->VertexAttrib1fARB = brw_VertexAttrib1fARB;
- vfmt->VertexAttrib1fvARB = brw_VertexAttrib1fvARB;
- vfmt->VertexAttrib2fARB = brw_VertexAttrib2fARB;
- vfmt->VertexAttrib2fvARB = brw_VertexAttrib2fvARB;
- vfmt->VertexAttrib3fARB = brw_VertexAttrib3fARB;
- vfmt->VertexAttrib3fvARB = brw_VertexAttrib3fvARB;
- vfmt->VertexAttrib4fARB = brw_VertexAttrib4fARB;
- vfmt->VertexAttrib4fvARB = brw_VertexAttrib4fvARB;
-
- vfmt->VertexAttrib1fNV = brw_VertexAttrib1fNV;
- vfmt->VertexAttrib1fvNV = brw_VertexAttrib1fvNV;
- vfmt->VertexAttrib2fNV = brw_VertexAttrib2fNV;
- vfmt->VertexAttrib2fvNV = brw_VertexAttrib2fvNV;
- vfmt->VertexAttrib3fNV = brw_VertexAttrib3fNV;
- vfmt->VertexAttrib3fvNV = brw_VertexAttrib3fvNV;
- vfmt->VertexAttrib4fNV = brw_VertexAttrib4fNV;
- vfmt->VertexAttrib4fvNV = brw_VertexAttrib4fvNV;
-
- vfmt->Materialfv = brw_Materialfv;
-
- vfmt->EdgeFlag = brw_EdgeFlag;
- vfmt->Indexf = brw_Indexf;
- vfmt->Indexfv = brw_Indexfv;
-
-}
-
-
-static void brw_exec_current_init( struct brw_exec_context *exec )
-{
- GLcontext *ctx = exec->ctx;
- GLint i;
-
- /* setup the pointers for the typical 16 vertex attributes */
- for (i = 0; i < BRW_ATTRIB_FIRST_MATERIAL; i++)
- exec->vtx.current[i] = ctx->Current.Attrib[i];
-
- /* setup pointers for the 12 material attributes */
- for (i = 0; i < MAT_ATTRIB_MAX; i++)
- exec->vtx.current[BRW_ATTRIB_FIRST_MATERIAL + i] =
- ctx->Light.Material.Attrib[i];
-
- exec->vtx.current[BRW_ATTRIB_INDEX] = &ctx->Current.Index;
- exec->vtx.current[BRW_ATTRIB_EDGEFLAG] = &exec->vtx.CurrentFloatEdgeFlag;
-}
-
-void brw_exec_vtx_init( struct brw_exec_context *exec )
-{
- GLcontext *ctx = exec->ctx;
- GLuint i;
-
- /* Allocate a buffer object. Will just reuse this object
- * continuously.
- */
- exec->vtx.bufferobj = ctx->Array.NullBufferObj;
- exec->vtx.buffer_map = ALIGN_MALLOC(BRW_VERT_BUFFER_SIZE * sizeof(GLfloat), 64);
-
- brw_exec_current_init( exec );
- brw_exec_vtxfmt_init( exec );
-
- /* Hook our functions into the dispatch table.
- */
- _mesa_install_exec_vtxfmt( exec->ctx, &exec->vtxfmt );
-
- for (i = 0 ; i < BRW_ATTRIB_MAX ; i++) {
- exec->vtx.attrsz[i] = 0;
- exec->vtx.active_sz[i] = 0;
- exec->vtx.inputs[i] = &exec->vtx.arrays[i];
- }
-
- exec->vtx.vertex_size = 0;
-}
-
-
-void brw_exec_vtx_destroy( struct brw_exec_context *exec )
-{
- if (exec->vtx.buffer_map) {
- ALIGN_FREE(exec->vtx.buffer_map);
- exec->vtx.buffer_map = NULL;
- }
-}
-
-
-void brw_exec_FlushVertices( GLcontext *ctx, GLuint flags )
-{
- struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec;
-
- if (exec->ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END)
- return;
-
- if (exec->vtx.vert_count) {
- brw_exec_vtx_flush( exec );
- }
-
- if (exec->vtx.vertex_size) {
- brw_exec_copy_to_current( exec );
- reset_attrfv( exec );
- }
-
- exec->ctx->Driver.NeedFlush = 0;
-}
-
-
-static void reset_attrfv( struct brw_exec_context *exec )
-{
- GLuint i;
-
- for (i = 0 ; i < BRW_ATTRIB_MAX ; i++) {
- exec->vtx.attrsz[i] = 0;
- exec->vtx.active_sz[i] = 0;
- }
-
- exec->vtx.vertex_size = 0;
-}
-
diff --git a/src/mesa/drivers/dri/i965/brw_exec_array.c b/src/mesa/drivers/dri/i965/brw_exec_array.c
deleted file mode 100644
index ca19a198374..00000000000
--- a/src/mesa/drivers/dri/i965/brw_exec_array.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-#include "glheader.h"
-#include "context.h"
-#include "state.h"
-#include "api_validate.h"
-#include "api_noop.h"
-#include "dispatch.h"
-
-#include "brw_attrib.h"
-#include "brw_draw.h"
-#include "brw_exec.h"
-#include "brw_fallback.h"
-
-static GLuint get_max_index( GLuint count, GLuint type,
- const GLvoid *indices )
-{
- GLint i;
-
- /* Compute max element. This is only needed for upload of non-VBO,
- * non-constant data elements.
- *
- * XXX: Postpone this calculation until it is known that it is
- * needed. Otherwise could scan this pointlessly in the all-vbo
- * case.
- */
- switch(type) {
- case GL_UNSIGNED_INT: {
- const GLuint *ui_indices = (const GLuint *)indices;
- GLuint max_ui = 0;
- for (i = 0; i < count; i++)
- if (ui_indices[i] > max_ui)
- max_ui = ui_indices[i];
- return max_ui;
- }
- case GL_UNSIGNED_SHORT: {
- const GLushort *us_indices = (const GLushort *)indices;
- GLuint max_us = 0;
- for (i = 0; i < count; i++)
- if (us_indices[i] > max_us)
- max_us = us_indices[i];
- return max_us;
- }
- case GL_UNSIGNED_BYTE: {
- const GLubyte *ub_indices = (const GLubyte *)indices;
- GLuint max_ub = 0;
- for (i = 0; i < count; i++)
- if (ub_indices[i] > max_ub)
- max_ub = ub_indices[i];
- return max_ub;
- }
- default:
- return 0;
- }
-}
-
-
-
-
-/***********************************************************************
- * API functions.
- */
-
-static void GLAPIENTRY
-brw_exec_DrawArrays(GLenum mode, GLint start, GLsizei count)
-{
- GET_CURRENT_CONTEXT(ctx);
- struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec;
- struct brw_draw_prim prim[1];
- GLboolean ok;
-
- if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))
- return;
-
- FLUSH_CURRENT( ctx, 0 );
-
- if (ctx->NewState)
- _mesa_update_state( ctx );
-
- prim[0].begin = 1;
- prim[0].end = 1;
- prim[0].weak = 0;
- prim[0].pad = 0;
-
- if (exec->array.inputs[0]->BufferObj->Name) {
- /* Use vertex attribute as a hint to tell us if we expect all
- * arrays to be in VBO's and if so, don't worry about avoiding
- * the upload of elements < start.
- */
- prim[0].mode = mode;
- prim[0].start = start;
- prim[0].count = count;
- prim[0].indexed = 0;
-
- ok = brw_draw_prims( ctx, exec->array.inputs, prim, 1, NULL, 0, start + count, 0 );
- }
- else {
- /* If not using VBO's, we don't want to upload any more elements
- * than necessary from the arrays as they will not be valid next
- * time the application tries to draw with them.
- */
- prim[0].mode = mode;
- prim[0].start = 0;
- prim[0].count = count;
- prim[0].indexed = 0;
-
- ok = brw_draw_prims( ctx, exec->array.inputs, prim, 1, NULL, start, start + count, 0 );
- }
-
- if (!ok) {
- brw_fallback(ctx);
- CALL_DrawArrays(ctx->Exec, ( mode, start, count ));
- brw_unfallback(ctx);
- }
-}
-
-
-
-static void GLAPIENTRY
-brw_exec_DrawRangeElements(GLenum mode,
- GLuint start, GLuint end,
- GLsizei count, GLenum type, const GLvoid *indices)
-{
- GET_CURRENT_CONTEXT(ctx);
- struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec;
- struct brw_draw_index_buffer ib;
- struct brw_draw_prim prim[1];
-
- if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count, type, indices ))
- return;
-
- FLUSH_CURRENT( ctx, 0 );
-
- if (ctx->NewState)
- _mesa_update_state( ctx );
-
- ib.count = count;
- ib.type = type;
- ib.obj = ctx->Array.ElementArrayBufferObj;
- ib.ptr = indices;
-
- if (ctx->Array.ElementArrayBufferObj->Name) {
- /* Use the fact that indices are in a VBO as a hint that the
- * program has put all the arrays in VBO's and we don't have to
- * worry about performance implications of start > 0.
- *
- * XXX: consider passing start as min_index to draw_prims instead.
- */
- ib.rebase = 0;
- }
- else {
- ib.rebase = start;
- }
-
- prim[0].begin = 1;
- prim[0].end = 1;
- prim[0].weak = 0;
- prim[0].pad = 0;
- prim[0].mode = mode;
- prim[0].start = 0;
- prim[0].count = count;
- prim[0].indexed = 1;
-
- if (!brw_draw_prims( ctx, exec->array.inputs, prim, 1, &ib, ib.rebase, end+1, 0 )) {
- brw_fallback(ctx);
- CALL_DrawRangeElements(ctx->Exec, (mode, start, end, count, type, indices));
- brw_unfallback(ctx);
- }
-}
-
-
-static void GLAPIENTRY
-brw_exec_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
-{
- GET_CURRENT_CONTEXT(ctx);
- GLuint max_index;
-
- if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))
- return;
-
- if (ctx->Array.ElementArrayBufferObj->Name) {
- const GLvoid *map = ctx->Driver.MapBuffer(ctx,
- GL_ELEMENT_ARRAY_BUFFER_ARB,
- GL_DYNAMIC_READ_ARB,
- ctx->Array.ElementArrayBufferObj);
-
- max_index = get_max_index(count, type, ADD_POINTERS(map, indices));
-
- ctx->Driver.UnmapBuffer(ctx,
- GL_ELEMENT_ARRAY_BUFFER_ARB,
- ctx->Array.ElementArrayBufferObj);
- }
- else {
- max_index = get_max_index(count, type, indices);
- }
-
- brw_exec_DrawRangeElements(mode, 0, max_index, count, type, indices);
-}
-
-
-/***********************************************************************
- * Initialization
- */
-
-
-static void init_arrays( GLcontext *ctx,
- const struct gl_client_array *arrays[] )
-{
- struct gl_array_object *obj = ctx->Array.ArrayObj;
- GLuint i;
-
- memset(arrays, 0, sizeof(*arrays) * BRW_ATTRIB_MAX);
-
- arrays[BRW_ATTRIB_POS] = &obj->Vertex;
- arrays[BRW_ATTRIB_NORMAL] = &obj->Normal;
- arrays[BRW_ATTRIB_COLOR0] = &obj->Color;
- arrays[BRW_ATTRIB_COLOR1] = &obj->SecondaryColor;
- arrays[BRW_ATTRIB_FOG] = &obj->FogCoord;
-
- for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++)
- arrays[BRW_ATTRIB_TEX0 + i] = &obj->TexCoord[i];
-
- arrays[BRW_ATTRIB_INDEX] = &obj->Index;
- arrays[BRW_ATTRIB_EDGEFLAG] = &obj->EdgeFlag;
-
- for (i = BRW_ATTRIB_GENERIC0; i <= BRW_ATTRIB_GENERIC15; i++)
- arrays[i] = &obj->VertexAttrib[i - BRW_ATTRIB_GENERIC0];
-}
-
-
-
-
-void brw_exec_array_init( struct brw_exec_context *exec )
-{
- GLcontext *ctx = exec->ctx;
-
- init_arrays(ctx, exec->array.inputs);
-
-#if 1
- exec->vtxfmt.DrawArrays = brw_exec_DrawArrays;
- exec->vtxfmt.DrawElements = brw_exec_DrawElements;
- exec->vtxfmt.DrawRangeElements = brw_exec_DrawRangeElements;
-#else
- exec->vtxfmt.DrawArrays = _mesa_noop_DrawArrays;
- exec->vtxfmt.DrawElements = _mesa_noop_DrawElements;
- exec->vtxfmt.DrawRangeElements = _mesa_noop_DrawRangeElements;
-#endif
-
- exec->array.index_obj = ctx->Driver.NewBufferObject(ctx, 1, GL_ARRAY_BUFFER_ARB);
-}
-
-
-void brw_exec_array_destroy( struct brw_exec_context *exec )
-{
- GLcontext *ctx = exec->ctx;
-
- ctx->Driver.DeleteBuffer(ctx, exec->array.index_obj);
-}
diff --git a/src/mesa/drivers/dri/i965/brw_exec_draw.c b/src/mesa/drivers/dri/i965/brw_exec_draw.c
deleted file mode 100644
index 62bda9845b9..00000000000
--- a/src/mesa/drivers/dri/i965/brw_exec_draw.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 5.1
- *
- * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Keith Whitwell <[email protected]>
- */
-
-#include "glheader.h"
-#include "context.h"
-#include "enums.h"
-#include "state.h"
-#include "macros.h"
-
-#include "brw_exec.h"
-#include "brw_draw.h"
-#include "brw_fallback.h"
-
-
-static void brw_exec_debug_verts( struct brw_exec_context *exec )
-{
- GLuint count = exec->vtx.vert_count;
- GLuint i;
-
- _mesa_printf("%s: %u vertices %d primitives, %d vertsize\n",
- __FUNCTION__,
- count,
- exec->vtx.prim_count,
- exec->vtx.vertex_size);
-
- for (i = 0 ; i < exec->vtx.prim_count ; i++) {
- struct brw_draw_prim *prim = &exec->vtx.prim[i];
- _mesa_printf(" prim %d: %s%s %d..%d %s %s\n",
- i,
- _mesa_lookup_enum_by_nr(prim->mode),
- prim->weak ? " (weak)" : "",
- prim->start,
- prim->start + prim->count,
- prim->begin ? "BEGIN" : "(wrap)",
- prim->end ? "END" : "(wrap)");
- }
-}
-
-
-/*
- * NOTE: Need to have calculated primitives by this point -- do it on the fly.
- * NOTE: Old 'parity' issue is gone.
- */
-static GLuint brw_copy_vertices( struct brw_exec_context *exec )
-{
- GLuint nr = exec->vtx.prim[exec->vtx.prim_count-1].count;
- GLuint ovf, i;
- GLuint sz = exec->vtx.vertex_size;
- GLfloat *dst = exec->vtx.copied.buffer;
- GLfloat *src = ((GLfloat *)exec->vtx.buffer_map +
- exec->vtx.prim[exec->vtx.prim_count-1].start *
- exec->vtx.vertex_size);
-
-
- switch( exec->ctx->Driver.CurrentExecPrimitive )
- {
- case GL_POINTS:
- return 0;
- case GL_LINES:
- ovf = nr&1;
- for (i = 0 ; i < ovf ; i++)
- _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) );
- return i;
- case GL_TRIANGLES:
- ovf = nr%3;
- for (i = 0 ; i < ovf ; i++)
- _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) );
- return i;
- case GL_QUADS:
- ovf = nr&3;
- for (i = 0 ; i < ovf ; i++)
- _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) );
- return i;
- case GL_LINE_STRIP:
- if (nr == 0)
- return 0;
- else {
- _mesa_memcpy( dst, src+(nr-1)*sz, sz * sizeof(GLfloat) );
- return 1;
- }
- case GL_LINE_LOOP:
- case GL_TRIANGLE_FAN:
- case GL_POLYGON:
- if (nr == 0)
- return 0;
- else if (nr == 1) {
- _mesa_memcpy( dst, src+0, sz * sizeof(GLfloat) );
- return 1;
- } else {
- _mesa_memcpy( dst, src+0, sz * sizeof(GLfloat) );
- _mesa_memcpy( dst+sz, src+(nr-1)*sz, sz * sizeof(GLfloat) );
- return 2;
- }
- case GL_TRIANGLE_STRIP:
- case GL_QUAD_STRIP:
- switch (nr) {
- case 0: ovf = 0; break;
- case 1: ovf = 1; break;
- default: ovf = 2 + (nr&1); break;
- }
- for (i = 0 ; i < ovf ; i++)
- _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) );
- return i;
- case GL_POLYGON+1:
- return 0;
- default:
- assert(0);
- return 0;
- }
-}
-
-
-/* TODO: populate these as the vertex is defined:
- */
-static void brw_exec_bind_arrays( struct brw_exec_context *exec )
-{
- struct gl_client_array *arrays = exec->vtx.arrays;
- GLuint count = exec->vtx.vert_count;
- GLubyte *data = exec->vtx.buffer_map;
- GLuint attr;
-
- memset(arrays, 0, BRW_ATTRIB_MAX * sizeof(arrays[0]));
-
- /* Make all active attributes (including edgeflag) available as
- * arrays of floats.
- */
- for (attr = 0; attr < BRW_ATTRIB_MAX ; attr++) {
- if (exec->vtx.attrsz[attr]) {
- arrays[attr].Ptr = (void *)data;
- arrays[attr].Size = exec->vtx.attrsz[attr];
- arrays[attr].StrideB = exec->vtx.vertex_size * sizeof(GLfloat);
- arrays[attr].Stride = exec->vtx.vertex_size * sizeof(GLfloat);
- arrays[attr].Type = GL_FLOAT;
- arrays[attr].Enabled = 1;
- arrays[attr].BufferObj = exec->vtx.bufferobj; /* NullBufferObj */
- arrays[attr]._MaxElement = count; /* ??? */
-
- data += exec->vtx.attrsz[attr] * sizeof(GLfloat);
- }
- }
-}
-
-
-static
-void brw_exec_loopback_vertex_list( GLcontext *ctx,
- struct brw_exec_context *exec )
-{
- const GLfloat *buffer = (const GLfloat *)exec->vtx.buffer_map;
-
- brw_fallback(ctx);
-
- brw_loopback_vertex_list( ctx,
- buffer,
- exec->vtx.attrsz,
- exec->vtx.prim,
- exec->vtx.prim_count,
- 0, /* XXX - copied.nr */
- exec->vtx.vertex_size);
-
-
- brw_unfallback(ctx);
-}
-
-
-/**
- * Execute the buffer and save copied verts.
- */
-void brw_exec_vtx_flush( struct brw_exec_context *exec )
-{
- if (0)
- brw_exec_debug_verts( exec );
-
-
- if (exec->vtx.prim_count &&
- exec->vtx.vert_count) {
-
- exec->vtx.copied.nr = brw_copy_vertices( exec );
-
- if (exec->vtx.copied.nr != exec->vtx.vert_count) {
- GLcontext *ctx = exec->ctx;
-
- brw_exec_bind_arrays( exec );
-
-
- if (!brw_draw_prims( ctx,
- exec->vtx.inputs,
- exec->vtx.prim,
- exec->vtx.prim_count,
- NULL,
- 0,
- exec->vtx.vert_count,
- 0 )) {
- /* Fallback path:
- */
- brw_exec_loopback_vertex_list(ctx, exec);
- }
- }
- }
-
- exec->vtx.prim_count = 0;
- exec->vtx.vert_count = 0;
- exec->vtx.vbptr = (GLfloat *)exec->vtx.buffer_map;
-}
diff --git a/src/mesa/drivers/dri/i965/brw_exec_eval.c b/src/mesa/drivers/dri/i965/brw_exec_eval.c
deleted file mode 100644
index 9dbeb1b58e4..00000000000
--- a/src/mesa/drivers/dri/i965/brw_exec_eval.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.1
- *
- * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Keith Whitwell <[email protected]>
- */
-
-#include "glheader.h"
-#include "api_eval.h"
-#include "context.h"
-#include "macros.h"
-#include "math/m_eval.h"
-#include "brw_exec.h"
-#include "dispatch.h"
-
-
-static void clear_active_eval1( struct brw_exec_context *exec, GLuint attr )
-{
- exec->eval.map1[attr].map = NULL;
-}
-
-static void clear_active_eval2( struct brw_exec_context *exec, GLuint attr )
-{
- exec->eval.map2[attr].map = NULL;
-}
-
-static void set_active_eval1( struct brw_exec_context *exec, GLuint attr, GLuint dim,
- struct gl_1d_map *map )
-{
- if (!exec->eval.map1[attr].map) {
- exec->eval.map1[attr].map = map;
- exec->eval.map1[attr].sz = dim;
- }
-}
-
-static void set_active_eval2( struct brw_exec_context *exec, GLuint attr, GLuint dim,
- struct gl_2d_map *map )
-{
- if (!exec->eval.map2[attr].map) {
- exec->eval.map2[attr].map = map;
- exec->eval.map2[attr].sz = dim;
- }
-}
-
-void brw_exec_eval_update( struct brw_exec_context *exec )
-{
- GLcontext *ctx = exec->ctx;
- GLuint attr;
-
- /* Vertex program maps have priority over conventional attribs */
-
- for (attr = 0; attr < BRW_ATTRIB_FIRST_MATERIAL; attr++) {
- clear_active_eval1( exec, attr );
- clear_active_eval2( exec, attr );
- }
-
- /* _NEW_PROGRAM */
- if (ctx->VertexProgram._Enabled) {
- for (attr = 0; attr < BRW_ATTRIB_FIRST_MATERIAL; attr++) {
- /* _NEW_EVAL */
- if (ctx->Eval.Map1Attrib[attr])
- set_active_eval1( exec, attr, 4, &ctx->EvalMap.Map1Attrib[attr] );
-
- if (ctx->Eval.Map2Attrib[attr])
- set_active_eval2( exec, attr, 4, &ctx->EvalMap.Map2Attrib[attr] );
- }
- }
-
- if (ctx->Eval.Map1Color4)
- set_active_eval1( exec, BRW_ATTRIB_COLOR0, 4, &ctx->EvalMap.Map1Color4 );
-
- if (ctx->Eval.Map2Color4)
- set_active_eval2( exec, BRW_ATTRIB_COLOR0, 4, &ctx->EvalMap.Map2Color4 );
-
- if (ctx->Eval.Map1TextureCoord4)
- set_active_eval1( exec, BRW_ATTRIB_TEX0, 4, &ctx->EvalMap.Map1Texture4 );
- else if (ctx->Eval.Map1TextureCoord3)
- set_active_eval1( exec, BRW_ATTRIB_TEX0, 3, &ctx->EvalMap.Map1Texture3 );
- else if (ctx->Eval.Map1TextureCoord2)
- set_active_eval1( exec, BRW_ATTRIB_TEX0, 2, &ctx->EvalMap.Map1Texture2 );
- else if (ctx->Eval.Map1TextureCoord1)
- set_active_eval1( exec, BRW_ATTRIB_TEX0, 1, &ctx->EvalMap.Map1Texture1 );
-
- if (ctx->Eval.Map2TextureCoord4)
- set_active_eval2( exec, BRW_ATTRIB_TEX0, 4, &ctx->EvalMap.Map2Texture4 );
- else if (ctx->Eval.Map2TextureCoord3)
- set_active_eval2( exec, BRW_ATTRIB_TEX0, 3, &ctx->EvalMap.Map2Texture3 );
- else if (ctx->Eval.Map2TextureCoord2)
- set_active_eval2( exec, BRW_ATTRIB_TEX0, 2, &ctx->EvalMap.Map2Texture2 );
- else if (ctx->Eval.Map2TextureCoord1)
- set_active_eval2( exec, BRW_ATTRIB_TEX0, 1, &ctx->EvalMap.Map2Texture1 );
-
- if (ctx->Eval.Map1Normal)
- set_active_eval1( exec, BRW_ATTRIB_NORMAL, 3, &ctx->EvalMap.Map1Normal );
-
- if (ctx->Eval.Map2Normal)
- set_active_eval2( exec, BRW_ATTRIB_NORMAL, 3, &ctx->EvalMap.Map2Normal );
-
- if (ctx->Eval.Map1Vertex4)
- set_active_eval1( exec, BRW_ATTRIB_POS, 4, &ctx->EvalMap.Map1Vertex4 );
- else if (ctx->Eval.Map1Vertex3)
- set_active_eval1( exec, BRW_ATTRIB_POS, 3, &ctx->EvalMap.Map1Vertex3 );
-
- if (ctx->Eval.Map2Vertex4)
- set_active_eval2( exec, BRW_ATTRIB_POS, 4, &ctx->EvalMap.Map2Vertex4 );
- else if (ctx->Eval.Map2Vertex3)
- set_active_eval2( exec, BRW_ATTRIB_POS, 3, &ctx->EvalMap.Map2Vertex3 );
-
- exec->eval.recalculate_maps = 0;
-}
-
-
-
-void brw_exec_do_EvalCoord1f(struct brw_exec_context *exec, GLfloat u)
-{
- GLuint attr;
-
- for (attr = 1; attr <= BRW_ATTRIB_INDEX; attr++) {
- struct gl_1d_map *map = exec->eval.map1[attr].map;
- if (map) {
- GLfloat uu = (u - map->u1) * map->du;
- GLfloat data[4];
-
- ASSIGN_4V(data, 0, 0, 0, 1);
-
- _math_horner_bezier_curve(map->Points, data, uu,
- exec->eval.map1[attr].sz,
- map->Order);
-
- COPY_SZ_4V( exec->vtx.attrptr[attr],
- exec->vtx.attrsz[attr],
- data );
- }
- }
-
- /** Vertex -- EvalCoord1f is a noop if this map not enabled:
- **/
- if (exec->eval.map1[0].map) {
- struct gl_1d_map *map = exec->eval.map1[0].map;
- GLfloat uu = (u - map->u1) * map->du;
- GLfloat vertex[4];
-
- ASSIGN_4V(vertex, 0, 0, 0, 1);
-
- _math_horner_bezier_curve(map->Points, vertex, uu,
- exec->eval.map1[0].sz,
- map->Order);
-
- if (exec->eval.map1[0].sz == 4)
- CALL_Vertex4fv(GET_DISPATCH(), ( vertex ));
- else
- CALL_Vertex3fv(GET_DISPATCH(), ( vertex ));
- }
-}
-
-
-
-void brw_exec_do_EvalCoord2f( struct brw_exec_context *exec,
- GLfloat u, GLfloat v )
-{
- GLuint attr;
-
- for (attr = 1; attr <= BRW_ATTRIB_INDEX; attr++) {
- struct gl_2d_map *map = exec->eval.map2[attr].map;
- if (map) {
- GLfloat uu = (u - map->u1) * map->du;
- GLfloat vv = (v - map->v1) * map->dv;
- GLfloat data[4];
-
- ASSIGN_4V(data, 0, 0, 0, 1);
-
- _math_horner_bezier_surf(map->Points,
- data,
- uu, vv,
- exec->eval.map2[attr].sz,
- map->Uorder, map->Vorder);
-
- COPY_SZ_4V( exec->vtx.attrptr[attr],
- exec->vtx.attrsz[attr],
- data );
- }
- }
-
- /** Vertex -- EvalCoord2f is a noop if this map not enabled:
- **/
- if (exec->eval.map2[0].map) {
- struct gl_2d_map *map = exec->eval.map2[0].map;
- GLfloat uu = (u - map->u1) * map->du;
- GLfloat vv = (v - map->v1) * map->dv;
- GLfloat vertex[4];
-
- ASSIGN_4V(vertex, 0, 0, 0, 1);
-
- if (exec->ctx->Eval.AutoNormal) {
- GLfloat normal[4];
- GLfloat du[4], dv[4];
-
- _math_de_casteljau_surf(map->Points, vertex, du, dv, uu, vv,
- exec->eval.map2[0].sz,
- map->Uorder, map->Vorder);
-
- if (exec->eval.map2[0].sz == 4) {
- du[0] = du[0]*vertex[3] - du[3]*vertex[0];
- du[1] = du[1]*vertex[3] - du[3]*vertex[1];
- du[2] = du[2]*vertex[3] - du[3]*vertex[2];
-
- dv[0] = dv[0]*vertex[3] - dv[3]*vertex[0];
- dv[1] = dv[1]*vertex[3] - dv[3]*vertex[1];
- dv[2] = dv[2]*vertex[3] - dv[3]*vertex[2];
- }
-
-
- CROSS3(normal, du, dv);
- NORMALIZE_3FV(normal);
- normal[3] = 1.0;
-
- COPY_SZ_4V( exec->vtx.attrptr[BRW_ATTRIB_NORMAL],
- exec->vtx.attrsz[BRW_ATTRIB_NORMAL],
- normal );
-
- }
- else {
- _math_horner_bezier_surf(map->Points, vertex, uu, vv,
- exec->eval.map2[0].sz,
- map->Uorder, map->Vorder);
- }
-
- if (exec->vtx.attrsz[0] == 4)
- CALL_Vertex4fv(GET_DISPATCH(), ( vertex ));
- else
- CALL_Vertex3fv(GET_DISPATCH(), ( vertex ));
- }
-}
-
-
diff --git a/src/mesa/drivers/dri/i965/brw_fallback.c b/src/mesa/drivers/dri/i965/brw_fallback.c
index 56e21e339ef..86464b2ec5f 100644
--- a/src/mesa/drivers/dri/i965/brw_fallback.c
+++ b/src/mesa/drivers/dri/i965/brw_fallback.c
@@ -30,8 +30,6 @@
#include "tnl/tnl.h"
#include "context.h"
#include "brw_context.h"
-#include "brw_exec.h"
-#include "brw_save.h"
#include "brw_fallback.h"
#include "glheader.h"
@@ -40,297 +38,6 @@
#include "imports.h"
#include "macros.h"
#include "mtypes.h"
-#include "dispatch.h"
-
-
-typedef void (*attr_func)( GLcontext *ctx, GLint target, const GLfloat * );
-
-
-/* Wrapper functions in case glVertexAttrib*fvNV doesn't exist */
-static void VertexAttrib1fvNV(GLcontext *ctx, GLint target, const GLfloat *v)
-{
- CALL_VertexAttrib1fvNV(ctx->Exec, (target, v));
-}
-
-static void VertexAttrib2fvNV(GLcontext *ctx, GLint target, const GLfloat *v)
-{
- CALL_VertexAttrib2fvNV(ctx->Exec, (target, v));
-}
-
-static void VertexAttrib3fvNV(GLcontext *ctx, GLint target, const GLfloat *v)
-{
- CALL_VertexAttrib3fvNV(ctx->Exec, (target, v));
-}
-
-static void VertexAttrib4fvNV(GLcontext *ctx, GLint target, const GLfloat *v)
-{
- CALL_VertexAttrib4fvNV(ctx->Exec, (target, v));
-}
-
-static attr_func vert_attrfunc[4] = {
- VertexAttrib1fvNV,
- VertexAttrib2fvNV,
- VertexAttrib3fvNV,
- VertexAttrib4fvNV
-};
-
-#if 0
-static void VertexAttrib1fvARB(GLcontext *ctx, GLint target, const GLfloat *v)
-{
- CALL_VertexAttrib1fvARB(ctx->Exec, (target, v));
-}
-
-static void VertexAttrib2fvARB(GLcontext *ctx, GLint target, const GLfloat *v)
-{
- CALL_VertexAttrib2fvARB(ctx->Exec, (target, v));
-}
-
-static void VertexAttrib3fvARB(GLcontext *ctx, GLint target, const GLfloat *v)
-{
- CALL_VertexAttrib3fvARB(ctx->Exec, (target, v));
-}
-
-static void VertexAttrib4fvARB(GLcontext *ctx, GLint target, const GLfloat *v)
-{
- CALL_VertexAttrib4fvARB(ctx->Exec, (target, v));
-}
-
-
-static attr_func vert_attrfunc_arb[4] = {
- VertexAttrib1fvARB,
- VertexAttrib2fvARB,
- VertexAttrib3fvARB,
- VertexAttrib4fvARB
-};
-#endif
-
-
-
-
-
-
-static void mat_attr1fv( GLcontext *ctx, GLint target, const GLfloat *v )
-{
- switch (target) {
- case BRW_ATTRIB_MAT_FRONT_SHININESS:
- CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_SHININESS, v ));
- break;
- case BRW_ATTRIB_MAT_BACK_SHININESS:
- CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_SHININESS, v ));
- break;
- }
-}
-
-
-static void mat_attr3fv( GLcontext *ctx, GLint target, const GLfloat *v )
-{
- switch (target) {
- case BRW_ATTRIB_MAT_FRONT_INDEXES:
- CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_COLOR_INDEXES, v ));
- break;
- case BRW_ATTRIB_MAT_BACK_INDEXES:
- CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_COLOR_INDEXES, v ));
- break;
- }
-}
-
-
-static void mat_attr4fv( GLcontext *ctx, GLint target, const GLfloat *v )
-{
- switch (target) {
- case BRW_ATTRIB_MAT_FRONT_EMISSION:
- CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_EMISSION, v ));
- break;
- case BRW_ATTRIB_MAT_BACK_EMISSION:
- CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_EMISSION, v ));
- break;
- case BRW_ATTRIB_MAT_FRONT_AMBIENT:
- CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_AMBIENT, v ));
- break;
- case BRW_ATTRIB_MAT_BACK_AMBIENT:
- CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_AMBIENT, v ));
- break;
- case BRW_ATTRIB_MAT_FRONT_DIFFUSE:
- CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_DIFFUSE, v ));
- break;
- case BRW_ATTRIB_MAT_BACK_DIFFUSE:
- CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_DIFFUSE, v ));
- break;
- case BRW_ATTRIB_MAT_FRONT_SPECULAR:
- CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_SPECULAR, v ));
- break;
- case BRW_ATTRIB_MAT_BACK_SPECULAR:
- CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_SPECULAR, v ));
- break;
- }
-}
-
-
-static attr_func mat_attrfunc[4] = {
- mat_attr1fv,
- NULL,
- mat_attr3fv,
- mat_attr4fv
-};
-
-
-static void index_attr1fv(GLcontext *ctx, GLint target, const GLfloat *v)
-{
- (void) target;
- CALL_Indexf(ctx->Exec, (v[0]));
-}
-
-static void edgeflag_attr1fv(GLcontext *ctx, GLint target, const GLfloat *v)
-{
- (void) target;
- CALL_EdgeFlag(ctx->Exec, ((GLboolean)(v[0] == 1.0)));
-}
-
-struct loopback_attr {
- GLint target;
- GLint sz;
- attr_func func;
-};
-
-/* Don't emit ends and begins on wrapped primitives. Don't replay
- * wrapped vertices. If we get here, it's probably because the the
- * precalculated wrapping is wrong.
- */
-static void loopback_prim( GLcontext *ctx,
- const GLfloat *buffer,
- const struct brw_draw_prim *prim,
- GLuint wrap_count,
- GLuint vertex_size,
- const struct loopback_attr *la, GLuint nr )
-{
- GLint start = prim->start;
- GLint end = start + prim->count;
- const GLfloat *data;
- GLint j;
- GLuint k;
-
- if (0)
- _mesa_printf("loopback prim %s(%s,%s) verts %d..%d\n",
- _mesa_lookup_enum_by_nr(prim->mode),
- prim->begin ? "begin" : "..",
- prim->end ? "end" : "..",
- start,
- end);
-
- if (prim->begin) {
- CALL_Begin(GET_DISPATCH(), ( prim->mode ));
- }
- else {
- assert(start == 0);
- start += wrap_count;
- }
-
- data = buffer + start * vertex_size;
-
- for (j = start ; j < end ; j++) {
- const GLfloat *tmp = data + la[0].sz;
-
- for (k = 1 ; k < nr ; k++) {
- la[k].func( ctx, la[k].target, tmp );
- tmp += la[k].sz;
- }
-
- /* Fire the vertex
- */
- la[0].func( ctx, BRW_ATTRIB_POS, data );
- data = tmp;
- }
-
- if (prim->end) {
- CALL_End(GET_DISPATCH(), ());
- }
-}
-
-/* Primitives generated by DrawArrays/DrawElements/Rectf may be
- * caught here. If there is no primitive in progress, execute them
- * normally, otherwise need to track and discard the generated
- * primitives.
- */
-static void loopback_weak_prim( GLcontext *ctx,
- const struct brw_draw_prim *prim )
-{
- /* Use the prim_weak flag to ensure that if this primitive
- * wraps, we don't mistake future vertex_lists for part of the
- * surrounding primitive.
- *
- * While this flag is set, we are simply disposing of data
- * generated by an operation now known to be a noop.
- */
- if (prim->begin)
- ctx->Driver.CurrentExecPrimitive |= BRW_SAVE_PRIM_WEAK;
- if (prim->end)
- ctx->Driver.CurrentExecPrimitive &= ~BRW_SAVE_PRIM_WEAK;
-}
-
-
-void brw_loopback_vertex_list( GLcontext *ctx,
- const GLfloat *buffer,
- const GLubyte *attrsz,
- const struct brw_draw_prim *prim,
- GLuint prim_count,
- GLuint wrap_count,
- GLuint vertex_size)
-{
- struct loopback_attr la[BRW_ATTRIB_MAX];
- GLuint i, nr = 0;
-
- for (i = 0 ; i <= BRW_ATTRIB_TEX7 ; i++) {
- if (i == BRW_ATTRIB_INDEX || i == BRW_ATTRIB_EDGEFLAG)
- continue;
-
- if (attrsz[i]) {
- la[nr].target = i;
- la[nr].sz = attrsz[i];
- la[nr].func = vert_attrfunc[attrsz[i]-1];
- nr++;
- }
- }
-
- for (i = BRW_ATTRIB_MAT_FRONT_AMBIENT ;
- i <= BRW_ATTRIB_MAT_BACK_INDEXES ;
- i++) {
- if (attrsz[i]) {
- la[nr].target = i;
- la[nr].sz = attrsz[i];
- la[nr].func = mat_attrfunc[attrsz[i]-1];
- nr++;
- }
- }
-
- if (attrsz[BRW_ATTRIB_EDGEFLAG]) {
- la[nr].target = BRW_ATTRIB_EDGEFLAG;
- la[nr].sz = attrsz[BRW_ATTRIB_EDGEFLAG];
- la[nr].func = edgeflag_attr1fv;
- nr++;
- }
-
- if (attrsz[BRW_ATTRIB_INDEX]) {
- la[nr].target = BRW_ATTRIB_INDEX;
- la[nr].sz = attrsz[BRW_ATTRIB_INDEX];
- la[nr].func = index_attr1fv;
- nr++;
- }
-
- /* XXX ARB vertex attribs */
-
- for (i = 0 ; i < prim_count ; i++) {
- if ((prim[i].mode & BRW_SAVE_PRIM_WEAK) &&
- (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END))
- {
- loopback_weak_prim( ctx, &prim[i] );
- }
- else
- {
- loopback_prim( ctx, buffer, &prim[i], wrap_count, vertex_size, la, nr );
- }
- }
-}
-
@@ -405,62 +112,6 @@ const struct brw_tracked_state brw_check_fallback = {
-/* If there is a fallback, fallback to software rasterization and
- * transformation together. There is never a requirement to have
- * software t&l but hardware rasterization.
- *
- * Further, all fallbacks are based on GL state, not on eg. primitive
- * or vertex data.
- */
-
-static void do_fallback( struct brw_context *brw,
- GLboolean fallback )
-{
- GLcontext *ctx = &brw->intel.ctx;
-
- /* flush:
- */
- ctx->Driver.Flush( ctx );
-
- if (fallback) {
- _swsetup_Wakeup( ctx );
- _tnl_wakeup_exec( ctx );
-
- /* Need this because tnl_wakeup_exec does too much:
- */
- brw_save_wakeup(ctx);
- brw_save_fallback(ctx, GL_TRUE);
- }
- else {
- /* Flush vertices and copy-to-current:
- */
- FLUSH_CURRENT(ctx, 0);
-
- _swrast_flush( ctx );
-
- brw_exec_wakeup(ctx);
-
- /* Need this because tnl_wakeup_exec does too much:
- */
- brw_save_wakeup(ctx);
- brw_save_fallback(ctx, GL_FALSE);
- }
-}
-
-
-void brw_fallback( GLcontext *ctx )
-{
- struct brw_context *brw = brw_context(ctx);
- do_fallback(brw, 1);
-}
-
-
-void brw_unfallback( GLcontext *ctx )
-{
- struct brw_context *brw = brw_context(ctx);
- do_fallback(brw, 0);
-}
-
/* Not used:
*/
void intelFallback( struct intel_context *intel, GLuint bit, GLboolean mode )
diff --git a/src/mesa/drivers/dri/i965/brw_fallback.h b/src/mesa/drivers/dri/i965/brw_fallback.h
index 81a2d344b81..684a46cd170 100644
--- a/src/mesa/drivers/dri/i965/brw_fallback.h
+++ b/src/mesa/drivers/dri/i965/brw_fallback.h
@@ -31,7 +31,7 @@
#include "mtypes.h" /* for GLcontext... */
struct brw_context;
-struct brw_draw_prim;
+struct vbo_prim;
void brw_fallback( GLcontext *ctx );
void brw_unfallback( GLcontext *ctx );
@@ -39,7 +39,7 @@ void brw_unfallback( GLcontext *ctx );
void brw_loopback_vertex_list( GLcontext *ctx,
const GLfloat *buffer,
const GLubyte *attrsz,
- const struct brw_draw_prim *prim,
+ const struct vbo_prim *prim,
GLuint prim_count,
GLuint wrap_count,
GLuint vertex_size);
diff --git a/src/mesa/drivers/dri/i965/brw_gs.c b/src/mesa/drivers/dri/i965/brw_gs.c
index 7d3f9dd5e3b..73263a5fff4 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.
*/
@@ -80,6 +82,9 @@ static void compile_gs_prog( struct brw_context *brw,
case GL_QUADS:
brw_gs_quads( &c );
break;
+ case GL_QUAD_STRIP:
+ brw_gs_quad_strip( &c );
+ break;
case GL_LINE_LOOP:
brw_gs_lines( &c );
break;
@@ -143,7 +148,7 @@ static const GLenum gs_prim[GL_POLYGON+1] = {
GL_TRIANGLES,
GL_TRIANGLES,
GL_QUADS,
- GL_QUADS,
+ GL_QUAD_STRIP,
GL_TRIANGLES
};
diff --git a/src/mesa/drivers/dri/i965/brw_gs.h b/src/mesa/drivers/dri/i965/brw_gs.h
index f9aa71d9199..29a4e80ce1b 100644
--- a/src/mesa/drivers/dri/i965/brw_gs.h
+++ b/src/mesa/drivers/dri/i965/brw_gs.h
@@ -67,6 +67,7 @@ struct brw_gs_compile {
#define ATTR_SIZE (4*4)
void brw_gs_quads( struct brw_gs_compile *c );
+void brw_gs_quad_strip( struct brw_gs_compile *c );
void brw_gs_tris( struct brw_gs_compile *c );
void brw_gs_lines( struct brw_gs_compile *c );
void brw_gs_points( struct brw_gs_compile *c );
diff --git a/src/mesa/drivers/dri/i965/brw_gs_emit.c b/src/mesa/drivers/dri/i965/brw_gs_emit.c
index e4eed36a464..9abb94d82ed 100644
--- a/src/mesa/drivers/dri/i965/brw_gs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_gs_emit.c
@@ -116,6 +116,16 @@ void brw_gs_quads( struct brw_gs_compile *c )
brw_gs_emit_vue(c, c->reg.vertex[2], 1, ((_3DPRIM_POLYGON << 2) | R02_PRIM_END));
}
+void brw_gs_quad_strip( struct brw_gs_compile *c )
+{
+ brw_gs_alloc_regs(c, 4);
+
+ brw_gs_emit_vue(c, c->reg.vertex[2], 0, ((_3DPRIM_POLYGON << 2) | R02_PRIM_START));
+ brw_gs_emit_vue(c, c->reg.vertex[3], 0, (_3DPRIM_POLYGON << 2));
+ brw_gs_emit_vue(c, c->reg.vertex[0], 0, (_3DPRIM_POLYGON << 2));
+ brw_gs_emit_vue(c, c->reg.vertex[1], 1, ((_3DPRIM_POLYGON << 2) | R02_PRIM_END));
+}
+
void brw_gs_tris( struct brw_gs_compile *c )
{
brw_gs_alloc_regs(c, 3);
diff --git a/src/mesa/drivers/dri/i965/brw_metaops.c b/src/mesa/drivers/dri/i965/brw_metaops.c
index 2deec5eae3d..1579762b6d1 100644
--- a/src/mesa/drivers/dri/i965/brw_metaops.c
+++ b/src/mesa/drivers/dri/i965/brw_metaops.c
@@ -47,7 +47,6 @@
#include "brw_context.h"
#include "brw_defines.h"
#include "brw_draw.h"
-#include "brw_attrib.h"
#include "brw_fallback.h"
#define INIT(brw, STRUCT, ATTRIB) \
@@ -388,8 +387,8 @@ static void meta_draw_quad(struct intel_context *intel,
struct brw_context *brw = brw_context(&intel->ctx);
struct gl_client_array pos_array;
struct gl_client_array color_array;
- struct gl_client_array *attribs[BRW_ATTRIB_MAX];
- struct brw_draw_prim prim[1];
+ struct gl_client_array *attribs[VERT_ATTRIB_MAX];
+ struct _mesa_prim prim[1];
GLfloat pos[4][3];
GLubyte color[4];
@@ -439,29 +438,29 @@ static void meta_draw_quad(struct intel_context *intel,
/* Ignoring texture coords.
*/
- memset(attribs, 0, BRW_ATTRIB_MAX * sizeof(*attribs));
-
- attribs[BRW_ATTRIB_POS] = &pos_array;
- attribs[BRW_ATTRIB_POS]->Ptr = 0;
- attribs[BRW_ATTRIB_POS]->Type = GL_FLOAT;
- attribs[BRW_ATTRIB_POS]->Enabled = 1;
- attribs[BRW_ATTRIB_POS]->Size = 3;
- attribs[BRW_ATTRIB_POS]->StrideB = 3 * sizeof(GLfloat);
- attribs[BRW_ATTRIB_POS]->Stride = 3 * sizeof(GLfloat);
- attribs[BRW_ATTRIB_POS]->_MaxElement = 4;
- attribs[BRW_ATTRIB_POS]->Normalized = 0;
- attribs[BRW_ATTRIB_POS]->BufferObj = brw->metaops.vbo;
-
- attribs[BRW_ATTRIB_COLOR0] = &color_array;
- attribs[BRW_ATTRIB_COLOR0]->Ptr = (const GLubyte *)sizeof(pos);
- attribs[BRW_ATTRIB_COLOR0]->Type = GL_UNSIGNED_BYTE;
- attribs[BRW_ATTRIB_COLOR0]->Enabled = 1;
- attribs[BRW_ATTRIB_COLOR0]->Size = 4;
- attribs[BRW_ATTRIB_COLOR0]->StrideB = 0;
- attribs[BRW_ATTRIB_COLOR0]->Stride = 0;
- attribs[BRW_ATTRIB_COLOR0]->_MaxElement = 1;
- attribs[BRW_ATTRIB_COLOR0]->Normalized = 1;
- attribs[BRW_ATTRIB_COLOR0]->BufferObj = brw->metaops.vbo;
+ memset(attribs, 0, VERT_ATTRIB_MAX * sizeof(*attribs));
+
+ attribs[VERT_ATTRIB_POS] = &pos_array;
+ attribs[VERT_ATTRIB_POS]->Ptr = 0;
+ attribs[VERT_ATTRIB_POS]->Type = GL_FLOAT;
+ attribs[VERT_ATTRIB_POS]->Enabled = 1;
+ attribs[VERT_ATTRIB_POS]->Size = 3;
+ attribs[VERT_ATTRIB_POS]->StrideB = 3 * sizeof(GLfloat);
+ attribs[VERT_ATTRIB_POS]->Stride = 3 * sizeof(GLfloat);
+ attribs[VERT_ATTRIB_POS]->_MaxElement = 4;
+ attribs[VERT_ATTRIB_POS]->Normalized = 0;
+ attribs[VERT_ATTRIB_POS]->BufferObj = brw->metaops.vbo;
+
+ attribs[VERT_ATTRIB_COLOR0] = &color_array;
+ attribs[VERT_ATTRIB_COLOR0]->Ptr = (const GLubyte *)sizeof(pos);
+ attribs[VERT_ATTRIB_COLOR0]->Type = GL_UNSIGNED_BYTE;
+ attribs[VERT_ATTRIB_COLOR0]->Enabled = 1;
+ attribs[VERT_ATTRIB_COLOR0]->Size = 4;
+ attribs[VERT_ATTRIB_COLOR0]->StrideB = 0;
+ attribs[VERT_ATTRIB_COLOR0]->Stride = 0;
+ attribs[VERT_ATTRIB_COLOR0]->_MaxElement = 1;
+ attribs[VERT_ATTRIB_COLOR0]->Normalized = 1;
+ attribs[VERT_ATTRIB_COLOR0]->BufferObj = brw->metaops.vbo;
/* Just ignoring texture coordinates for now.
*/
@@ -476,24 +475,16 @@ static void meta_draw_quad(struct intel_context *intel,
prim[0].start = 0;
prim[0].count = 4;
- if (!brw_draw_prims(&brw->intel.ctx,
- (const struct gl_client_array **)attribs,
- prim, 1,
- NULL,
- 0,
- 4,
- BRW_DRAW_LOCKED ))
- {
- /* This should not be possible:
- */
- _mesa_printf("brw_draw_prims failed in metaops!\n");
- assert(0);
- }
+ brw_draw_prims(&brw->intel.ctx,
+ (const struct gl_client_array **)attribs,
+ prim, 1,
+ NULL,
+ 0,
+ 3 );
}
-static void install_meta_state( struct intel_context *intel,
- GLenum state )
+static void install_meta_state( struct intel_context *intel )
{
GLcontext *ctx = &intel->ctx;
struct brw_context *brw = brw_context(ctx);
diff --git a/src/mesa/drivers/dri/i965/brw_save.c b/src/mesa/drivers/dri/i965/brw_save.c
deleted file mode 100644
index 1af7791c4d4..00000000000
--- a/src/mesa/drivers/dri/i965/brw_save.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.3
- *
- * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Keith Whitwell <[email protected]>
- */
-
-
-#include "mtypes.h"
-#include "api_arrayelt.h"
-#include "dlist.h"
-#include "vtxfmt.h"
-#include "imports.h"
-
-#include "brw_save.h"
-
-
-
-void brw_save_init( GLcontext *ctx )
-{
- struct brw_save_context *save = CALLOC_STRUCT(brw_save_context);
-
- if (ctx->swtnl_im == NULL) {
- ctx->swtnl_im = CALLOC_STRUCT(brw_exec_save);
- }
-
- save->ctx = ctx;
- IMM_CONTEXT(ctx)->save = save;
-
- /* Initialize the arrayelt helper
- */
- if (!ctx->aelt_context &&
- !_ae_create_context( ctx ))
- return;
-
- brw_save_api_init( save );
- brw_save_wakeup(ctx);
-
- ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN;
-}
-
-
-void brw_save_destroy( GLcontext *ctx )
-{
- struct brw_save_context *save = IMM_CONTEXT(ctx)->save;
- if (save) {
- FREE(save);
- IMM_CONTEXT(ctx)->save = NULL;
- }
-
- if (ctx->aelt_context) {
- _ae_destroy_context( ctx );
- ctx->aelt_context = NULL;
- }
-
- if (IMM_CONTEXT(ctx)->exec == NULL &&
- IMM_CONTEXT(ctx)->save == NULL) {
- FREE(IMM_CONTEXT(ctx));
- ctx->swtnl_im = NULL;
- }
-}
-
-
-void brw_save_invalidate_state( GLcontext *ctx, GLuint new_state )
-{
- _ae_invalidate_state(ctx, new_state);
-}
-
-
-/* Note that this can occur during the playback of a display list:
- */
-void brw_save_fallback( GLcontext *ctx, GLboolean fallback )
-{
- struct brw_save_context *save = IMM_CONTEXT(ctx)->save;
-
- if (fallback)
- save->replay_flags |= BRW_SAVE_FALLBACK;
- else
- save->replay_flags &= ~BRW_SAVE_FALLBACK;
-}
-
-
-/* I don't see any reason to swap this code out on fallbacks. It
- * wouldn't really mean anything to do so anyway as the old lists are
- * still around from pre-fallback. Instead, the above code ensures
- * that vertices are routed back through immediate mode dispatch on
- * fallback.
- *
- * The below can be moved into init or removed:
- */
-void brw_save_wakeup( GLcontext *ctx )
-{
- ctx->Driver.NewList = brw_save_NewList;
- ctx->Driver.EndList = brw_save_EndList;
- ctx->Driver.SaveFlushVertices = brw_save_SaveFlushVertices;
- ctx->Driver.BeginCallList = brw_save_BeginCallList;
- ctx->Driver.EndCallList = brw_save_EndCallList;
- ctx->Driver.NotifySaveBegin = brw_save_NotifyBegin;
-
- /* Assume we haven't been getting state updates either:
- */
- brw_save_invalidate_state( ctx, ~0 );
-}
-
-
-
diff --git a/src/mesa/drivers/dri/i965/brw_save.h b/src/mesa/drivers/dri/i965/brw_save.h
deleted file mode 100644
index 41cabe65084..00000000000
--- a/src/mesa/drivers/dri/i965/brw_save.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/**************************************************************************
-
-Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas.
-
-All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-on the rights to use, copy, modify, merge, publish, distribute, sub
-license, and/or sell copies of the Software, and to permit persons to whom
-the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice (including the next
-paragraph) shall be included in all copies or substantial portions of the
-Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
-TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Keith Whitwell <[email protected]>
- *
- */
-
-#ifndef BRW_SAVE_H
-#define BRW_SAVE_H
-
-#include "mtypes.h"
-#include "brw_attrib.h"
-#include "brw_draw.h"
-
-
-struct brw_save_copied_vtx {
- GLfloat buffer[BRW_ATTRIB_MAX * 4 * BRW_MAX_COPIED_VERTS];
- GLuint nr;
-};
-
-
-/* For display lists, this structure holds a run of vertices of the
- * same format, and a strictly well-formed set of begin/end pairs,
- * starting on the first vertex and ending at the last. Vertex
- * copying on buffer breaks is precomputed according to these
- * primitives, though there are situations where the copying will need
- * correction at execute-time, perhaps by replaying the list as
- * immediate mode commands.
- *
- * On executing this list, the 'current' values may be updated with
- * the values of the final vertex, and often no fixup of the start of
- * the vertex list is required.
- *
- * Eval and other commands that don't fit into these vertex lists are
- * compiled using the fallback opcode mechanism provided by dlist.c.
- */
-struct brw_save_vertex_list {
- GLubyte attrsz[BRW_ATTRIB_MAX];
- GLuint vertex_size;
-
- GLuint buffer_offset;
- GLuint count;
- GLuint wrap_count; /* number of copied vertices at start */
- GLboolean dangling_attr_ref; /* current attr implicitly referenced
- outside the list */
-
- struct brw_draw_prim *prim;
- GLuint prim_count;
-
- struct brw_save_vertex_store *vertex_store;
- struct brw_save_primitive_store *prim_store;
-};
-
-/* These buffers should be a reasonable size to support upload to
- * hardware. Current brw implementation will re-upload on any
- * changes, so don't make too big or apps which dynamically create
- * dlists and use only a few times will suffer.
- *
- * Consider stategy of uploading regions from the VBO on demand in the
- * case of dynamic vbos. Then make the dlist code signal that
- * likelyhood as it occurs. No reason we couldn't change usage
- * internally even though this probably isn't allowed for client VBOs?
- */
-#define BRW_SAVE_BUFFER_SIZE (8*1024) /* dwords */
-#define BRW_SAVE_PRIM_SIZE 128
-#define BRW_SAVE_PRIM_WEAK 0x40
-
-#define BRW_SAVE_FALLBACK 0x10000000
-
-/* Storage to be shared among several vertex_lists.
- */
-struct brw_save_vertex_store {
- struct gl_buffer_object *bufferobj;
- GLfloat *buffer;
- GLuint used;
- GLuint refcount;
-};
-
-struct brw_save_primitive_store {
- struct brw_draw_prim buffer[BRW_SAVE_PRIM_SIZE];
- GLuint used;
- GLuint refcount;
-};
-
-
-struct brw_save_context {
- GLcontext *ctx;
- GLvertexformat vtxfmt;
- struct gl_client_array arrays[BRW_ATTRIB_MAX];
- const struct gl_client_array *inputs[BRW_ATTRIB_MAX];
-
- GLubyte attrsz[BRW_ATTRIB_MAX];
- GLubyte active_sz[BRW_ATTRIB_MAX];
- GLuint vertex_size;
-
- GLfloat *buffer;
- GLuint count;
- GLuint wrap_count;
- GLuint replay_flags;
-
- struct brw_draw_prim *prim;
- GLuint prim_count, prim_max;
-
- struct brw_save_vertex_store *vertex_store;
- struct brw_save_primitive_store *prim_store;
-
- GLfloat *vbptr; /* cursor, points into buffer */
- GLfloat vertex[BRW_ATTRIB_MAX*4]; /* current values */
- GLfloat *attrptr[BRW_ATTRIB_MAX];
- GLuint vert_count;
- GLuint max_vert;
- GLboolean dangling_attr_ref;
- GLboolean have_materials;
-
- GLuint opcode_vertex_list;
-
- struct brw_save_copied_vtx copied;
-
- GLfloat CurrentFloatEdgeFlag;
-
- GLfloat *current[BRW_ATTRIB_MAX]; /* points into ctx->ListState */
- GLubyte *currentsz[BRW_ATTRIB_MAX];
-};
-
-
-void brw_save_init( GLcontext *ctx );
-void brw_save_destroy( GLcontext *ctx );
-void brw_save_wakeup( GLcontext *ctx );
-void brw_save_invalidate_state( GLcontext *ctx, GLuint new_state );
-void brw_save_fallback( GLcontext *ctx, GLboolean fallback );
-
-/* Callbacks:
- */
-void brw_save_EndList( GLcontext *ctx );
-void brw_save_NewList( GLcontext *ctx, GLuint list, GLenum mode );
-void brw_save_EndCallList( GLcontext *ctx );
-void brw_save_BeginCallList( GLcontext *ctx, struct mesa_display_list *list );
-void brw_save_SaveFlushVertices( GLcontext *ctx );
-GLboolean brw_save_NotifyBegin( GLcontext *ctx, GLenum mode );
-
-void brw_save_playback_vertex_list( GLcontext *ctx, void *data );
-
-void brw_save_api_init( struct brw_save_context *save );
-
-#endif
diff --git a/src/mesa/drivers/dri/i965/brw_save_api.c b/src/mesa/drivers/dri/i965/brw_save_api.c
deleted file mode 100644
index 06ed1d23aa2..00000000000
--- a/src/mesa/drivers/dri/i965/brw_save_api.c
+++ /dev/null
@@ -1,1170 +0,0 @@
-/**************************************************************************
-
-Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas.
-
-All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-on the rights to use, copy, modify, merge, publish, distribute, sub
-license, and/or sell copies of the Software, and to permit persons to whom
-the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice (including the next
-paragraph) shall be included in all copies or substantial portions of the
-Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
-TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Keith Whitwell <[email protected]>
- */
-
-
-
-/* Display list compiler attempts to store lists of vertices with the
- * same vertex layout. Additionally it attempts to minimize the need
- * for execute-time fixup of these vertex lists, allowing them to be
- * cached on hardware.
- *
- * There are still some circumstances where this can be thwarted, for
- * example by building a list that consists of one very long primitive
- * (eg Begin(Triangles), 1000 vertices, End), and calling that list
- * from inside a different begin/end object (Begin(Lines), CallList,
- * End).
- *
- * In that case the code will have to replay the list as individual
- * commands through the Exec dispatch table, or fix up the copied
- * vertices at execute-time.
- *
- * The other case where fixup is required is when a vertex attribute
- * is introduced in the middle of a primitive. Eg:
- * Begin(Lines)
- * TexCoord1f() Vertex2f()
- * TexCoord1f() Color3f() Vertex2f()
- * End()
- *
- * If the current value of Color isn't known at compile-time, this
- * primitive will require fixup.
- *
- *
- * The list compiler currently doesn't attempt to compile lists
- * containing EvalCoord or EvalPoint commands. On encountering one of
- * these, compilation falls back to opcodes.
- *
- * This could be improved to fallback only when a mix of EvalCoord and
- * Vertex commands are issued within a single primitive.
- */
-
-
-#include "glheader.h"
-#include "context.h"
-#include "dlist.h"
-#include "enums.h"
-#include "macros.h"
-#include "api_validate.h"
-#include "api_arrayelt.h"
-#include "vtxfmt.h"
-#include "dispatch.h"
-
-#include "brw_save.h"
-#include "brw_fallback.h"
-
-
-
-
-/*
- * NOTE: Old 'parity' issue is gone, but copying can still be
- * wrong-footed on replay.
- */
-static GLuint _save_copy_vertices( GLcontext *ctx,
- const struct brw_save_vertex_list *node,
- const GLfloat *src_buffer)
-{
- struct brw_save_context *save = IMM_CONTEXT( ctx )->save;
- const struct brw_draw_prim *prim = &node->prim[node->prim_count-1];
- GLuint nr = prim->count;
- GLuint sz = save->vertex_size;
- const GLfloat *src = src_buffer + prim->start * sz;
- GLfloat *dst = save->copied.buffer;
- GLuint ovf, i;
-
- if (prim->end)
- return 0;
-
- switch( prim->mode )
- {
- case GL_POINTS:
- return 0;
- case GL_LINES:
- ovf = nr&1;
- for (i = 0 ; i < ovf ; i++)
- _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) );
- return i;
- case GL_TRIANGLES:
- ovf = nr%3;
- for (i = 0 ; i < ovf ; i++)
- _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) );
- return i;
- case GL_QUADS:
- ovf = nr&3;
- for (i = 0 ; i < ovf ; i++)
- _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) );
- return i;
- case GL_LINE_STRIP:
- if (nr == 0)
- return 0;
- else {
- _mesa_memcpy( dst, src+(nr-1)*sz, sz*sizeof(GLfloat) );
- return 1;
- }
- case GL_LINE_LOOP:
- case GL_TRIANGLE_FAN:
- case GL_POLYGON:
- if (nr == 0)
- return 0;
- else if (nr == 1) {
- _mesa_memcpy( dst, src+0, sz*sizeof(GLfloat) );
- return 1;
- } else {
- _mesa_memcpy( dst, src+0, sz*sizeof(GLfloat) );
- _mesa_memcpy( dst+sz, src+(nr-1)*sz, sz*sizeof(GLfloat) );
- return 2;
- }
- case GL_TRIANGLE_STRIP:
- case GL_QUAD_STRIP:
- switch (nr) {
- case 0: ovf = 0; break;
- case 1: ovf = 1; break;
- default: ovf = 2 + (nr&1); break;
- }
- for (i = 0 ; i < ovf ; i++)
- _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) );
- return i;
- default:
- assert(0);
- return 0;
- }
-}
-
-
-static struct brw_save_vertex_store *alloc_vertex_store( GLcontext *ctx )
-{
- struct brw_save_vertex_store *vertex_store = CALLOC_STRUCT(brw_save_vertex_store);
-
- /* obj->Name needs to be non-zero, but won't ever be examined more
- * closely than that. In particular these buffers won't be entered
- * into the hash and can never be confused with ones visible to the
- * user. Perhaps there could be a special number for internal
- * buffers:
- */
- vertex_store->bufferobj = ctx->Driver.NewBufferObject(ctx, 1, GL_ARRAY_BUFFER_ARB);
-
- ctx->Driver.BufferData( ctx,
- GL_ARRAY_BUFFER_ARB,
- BRW_SAVE_BUFFER_SIZE * sizeof(GLfloat),
- NULL,
- GL_STATIC_DRAW_ARB,
- vertex_store->bufferobj);
-
- vertex_store->buffer = NULL;
- vertex_store->used = 0;
- vertex_store->refcount = 1;
-
- return vertex_store;
-}
-
-static void free_vertex_store( GLcontext *ctx, struct brw_save_vertex_store *vertex_store )
-{
- assert(!vertex_store->buffer);
-
- if (vertex_store->bufferobj)
- ctx->Driver.DeleteBuffer( ctx, vertex_store->bufferobj );
-
- FREE( vertex_store );
-}
-
-static GLfloat *map_vertex_store( GLcontext *ctx, struct brw_save_vertex_store *vertex_store )
-{
- assert(vertex_store->bufferobj);
- assert(!vertex_store->buffer);
- vertex_store->buffer = (GLfloat *)ctx->Driver.MapBuffer(ctx,
- GL_ARRAY_BUFFER_ARB, /* not used */
- GL_STATIC_DRAW_ARB, /* not used */
- vertex_store->bufferobj);
-
- assert(vertex_store->buffer);
- return vertex_store->buffer + vertex_store->used;
-}
-
-static void unmap_vertex_store( GLcontext *ctx, struct brw_save_vertex_store *vertex_store )
-{
- ctx->Driver.UnmapBuffer( ctx, GL_ARRAY_BUFFER_ARB, vertex_store->bufferobj );
- vertex_store->buffer = NULL;
-}
-
-
-static struct brw_save_primitive_store *alloc_prim_store( GLcontext *ctx )
-{
- struct brw_save_primitive_store *store = CALLOC_STRUCT(brw_save_primitive_store);
- (void) ctx;
- store->used = 0;
- store->refcount = 1;
- return store;
-}
-
-static void _save_reset_counters( GLcontext *ctx )
-{
- struct brw_save_context *save = IMM_CONTEXT(ctx)->save;
-
- save->prim = save->prim_store->buffer + save->prim_store->used;
- save->buffer = (save->vertex_store->buffer +
- save->vertex_store->used);
-
- assert(save->buffer == save->vbptr);
-
- if (save->vertex_size)
- save->max_vert = ((BRW_SAVE_BUFFER_SIZE - save->vertex_store->used) /
- save->vertex_size);
- else
- save->max_vert = 0;
-
- save->vert_count = 0;
- save->prim_count = 0;
- save->prim_max = BRW_SAVE_PRIM_SIZE - save->prim_store->used;
- save->dangling_attr_ref = 0;
-}
-
-
-/* Insert the active immediate struct onto the display list currently
- * being built.
- */
-static void _save_compile_vertex_list( GLcontext *ctx )
-{
- struct brw_save_context *save = IMM_CONTEXT(ctx)->save;
- struct brw_save_vertex_list *node;
-
- /* Allocate space for this structure in the display list currently
- * being compiled.
- */
- node = (struct brw_save_vertex_list *)
- _mesa_alloc_instruction(ctx, save->opcode_vertex_list, sizeof(*node));
-
- if (!node)
- return;
-
- /* Duplicate our template, increment refcounts to the storage structs:
- */
- _mesa_memcpy(node->attrsz, save->attrsz, sizeof(node->attrsz));
- node->vertex_size = save->vertex_size;
- node->buffer_offset = (save->buffer - save->vertex_store->buffer) * sizeof(GLfloat);
- node->count = save->vert_count;
- node->wrap_count = save->copied.nr;
- node->dangling_attr_ref = save->dangling_attr_ref;
- node->prim = save->prim;
- node->prim_count = save->prim_count;
- node->vertex_store = save->vertex_store;
- node->prim_store = save->prim_store;
-
- node->vertex_store->refcount++;
- node->prim_store->refcount++;
-
- assert(node->attrsz[BRW_ATTRIB_POS] != 0 ||
- node->count == 0);
-
- if (save->dangling_attr_ref)
- ctx->ListState.CurrentList->flags |= MESA_DLIST_DANGLING_REFS;
-
- save->vertex_store->used += save->vertex_size * node->count;
- save->prim_store->used += node->prim_count;
-
-
- /* Copy duplicated vertices
- */
- save->copied.nr = _save_copy_vertices( ctx, node, save->buffer );
-
-
- /* Deal with GL_COMPILE_AND_EXECUTE:
- */
- if (ctx->ExecuteFlag) {
- struct _glapi_table *dispatch = GET_DISPATCH();
-
- _glapi_set_dispatch(ctx->Exec);
-
- brw_loopback_vertex_list( ctx,
- (const GLfloat *)((const char *)save->vertex_store->buffer +
- node->buffer_offset),
- node->attrsz,
- node->prim,
- node->prim_count,
- node->wrap_count,
- node->vertex_size);
-
- _glapi_set_dispatch(dispatch);
- }
-
-
- /* Decide whether the storage structs are full, or can be used for
- * the next vertex lists as well.
- */
- if (save->vertex_store->used >
- BRW_SAVE_BUFFER_SIZE - 16 * (save->vertex_size + 4)) {
-
- /* Unmap old store:
- */
- unmap_vertex_store( ctx, save->vertex_store );
-
- /* Release old reference:
- */
- save->vertex_store->refcount--;
- assert(save->vertex_store->refcount != 0);
- save->vertex_store = NULL;
-
- /* Allocate and map new store:
- */
- save->vertex_store = alloc_vertex_store( ctx );
- save->vbptr = map_vertex_store( ctx, save->vertex_store );
- }
-
- if (save->prim_store->used > BRW_SAVE_PRIM_SIZE - 6) {
- save->prim_store->refcount--;
- assert(save->prim_store->refcount != 0);
- save->prim_store = alloc_prim_store( ctx );
- }
-
- /* Reset our structures for the next run of vertices:
- */
- _save_reset_counters( ctx );
-}
-
-
-/* TODO -- If no new vertices have been stored, don't bother saving
- * it.
- */
-static void _save_wrap_buffers( GLcontext *ctx )
-{
- struct brw_save_context *save = IMM_CONTEXT(ctx)->save;
- GLint i = save->prim_count - 1;
- GLenum mode;
- GLboolean weak;
-
- assert(i < (GLint) save->prim_max);
- assert(i >= 0);
-
- /* Close off in-progress primitive.
- */
- save->prim[i].count = (save->vert_count -
- save->prim[i].start);
- mode = save->prim[i].mode;
- weak = save->prim[i].weak;
-
- /* store the copied vertices, and allocate a new list.
- */
- _save_compile_vertex_list( ctx );
-
- /* Restart interrupted primitive
- */
- save->prim[0].mode = mode;
- save->prim[0].weak = weak;
- save->prim[0].begin = 0;
- save->prim[0].end = 0;
- save->prim[0].pad = 0;
- save->prim[0].start = 0;
- save->prim[0].count = 0;
- save->prim_count = 1;
-}
-
-
-
-/* Called only when buffers are wrapped as the result of filling the
- * vertex_store struct.
- */
-static void _save_wrap_filled_vertex( GLcontext *ctx )
-{
- struct brw_save_context *save = IMM_CONTEXT(ctx)->save;
- GLfloat *data = save->copied.buffer;
- GLuint i;
-
- /* Emit a glEnd to close off the last vertex list.
- */
- _save_wrap_buffers( ctx );
-
- /* Copy stored stored vertices to start of new list.
- */
- assert(save->max_vert - save->vert_count > save->copied.nr);
-
- for (i = 0 ; i < save->copied.nr ; i++) {
- _mesa_memcpy( save->vbptr, data, save->vertex_size * sizeof(GLfloat));
- data += save->vertex_size;
- save->vbptr += save->vertex_size;
- save->vert_count++;
- }
-}
-
-
-static void _save_copy_to_current( GLcontext *ctx )
-{
- struct brw_save_context *save = IMM_CONTEXT(ctx)->save;
- GLuint i;
-
- for (i = BRW_ATTRIB_POS+1 ; i < BRW_ATTRIB_MAX ; i++) {
- if (save->attrsz[i]) {
- save->currentsz[i][0] = save->attrsz[i];
- COPY_CLEAN_4V(save->current[i],
- save->attrsz[i],
- save->attrptr[i]);
- }
- }
-
- /* Edgeflag requires special treatment:
- *
- * TODO: change edgeflag to GLfloat in Mesa.
- */
- if (save->attrsz[BRW_ATTRIB_EDGEFLAG]) {
- ctx->ListState.ActiveEdgeFlag = 1;
- save->CurrentFloatEdgeFlag =
- save->attrptr[BRW_ATTRIB_EDGEFLAG][0];
- ctx->ListState.CurrentEdgeFlag =
- (save->CurrentFloatEdgeFlag == 1.0);
- }
-}
-
-
-static void _save_copy_from_current( GLcontext *ctx )
-{
- struct brw_save_context *save = IMM_CONTEXT(ctx)->save;
- GLint i;
-
- for (i = BRW_ATTRIB_POS+1 ; i < BRW_ATTRIB_MAX ; i++)
- switch (save->attrsz[i]) {
- case 4: save->attrptr[i][3] = save->current[i][3];
- case 3: save->attrptr[i][2] = save->current[i][2];
- case 2: save->attrptr[i][1] = save->current[i][1];
- case 1: save->attrptr[i][0] = save->current[i][0];
- case 0: break;
- }
-
- /* Edgeflag requires special treatment:
- */
- if (save->attrsz[BRW_ATTRIB_EDGEFLAG]) {
- save->CurrentFloatEdgeFlag = (GLfloat)ctx->ListState.CurrentEdgeFlag;
- save->attrptr[BRW_ATTRIB_EDGEFLAG][0] = save->CurrentFloatEdgeFlag;
- }
-}
-
-
-
-
-/* Flush existing data, set new attrib size, replay copied vertices.
- */
-static void _save_upgrade_vertex( GLcontext *ctx,
- GLuint attr,
- GLuint newsz )
-{
- struct brw_save_context *save = IMM_CONTEXT(ctx)->save;
- GLuint oldsz;
- GLuint i;
- GLfloat *tmp;
-
- /* Store the current run of vertices, and emit a GL_END. Emit a
- * BEGIN in the new buffer.
- */
- if (save->vert_count)
- _save_wrap_buffers( ctx );
- else
- assert( save->copied.nr == 0 );
-
- /* Do a COPY_TO_CURRENT to ensure back-copying works for the case
- * when the attribute already exists in the vertex and is having
- * its size increased.
- */
- _save_copy_to_current( ctx );
-
- /* Fix up sizes:
- */
- oldsz = save->attrsz[attr];
- save->attrsz[attr] = newsz;
-
- save->vertex_size += newsz - oldsz;
- save->max_vert = ((BRW_SAVE_BUFFER_SIZE - save->vertex_store->used) /
- save->vertex_size);
- save->vert_count = 0;
-
- /* Recalculate all the attrptr[] values:
- */
- for (i = 0, tmp = save->vertex ; i < BRW_ATTRIB_MAX ; i++) {
- if (save->attrsz[i]) {
- save->attrptr[i] = tmp;
- tmp += save->attrsz[i];
- }
- else
- save->attrptr[i] = NULL; /* will not be dereferenced. */
- }
-
- /* Copy from current to repopulate the vertex with correct values.
- */
- _save_copy_from_current( ctx );
-
- /* Replay stored vertices to translate them to new format here.
- *
- * If there are copied vertices and the new (upgraded) attribute
- * has not been defined before, this list is somewhat degenerate,
- * and will need fixup at runtime.
- */
- if (save->copied.nr)
- {
- GLfloat *data = save->copied.buffer;
- GLfloat *dest = save->buffer;
- GLuint j;
-
- /* Need to note this and fix up at runtime (or loopback):
- */
- if (attr != BRW_ATTRIB_POS && save->currentsz[attr][0] == 0) {
- assert(oldsz == 0);
- save->dangling_attr_ref = GL_TRUE;
- }
-
- for (i = 0 ; i < save->copied.nr ; i++) {
- for (j = 0 ; j < BRW_ATTRIB_MAX ; j++) {
- if (save->attrsz[j]) {
- if (j == attr) {
- if (oldsz) {
- COPY_CLEAN_4V( dest, oldsz, data );
- data += oldsz;
- dest += newsz;
- }
- else {
- COPY_SZ_4V( dest, newsz, save->current[attr] );
- dest += newsz;
- }
- }
- else {
- GLint sz = save->attrsz[j];
- COPY_SZ_4V( dest, sz, data );
- data += sz;
- dest += sz;
- }
- }
- }
- }
-
- save->vbptr = dest;
- save->vert_count += save->copied.nr;
- }
-}
-
-static void save_fixup_vertex( GLcontext *ctx, GLuint attr, GLuint sz )
-{
- struct brw_save_context *save = IMM_CONTEXT(ctx)->save;
-
- if (sz > save->attrsz[attr]) {
- /* New size is larger. Need to flush existing vertices and get
- * an enlarged vertex format.
- */
- _save_upgrade_vertex( ctx, attr, sz );
- }
- else if (sz < save->active_sz[attr]) {
- static GLfloat id[4] = { 0, 0, 0, 1 };
- GLuint i;
-
- /* New size is equal or smaller - just need to fill in some
- * zeros.
- */
- for (i = sz ; i <= save->attrsz[attr] ; i++)
- save->attrptr[attr][i-1] = id[i-1];
- }
-
- save->active_sz[attr] = sz;
-}
-
-static void _save_reset_vertex( GLcontext *ctx )
-{
- struct brw_save_context *save = IMM_CONTEXT(ctx)->save;
- GLuint i;
-
- for (i = 0 ; i < BRW_ATTRIB_MAX ; i++) {
- save->attrsz[i] = 0;
- save->active_sz[i] = 0;
- }
-
- save->vertex_size = 0;
-}
-
-
-
-#define ERROR() _mesa_compile_error( ctx, GL_INVALID_ENUM, __FUNCTION__ );
-
-
-/* Only one size for each attribute may be active at once. Eg. if
- * Color3f is installed/active, then Color4f may not be, even if the
- * vertex actually contains 4 color coordinates. This is because the
- * 3f version won't otherwise set color[3] to 1.0 -- this is the job
- * of the chooser function when switching between Color4f and Color3f.
- */
-#define ATTR( A, N, V0, V1, V2, V3 ) \
-do { \
- struct brw_save_context *save = IMM_CONTEXT(ctx)->save; \
- \
- if (save->active_sz[A] != N) \
- save_fixup_vertex(ctx, A, N); \
- \
- { \
- GLfloat *dest = save->attrptr[A]; \
- if (N>0) dest[0] = V0; \
- if (N>1) dest[1] = V1; \
- if (N>2) dest[2] = V2; \
- if (N>3) dest[3] = V3; \
- } \
- \
- if ((A) == 0) { \
- GLuint i; \
- \
- for (i = 0; i < save->vertex_size; i++) \
- save->vbptr[i] = save->vertex[i]; \
- \
- save->vbptr += save->vertex_size; \
- \
- if (++save->vert_count >= save->max_vert) \
- _save_wrap_filled_vertex( ctx ); \
- } \
-} while (0)
-
-#define TAG(x) _save_##x
-
-#include "brw_attrib_tmp.h"
-
-
-
-
-/* Cope with EvalCoord/CallList called within a begin/end object:
- * -- Flush current buffer
- * -- Fallback to opcodes for the rest of the begin/end object.
- */
-#define DO_FALLBACK(ctx) \
-do { \
- struct brw_save_context *save = IMM_CONTEXT(ctx)->save; \
- \
- if (save->vert_count || save->prim_count) \
- _save_compile_vertex_list( ctx ); \
- \
- _save_copy_to_current( ctx ); \
- _save_reset_vertex( ctx ); \
- _save_reset_counters( ctx ); \
- _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); \
- ctx->Driver.SaveNeedFlush = 0; \
-} while (0)
-
-static void GLAPIENTRY _save_EvalCoord1f( GLfloat u )
-{
- GET_CURRENT_CONTEXT(ctx);
- DO_FALLBACK(ctx);
- ctx->Save->EvalCoord1f( u );
-}
-
-static void GLAPIENTRY _save_EvalCoord1fv( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- DO_FALLBACK(ctx);
- ctx->Save->EvalCoord1fv( v );
-}
-
-static void GLAPIENTRY _save_EvalCoord2f( GLfloat u, GLfloat v )
-{
- GET_CURRENT_CONTEXT(ctx);
- DO_FALLBACK(ctx);
- ctx->Save->EvalCoord2f( u, v );
-}
-
-static void GLAPIENTRY _save_EvalCoord2fv( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- DO_FALLBACK(ctx);
- ctx->Save->EvalCoord2fv( v );
-}
-
-static void GLAPIENTRY _save_EvalPoint1( GLint i )
-{
- GET_CURRENT_CONTEXT(ctx);
- DO_FALLBACK(ctx);
- ctx->Save->EvalPoint1( i );
-}
-
-static void GLAPIENTRY _save_EvalPoint2( GLint i, GLint j )
-{
- GET_CURRENT_CONTEXT(ctx);
- DO_FALLBACK(ctx);
- ctx->Save->EvalPoint2( i, j );
-}
-
-static void GLAPIENTRY _save_CallList( GLuint l )
-{
- GET_CURRENT_CONTEXT(ctx);
- DO_FALLBACK(ctx);
- ctx->Save->CallList( l );
-}
-
-static void GLAPIENTRY _save_CallLists( GLsizei n, GLenum type, const GLvoid *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- DO_FALLBACK(ctx);
- ctx->Save->CallLists( n, type, v );
-}
-
-
-
-
-/* This begin is hooked into ... Updating of
- * ctx->Driver.CurrentSavePrimitive is already taken care of.
- */
-GLboolean brw_save_NotifyBegin( GLcontext *ctx, GLenum mode )
-{
- struct brw_save_context *save = IMM_CONTEXT(ctx)->save;
-
- GLuint i = save->prim_count++;
-
- assert(i < save->prim_max);
- save->prim[i].mode = mode & ~BRW_SAVE_PRIM_WEAK;
- save->prim[i].begin = 1;
- save->prim[i].end = 0;
- save->prim[i].weak = (mode & BRW_SAVE_PRIM_WEAK) ? 1 : 0;
- save->prim[i].pad = 0;
- save->prim[i].start = save->vert_count;
- save->prim[i].count = 0;
-
- _mesa_install_save_vtxfmt( ctx, &save->vtxfmt );
- ctx->Driver.SaveNeedFlush = 1;
- return GL_TRUE;
-}
-
-
-
-static void GLAPIENTRY _save_End( void )
-{
- GET_CURRENT_CONTEXT( ctx );
- struct brw_save_context *save = IMM_CONTEXT(ctx)->save;
- GLint i = save->prim_count - 1;
-
- ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END;
- save->prim[i].end = 1;
- save->prim[i].count = (save->vert_count -
- save->prim[i].start);
-
- if (i == (GLint) save->prim_max - 1) {
- _save_compile_vertex_list( ctx );
- assert(save->copied.nr == 0);
- }
-
- /* Swap out this vertex format while outside begin/end. Any color,
- * etc. received between here and the next begin will be compiled
- * as opcodes.
- */
- _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
-}
-
-
-/* These are all errors as this vtxfmt is only installed inside
- * begin/end pairs.
- */
-static void GLAPIENTRY _save_DrawElements(GLenum mode, GLsizei count, GLenum type,
- const GLvoid *indices)
-{
- GET_CURRENT_CONTEXT(ctx);
- (void) mode; (void) count; (void) type; (void) indices;
- _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawElements" );
-}
-
-
-static void GLAPIENTRY _save_DrawRangeElements(GLenum mode,
- GLuint start, GLuint end,
- GLsizei count, GLenum type,
- const GLvoid *indices)
-{
- GET_CURRENT_CONTEXT(ctx);
- (void) mode; (void) start; (void) end; (void) count; (void) type; (void) indices;
- _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawRangeElements" );
-}
-
-static void GLAPIENTRY _save_DrawArrays(GLenum mode, GLint start, GLsizei count)
-{
- GET_CURRENT_CONTEXT(ctx);
- (void) mode; (void) start; (void) count;
- _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawArrays" );
-}
-
-static void GLAPIENTRY _save_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
-{
- GET_CURRENT_CONTEXT(ctx);
- (void) x1; (void) y1; (void) x2; (void) y2;
- _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glRectf" );
-}
-
-static void GLAPIENTRY _save_EvalMesh1( GLenum mode, GLint i1, GLint i2 )
-{
- GET_CURRENT_CONTEXT(ctx);
- (void) mode; (void) i1; (void) i2;
- _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glEvalMesh1" );
-}
-
-static void GLAPIENTRY _save_EvalMesh2( GLenum mode, GLint i1, GLint i2,
- GLint j1, GLint j2 )
-{
- GET_CURRENT_CONTEXT(ctx);
- (void) mode; (void) i1; (void) i2; (void) j1; (void) j2;
- _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glEvalMesh2" );
-}
-
-static void GLAPIENTRY _save_Begin( GLenum mode )
-{
- GET_CURRENT_CONTEXT( ctx );
- (void) mode;
- _mesa_compile_error( ctx, GL_INVALID_OPERATION, "Recursive glBegin" );
-}
-
-
-/* Unlike the functions above, these are to be hooked into the vtxfmt
- * maintained in ctx->ListState, active when the list is known or
- * suspected to be outside any begin/end primitive.
- */
-static void GLAPIENTRY _save_OBE_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
-{
- GET_CURRENT_CONTEXT(ctx);
- brw_save_NotifyBegin( ctx, GL_QUADS | BRW_SAVE_PRIM_WEAK );
- CALL_Vertex2f(GET_DISPATCH(), ( x1, y1 ));
- CALL_Vertex2f(GET_DISPATCH(), ( x2, y1 ));
- CALL_Vertex2f(GET_DISPATCH(), ( x2, y2 ));
- CALL_Vertex2f(GET_DISPATCH(), ( x1, y2 ));
- CALL_End(GET_DISPATCH(), ());
-}
-
-
-static void GLAPIENTRY _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei count)
-{
- GET_CURRENT_CONTEXT(ctx);
- GLint i;
-
- if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))
- return;
-
- _ae_map_vbos( ctx );
-
- brw_save_NotifyBegin( ctx, mode | BRW_SAVE_PRIM_WEAK );
- for (i = 0; i < count; i++)
- CALL_ArrayElement(GET_DISPATCH(), (start + i));
- CALL_End(GET_DISPATCH(), ());
-
- _ae_unmap_vbos( ctx );
-}
-
-/* Could do better by copying the arrays and element list intact and
- * then emitting an indexed prim at runtime.
- */
-static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum type,
- const GLvoid *indices)
-{
- GET_CURRENT_CONTEXT(ctx);
- GLint i;
-
- if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))
- return;
-
- _ae_map_vbos( ctx );
-
- brw_save_NotifyBegin( ctx, mode | BRW_SAVE_PRIM_WEAK );
-
- switch (type) {
- case GL_UNSIGNED_BYTE:
- for (i = 0 ; i < count ; i++)
- CALL_ArrayElement(GET_DISPATCH(), ( ((GLubyte *)indices)[i] ));
- break;
- case GL_UNSIGNED_SHORT:
- for (i = 0 ; i < count ; i++)
- CALL_ArrayElement(GET_DISPATCH(), ( ((GLushort *)indices)[i] ));
- break;
- case GL_UNSIGNED_INT:
- for (i = 0 ; i < count ; i++)
- CALL_ArrayElement(GET_DISPATCH(), ( ((GLuint *)indices)[i] ));
- break;
- default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" );
- break;
- }
-
- CALL_End(GET_DISPATCH(), ());
-
- _ae_unmap_vbos( ctx );
-}
-
-static void GLAPIENTRY _save_OBE_DrawRangeElements(GLenum mode,
- GLuint start, GLuint end,
- GLsizei count, GLenum type,
- const GLvoid *indices)
-{
- GET_CURRENT_CONTEXT(ctx);
- if (_mesa_validate_DrawRangeElements( ctx, mode,
- start, end,
- count, type, indices ))
- _save_OBE_DrawElements( mode, count, type, indices );
-}
-
-
-
-
-
-static void _save_vtxfmt_init( GLcontext *ctx )
-{
- struct brw_save_context *save = IMM_CONTEXT(ctx)->save;
- GLvertexformat *vfmt = &save->vtxfmt;
-
- vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */
- vfmt->Begin = _save_Begin;
- vfmt->Color3f = _save_Color3f;
- vfmt->Color3fv = _save_Color3fv;
- vfmt->Color4f = _save_Color4f;
- vfmt->Color4fv = _save_Color4fv;
- vfmt->EdgeFlag = _save_EdgeFlag;
- vfmt->End = _save_End;
- vfmt->FogCoordfEXT = _save_FogCoordfEXT;
- vfmt->FogCoordfvEXT = _save_FogCoordfvEXT;
- vfmt->Indexf = _save_Indexf;
- vfmt->Indexfv = _save_Indexfv;
- vfmt->Materialfv = _save_Materialfv;
- vfmt->MultiTexCoord1fARB = _save_MultiTexCoord1f;
- vfmt->MultiTexCoord1fvARB = _save_MultiTexCoord1fv;
- vfmt->MultiTexCoord2fARB = _save_MultiTexCoord2f;
- vfmt->MultiTexCoord2fvARB = _save_MultiTexCoord2fv;
- vfmt->MultiTexCoord3fARB = _save_MultiTexCoord3f;
- vfmt->MultiTexCoord3fvARB = _save_MultiTexCoord3fv;
- vfmt->MultiTexCoord4fARB = _save_MultiTexCoord4f;
- vfmt->MultiTexCoord4fvARB = _save_MultiTexCoord4fv;
- vfmt->Normal3f = _save_Normal3f;
- vfmt->Normal3fv = _save_Normal3fv;
- vfmt->SecondaryColor3fEXT = _save_SecondaryColor3fEXT;
- vfmt->SecondaryColor3fvEXT = _save_SecondaryColor3fvEXT;
- vfmt->TexCoord1f = _save_TexCoord1f;
- vfmt->TexCoord1fv = _save_TexCoord1fv;
- vfmt->TexCoord2f = _save_TexCoord2f;
- vfmt->TexCoord2fv = _save_TexCoord2fv;
- vfmt->TexCoord3f = _save_TexCoord3f;
- vfmt->TexCoord3fv = _save_TexCoord3fv;
- vfmt->TexCoord4f = _save_TexCoord4f;
- vfmt->TexCoord4fv = _save_TexCoord4fv;
- vfmt->Vertex2f = _save_Vertex2f;
- vfmt->Vertex2fv = _save_Vertex2fv;
- vfmt->Vertex3f = _save_Vertex3f;
- vfmt->Vertex3fv = _save_Vertex3fv;
- vfmt->Vertex4f = _save_Vertex4f;
- vfmt->Vertex4fv = _save_Vertex4fv;
- vfmt->VertexAttrib1fARB = _save_VertexAttrib1fARB;
- vfmt->VertexAttrib1fvARB = _save_VertexAttrib1fvARB;
- vfmt->VertexAttrib2fARB = _save_VertexAttrib2fARB;
- vfmt->VertexAttrib2fvARB = _save_VertexAttrib2fvARB;
- vfmt->VertexAttrib3fARB = _save_VertexAttrib3fARB;
- vfmt->VertexAttrib3fvARB = _save_VertexAttrib3fvARB;
- vfmt->VertexAttrib4fARB = _save_VertexAttrib4fARB;
- vfmt->VertexAttrib4fvARB = _save_VertexAttrib4fvARB;
-
- vfmt->VertexAttrib1fNV = _save_VertexAttrib1fNV;
- vfmt->VertexAttrib1fvNV = _save_VertexAttrib1fvNV;
- vfmt->VertexAttrib2fNV = _save_VertexAttrib2fNV;
- vfmt->VertexAttrib2fvNV = _save_VertexAttrib2fvNV;
- vfmt->VertexAttrib3fNV = _save_VertexAttrib3fNV;
- vfmt->VertexAttrib3fvNV = _save_VertexAttrib3fvNV;
- vfmt->VertexAttrib4fNV = _save_VertexAttrib4fNV;
- vfmt->VertexAttrib4fvNV = _save_VertexAttrib4fvNV;
-
- /* This will all require us to fallback to saving the list as opcodes:
- */
- vfmt->CallList = _save_CallList; /* inside begin/end */
- vfmt->CallLists = _save_CallLists; /* inside begin/end */
- vfmt->EvalCoord1f = _save_EvalCoord1f;
- vfmt->EvalCoord1fv = _save_EvalCoord1fv;
- vfmt->EvalCoord2f = _save_EvalCoord2f;
- vfmt->EvalCoord2fv = _save_EvalCoord2fv;
- vfmt->EvalPoint1 = _save_EvalPoint1;
- vfmt->EvalPoint2 = _save_EvalPoint2;
-
- /* These are all errors as we at least know we are in some sort of
- * begin/end pair:
- */
- vfmt->EvalMesh1 = _save_EvalMesh1;
- vfmt->EvalMesh2 = _save_EvalMesh2;
- vfmt->Begin = _save_Begin;
- vfmt->Rectf = _save_Rectf;
- vfmt->DrawArrays = _save_DrawArrays;
- vfmt->DrawElements = _save_DrawElements;
- vfmt->DrawRangeElements = _save_DrawRangeElements;
-
-}
-
-
-void brw_save_SaveFlushVertices( GLcontext *ctx )
-{
- struct brw_save_context *save = IMM_CONTEXT(ctx)->save;
-
- /* Noop when we are actually active:
- */
- if (ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM ||
- ctx->Driver.CurrentSavePrimitive <= GL_POLYGON)
- return;
-
- if (save->vert_count ||
- save->prim_count)
- _save_compile_vertex_list( ctx );
-
- _save_copy_to_current( ctx );
- _save_reset_vertex( ctx );
- _save_reset_counters( ctx );
- ctx->Driver.SaveNeedFlush = 0;
-}
-
-void brw_save_NewList( GLcontext *ctx, GLuint list, GLenum mode )
-{
- struct brw_save_context *save = IMM_CONTEXT(ctx)->save;
-
- (void) list; (void) mode;
-
- if (!save->prim_store)
- save->prim_store = alloc_prim_store( ctx );
-
- if (!save->vertex_store)
- save->vertex_store = alloc_vertex_store( ctx );
-
- save->vbptr = map_vertex_store( ctx, save->vertex_store );
-
- _save_reset_vertex( ctx );
- _save_reset_counters( ctx );
- ctx->Driver.SaveNeedFlush = 0;
-}
-
-void brw_save_EndList( GLcontext *ctx )
-{
- struct brw_save_context *save = IMM_CONTEXT(ctx)->save;
- unmap_vertex_store( ctx, save->vertex_store );
-
- assert(save->vertex_size == 0);
-}
-
-void brw_save_BeginCallList( GLcontext *ctx, struct mesa_display_list *dlist )
-{
- struct brw_save_context *save = IMM_CONTEXT(ctx)->save;
- save->replay_flags |= dlist->flags;
-}
-
-void brw_save_EndCallList( GLcontext *ctx )
-{
- struct brw_save_context *save = IMM_CONTEXT(ctx)->save;
-
- if (ctx->ListState.CallDepth == 1) {
- /* This is correct: want to keep only the BRW_SAVE_FALLBACK
- * flag, if it is set:
- */
- save->replay_flags &= BRW_SAVE_FALLBACK;
- }
-}
-
-
-static void brw_destroy_vertex_list( GLcontext *ctx, void *data )
-{
- struct brw_save_vertex_list *node = (struct brw_save_vertex_list *)data;
- (void) ctx;
-
- if ( --node->vertex_store->refcount == 0 )
- free_vertex_store( ctx, node->vertex_store );
-
- if ( --node->prim_store->refcount == 0 )
- FREE( node->prim_store );
-}
-
-
-static void brw_print_vertex_list( GLcontext *ctx, void *data )
-{
- struct brw_save_vertex_list *node = (struct brw_save_vertex_list *)data;
- GLuint i;
- (void) ctx;
-
- _mesa_debug(NULL, "BRW-VERTEX-LIST, %u vertices %d primitives, %d vertsize\n",
- node->count,
- node->prim_count,
- node->vertex_size);
-
- for (i = 0 ; i < node->prim_count ; i++) {
- struct brw_draw_prim *prim = &node->prim[i];
- _mesa_debug(NULL, " prim %d: %s%s %d..%d %s %s\n",
- i,
- _mesa_lookup_enum_by_nr(prim->mode),
- prim->weak ? " (weak)" : "",
- prim->start,
- prim->start + prim->count,
- (prim->begin) ? "BEGIN" : "(wrap)",
- (prim->end) ? "END" : "(wrap)");
- }
-}
-
-
-static void _save_current_init( GLcontext *ctx )
-{
- struct brw_save_context *save = IMM_CONTEXT(ctx)->save;
- GLint i;
-
- for (i = 0; i < BRW_ATTRIB_FIRST_MATERIAL; i++) {
- save->currentsz[i] = &ctx->ListState.ActiveAttribSize[i];
- save->current[i] = ctx->ListState.CurrentAttrib[i];
- }
-
- for (i = BRW_ATTRIB_FIRST_MATERIAL; i <= BRW_ATTRIB_LAST_MATERIAL; i++) {
- const GLuint j = i - BRW_ATTRIB_FIRST_MATERIAL;
- ASSERT(j < MAT_ATTRIB_MAX);
- save->currentsz[i] = &ctx->ListState.ActiveMaterialSize[j];
- save->current[i] = ctx->ListState.CurrentMaterial[j];
- }
-
- save->currentsz[BRW_ATTRIB_INDEX] = &ctx->ListState.ActiveIndex;
- save->current[BRW_ATTRIB_INDEX] = &ctx->ListState.CurrentIndex;
-
- save->currentsz[BRW_ATTRIB_EDGEFLAG] = &ctx->ListState.ActiveEdgeFlag;
- save->current[BRW_ATTRIB_EDGEFLAG] = &save->CurrentFloatEdgeFlag;
-}
-
-/**
- * Initialize the display list compiler
- */
-void brw_save_api_init( struct brw_save_context *save )
-{
- GLcontext *ctx = save->ctx;
- GLuint i;
-
- save->opcode_vertex_list =
- _mesa_alloc_opcode( ctx,
- sizeof(struct brw_save_vertex_list),
- brw_save_playback_vertex_list,
- brw_destroy_vertex_list,
- brw_print_vertex_list );
-
- ctx->Driver.NotifySaveBegin = brw_save_NotifyBegin;
-
- _save_vtxfmt_init( ctx );
- _save_current_init( ctx );
-
- for (i = 0; i < BRW_ATTRIB_MAX; i++)
- save->inputs[i] = &save->arrays[i];
-
- /* Hook our array functions into the outside-begin-end vtxfmt in
- * ctx->ListState.
- */
- ctx->ListState.ListVtxfmt.Rectf = _save_OBE_Rectf;
- ctx->ListState.ListVtxfmt.DrawArrays = _save_OBE_DrawArrays;
- ctx->ListState.ListVtxfmt.DrawElements = _save_OBE_DrawElements;
- ctx->ListState.ListVtxfmt.DrawRangeElements = _save_OBE_DrawRangeElements;
- _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
-}
-
diff --git a/src/mesa/drivers/dri/i965/brw_save_draw.c b/src/mesa/drivers/dri/i965/brw_save_draw.c
deleted file mode 100644
index cebdd8d0607..00000000000
--- a/src/mesa/drivers/dri/i965/brw_save_draw.c
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.1
- *
- * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/* Author:
- * Keith Whitwell <[email protected]>
- */
-
-#include "glheader.h"
-#include "context.h"
-#include "imports.h"
-#include "mtypes.h"
-#include "macros.h"
-#include "light.h"
-#include "state.h"
-
-#include "brw_save.h"
-#include "brw_draw.h"
-#include "brw_fallback.h"
-
-/*
- * After playback, copy everything but the position from the
- * last vertex to the saved state
- */
-static void _playback_copy_to_current( GLcontext *ctx,
- const struct brw_save_vertex_list *node )
-{
- struct brw_save_context *save = IMM_CONTEXT(ctx)->save;
- GLfloat vertex[BRW_ATTRIB_MAX * 4], *data = vertex;
- GLuint i, offset;
-
- if (node->count)
- offset = (node->buffer_offset +
- (node->count-1) * node->vertex_size * sizeof(GLfloat));
- else
- offset = node->buffer_offset;
-
- ctx->Driver.GetBufferSubData( ctx, 0, offset,
- node->vertex_size * sizeof(GLfloat),
- data, node->vertex_store->bufferobj );
-
- for (i = 0 ; i < BRW_ATTRIB_MAX ; i++) {
- if (node->attrsz[i]) {
- if (i != BRW_ATTRIB_POS)
- COPY_CLEAN_4V(save->current[i], node->attrsz[i], data);
-
- if (i >= BRW_ATTRIB_MAT_FRONT_AMBIENT &&
- i <= BRW_ATTRIB_MAT_BACK_INDEXES)
- ctx->NewState |= _NEW_LIGHT;
-
- /* Edgeflag requires special treatment:
- */
- if (i == BRW_ATTRIB_EDGEFLAG)
- ctx->Current.EdgeFlag = (data[0] == 1.0);
-
- data += node->attrsz[i] * sizeof(GLfloat);
- }
- }
-
- /* Edgeflag requires special treatment:
- */
- if (node->attrsz[BRW_ATTRIB_EDGEFLAG]) {
- ctx->Current.EdgeFlag = (data[0] == 1.0);
- }
-
-
-#if 1
- /* Colormaterial -- this kindof sucks.
- */
- if (ctx->Light.ColorMaterialEnabled) {
- _mesa_update_color_material(ctx, ctx->Current.Attrib[BRW_ATTRIB_COLOR0]);
- }
-#endif
-
- /* CurrentExecPrimitive
- */
- if (node->prim_count) {
- const struct brw_draw_prim *prim = &node->prim[node->prim_count - 1];
- if (prim->end)
- ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
- else
- ctx->Driver.CurrentExecPrimitive = prim->mode;
- }
-}
-
-
-
-/* Treat the vertex storage as a VBO, define vertex arrays pointing
- * into it:
- */
-static void brw_bind_vertex_list( struct brw_save_context *save,
- const struct brw_save_vertex_list *node )
-{
- struct gl_client_array *arrays = save->arrays;
- GLuint data = node->buffer_offset;
- GLuint attr;
-
- memset(arrays, 0, BRW_ATTRIB_MAX * sizeof(arrays[0]));
-
- for (attr = 0; attr < BRW_ATTRIB_MAX; attr++) {
- if (node->attrsz[attr]) {
- arrays[attr].Ptr = (const GLubyte *)data;
- arrays[attr].Size = node->attrsz[attr];
- arrays[attr].StrideB = node->vertex_size * sizeof(GLfloat);
- arrays[attr].Stride = node->vertex_size * sizeof(GLfloat);
- arrays[attr].Type = GL_FLOAT;
- arrays[attr].Enabled = 1;
- arrays[attr].BufferObj = node->vertex_store->bufferobj;
- arrays[attr]._MaxElement = node->count; /* ??? */
-
- assert(arrays[attr].BufferObj->Name);
-
- data += node->attrsz[attr] * sizeof(GLfloat);
- }
- }
-}
-
-static void brw_save_loopback_vertex_list( GLcontext *ctx,
- const struct brw_save_vertex_list *list )
-{
- const char *buffer = ctx->Driver.MapBuffer(ctx,
- GL_ARRAY_BUFFER_ARB,
- GL_DYNAMIC_READ_ARB, /* ? */
- list->vertex_store->bufferobj);
-
- brw_loopback_vertex_list( ctx,
- (const GLfloat *)(buffer + list->buffer_offset),
- list->attrsz,
- list->prim,
- list->prim_count,
- list->wrap_count,
- list->vertex_size);
-
- ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER_ARB,
- list->vertex_store->bufferobj);
-}
-
-
-/**
- * Execute the buffer and save copied verts.
- */
-void brw_save_playback_vertex_list( GLcontext *ctx, void *data )
-{
- const struct brw_save_vertex_list *node = (const struct brw_save_vertex_list *) data;
- struct brw_save_context *save = IMM_CONTEXT(ctx)->save;
-
- FLUSH_CURRENT(ctx, 0);
-
- if (node->prim_count > 0 && node->count > 0) {
-
- if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END &&
- node->prim[0].begin) {
-
- /* Degenerate case: list is called inside begin/end pair and
- * includes operations such as glBegin or glDrawArrays.
- */
- if (0)
- _mesa_printf("displaylist recursive begin");
-
- brw_save_loopback_vertex_list( ctx, node );
- return;
- }
- else if (save->replay_flags) {
- /* Various degnerate cases: translate into immediate mode
- * calls rather than trying to execute in place.
- */
- brw_save_loopback_vertex_list( ctx, node );
- return;
- }
-
- if (ctx->NewState)
- _mesa_update_state( ctx );
-
- if ((ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) ||
- (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBegin (invalid vertex/fragment program)");
- return;
- }
-
- brw_bind_vertex_list( save, node );
-
- if (!brw_draw_prims( save->ctx,
- save->inputs,
- node->prim,
- node->prim_count,
- NULL,
- 0, /* Node is a VBO, so this is ok */
- node->count,
- 0 )) {
- brw_fallback(ctx);
- brw_save_loopback_vertex_list( ctx, node );
- brw_unfallback(ctx);
- return;
- }
- }
-
- /* Copy to current?
- */
- _playback_copy_to_current( ctx, node );
-}
diff --git a/src/mesa/drivers/dri/i965/brw_structs.h b/src/mesa/drivers/dri/i965/brw_structs.h
index 25acdcfe947..10fee944e8d 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_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c
index 1353325afff..af1ad0f1ef1 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.c b/src/mesa/drivers/dri/i965/brw_vs.c
index e5a28b96e32..74c9d88e464 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.c
+++ b/src/mesa/drivers/dri/i965/brw_vs.c
@@ -54,12 +54,11 @@ static void do_vs_prog( struct brw_context *brw,
c.vp = vp;
c.prog_data.outputs_written = vp->program.Base.OutputsWritten;
- c.prog_data.inputs_read = brw_translate_inputs(brw->intel.ctx.VertexProgram._Enabled,
- vp->program.Base.InputsRead);
+ c.prog_data.inputs_read = vp->program.Base.InputsRead;
if (c.key.copy_edgeflag) {
c.prog_data.outputs_written |= 1<<VERT_RESULT_EDGE;
- c.prog_data.inputs_read |= 1<<BRW_ATTRIB_EDGEFLAG;
+ c.prog_data.inputs_read |= 1<<VERT_ATTRIB_EDGEFLAG;
}
if (0)
diff --git a/src/mesa/drivers/dri/i965/brw_vs_constval.c b/src/mesa/drivers/dri/i965/brw_vs_constval.c
index 502d8283970..528e164db8c 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_constval.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_constval.c
@@ -162,6 +162,7 @@ static GLuint get_input_size(struct brw_context *brw,
GLuint sizes_dword = brw->vb.info.sizes[attr/16];
GLuint sizes_bits = (sizes_dword>>((attr%16)*2)) & 0x3;
return sizes_bits + 1;
+/* return brw->vb.inputs[attr].glarray->Size; */
}
/* Calculate sizes of vertex program outputs. Size is the largest
@@ -176,8 +177,6 @@ static void calc_wm_input_sizes( struct brw_context *brw )
struct tracker t;
GLuint insn;
GLuint i;
- GLuint64EXT inputs = brw_translate_inputs(brw->intel.ctx.VertexProgram._Enabled,
- vp->program.Base.InputsRead);
memset(&t, 0, sizeof(t));
@@ -185,8 +184,8 @@ static void calc_wm_input_sizes( struct brw_context *brw )
if (brw->attribs.Light->Model.TwoSide)
t.twoside = 1;
- for (i = 0; i < BRW_ATTRIB_MAX; i++)
- if (inputs & (1<<i))
+ for (i = 0; i < VERT_ATTRIB_MAX; i++)
+ if (vp->program.Base.InputsRead & (1<<i))
set_active_component(&t, PROGRAM_INPUT, i,
szflag[get_input_size(brw, i)]);
diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index 8403e1bd7b6..ffdb843e85f 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c
@@ -77,8 +77,8 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
/* Allocate input regs:
*/
c->nr_inputs = 0;
- for (i = 0; i < BRW_ATTRIB_MAX; i++) {
- if (c->prog_data.inputs_read & ((GLuint64EXT)1<<i)) {
+ for (i = 0; i < VERT_ATTRIB_MAX; i++) {
+ if (c->prog_data.inputs_read & (1<<i)) {
c->nr_inputs++;
c->regs[PROGRAM_INPUT][i] = brw_vec8_grf(reg, 0);
reg++;
@@ -791,7 +791,7 @@ static void emit_vertex_write( struct brw_vs_compile *c)
if (c->key.copy_edgeflag) {
brw_MOV(p,
get_reg(c, PROGRAM_OUTPUT, VERT_RESULT_EDGE),
- get_reg(c, PROGRAM_INPUT, BRW_ATTRIB_EDGEFLAG));
+ get_reg(c, PROGRAM_INPUT, VERT_ATTRIB_EDGEFLAG));
}
diff --git a/src/mesa/drivers/dri/i965/brw_vs_tnl.c b/src/mesa/drivers/dri/i965/brw_vs_tnl.c
index b7893ca3e55..0d61092247a 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:
@@ -146,9 +146,13 @@ static void make_state_key( GLcontext *ctx, struct state_key *key )
}
/* BRW_NEW_INPUT_VARYING */
- for (i = BRW_ATTRIB_MAT_FRONT_AMBIENT ; i < BRW_ATTRIB_MAX ; i++)
- if (brw->vb.info.varying & ((GLuint64EXT)1<<i))
- key->light_material_mask |= 1<<(i-BRW_ATTRIB_MAT_FRONT_AMBIENT);
+
+ /* For these programs, material values are stuffed into the
+ * generic slots:
+ */
+ for (i = 0 ; i < MAT_ATTRIB_MAX ; i++)
+ if (brw->vb.info.varying & (1<<(VERT_ATTRIB_GENERIC0 + i)))
+ key->light_material_mask |= 1<<i;
for (i = 0; i < MAX_LIGHTS; i++) {
struct gl_light *light = &brw->attribs.Light->Light[i];
@@ -374,17 +378,10 @@ static void release_temps( struct tnl_program *p )
static struct ureg register_input( struct tnl_program *p, GLuint input )
{
- GLuint orig_input = input;
- /* Cram the material flags into the generic range. We'll translate
- * them back later.
- */
- if (input >= BRW_ATTRIB_MAT_FRONT_AMBIENT)
- input -= BRW_ATTRIB_MAT_FRONT_AMBIENT - BRW_ATTRIB_GENERIC0;
-
assert(input < 32);
p->program->Base.InputsRead |= (1<<input);
- return make_ureg(PROGRAM_INPUT, orig_input);
+ return make_ureg(PROGRAM_INPUT, input);
}
static struct ureg register_output( struct tnl_program *p, GLuint output )
@@ -647,7 +644,7 @@ static void emit_passthrough( struct tnl_program *p,
static struct ureg get_eye_position( struct tnl_program *p )
{
if (is_undef(p->eye_position)) {
- struct ureg pos = register_input( p, BRW_ATTRIB_POS );
+ struct ureg pos = register_input( p, VERT_ATTRIB_POS );
struct ureg modelview[4];
p->eye_position = reserve_temp(p);
@@ -710,7 +707,7 @@ static struct ureg get_eye_position_normalized( struct tnl_program *p )
static struct ureg get_eye_normal( struct tnl_program *p )
{
if (is_undef(p->eye_normal)) {
- struct ureg normal = register_input(p, BRW_ATTRIB_NORMAL );
+ struct ureg normal = register_input(p, VERT_ATTRIB_NORMAL );
struct ureg mvinv[3];
register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 2,
@@ -743,7 +740,7 @@ static struct ureg get_eye_normal( struct tnl_program *p )
static void build_hpos( struct tnl_program *p )
{
- struct ureg pos = register_input( p, BRW_ATTRIB_POS );
+ struct ureg pos = register_input( p, VERT_ATTRIB_POS );
struct ureg hpos = register_output( p, VERT_RESULT_HPOS );
struct ureg mvp[4];
@@ -787,9 +784,9 @@ static struct ureg get_material( struct tnl_program *p, GLuint side,
GLuint attrib = material_attrib(side, property);
if (p->color_materials & (1<<attrib))
- return register_input(p, BRW_ATTRIB_COLOR0);
+ return register_input(p, VERT_ATTRIB_COLOR0);
else if (p->materials & (1<<attrib))
- return register_input( p, attrib + BRW_ATTRIB_MAT_FRONT_AMBIENT );
+ return register_input( p, attrib + _TNL_ATTRIB_MAT_FRONT_AMBIENT );
else
return register_param3( p, STATE_MATERIAL, side, property );
}
@@ -1157,7 +1154,7 @@ static void build_fog( struct tnl_program *p )
input = swizzle1(get_eye_position(p), Z);
}
else {
- input = swizzle1(register_input(p, BRW_ATTRIB_FOG), X);
+ input = swizzle1(register_input(p, VERT_ATTRIB_FOG), X);
}
if (p->state->fog_option &&
@@ -1299,7 +1296,7 @@ static void build_texture_transform( struct tnl_program *p )
for (j = 0; j < 4; j++) {
switch (modes[j]) {
case TXG_OBJ_LINEAR: {
- struct ureg obj = register_input(p, BRW_ATTRIB_POS);
+ struct ureg obj = register_input(p, VERT_ATTRIB_POS);
struct ureg plane =
register_param3(p, STATE_TEXGEN, i,
STATE_TEXGEN_OBJECT_S + j);
@@ -1348,7 +1345,7 @@ static void build_texture_transform( struct tnl_program *p )
}
if (copy_mask) {
- struct ureg in = register_input(p, BRW_ATTRIB_TEX0+i);
+ struct ureg in = register_input(p, VERT_ATTRIB_TEX0+i);
emit_op1(p, OPCODE_MOV, out_texgen, copy_mask, in );
}
}
@@ -1357,7 +1354,7 @@ static void build_texture_transform( struct tnl_program *p )
struct ureg texmat[4];
struct ureg in = (!is_undef(out_texgen) ?
out_texgen :
- register_input(p, BRW_ATTRIB_TEX0+i));
+ register_input(p, VERT_ATTRIB_TEX0+i));
if (PREFER_DP4) {
register_matrix_param6( p, STATE_MATRIX, STATE_TEXTURE, i,
0, 3, STATE_MATRIX, texmat );
@@ -1373,7 +1370,7 @@ static void build_texture_transform( struct tnl_program *p )
release_temps(p);
}
else {
- emit_passthrough(p, BRW_ATTRIB_TEX0+i, VERT_RESULT_TEX0+i);
+ emit_passthrough(p, VERT_ATTRIB_TEX0+i, VERT_RESULT_TEX0+i);
}
}
}
@@ -1425,10 +1422,10 @@ static void build_tnl_program( struct tnl_program *p )
build_lighting(p);
else {
if (p->state->fragprog_inputs_read & FRAG_BIT_COL0)
- emit_passthrough(p, BRW_ATTRIB_COLOR0, VERT_RESULT_COL0);
+ emit_passthrough(p, VERT_ATTRIB_COLOR0, VERT_RESULT_COL0);
if (p->state->fragprog_inputs_read & FRAG_BIT_COL1)
- emit_passthrough(p, BRW_ATTRIB_COLOR1, VERT_RESULT_COL1);
+ emit_passthrough(p, VERT_ATTRIB_COLOR1, VERT_RESULT_COL1);
}
}
@@ -1628,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 ac09754e3ae..786f30e641e 100644
--- a/src/mesa/drivers/dri/i965/brw_vtbl.c
+++ b/src/mesa/drivers/dri/i965/brw_vtbl.c
@@ -46,8 +46,6 @@
#include "brw_state.h"
#include "brw_draw.h"
-#include "brw_exec.h"
-#include "brw_save.h"
#include "brw_state.h"
#include "brw_aub.h"
#include "brw_fallback.h"
@@ -68,9 +66,6 @@ static void brw_destroy_context( struct intel_context *intel )
brw_destroy_state(brw);
brw_draw_destroy( brw );
- brw_exec_destroy( ctx );
- brw_save_destroy( ctx );
-
brw_ProgramCacheDestroy( ctx );
brw_FrameBufferTexDestroy( brw );
}
@@ -166,10 +161,7 @@ static GLuint brw_flush_cmd( void )
static void brw_invalidate_state( struct intel_context *intel, GLuint new_state )
{
- GLcontext *ctx = &intel->ctx;
-
- brw_exec_invalidate_state(ctx, new_state);
- brw_save_invalidate_state(ctx, new_state);
+ /* nothing */
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c
index 4707a709e77..ff5cb31bdd1 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/bufmgr.h b/src/mesa/drivers/dri/i965/bufmgr.h
index 6932522d3d3..e748c0d6d0b 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 ed88ab3797a..24ee11edd8c 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 c8c5bf93c95..173d1d5b6c2 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)
diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c
index d13e287fa76..34560e4353e 100644
--- a/src/mesa/drivers/dri/i965/intel_context.c
+++ b/src/mesa/drivers/dri/i965/intel_context.c
@@ -33,11 +33,12 @@
#include "extensions.h"
#include "framebuffer.h"
#include "imports.h"
+#include "points.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/t_pipeline.h"
#include "tnl/t_vertex.h"
@@ -60,6 +61,7 @@
#include "bufmgr.h"
#include "utils.h"
+#include "vblank.h"
#ifndef INTEL_DEBUG
int INTEL_DEBUG = (0);
#endif
@@ -70,6 +72,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
@@ -84,11 +87,6 @@ int INTEL_DEBUG = (0);
int VERBOSE = 0;
#endif
-#if DEBUG_LOCKING
-char *prevLockFile;
-int prevLockLine;
-#endif
-
/***************************************
* Mesa's Driver Functions
***************************************/
@@ -182,7 +180,16 @@ const struct dri_extension card_extensions[] =
{ NULL, NULL }
};
+const struct dri_extension arb_oc_extension =
+ { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions};
+void intelInitExtensions(GLcontext *ctx, GLboolean enable_imaging)
+{
+ struct intel_context *intel = ctx?intel_context(ctx):NULL;
+ driInitExtensions(ctx, card_extensions, enable_imaging);
+ if (!ctx || intel->intelScreen->drmMinor >= 8)
+ driInitSingleExtension (ctx, &arb_oc_extension);
+}
static const struct dri_debug_control debug_control[] =
{
@@ -216,7 +223,7 @@ static void intelInvalidateState( GLcontext *ctx, GLuint new_state )
_swrast_InvalidateState( ctx, new_state );
_swsetup_InvalidateState( ctx, new_state );
- _ac_InvalidateState( ctx, new_state );
+ _vbo_InvalidateState( ctx, new_state );
_tnl_InvalidateState( ctx, new_state );
_tnl_invalidate_vertex_state( ctx, new_state );
@@ -241,6 +248,37 @@ 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 );
+ drmI830MMIO io = {
+ .read_write = MMIO_READ,
+ .reg = MMIO_REGS_PS_DEPTH_COUNT,
+ .data = &q->Result
+ };
+ intel->stats_wm++;
+ intelFinish(&intel->ctx);
+ drmCommandRead(intel->driFd, DRM_I830_MMIO, &io, sizeof(io));
+}
+
+static void
+intelEndQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q)
+{
+ struct intel_context *intel = intel_context( ctx );
+ GLuint64EXT tmp;
+ drmI830MMIO io = {
+ .read_write = MMIO_READ,
+ .reg = MMIO_REGS_PS_DEPTH_COUNT,
+ .data = &tmp
+ };
+ intelFinish(&intel->ctx);
+ drmCommandRead(intel->driFd, DRM_I830_MMIO, &io, sizeof(io));
+ q->Result = tmp - q->Result;
+ q->Ready = GL_TRUE;
+ intel->stats_wm--;
+}
+
void intelInitDriverFunctions( struct dd_function_table *functions )
{
@@ -250,6 +288,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:
@@ -292,6 +332,11 @@ GLboolean intelInitContext( struct intel_context *intel,
intel->driScreen = sPriv;
intel->sarea = saPriv;
+ driParseConfigFiles (&intel->optionCache, &intelScreen->optionCache,
+ intel->driScreen->myNum, "i965");
+
+ intel->vblank_flags = (intel->intelScreen->irq_active != 0)
+ ? driGetDefaultVBlankFlags(&intel->optionCache) : VBLANK_FLAG_NO_IRQ;
ctx->Const.MaxTextureMaxAnisotropy = 2.0;
@@ -327,7 +372,7 @@ GLboolean intelInitContext( struct intel_context *intel,
/* Initialize the software rasterizer and helper modules. */
_swrast_CreateContext( ctx );
- _ac_CreateContext( ctx );
+ _vbo_CreateContext( ctx );
_tnl_CreateContext( ctx );
_swsetup_CreateContext( ctx );
@@ -374,9 +419,7 @@ GLboolean intelInitContext( struct intel_context *intel,
_mesa_printf("IRQs not active. Exiting\n");
exit(1);
}
-
- driInitExtensions( ctx, card_extensions,
- GL_TRUE );
+ intelInitExtensions(ctx, GL_TRUE);
INTEL_DEBUG = driParseDebugString( getenv( "INTEL_DEBUG" ),
debug_control );
@@ -403,8 +446,8 @@ GLboolean intelInitContext( struct intel_context *intel,
intelScreen->cpp,
intelScreen->front.pitch / intelScreen->cpp,
intelScreen->height,
- GL_FALSE);
-
+ intelScreen->front.size,
+ intelScreen->front.tiled != 0);
intel->back_region =
intel_region_create_static(intel,
@@ -414,7 +457,8 @@ GLboolean intelInitContext( struct intel_context *intel,
intelScreen->cpp,
intelScreen->back.pitch / intelScreen->cpp,
intelScreen->height,
- (INTEL_DEBUG & DEBUG_TILE) ? 0 : 1);
+ intelScreen->back.size,
+ intelScreen->back.tiled != 0);
/* Still assuming front.cpp == depth.cpp
*
@@ -430,7 +474,8 @@ GLboolean intelInitContext( struct intel_context *intel,
intelScreen->cpp,
intelScreen->depth.pitch / intelScreen->cpp,
intelScreen->height,
- (INTEL_DEBUG & DEBUG_TILE) ? 0 : 1);
+ intelScreen->depth.size,
+ intelScreen->depth.tiled != 0);
intel_bufferobj_init( intel );
intel->batch = intel_batchbuffer_alloc( intel );
@@ -472,7 +517,7 @@ void intelDestroyContext(__DRIcontextPrivate *driContextPriv)
release_texture_heaps = (intel->ctx.Shared->RefCount == 1);
_swsetup_DestroyContext (&intel->ctx);
_tnl_DestroyContext (&intel->ctx);
- _ac_DestroyContext (&intel->ctx);
+ _vbo_DestroyContext (&intel->ctx);
_swrast_DestroyContext (&intel->ctx);
intel->Fallback = 0; /* don't call _swrast_Flush later */
@@ -521,6 +566,9 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv,
if ( intel->driDrawable != driDrawPriv ) {
/* Shouldn't the readbuffer be stored also? */
+ driDrawableInitVBlank( driDrawPriv, intel->vblank_flags,
+ &intel->vbl_seq );
+
intel->driDrawable = driDrawPriv;
intelWindowMoved( intel );
}
@@ -655,3 +703,4 @@ void UNLOCK_HARDWARE( struct intel_context *intel )
_glthread_UNLOCK_MUTEX(lockMutex);
}
+
diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h
index 8367a957109..a0f392f9353 100644
--- a/src/mesa/drivers/dri/i965/intel_context.h
+++ b/src/mesa/drivers/dri/i965/intel_context.h
@@ -177,6 +177,7 @@ struct intel_context
GLuint second_last_swap_fence;
GLboolean aub_wrap;
+ GLuint stats_wm;
struct intel_batchbuffer *batch;
@@ -499,6 +500,7 @@ void intelBitmap(GLcontext * ctx,
const struct gl_pixelstore_attrib *unpack,
const GLubyte * pixels);
+void intelInitExtensions(GLcontext *ctx, GLboolean enable_imaging);
#define _NEW_WINDOW_POS 0x40000000
@@ -521,6 +523,5 @@ static inline struct intel_texture_image *intel_texture_image( struct gl_texture
return (struct intel_texture_image *)img;
}
-
#endif
diff --git a/src/mesa/drivers/dri/i965/intel_ioctl.c b/src/mesa/drivers/dri/i965/intel_ioctl.c
index f3b76db2153..0a8e976f706 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 )
{
@@ -88,7 +108,8 @@ void intelWaitIrq( struct intel_context *intel, int seq )
/* This seems quite often to return before it should!?!
*/
- } while (ret == -EAGAIN || ret == -EINTR || (ret == -EBUSY && lastdispatch != intel->sarea->last_dispatch) || (ret == 0 && seq > intel->sarea->last_dispatch));
+ } while (ret == -EAGAIN || ret == -EINTR || (ret == -EBUSY && lastdispatch != intel->sarea->last_dispatch) || (ret == 0 && seq > intel->sarea->last_dispatch)
+ || (ret == 0 && intel->sarea->last_dispatch - seq >= (1 << 24)));
if ( ret ) {
@@ -140,7 +161,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,
@@ -172,5 +197,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_regions.c b/src/mesa/drivers/dri/i965/intel_regions.c
index 398b0a0a3b5..835ecdd7257 100644
--- a/src/mesa/drivers/dri/i965/intel_regions.c
+++ b/src/mesa/drivers/dri/i965/intel_regions.c
@@ -122,10 +122,10 @@ struct intel_region *intel_region_create_static( struct intel_context *intel,
GLuint cpp,
GLuint pitch,
GLuint height,
+ GLuint size,
GLboolean tiled )
{
struct intel_region *region = calloc(sizeof(*region), 1);
- GLuint size = cpp * pitch * height;
GLint pool;
DBG("%s\n", __FUNCTION__);
diff --git a/src/mesa/drivers/dri/i965/intel_regions.h b/src/mesa/drivers/dri/i965/intel_regions.h
index 2413f0de33c..d2235f1275b 100644
--- a/src/mesa/drivers/dri/i965/intel_regions.h
+++ b/src/mesa/drivers/dri/i965/intel_regions.h
@@ -78,6 +78,7 @@ struct intel_region *intel_region_create_static( struct intel_context *intel,
GLuint cpp,
GLuint pitch,
GLuint height,
+ GLuint size,
GLboolean tiled );
/* Map/unmap regions. This is refcounted also:
diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c
index 56e6a792fa2..08f0bb340f7 100644
--- a/src/mesa/drivers/dri/i965/intel_screen.c
+++ b/src/mesa/drivers/dri/i965/intel_screen.c
@@ -38,6 +38,7 @@
#include "intel_screen.h"
+#include "intel_context.h"
#include "intel_tex.h"
#include "intel_span.h"
#include "intel_ioctl.h"
@@ -61,8 +62,6 @@ const GLuint __driNConfigOptions = 4;
static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
#endif /*USE_NEW_INTERFACE*/
-extern const struct dri_extension card_extensions[];
-
/**
* Map all the memory regions described by the screen.
* \return GL_TRUE if success, GL_FALSE if error.
@@ -230,16 +229,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 +251,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,
@@ -683,7 +686,6 @@ void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIsc
(dri_priv->cpp == 2) ? 16 : 24,
(dri_priv->cpp == 2) ? 0 : 8,
GL_TRUE );
-
/* Calling driInitExtensions here, with a NULL context pointer, does not actually
* enable the extensions. It just makes sure that all the dispatch offsets for all
* the extensions that *might* be enables are known. This is needed because the
@@ -692,7 +694,7 @@ void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIsc
*
* Hello chicken. Hello egg. How are you two today?
*/
- driInitExtensions( NULL, card_extensions, GL_FALSE );
+ intelInitExtensions(NULL, GL_FALSE);
}
return (void *) psp;
diff --git a/src/mesa/drivers/dri/i965/intel_screen.h b/src/mesa/drivers/dri/i965/intel_screen.h
index 094158afd85..bf9a716082d 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 00000000000..fe61b441945
--- /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/server/i830_common.h b/src/mesa/drivers/dri/i965/server/i830_common.h
index e3bbdc79070..f320378c2a5 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 00000000000..f3564802171
--- /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 <[email protected]>
+ * Michel Dänzer <[email protected]>
+ */
+
+#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 00000000000..1e37f8f525f
--- /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 <[email protected]>
+ * Michel Dänzer <[email protected]>
+ */
+
+#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 2ab1cf2617e..5a6c301da2d 100644
--- a/src/mesa/drivers/dri/mach64/mach64_context.c
+++ b/src/mesa/drivers/dri/mach64/mach64_context.c
@@ -38,7 +38,7 @@
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
@@ -225,7 +225,7 @@ GLboolean mach64CreateContext( const __GLcontextModes *glVisual,
/* Initialize the software rasterizer and helper modules.
*/
_swrast_CreateContext( ctx );
- _ac_CreateContext( ctx );
+ _vbo_CreateContext( ctx );
_tnl_CreateContext( ctx );
_swsetup_CreateContext( ctx );
@@ -278,7 +278,7 @@ void mach64DestroyContext( __DRIcontextPrivate *driContextPriv )
_swsetup_DestroyContext( mmesa->glCtx );
_tnl_DestroyContext( mmesa->glCtx );
- _ac_DestroyContext( mmesa->glCtx );
+ _vbo_DestroyContext( mmesa->glCtx );
_swrast_DestroyContext( mmesa->glCtx );
if (release_texture_heaps) {
diff --git a/src/mesa/drivers/dri/mach64/mach64_state.c b/src/mesa/drivers/dri/mach64/mach64_state.c
index d4804a2c550..667a3945206 100644
--- a/src/mesa/drivers/dri/mach64/mach64_state.c
+++ b/src/mesa/drivers/dri/mach64/mach64_state.c
@@ -40,7 +40,7 @@
#include "enums.h"
#include "colormac.h"
#include "swrast/swrast.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "swrast_setup/swrast_setup.h"
@@ -1023,7 +1023,7 @@ static void mach64DDInvalidateState( GLcontext *ctx, GLuint new_state )
{
_swrast_InvalidateState( ctx, new_state );
_swsetup_InvalidateState( ctx, new_state );
- _ac_InvalidateState( ctx, new_state );
+ _vbo_InvalidateState( ctx, new_state );
_tnl_InvalidateState( ctx, new_state );
MACH64_CONTEXT(ctx)->NewGLState |= new_state;
}
diff --git a/src/mesa/drivers/dri/mga/mga_xmesa.c b/src/mesa/drivers/dri/mga/mga_xmesa.c
index f02913c6af2..f024f73eb6a 100644
--- a/src/mesa/drivers/dri/mga/mga_xmesa.c
+++ b/src/mesa/drivers/dri/mga/mga_xmesa.c
@@ -45,7 +45,7 @@
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/t_pipeline.h"
@@ -593,7 +593,7 @@ mgaCreateContext( const __GLcontextModes *mesaVis,
/* Initialize the software rasterizer and helper modules.
*/
_swrast_CreateContext( ctx );
- _ac_CreateContext( ctx );
+ _vbo_CreateContext( ctx );
_tnl_CreateContext( ctx );
_swsetup_CreateContext( ctx );
@@ -676,7 +676,7 @@ mgaDestroyContext(__DRIcontextPrivate *driContextPriv)
release_texture_heaps = (mmesa->glCtx->Shared->RefCount == 1);
_swsetup_DestroyContext( mmesa->glCtx );
_tnl_DestroyContext( mmesa->glCtx );
- _ac_DestroyContext( mmesa->glCtx );
+ _vbo_DestroyContext( mmesa->glCtx );
_swrast_DestroyContext( mmesa->glCtx );
mgaFreeVB( mmesa->glCtx );
diff --git a/src/mesa/drivers/dri/mga/mgastate.c b/src/mesa/drivers/dri/mga/mgastate.c
index 075fd348cf4..c20a76f29ef 100644
--- a/src/mesa/drivers/dri/mga/mgastate.c
+++ b/src/mesa/drivers/dri/mga/mgastate.c
@@ -41,7 +41,7 @@
#include "mgaregs.h"
#include "swrast/swrast.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "tnl/t_context.h"
#include "tnl/t_pipeline.h"
@@ -1042,7 +1042,7 @@ static void mgaDDInvalidateState( GLcontext *ctx, GLuint new_state )
{
_swrast_InvalidateState( ctx, new_state );
_swsetup_InvalidateState( ctx, new_state );
- _ac_InvalidateState( ctx, new_state );
+ _vbo_InvalidateState( ctx, new_state );
_tnl_InvalidateState( ctx, new_state );
MGA_CONTEXT(ctx)->NewGLState |= new_state;
}
diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile
new file mode 100644
index 00000000000..20d2de5eefb
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/Makefile
@@ -0,0 +1,53 @@
+# src/mesa/drivers/dri/nouveau/Makefile
+
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = nouveau_dri.so
+
+MINIGLX_SOURCES =
+
+DRIVER_SOURCES = \
+ nouveau_bufferobj.c \
+ nouveau_buffers.c \
+ nouveau_card.c \
+ nouveau_context.c \
+ nouveau_driver.c \
+ nouveau_fifo.c \
+ nouveau_lock.c \
+ nouveau_object.c \
+ nouveau_screen.c \
+ nouveau_span.c \
+ nouveau_state.c \
+ nouveau_state_cache.c \
+ nouveau_shader.c \
+ nouveau_shader_0.c \
+ nouveau_shader_1.c \
+ nouveau_shader_2.c \
+ nouveau_tex.c \
+ nouveau_swtcl.c \
+ nouveau_sync.c \
+ nouveau_query.c \
+ nv04_state.c \
+ nv04_swtcl.c \
+ nv10_state.c \
+ nv10_swtcl.c \
+ nv20_state.c \
+ nv20_vertprog.c \
+ nv30_state.c \
+ nv30_fragprog.c \
+ nv30_vertprog.c \
+ nv40_fragprog.c \
+ nv40_vertprog.c \
+ nv50_state.c
+
+C_SOURCES = \
+ $(COMMON_SOURCES) \
+ $(DRIVER_SOURCES)
+
+ASM_SOURCES =
+
+
+include ../Makefile.template
+
+symlinks:
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c
new file mode 100644
index 00000000000..684ed7b017d
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c
@@ -0,0 +1,616 @@
+#include "bufferobj.h"
+#include "enums.h"
+
+#include "nouveau_bufferobj.h"
+#include "nouveau_buffers.h"
+#include "nouveau_context.h"
+#include "nouveau_drm.h"
+#include "nouveau_object.h"
+#include "nouveau_msg.h"
+
+#define NOUVEAU_MEM_FREE(mem) do { \
+ nouveau_mem_free(ctx, (mem)); \
+ (mem) = NULL; \
+} while(0)
+
+#define DEBUG(fmt,args...) do { \
+ if (NOUVEAU_DEBUG & DEBUG_BUFFEROBJ) { \
+ fprintf(stderr, "%s: "fmt, __func__, ##args); \
+ } \
+} while(0)
+
+static GLboolean
+nouveau_bo_download_from_screen(GLcontext *ctx, GLuint offset, GLuint size,
+ struct gl_buffer_object *bo)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo;
+ nouveau_mem *in_mem;
+
+ DEBUG("bo=%p, offset=%d, size=%d\n", bo, offset, size);
+
+ /* If there's a permanent backing store, blit directly into it */
+ if (nbo->cpu_mem) {
+ if (nbo->cpu_mem != nbo->gpu_mem) {
+ DEBUG("..cpu_mem\n");
+ nouveau_memformat_flat_emit(ctx, nbo->cpu_mem,
+ nbo->gpu_mem,
+ offset, offset, size);
+ }
+ } else {
+ DEBUG("..sys_mem\n");
+ in_mem = nouveau_mem_alloc(ctx, NOUVEAU_MEM_AGP, size, 0);
+ if (in_mem) {
+ DEBUG("....via AGP\n");
+ /* otherwise, try blitting to faster memory and
+ * copying from there
+ */
+ nouveau_memformat_flat_emit(ctx, in_mem, nbo->gpu_mem,
+ 0, offset, size);
+ nouveau_notifier_wait_nop(ctx, nmesa->syncNotifier,
+ NvSubMemFormat);
+ _mesa_memcpy(nbo->cpu_mem_sys + offset,
+ in_mem->map, size);
+ NOUVEAU_MEM_FREE(in_mem);
+ } else {
+ DEBUG("....direct VRAM copy\n");
+ /* worst case, copy directly from vram */
+ _mesa_memcpy(nbo->cpu_mem_sys + offset,
+ nbo->gpu_mem + offset,
+ size);
+ }
+ }
+
+ return GL_TRUE;
+}
+
+static GLboolean
+nouveau_bo_upload_to_screen(GLcontext *ctx, GLuint offset, GLuint size,
+ struct gl_buffer_object *bo)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo;
+ nouveau_mem *out_mem;
+
+ DEBUG("bo=%p, offset=%d, size=%d\n", bo, offset, size);
+
+ if (nbo->cpu_mem) {
+ if (nbo->cpu_mem != nbo->gpu_mem) {
+ DEBUG("..cpu_mem\n");
+ nouveau_memformat_flat_emit(ctx, nbo->gpu_mem,
+ nbo->cpu_mem,
+ offset, offset, size);
+ }
+ } else {
+ out_mem = nouveau_mem_alloc(ctx, NOUVEAU_MEM_AGP |
+ NOUVEAU_MEM_MAPPED,
+ size, 0);
+ if (out_mem) {
+ DEBUG("....via AGP\n");
+ _mesa_memcpy(out_mem->map,
+ nbo->cpu_mem_sys + offset, size);
+ nouveau_memformat_flat_emit(ctx, nbo->gpu_mem, out_mem,
+ offset, 0, size);
+ nouveau_notifier_wait_nop(ctx, nmesa->syncNotifier,
+ NvSubMemFormat);
+ NOUVEAU_MEM_FREE(out_mem);
+ } else {
+ DEBUG("....direct VRAM copy\n");
+ _mesa_memcpy(nbo->gpu_mem->map + offset,
+ nbo->cpu_mem_sys + offset,
+ size);
+ }
+ }
+
+ return GL_TRUE;
+}
+
+GLboolean
+nouveau_bo_move_in(GLcontext *ctx, struct gl_buffer_object *bo)
+{
+ nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo;
+
+ DEBUG("bo=%p\n", bo);
+
+ if (bo->OnCard)
+ return GL_TRUE;
+ assert(nbo->gpu_mem_flags);
+
+ nbo->gpu_mem = nouveau_mem_alloc(ctx, nbo->gpu_mem_flags |
+ NOUVEAU_MEM_MAPPED,
+ bo->Size, 0);
+ assert(nbo->gpu_mem);
+
+ if (nbo->cpu_mem_flags) {
+ if ((nbo->cpu_mem_flags|NOUVEAU_MEM_MAPPED) != nbo->gpu_mem->type) {
+ DEBUG("..need cpu_mem buffer\n");
+
+ nbo->cpu_mem = nouveau_mem_alloc(ctx,
+ nbo->cpu_mem_flags |
+ NOUVEAU_MEM_MAPPED,
+ bo->Size, 0);
+
+ if (nbo->cpu_mem) {
+ DEBUG("....alloc ok, kill sys_mem buffer\n");
+ _mesa_memcpy(nbo->cpu_mem->map,
+ nbo->cpu_mem_sys, bo->Size);
+ FREE(nbo->cpu_mem_sys);
+ }
+ } else {
+ DEBUG("..cpu direct access to GPU buffer\n");
+ nbo->cpu_mem = nbo->gpu_mem;
+ }
+ }
+ nouveau_bo_upload_to_screen(ctx, 0, bo->Size, bo);
+
+ bo->OnCard = GL_TRUE;
+ return GL_TRUE;
+}
+
+GLboolean
+nouveau_bo_move_out(GLcontext *ctx, struct gl_buffer_object *bo)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo;
+ GLuint nr_dirty;
+
+ DEBUG("bo=%p\n", bo);
+ if (!bo->OnCard)
+ return GL_TRUE;
+
+ nr_dirty = nouveau_bo_download_dirty(ctx, bo);
+ if (nbo->cpu_mem) {
+ if (nr_dirty && nbo->cpu_mem != nbo->gpu_mem)
+ nouveau_notifier_wait_nop(ctx, nmesa->syncNotifier,
+ NvSubMemFormat);
+ DEBUG("..destroy cpu_mem buffer\n");
+ nbo->cpu_mem_sys = malloc(bo->Size);
+ assert(nbo->cpu_mem_sys);
+ _mesa_memcpy(nbo->cpu_mem_sys, nbo->cpu_mem->map, bo->Size);
+ if (nbo->cpu_mem == nbo->gpu_mem)
+ nbo->cpu_mem = NULL;
+ else
+ NOUVEAU_MEM_FREE(nbo->cpu_mem);
+ }
+ NOUVEAU_MEM_FREE(nbo->gpu_mem);
+
+ bo->OnCard = GL_FALSE;
+ return GL_TRUE;
+}
+
+static void
+nouveau_bo_choose_storage_method(GLcontext *ctx, GLenum usage,
+ struct gl_buffer_object *bo)
+{
+ nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo;
+ GLuint gpu_type = 0;
+ GLuint cpu_type = 0;
+
+ switch (usage) {
+ /* Client source, changes often, used by GL many times */
+ case GL_DYNAMIC_DRAW_ARB:
+ gpu_type = NOUVEAU_MEM_AGP | NOUVEAU_MEM_FB_ACCEPTABLE;
+ cpu_type = NOUVEAU_MEM_AGP;
+ break;
+ /* GL source, changes often, client reads many times */
+ case GL_DYNAMIC_READ_ARB:
+ /* Client source, specified once, used by GL many times */
+ case GL_STATIC_DRAW_ARB:
+ /* GL source, specified once, client reads many times */
+ case GL_STATIC_READ_ARB:
+ /* Client source, specified once, used by GL a few times */
+ case GL_STREAM_DRAW_ARB:
+ /* GL source, specified once, client reads a few times */
+ case GL_STREAM_READ_ARB:
+ /* GL source, changes often, used by GL many times*/
+ case GL_DYNAMIC_COPY_ARB:
+ /* GL source, specified once, used by GL many times */
+ case GL_STATIC_COPY_ARB:
+ /* GL source, specified once, used by GL a few times */
+ case GL_STREAM_COPY_ARB:
+ gpu_type = NOUVEAU_MEM_FB;
+ break;
+ default:
+ assert(0);
+ }
+
+ nbo->gpu_mem_flags = gpu_type;
+ nbo->cpu_mem_flags = cpu_type;
+ nbo->usage = usage;
+}
+
+void
+nouveau_bo_init_storage(GLcontext *ctx, GLuint valid_gpu_access,
+ GLsizeiptrARB size,
+ const GLvoid *data,
+ GLenum usage,
+ struct gl_buffer_object *bo)
+{
+ nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo;
+
+ DEBUG("bo=%p\n", bo);
+
+ /* Free up previous buffers if we can't reuse them */
+ if (nbo->usage != usage ||
+ (nbo->gpu_mem && (nbo->gpu_mem->size != size))) {
+ if (nbo->cpu_mem_sys)
+ FREE(nbo->cpu_mem_sys);
+ if (nbo->cpu_mem) {
+ if (nbo->cpu_mem != nbo->gpu_mem)
+ NOUVEAU_MEM_FREE(nbo->cpu_mem);
+ else
+ nbo->cpu_mem = NULL;
+ }
+ if (nbo->gpu_mem)
+ NOUVEAU_MEM_FREE(nbo->gpu_mem);
+
+ bo->OnCard = GL_FALSE;
+ nbo->cpu_mem_sys = calloc(1, size);
+ }
+
+ nouveau_bo_choose_storage_method(ctx, usage, bo);
+ /* Force off flags that may not be ok for a given buffer */
+ nbo->gpu_mem_flags &= valid_gpu_access;
+
+ bo->Usage = usage;
+ bo->Size = size;
+
+ if (data) {
+ GLvoid *map = nouveau_bo_map(ctx, GL_WRITE_ONLY_ARB, bo);
+ _mesa_memcpy(map, data, size);
+ nouveau_bo_dirty_all(ctx, GL_FALSE, bo);
+ nouveau_bo_unmap(ctx, bo);
+ }
+}
+
+void *
+nouveau_bo_map(GLcontext *ctx, GLenum access, struct gl_buffer_object *bo)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo;
+
+ DEBUG("bo=%p, access=%s\n", bo, _mesa_lookup_enum_by_nr(access));
+
+ if (bo->OnCard &&
+ (access == GL_READ_ONLY_ARB || access == GL_READ_WRITE_ARB)) {
+ GLuint nr_dirty;
+
+ DEBUG("..on card\n");
+ nr_dirty = nouveau_bo_download_dirty(ctx, bo);
+
+ /* nouveau_bo_download_dirty won't wait unless it needs to
+ * free a temp buffer, which isn't the case if cpu_mem is
+ * present.
+ */
+ if (nr_dirty && nbo->cpu_mem && nbo->cpu_mem != nbo->gpu_mem)
+ nouveau_notifier_wait_nop(ctx, nmesa->syncNotifier,
+ NvSubMemFormat);
+ }
+
+ if (nbo->cpu_mem) {
+ DEBUG("..access via cpu_mem\n");
+ return nbo->cpu_mem->map;
+ } else {
+ DEBUG("..access via cpu_mem_sys\n");
+ return nbo->cpu_mem_sys;
+ }
+}
+
+void
+nouveau_bo_unmap(GLcontext *ctx, struct gl_buffer_object *bo)
+{
+ DEBUG("unmap bo=%p\n", bo);
+}
+
+uint32_t
+nouveau_bo_gpu_ref(GLcontext *ctx, struct gl_buffer_object *bo)
+{
+ nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo;
+
+ assert(nbo->mapped == GL_FALSE);
+
+ DEBUG("gpu_ref\n");
+
+ if (!bo->OnCard) {
+ nouveau_bo_move_in(ctx, bo);
+ bo->OnCard = GL_TRUE;
+ }
+ nouveau_bo_upload_dirty(ctx, bo);
+
+ return nouveau_mem_gpu_offset_get(ctx, nbo->gpu_mem);
+}
+
+void
+nouveau_bo_dirty_linear(GLcontext *ctx, GLboolean on_card,
+ uint32_t offset, uint32_t size,
+ struct gl_buffer_object *bo)
+{
+ nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo;
+ nouveau_bufferobj_dirty *dirty;
+ uint32_t start = offset;
+ uint32_t end = offset + size;
+ int i;
+
+ if (nbo->cpu_mem == nbo->gpu_mem)
+ return;
+
+ dirty = on_card ? &nbo->gpu_dirty : &nbo->cpu_dirty;
+
+ DEBUG("on_card=%d, offset=%d, size=%d, bo=%p\n",
+ on_card, offset, size, bo);
+
+ for (i=0; i<dirty->nr_dirty; i++) {
+ nouveau_bufferobj_region *r = &dirty->dirty[i];
+
+ /* already dirty */
+ if (start >= r->start && end <= r->end) {
+ DEBUG("..already dirty\n");
+ return;
+ }
+
+ /* add to the end of a region */
+ if (start >= r->start && start <= r->end) {
+ if (end > r->end) {
+ DEBUG("..extend end of region\n");
+ r->end = end;
+ return;
+ }
+ }
+
+ /* add to the start of a region */
+ if (start < r->start && end >= r->end) {
+ DEBUG("..extend start of region\n");
+ r->start = start;
+ /* .. and to the end */
+ if (end > r->end) {
+ DEBUG("....and end\n");
+ r->end = end;
+ }
+ return;
+ }
+ }
+
+ /* new region */
+ DEBUG("..new dirty\n");
+ dirty->nr_dirty++;
+ dirty->dirty = realloc(dirty->dirty,
+ sizeof(nouveau_bufferobj_region) *
+ dirty->nr_dirty);
+ dirty->dirty[dirty->nr_dirty - 1].start = start;
+ dirty->dirty[dirty->nr_dirty - 1].end = end;
+}
+
+void
+nouveau_bo_dirty_all(GLcontext *ctx, GLboolean on_card,
+ struct gl_buffer_object *bo)
+{
+ nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo;
+ nouveau_bufferobj_dirty *dirty;
+
+ dirty = on_card ? &nbo->gpu_dirty : &nbo->cpu_dirty;
+
+ DEBUG("dirty all\n");
+ if (dirty->nr_dirty) {
+ FREE(dirty->dirty);
+ dirty->dirty = NULL;
+ dirty->nr_dirty = 0;
+ }
+
+ nouveau_bo_dirty_linear(ctx, on_card, 0, bo->Size, bo);
+}
+
+GLuint
+nouveau_bo_upload_dirty(GLcontext *ctx, struct gl_buffer_object *bo)
+{
+ nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo;
+ nouveau_bufferobj_dirty *dirty = &nbo->cpu_dirty;
+ GLuint nr_dirty;
+ int i;
+
+ nr_dirty = dirty->nr_dirty;
+ if (!nr_dirty) {
+ DEBUG("clean\n");
+ return nr_dirty;
+ }
+
+ for (i=0; i<nr_dirty; i++) {
+ nouveau_bufferobj_region *r = &dirty->dirty[i];
+
+ DEBUG("dirty %d: o=0x%08x, s=0x%08x\n",
+ i, r->start, r->end - r->start);
+ nouveau_bo_upload_to_screen(ctx,
+ r->start, r->end - r->start, bo);
+ }
+
+ FREE(dirty->dirty);
+ dirty->dirty = NULL;
+ dirty->nr_dirty = 0;
+
+ return nr_dirty;
+}
+
+GLuint
+nouveau_bo_download_dirty(GLcontext *ctx, struct gl_buffer_object *bo)
+{
+ nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo;
+ nouveau_bufferobj_dirty *dirty = &nbo->gpu_dirty;
+ GLuint nr_dirty;
+ int i;
+
+ nr_dirty = dirty->nr_dirty;
+ if (nr_dirty) {
+ DEBUG("clean\n");
+ return nr_dirty;
+ }
+
+ for (i=0; i<nr_dirty; i++) {
+ nouveau_bufferobj_region *r = &dirty->dirty[i];
+
+ DEBUG("dirty %d: o=0x%08x, s=0x%08x\n",
+ i, r->start, r->end - r->start);
+ nouveau_bo_download_from_screen(ctx,
+ r->start,
+ r->end - r->start, bo);
+ }
+
+ FREE(dirty->dirty);
+ dirty->dirty = NULL;
+ dirty->nr_dirty = 0;
+
+ return nr_dirty;
+}
+
+static void
+nouveauBindBuffer(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj)
+{
+}
+
+static struct gl_buffer_object *
+nouveauNewBufferObject(GLcontext *ctx, GLuint buffer, GLenum target)
+{
+ nouveau_buffer_object *nbo;
+
+ nbo = CALLOC_STRUCT(nouveau_buffer_object_t);
+ if (nbo)
+ _mesa_initialize_buffer_object(&nbo->mesa, buffer, target);
+ DEBUG("bo=%p\n", nbo);
+
+ return nbo ? &nbo->mesa : NULL;
+}
+
+static void
+nouveauDeleteBuffer(GLcontext *ctx, struct gl_buffer_object *obj)
+{
+ nouveau_buffer_object *nbo = (nouveau_buffer_object *)obj;
+
+ if (nbo->gpu_dirty.nr_dirty)
+ FREE(nbo->gpu_dirty.dirty);
+ if (nbo->cpu_dirty.nr_dirty)
+ FREE(nbo->cpu_dirty.dirty);
+ if (nbo->cpu_mem) nouveau_mem_free(ctx, nbo->cpu_mem);
+ if (nbo->gpu_mem) nouveau_mem_free(ctx, nbo->gpu_mem);
+
+ _mesa_delete_buffer_object(ctx, obj);
+}
+
+static void
+nouveauBufferData(GLcontext *ctx, GLenum target, GLsizeiptrARB size,
+ const GLvoid *data, GLenum usage,
+ struct gl_buffer_object *obj)
+{
+ GLuint gpu_flags;
+
+ DEBUG("target=%s, size=%d, data=%p, usage=%s, obj=%p\n",
+ _mesa_lookup_enum_by_nr(target),
+ (GLuint)size, data,
+ _mesa_lookup_enum_by_nr(usage),
+ obj);
+
+ switch (target) {
+ case GL_ELEMENT_ARRAY_BUFFER_ARB:
+ gpu_flags = 0;
+ break;
+ default:
+ gpu_flags = NOUVEAU_BO_VRAM_OK | NOUVEAU_BO_AGP_OK;
+ break;
+ }
+ nouveau_bo_init_storage(ctx, gpu_flags, size, data, usage, obj);
+}
+
+static void
+nouveauBufferSubData(GLcontext *ctx, GLenum target, GLintptrARB offset,
+ GLsizeiptrARB size, const GLvoid *data,
+ struct gl_buffer_object *obj)
+{
+ GLvoid *out;
+
+ DEBUG("target=%s, offset=0x%x, size=%d, data=%p, obj=%p\n",
+ _mesa_lookup_enum_by_nr(target),
+ (GLuint)offset, (GLuint)size, data, obj);
+
+ out = nouveau_bo_map(ctx, GL_WRITE_ONLY_ARB, obj);
+ _mesa_memcpy(out + offset, data, size);
+ nouveau_bo_dirty_linear(ctx, GL_FALSE, offset, size, obj);
+ nouveau_bo_unmap(ctx, obj);
+}
+
+static void
+nouveauGetBufferSubData(GLcontext *ctx, GLenum target, GLintptrARB offset,
+ GLsizeiptrARB size, GLvoid *data,
+ struct gl_buffer_object *obj)
+{
+ const GLvoid *in;
+
+ DEBUG("target=%s, offset=0x%x, size=%d, data=%p, obj=%p\n",
+ _mesa_lookup_enum_by_nr(target),
+ (GLuint)offset, (GLuint)size, data, obj);
+
+ in = nouveau_bo_map(ctx, GL_READ_ONLY_ARB, obj);
+ _mesa_memcpy(data, in + offset, size);
+ nouveau_bo_unmap(ctx, obj);
+}
+
+static void *
+nouveauMapBuffer(GLcontext *ctx, GLenum target, GLenum access,
+ struct gl_buffer_object *obj)
+{
+ DEBUG("target=%s, access=%s, obj=%p\n",
+ _mesa_lookup_enum_by_nr(target),
+ _mesa_lookup_enum_by_nr(access),
+ obj
+ );
+
+ /* Already mapped.. */
+ if (obj->Pointer)
+ return NULL;
+
+ /* Have to pass READ_WRITE here, nouveau_bo_map will only ensure that
+ * the cpu_mem buffer is up-to-date if we ask for read access.
+ *
+ * However, even if the client only asks for write access, we're still
+ * forced to reupload the entire buffer. So, we need the cpu_mem buffer
+ * to have the correct data all the time.
+ */
+ obj->Pointer = nouveau_bo_map(ctx, GL_READ_WRITE_ARB, obj);
+
+ /* The GL spec says that a client attempting to write to a bufferobj
+ * mapped READ_ONLY object may have unpredictable results, possibly
+ * even program termination.
+ *
+ * We're going to use this, and only mark the buffer as dirtied if
+ * the client asks for write access.
+ */
+ if (target != GL_READ_ONLY_ARB) {
+ /* We have no way of knowing what was modified by the client,
+ * so the entire buffer gets dirtied. */
+ nouveau_bo_dirty_all(ctx, GL_FALSE, obj);
+ }
+
+ return obj->Pointer;
+}
+
+static GLboolean
+nouveauUnmapBuffer(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj)
+{
+ DEBUG("target=%s, obj=%p\n", _mesa_lookup_enum_by_nr(target), obj);
+
+ assert(obj->Pointer);
+
+ nouveau_bo_unmap(ctx, obj);
+ obj->Pointer = NULL;
+ return GL_TRUE;
+}
+
+void
+nouveauInitBufferObjects(GLcontext *ctx)
+{
+ ctx->Driver.BindBuffer = nouveauBindBuffer;
+ ctx->Driver.NewBufferObject = nouveauNewBufferObject;
+ ctx->Driver.DeleteBuffer = nouveauDeleteBuffer;
+ ctx->Driver.BufferData = nouveauBufferData;
+ ctx->Driver.BufferSubData = nouveauBufferSubData;
+ ctx->Driver.GetBufferSubData = nouveauGetBufferSubData;
+ ctx->Driver.MapBuffer = nouveauMapBuffer;
+ ctx->Driver.UnmapBuffer = nouveauUnmapBuffer;
+}
+
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h
new file mode 100644
index 00000000000..932450fd877
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h
@@ -0,0 +1,77 @@
+#ifndef __NOUVEAU_BUFFEROBJ_H__
+#define __NOUVEAU_BUFFEROBJ_H__
+
+#include "mtypes.h"
+#include "nouveau_buffers.h"
+
+#define NOUVEAU_BO_VRAM_OK (NOUVEAU_MEM_FB | NOUVEAU_MEM_FB_ACCEPTABLE)
+#define NOUVEAU_BO_AGP_OK (NOUVEAU_MEM_AGP | NOUVEAU_MEM_AGP_ACCEPTABLE)
+
+typedef struct nouveau_bufferobj_region_t {
+ uint32_t start;
+ uint32_t end;
+} nouveau_bufferobj_region;
+
+typedef struct nouveau_bufferobj_dirty_t {
+ nouveau_bufferobj_region *dirty;
+ int nr_dirty;
+} nouveau_bufferobj_dirty;
+
+typedef struct nouveau_buffer_object_t {
+ /* Base class, must be first */
+ struct gl_buffer_object mesa;
+
+ GLboolean mapped;
+ GLenum usage;
+
+ /* Memory used for GPU access to the buffer*/
+ GLuint gpu_mem_flags;
+ nouveau_mem * gpu_mem;
+ nouveau_bufferobj_dirty gpu_dirty;
+
+ /* Memory used for CPU access to the buffer */
+ GLuint cpu_mem_flags;
+ nouveau_mem * cpu_mem;
+ GLvoid * cpu_mem_sys;
+ nouveau_bufferobj_dirty cpu_dirty;
+} nouveau_buffer_object;
+
+extern void
+nouveau_bo_init_storage(GLcontext *ctx, GLuint valid_gpu_access,
+ GLsizeiptrARB size, const GLvoid *data, GLenum usage,
+ struct gl_buffer_object *bo);
+
+extern GLboolean
+nouveau_bo_move_in(GLcontext *ctx, struct gl_buffer_object *bo);
+
+extern GLboolean
+nouveau_bo_move_out(GLcontext *ctx, struct gl_buffer_object *bo);
+
+extern void *
+nouveau_bo_map(GLcontext *ctx, GLenum usage, struct gl_buffer_object *bo);
+
+extern void
+nouveau_bo_unmap(GLcontext *ctx, struct gl_buffer_object *bo);
+
+extern uint32_t
+nouveau_bo_gpu_ref(GLcontext *ctx, struct gl_buffer_object *bo);
+
+extern void
+nouveau_bo_dirty_linear(GLcontext *ctx, GLboolean on_card,
+ uint32_t offset, uint32_t size,
+ struct gl_buffer_object *bo);
+
+extern void
+nouveau_bo_dirty_all(GLcontext *ctx, GLboolean on_card,
+ struct gl_buffer_object *bo);
+
+extern GLuint
+nouveau_bo_upload_dirty(GLcontext *ctx, struct gl_buffer_object *bo);
+
+extern GLuint
+nouveau_bo_download_dirty(GLcontext *ctx, struct gl_buffer_object *bo);
+
+extern void
+nouveauInitBufferObjects(GLcontext *ctx);
+
+#endif
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c
new file mode 100644
index 00000000000..b54f68f4023
--- /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 00000000000..d86455184c2
--- /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 00000000000..91f12f0d704
--- /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 00000000000..8a4c5f2244e
--- /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 00000000000..8ec5c4a188a
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_card_list.h
@@ -0,0 +1,232 @@
+static nouveau_card nouveau_card_list[]={
+{0x0008, "EDGE 3D", 0, NV_03, 0},
+{0x0009, "EDGE 3D", 0, NV_03, 0},
+{0x0010, "Mutara V08", 0, NV_03, 0},
+{0x0020, "RIVA TNT", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
+{0x0028, "RIVA TNT2/TNT2 Pro", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
+{0x0029, "RIVA TNT2 Ultra", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
+{0x002A, "Riva TnT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
+{0x002B, "Riva TnT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
+{0x002C, "Vanta/Vanta LT", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
+{0x002D, "RIVA TNT2 Model 64/Model 64 Pro", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
+{0x002E, "Vanta", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
+{0x002F, "Vanta", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
+{0x0040, "GeForce 6800 Ultra", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0041, "GeForce 6800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0042, "GeForce 6800 LE", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0043, "NV40.3", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0044, "GeForce 6800 XT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0045, "GeForce 6800 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0046, "GeForce 6800 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0047, "GeForce 6800 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0048, "GeForce 6800 XT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0049, "NV40GL", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x004D, "Quadro FX 4000", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x004E, "Quadro FX 4000", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0090, "GeForce 7800 GTX", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0091, "GeForce 7800 GTX", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0092, "GeForce 7800 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0093, "GeForce 7800 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0098, "GeForce Go 7800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0099, "GE Force Go 7800 GTX", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x009D, "Quadro FX4500", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00A0, "Aladdin TNT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
+{0x00C0, "GeForce 6800 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00C1, "GeForce 6800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00C2, "GeForce 6800 LE", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00C3, "Geforce 6800 XT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00C8, "GeForce Go 6800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00C9, "GeForce Go 6800 Ultra", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00CC, "Quadro FX Go1400", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00CD, "Quadro FX 3450/4000 SDI", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00CE, "Quadro FX 1400", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00F0, "GeForce 6800/GeForce 6800 Ultra", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00F1, "GeForce 6600/GeForce 6600 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00F2, "GeForce 6600/GeForce 6600 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00F3, "GeForce 6200", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00F4, "GeForce 6600 LE", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00F5, "GeForce 7800 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00F6, "GeForce 6600 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00F8, "Quadro FX 3400/4400", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00F9, "GeForce 6800 Ultra/GeForce 6800 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x00FA, "GeForce PCX 5750", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
+{0x00FB, "GeForce PCX 5900", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
+{0x00FC, "Quadro FX 330/GeForce PCX 5300", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
+{0x00FD, "Quadro FX 330/Quadro NVS280", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
+{0x00FE, "Quadro FX 1300", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
+{0x00FF, "GeForce PCX 4300", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0100, "GeForce 256 SDR", NV10_TCL_PRIMITIVE_3D, NV_10, 0},
+{0x0101, "GeForce 256 DDR", NV10_TCL_PRIMITIVE_3D, NV_10, 0},
+{0x0103, "Quadro", NV10_TCL_PRIMITIVE_3D, NV_10, 0},
+{0x0110, "GeForce2 MX/MX 400", NV11_TCL_PRIMITIVE_3D, NV_11, 0},
+{0x0111, "GeForce2 MX 100 DDR/200 DDR", NV11_TCL_PRIMITIVE_3D, NV_11, 0},
+{0x0112, "GeForce2 Go", NV11_TCL_PRIMITIVE_3D, NV_11, 0},
+{0x0113, "Quadro2 MXR/EX/Go", NV11_TCL_PRIMITIVE_3D, NV_11, 0},
+{0x0140, "GeForce 6600 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0141, "GeForce 6600", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0142, "GeForce 6600 PCIe", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0144, "GeForce Go 6600", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0145, "GeForce 6610 XL", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0146, "Geforce Go 6600TE/6200TE", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0148, "GeForce Go 6600", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0149, "GeForce Go 6600 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x014A, "Quadro NVS 440", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x014C, "Quadro FX 550", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x014D, "Quadro FX 550", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x014E, "Quadro FX 540", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x014F, "GeForce 6200", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0150, "GeForce2 GTS/Pro", NV11_TCL_PRIMITIVE_3D, NV_15, 0},
+{0x0151, "GeForce2 Ti", NV11_TCL_PRIMITIVE_3D, NV_15, 0},
+{0x0152, "GeForce2 Ultra, Bladerunner", NV11_TCL_PRIMITIVE_3D, NV_15, 0},
+{0x0153, "Quadro2 Pro", NV11_TCL_PRIMITIVE_3D, NV_15, 0},
+{0x0161, "GeForce 6200 TurboCache(TM)", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x0162, "GeForce 6200 SE TurboCache (TM)", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x0163, "GeForce 6200 LE", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x0164, "GeForce Go 6200", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x0165, "Quadro NVS 285", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x0166, "GeForce Go 6400", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x0167, "GeForce Go 6200 TurboCache", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x0168, "GeForce Go 6200 TurboCache", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x0170, "GeForce4 MX 460", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0171, "GeForce4 MX 440", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0172, "GeForce4 MX 420", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0173, "GeForce4 MX 440-SE", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0174, "GeForce4 440 Go", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0175, "GeForce4 420 Go", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0176, "GeForce4 420 Go 32M", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0177, "GeForce4 460 Go", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0178, "Quadro4 550 XGL", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0179, "GeForce4 420 Go 32M", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x017A, "Quadro4 200/400 NVS", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x017B, "Quadro4 550 XGL", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x017C, "Quadro4 500 GoGL", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x017D, "GeForce4 410 Go 16M", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0181, "GeForce4 MX 440 AGP 8x", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0182, "GeForce4 MX 440SE AGP 8x", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0183, "GeForce4 MX 420 AGP 8x", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0185, "GeForce4 MX 4000 AGP 8x", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0186, "GeForce4 448 Go", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0187, "GeForce4 488 Go", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0188, "Quadro4 580 XGL", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x018A, "Quadro4 NVS AGP 8x", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x018B, "Quadro4 380 XGL", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x018C, "Quadro NVS 50 PCI", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x018D, "GeForce4 448 Go", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0191, "GeForce 8800 GTX", NV30_TCL_PRIMITIVE_3D|0x5000, NV_50, 0},
+{0x0193, "GeForce 8800 GTS", NV30_TCL_PRIMITIVE_3D|0x5000, NV_50, 0},
+{0x01A0, "GeForce2 MX Integrated Graphics", NV11_TCL_PRIMITIVE_3D, NV_11, 0},
+{0x01D1, "GeForce 7300 LE", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x01D6, "GeForce Go 7200", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x01D7, "Quadro NVS 110M / GeForce Go 7300", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x01D8, "GeForce Go 7400", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x01DA, "Quadro NVS 110M", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x01DF, "GeForce 7300 GS", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x01F0, "GeForce4 MX - nForce GPU", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
+{0x0200, "GeForce3", NV20_TCL_PRIMITIVE_3D, NV_20, 0},
+{0x0201, "GeForce3 Ti 200", NV20_TCL_PRIMITIVE_3D, NV_20, 0},
+{0x0202, "GeForce3 Ti 500", NV20_TCL_PRIMITIVE_3D, NV_20, 0},
+{0x0203, "Quadro DCC", NV20_TCL_PRIMITIVE_3D, NV_20, 0},
+{0x0211, "GeForce 6800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0212, "GeForce 6800 LE", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0215, "GeForce 6800 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0218, "GeForce 6800 XT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0221, "GeForce 6200", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x0240, "GeForce 6150", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x0242, "GeForce 6100", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x0244, "Geforce 6150 Go", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x0250, "GeForce4 Ti 4600", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0},
+{0x0251, "GeForce4 Ti 4400", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0},
+{0x0252, "GeForce4 Ti", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0},
+{0x0253, "GeForce4 Ti 4200", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0},
+{0x0258, "Quadro4 900 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0},
+{0x0259, "Quadro4 750 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0},
+{0x025B, "Quadro4 700 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0},
+{0x0280, "GeForce4 Ti 4800", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0},
+{0x0281, "GeForce4 Ti 4200 AGP 8x", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0},
+{0x0282, "GeForce4 Ti 4800 SE", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0},
+{0x0286, "GeForce4 Ti 4200 Go AGP 8x", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0},
+{0x0288, "Quadro4 980 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0},
+{0x0289, "Quadro4 780 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0},
+{0x028C, "Quadro4 700 GoGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0},
+{0x0290, "GeForce 7900 GTX", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0291, "GeForce 7900 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0292, "GeForce 7900 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0298, "GeForce Go 7900 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0299, "GeForce Go 7900 GTX", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x029A, "Quadro FX 2500M", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x029B, "Quadro FX 1500M", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x029C, "Quadro FX 5500", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x029D, "Quadro FX 3500", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x029E, "Quadro FX 1500", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x029F, "Quadro FX 4500 X2", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x02A0, "XGPU", NV20_TCL_PRIMITIVE_3D, NV_20, 0},
+{0x02E1, "GeForce 7600 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0300, "GeForce FX", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
+{0x0301, "GeForce FX 5800 Ultra", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
+{0x0302, "GeForce FX 5800", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
+{0x0308, "Quadro FX 2000", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
+{0x0309, "Quadro FX 1000", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
+{0x0311, "GeForce FX 5600 Ultra", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
+{0x0312, "GeForce FX 5600", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
+{0x0313, "NV31", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
+{0x0314, "GeForce FX 5600XT", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
+{0x0316, "NV31M", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
+{0x0317, "NV31M Pro", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
+{0x031A, "GeForce FX Go5600", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
+{0x031B, "GeForce FX Go5650", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
+{0x031C, "NVIDIA Quadro FX Go700", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
+{0x031D, "NV31GLM", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
+{0x031E, "NV31GLM Pro", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
+{0x031F, "NV31GLM Pro", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
+{0x0320, "GeForce FX 5200", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
+{0x0321, "GeForce FX 5200 Ultra", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
+{0x0322, "GeForce FX 5200", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
+{0x0323, "GeForce FX 5200LE", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
+{0x0324, "GeForce FX Go5200", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
+{0x0325, "GeForce FX Go5250", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
+{0x0326, "GeForce FX 5500", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
+{0x0327, "GeForce FX 5100", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
+{0x0328, "GeForce FX Go5200 32M/64M", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
+{0x0329, "GeForce FX Go5200", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
+{0x032A, "Quadro NVS 280 PCI", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
+{0x032B, "Quadro FX 500/600 PCI", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
+{0x032C, "GeForce FX Go 5300", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
+{0x032D, "GeForce FX Go5100", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
+{0x032F, "NV34GL", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0},
+{0x0330, "GeForce FX 5900 Ultra", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
+{0x0331, "GeForce FX 5900", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
+{0x0332, "GeForce FX 5900XT", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
+{0x0333, "GeForce FX 5950 Ultra", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
+{0x0334, "GeForce FX 5900ZT", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
+{0x0338, "Quadro FX 3000", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
+{0x033F, "Quadro FX 700", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
+{0x0341, "GeForce FX 5700 Ultra", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
+{0x0342, "GeForce FX 5700", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
+{0x0343, "GeForce FX 5700LE", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
+{0x0344, "GeForce FX 5700VE", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
+{0x0345, "NV36.5", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
+{0x0347, "GeForce FX Go5700", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
+{0x0348, "GeForce FX Go5700", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
+{0x0349, "NV36M Pro", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
+{0x034B, "NV36MAP", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
+{0x034C, "Quadro FX Go1000", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
+{0x034E, "Quadro FX 1100", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
+{0x034F, "NV36GL", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
+{0x0391, "GeForce 7600 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0392, "GeForce 7600 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0393, "GeForce 7300 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x0398, "GeForce Go 7600", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
+{0x03D0, "GeForce 6100 nForce 430", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x03D1, "GeForce 6100 nForce 405", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x03D2, "GeForce 6100 nForce 400", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x03D5, "GeForce 6100 nForce 420", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
+{0x0008, "NV1", 0, NV_03, 0},
+{0x0009, "DAC64", 0, NV_03, 0},
+{0x0018, "Riva128", 0, NV_03, 0},
+{0x0019, "Riva128ZX", 0, NV_03, 0},
+{0x0020, "TNT", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
+{0x0028, "TNT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
+{0x0029, "UTNT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
+{0x002C, "VTNT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
+{0x00A0, "ITNT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
+};
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c
new file mode 100644
index 00000000000..f811dc1b72e
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c
@@ -0,0 +1,371 @@
+/**************************************************************************
+
+Copyright 2006 Stephane Marchesin
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#include "glheader.h"
+#include "context.h"
+#include "simple_list.h"
+#include "imports.h"
+#include "matrix.h"
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "framebuffer.h"
+
+#include "tnl/tnl.h"
+#include "tnl/t_pipeline.h"
+#include "tnl/t_vp_build.h"
+
+#include "drivers/common/driverfuncs.h"
+
+#include "nouveau_context.h"
+#include "nouveau_driver.h"
+//#include "nouveau_state.h"
+#include "nouveau_span.h"
+#include "nouveau_object.h"
+#include "nouveau_fifo.h"
+#include "nouveau_tex.h"
+#include "nouveau_msg.h"
+#include "nouveau_reg.h"
+#include "nouveau_lock.h"
+#include "nouveau_query.h"
+#include "nv04_swtcl.h"
+#include "nv10_swtcl.h"
+
+#include "vblank.h"
+#include "utils.h"
+#include "texmem.h"
+#include "xmlpool.h" /* for symbolic values of enum-type options */
+
+#ifndef NOUVEAU_DEBUG
+int NOUVEAU_DEBUG = 0;
+#endif
+
+static const struct dri_debug_control debug_control[] =
+{
+ { "shaders" , DEBUG_SHADERS },
+ { "mem" , DEBUG_MEM },
+ { "bufferobj" , DEBUG_BUFFEROBJ },
+ { NULL , 0 }
+};
+
+#define need_GL_ARB_vertex_program
+#define need_GL_ARB_occlusion_query
+#include "extension_helper.h"
+
+const struct dri_extension common_extensions[] =
+{
+ { NULL, 0 }
+};
+
+const struct dri_extension nv10_extensions[] =
+{
+ { NULL, 0 }
+};
+
+const struct dri_extension nv20_extensions[] =
+{
+ { NULL, 0 }
+};
+
+const struct dri_extension nv30_extensions[] =
+{
+ { "GL_ARB_fragment_program", NULL },
+ { NULL, 0 }
+};
+
+const struct dri_extension nv40_extensions[] =
+{
+ /* ARB_vp can be moved to nv20/30 once the shader backend has been
+ * written for those cards.
+ */
+ { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions },
+ { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions},
+ { NULL, 0 }
+};
+
+const struct dri_extension nv50_extensions[] =
+{
+ { NULL, 0 }
+};
+
+/* Create the device specific context.
+ */
+GLboolean nouveauCreateContext( const __GLcontextModes *glVisual,
+ __DRIcontextPrivate *driContextPriv,
+ void *sharedContextPrivate )
+{
+ GLcontext *ctx, *shareCtx;
+ __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+ struct dd_function_table functions;
+ nouveauContextPtr nmesa;
+ nouveauScreenPtr screen;
+
+ /* Allocate the context */
+ nmesa = (nouveauContextPtr) CALLOC( sizeof(*nmesa) );
+ if ( !nmesa )
+ return GL_FALSE;
+
+ nmesa->driContext = driContextPriv;
+ nmesa->driScreen = sPriv;
+ nmesa->driDrawable = NULL;
+ nmesa->hHWContext = driContextPriv->hHWContext;
+ nmesa->driHwLock = &sPriv->pSAREA->lock;
+ nmesa->driFd = sPriv->fd;
+
+ nmesa->screen = (nouveauScreenPtr)(sPriv->private);
+ screen=nmesa->screen;
+
+ /* Create the hardware context */
+ if (!nouveauDRMGetParam(nmesa, NOUVEAU_GETPARAM_FB_PHYSICAL,
+ &nmesa->vram_phys))
+ return GL_FALSE;
+ if (!nouveauDRMGetParam(nmesa, NOUVEAU_GETPARAM_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;
+ nouveauQueryInitFuncs(ctx);
+ nmesa->hw_func.InitCard(nmesa);
+ nouveauInitState(ctx);
+
+ driContextPriv->driverPrivate = (void *)nmesa;
+
+ NOUVEAU_DEBUG = driParseDebugString( getenv( "NOUVEAU_DEBUG" ),
+ debug_control );
+
+ if (driQueryOptionb(&nmesa->optionCache, "no_rast")) {
+ fprintf(stderr, "disabling 3D acceleration\n");
+ FALLBACK(nmesa, NOUVEAU_FALLBACK_DISABLE, 1);
+ }
+
+ return GL_TRUE;
+}
+
+/* Destroy the device specific context. */
+void nouveauDestroyContext( __DRIcontextPrivate *driContextPriv )
+{
+ nouveauContextPtr nmesa = (nouveauContextPtr) driContextPriv->driverPrivate;
+
+ assert(nmesa);
+ if ( nmesa ) {
+ /* free the option cache */
+ driDestroyOptionCache (&nmesa->optionCache);
+
+ FREE( nmesa );
+ }
+
+}
+
+
+/* Force the context `c' to be the current context and associate with it
+ * buffer `b'.
+ */
+GLboolean nouveauMakeCurrent( __DRIcontextPrivate *driContextPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ __DRIdrawablePrivate *driReadPriv )
+{
+ if ( driContextPriv ) {
+ nouveauContextPtr nmesa = (nouveauContextPtr) driContextPriv->driverPrivate;
+ struct gl_framebuffer *draw_fb =
+ (struct gl_framebuffer*)driDrawPriv->driverPrivate;
+ struct gl_framebuffer *read_fb =
+ (struct gl_framebuffer*)driReadPriv->driverPrivate;
+
+ driDrawableInitVBlank(driDrawPriv, nmesa->vblank_flags, &nmesa->vblank_seq );
+ nmesa->driDrawable = driDrawPriv;
+
+ _mesa_resize_framebuffer(nmesa->glCtx, draw_fb,
+ driDrawPriv->w, driDrawPriv->h);
+ if (draw_fb != read_fb) {
+ _mesa_resize_framebuffer(nmesa->glCtx, draw_fb,
+ driReadPriv->w,
+ driReadPriv->h);
+ }
+ _mesa_make_current(nmesa->glCtx, draw_fb, read_fb);
+
+ nouveau_build_framebuffer(nmesa->glCtx,
+ driDrawPriv->driverPrivate);
+ } else {
+ _mesa_make_current( NULL, NULL, NULL );
+ }
+
+ return GL_TRUE;
+}
+
+
+/* Force the context `c' to be unbound from its buffer.
+ */
+GLboolean nouveauUnbindContext( __DRIcontextPrivate *driContextPriv )
+{
+ return GL_TRUE;
+}
+
+static void nouveauDoSwapBuffers(nouveauContextPtr nmesa,
+ __DRIdrawablePrivate *dPriv)
+{
+ struct gl_framebuffer *fb;
+ nouveau_renderbuffer *src, *dst;
+ drm_clip_rect_t *box;
+ int nbox, i;
+
+ fb = (struct gl_framebuffer *)dPriv->driverPrivate;
+ dst = (nouveau_renderbuffer*)
+ fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
+ src = (nouveau_renderbuffer*)
+ fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
+
+#ifdef ALLOW_MULTI_SUBCHANNEL
+ LOCK_HARDWARE(nmesa);
+ nbox = dPriv->numClipRects;
+ box = dPriv->pClipRects;
+
+ if (nbox) {
+ BEGIN_RING_SIZE(NvSubCtxSurf2D,
+ NV10_CONTEXT_SURFACES_2D_FORMAT, 4);
+ if (src->mesa._ActualFormat == GL_RGBA8)
+ OUT_RING (6); /* X8R8G8B8 */
+ else
+ OUT_RING (4); /* R5G6B5 */
+ OUT_RING ((dst->pitch << 16) | src->pitch);
+ OUT_RING (src->offset);
+ OUT_RING (dst->offset);
+ }
+
+ for (i=0; i<nbox; i++, box++) {
+ BEGIN_RING_SIZE(NvSubImageBlit, NV10_IMAGE_BLIT_SET_POINT, 3);
+ OUT_RING (((box->y1 - dPriv->y) << 16) |
+ (box->x1 - dPriv->x));
+ OUT_RING ((box->y1 << 16) | box->x1);
+ OUT_RING (((box->y2 - box->y1) << 16) |
+ (box->x2 - box->x1));
+ }
+
+ 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 00000000000..f61fcbb48c0
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h
@@ -0,0 +1,233 @@
+/**************************************************************************
+
+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;
+
+ /* ARB_occlusion_query / EXT_timer_query */
+ GLuint query_object_max;
+ GLboolean * query_alloc;
+ nouveau_notifier *queryNotifier;
+
+ /* Additional hw-specific functions */
+ nouveau_hw_func hw_func;
+
+ /* FIXME : do we want to put all state into a separate struct ? */
+ /* State for tris */
+ GLuint color_offset;
+ GLuint specular_offset;
+
+ /* Vertex state */
+ GLuint vertex_size;
+ GLubyte *verts;
+ struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX];
+ GLuint vertex_attr_count;
+
+ /* Color buffer clear value */
+ uint32_t clear_color_value;
+
+ /* Depth/stencil clear value */
+ uint32_t clear_value;
+
+ /* Light state */
+ GLboolean lighting_enabled;
+ uint32_t enabled_lights;
+
+ /* Cached state */
+ nouveau_state_cache state_cache;
+
+ /* The drawing fallbacks */
+ GLuint Fallback;
+ nouveau_tri_func draw_tri;
+ nouveau_line_func draw_line;
+ nouveau_point_func draw_point;
+
+ /* Cliprects information */
+ GLuint numClipRects;
+ drm_clip_rect_t *pClipRects;
+ drm_clip_rect_t osClipRect;
+ GLuint drawX, drawY;
+
+ /* The rendering context information */
+ GLenum current_primitive; /* the current primitive enum */
+ DECLARE_RENDERINPUTS(render_inputs_bitset); /* the current render inputs */
+
+ /* Shader state */
+ nvsFunc VPfunc;
+ nvsFunc FPfunc;
+ nouveauShader *current_fragprog;
+ nouveauShader *current_vertprog;
+ nouveauShader *passthrough_vp;
+ nouveauShader *passthrough_fp;
+
+ nouveauScreenRec *screen;
+ drm_nouveau_sarea_t *sarea;
+
+ __DRIcontextPrivate *driContext; /* DRI context */
+ __DRIscreenPrivate *driScreen; /* DRI screen */
+ __DRIdrawablePrivate *driDrawable; /* DRI drawable bound to this ctx */
+ GLint lastStamp;
+
+ drm_context_t hHWContext;
+ drm_hw_lock_t *driHwLock;
+ int driFd;
+
+ /* Configuration cache */
+ driOptionCache optionCache;
+
+ /* vblank stuff */
+ uint32_t vblank_flags;
+ uint32_t vblank_seq;
+
+ GLuint new_state;
+ GLuint new_render_state;
+ GLuint render_index;
+ GLmatrix viewport;
+ GLfloat depth_scale;
+
+}nouveauContextRec, *nouveauContextPtr;
+
+
+#define NOUVEAU_CONTEXT(ctx) ((nouveauContextPtr)(ctx->DriverCtx))
+
+/* Flags for software fallback cases: */
+#define NOUVEAU_FALLBACK_TEXTURE 0x0001
+#define NOUVEAU_FALLBACK_DRAW_BUFFER 0x0002
+#define NOUVEAU_FALLBACK_READ_BUFFER 0x0004
+#define NOUVEAU_FALLBACK_STENCIL 0x0008
+#define NOUVEAU_FALLBACK_RENDER_MODE 0x0010
+#define NOUVEAU_FALLBACK_LOGICOP 0x0020
+#define NOUVEAU_FALLBACK_SEP_SPECULAR 0x0040
+#define NOUVEAU_FALLBACK_BLEND_EQ 0x0080
+#define NOUVEAU_FALLBACK_BLEND_FUNC 0x0100
+#define NOUVEAU_FALLBACK_PROJTEX 0x0200
+#define NOUVEAU_FALLBACK_DISABLE 0x0400
+
+
+extern GLboolean nouveauCreateContext( const __GLcontextModes *glVisual,
+ __DRIcontextPrivate *driContextPriv,
+ void *sharedContextPrivate );
+
+extern void nouveauDestroyContext( __DRIcontextPrivate * );
+
+extern GLboolean nouveauMakeCurrent( __DRIcontextPrivate *driContextPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ __DRIdrawablePrivate *driReadPriv );
+
+extern GLboolean nouveauUnbindContext( __DRIcontextPrivate *driContextPriv );
+
+extern void nouveauSwapBuffers(__DRIdrawablePrivate *dPriv);
+
+extern void nouveauCopySubBuffer(__DRIdrawablePrivate *dPriv,
+ int x, int y, int w, int h);
+
+/* Debugging utils: */
+extern int NOUVEAU_DEBUG;
+
+#define DEBUG_SHADERS 0x00000001
+#define DEBUG_MEM 0x00000002
+#define DEBUG_BUFFEROBJ 0x00000004
+
+#endif /* __NOUVEAU_CONTEXT_H__ */
+
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_ctrlreg.h b/src/mesa/drivers/dri/nouveau/nouveau_ctrlreg.h
new file mode 100644
index 00000000000..c9b2d590077
--- /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 00000000000..ce3c3fb9cc4
--- /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 00000000000..00956aa8f8b
--- /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 00000000000..6164012b5b7
--- /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 00000000000..7af9f1e3c2f
--- /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 00000000000..490089f71a4
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h
@@ -0,0 +1,179 @@
+/**************************************************************************
+
+Copyright 2006 Stephane Marchesin
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+
+
+#ifndef __NOUVEAU_FIFO_H__
+#define __NOUVEAU_FIFO_H__
+
+#include "nouveau_context.h"
+#include "nouveau_ctrlreg.h"
+#include "nouveau_state_cache.h"
+
+//#define NOUVEAU_RING_TRACE
+//#define NOUVEAU_RING_DEBUG
+//#define NOUVEAU_STATE_CACHE_DISABLE
+
+#ifndef NOUVEAU_RING_TRACE
+#define NOUVEAU_RING_TRACE 0
+#else
+#undef NOUVEAU_RING_TRACE
+#define NOUVEAU_RING_TRACE 1
+#endif
+
+#define NV_READ(reg) *(volatile u_int32_t *)(nmesa->mmio + (reg))
+
+#define NV_FIFO_READ(reg) *(volatile u_int32_t *)(nmesa->fifo.mmio + (reg/4))
+#define NV_FIFO_WRITE(reg,value) *(volatile u_int32_t *)(nmesa->fifo.mmio + (reg/4)) = value;
+#define NV_FIFO_READ_GET() ((NV_FIFO_READ(NV03_FIFO_REGS_DMAGET) - nmesa->fifo.put_base) >> 2)
+#define NV_FIFO_WRITE_PUT(val) do { \
+ if (NOUVEAU_RING_TRACE) {\
+ printf("FIRE_RING : 0x%08x\n", nmesa->fifo.current << 2); \
+ fflush(stdout); \
+ sleep(1); \
+ } \
+ NV_FIFO_WRITE(NV03_FIFO_REGS_DMAPUT, ((val)<<2) + nmesa->fifo.put_base); \
+} while(0)
+
+/*
+ * Ring/fifo interface
+ *
+ * - Begin a ring section with BEGIN_RING_SIZE (if you know the full size in advance)
+ * - Output stuff to the ring with either OUT_RINGp (outputs a raw mem chunk), OUT_RING (1 uint32_t) or OUT_RINGf (1 float)
+ * - RING_AVAILABLE returns the available fifo (in uint32_ts)
+ * - RING_AHEAD returns how much ahead of the last submission point we are
+ * - FIRE_RING fires whatever we have that wasn't fired before
+ * - WAIT_RING waits for size (in uint32_ts) to be available in the fifo
+ */
+
+/* Enable for ring debugging. Prints out writes to the ring buffer
+ * but does not actually write to it.
+ */
+#ifdef NOUVEAU_RING_DEBUG
+
+#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{ \
+ if (NOUVEAU_RING_TRACE) { \
+ uint32_t* p=(uint32_t*)(ptr); \
+ int i; printf("OUT_RINGp: (size 0x%x dwords) (%s)\n",sz, __func__); for(i=0;i<sz;i++) printf(" [0x%08x] 0x%08x %f\n", (nmesa->fifo.current+i) << 2, *(p+i), *((float*)(p+i))); \
+ } \
+ memcpy(nmesa->fifo.buffer+nmesa->fifo.current,ptr,(sz)*4); \
+ nmesa->fifo.current+=(sz); \
+}while(0)
+
+#define OUT_RING(n) do { \
+if (NOUVEAU_RING_TRACE) \
+ printf("OUT_RINGn: [0x%08x] 0x%08x (%s)\n", nmesa->fifo.current << 2, n, __func__); \
+nmesa->fifo.buffer[nmesa->fifo.current++]=(n); \
+}while(0)
+
+#define OUT_RINGf(n) do { \
+if (NOUVEAU_RING_TRACE) \
+ printf("OUT_RINGf: [0x%08x] %.04f (%s)\n", nmesa->fifo.current << 2, n, __func__); \
+*((float*)(nmesa->fifo.buffer+nmesa->fifo.current++))=(n); \
+}while(0)
+
+#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 00000000000..c119d14dd75
--- /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 00000000000..38bb0014258
--- /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 00000000000..5dea2189c72
--- /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 <[email protected]>
+ * Nicolai Haehnle <[email protected]>
+ */
+
+
+#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 00000000000..302009c8b17
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_object.c
@@ -0,0 +1,101 @@
+
+#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);
+ if (nmesa->screen->card->type>=NV_10) {
+ 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);
+ } else {
+ nouveauCreateContextObject(nmesa, NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D,
+ 0, 0, 0, 0);
+ nouveauCreateContextObject(nmesa, NvCtxSurf3D, NV04_CONTEXT_SURFACES_3D,
+ 0, 0, 0, 0);
+ nouveauCreateContextObject(nmesa, NvImageBlit, NV_IMAGE_BLIT,
+ NV_DMA_CONTEXT_FLAGS_PATCH_SRCCOPY, 0, 0, 0);
+ }
+ 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 00000000000..daad281029f
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_object.h
@@ -0,0 +1,44 @@
+#ifndef __NOUVEAU_OBJECT_H__
+#define __NOUVEAU_OBJECT_H__
+
+#include "nouveau_context.h"
+
+#define ALLOW_MULTI_SUBCHANNEL
+
+void nouveauObjectInit(nouveauContextPtr nmesa);
+
+enum DMAObjects {
+ Nv3D = 0x80000019,
+ NvCtxSurf2D = 0x80000020,
+ NvImageBlit = 0x80000021,
+ NvMemFormat = 0x80000022,
+ NvCtxSurf3D = 0x80000023,
+ NvDmaFB = 0xD0FB0001,
+ NvDmaAGP = 0xD0AA0001,
+ NvSyncNotify = 0xD0000001,
+ NvQueryNotify = 0xD0000002
+};
+
+enum DMASubchannel {
+ NvSubCtxSurf2D = 0,
+ NvSubImageBlit = 1,
+ NvSubMemFormat = 2,
+ NvSubCtxSurf3D = 3,
+ NvSub3D = 7,
+};
+
+extern void nouveauObjectOnSubchannel(nouveauContextPtr nmesa, int subchannel, int handle);
+
+extern GLboolean nouveauCreateContextObject(nouveauContextPtr nmesa,
+ 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_query.c b/src/mesa/drivers/dri/nouveau/nouveau_query.c
new file mode 100644
index 00000000000..de3f5b0378b
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_query.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/* GL_ARB_occlusion_query support for NV20/30/40 */
+
+#include "mtypes.h"
+
+#include "nouveau_fifo.h"
+#include "nouveau_msg.h"
+#include "nouveau_object.h"
+#include "nouveau_reg.h"
+#include "nouveau_sync.h"
+#include "nouveau_query.h"
+
+static struct gl_query_object *
+nouveauNewQueryObject(GLcontext *ctx, GLuint id)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nouveau_query_object *nq;
+ int i;
+
+ for (i=0; i<nmesa->query_object_max; i++)
+ if (nmesa->query_alloc[i] == GL_FALSE)
+ break;
+ if (i==nmesa->query_object_max)
+ return NULL;
+
+ nq = CALLOC_STRUCT(nouveau_query_object_t);
+ if (nq) {
+ nq->notifier_id = i;
+
+ nq->mesa.Id = id;
+ nq->mesa.Result = 0;
+ nq->mesa.Active = GL_FALSE;
+ nq->mesa.Ready = GL_TRUE;
+ }
+
+ return (struct gl_query_object *)nq;
+}
+
+static void
+nouveauBeginQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nouveau_query_object *nq = (nouveau_query_object *)q;
+
+ nouveau_notifier_reset(nmesa->queryNotifier, nq->notifier_id);
+
+ switch (nmesa->screen->card->type) {
+ case NV_20:
+ BEGIN_RING_CACHE(NvSub3D, 0x17c8, 1);
+ OUT_RING_CACHE (1);
+ BEGIN_RING_CACHE(NvSub3D, 0x17cc, 1);
+ OUT_RING_CACHE (1);
+ break;
+ case NV_30:
+ case NV_40:
+ case NV_44:
+ /* I don't think this is OCC_QUERY enable, but it *is* needed to make
+ * the SET_OBJECT7 notifier block work with STORE_RESULT.
+ *
+ * Also, this appears to reset the pixel pass counter */
+ BEGIN_RING_SIZE(NvSub3D,
+ NV30_TCL_PRIMITIVE_3D_OCC_QUERY_OR_COLOR_BUFF_ENABLE,
+ 1);
+ OUT_RING (1);
+ /* Probably OCC_QUERY_ENABLE */
+ BEGIN_RING_CACHE(NvSub3D, 0x17cc, 1);
+ OUT_RING_CACHE (1);
+ break;
+ default:
+ WARN_ONCE("no support for this card\n");
+ break;
+ }
+}
+
+static void
+nouveauUpdateQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nouveau_query_object *nq = (nouveau_query_object *)q;
+ int status;
+
+ status = nouveau_notifier_status(nmesa->queryNotifier,
+ nq->notifier_id);
+
+ q->Ready = (status == NV_NOTIFY_STATE_STATUS_COMPLETED);
+ if (q->Ready)
+ q->Result = nouveau_notifier_return_val(nmesa->queryNotifier,
+ nq->notifier_id);
+}
+
+static void
+nouveauWaitQueryResult(GLcontext *ctx, GLenum target, struct gl_query_object *q)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nouveau_query_object *nq = (nouveau_query_object *)q;
+
+ nouveau_notifier_wait_status(nmesa->queryNotifier, nq->notifier_id,
+ NV_NOTIFY_STATE_STATUS_COMPLETED, 0);
+ nouveauUpdateQuery(ctx, target, q);
+}
+
+static void
+nouveauEndQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q)
+{
+ nouveau_query_object *nq = (nouveau_query_object *)q;
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ switch (nmesa->screen->card->type) {
+ case NV_20:
+ BEGIN_RING_SIZE(NvSub3D, 0x17d0, 1);
+ OUT_RING (0x01000000 | nq->notifier_id*32);
+ break;
+ case NV_30:
+ case NV_40:
+ case NV_44:
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STORE_RESULT, 1);
+ OUT_RING (0x01000000 | nq->notifier_id*32);
+ break;
+ default:
+ WARN_ONCE("no support for this card\n");
+ break;
+ }
+ FIRE_RING();
+
+ /*XXX: wait for query to complete, mesa doesn't give the driver
+ * an interface to query the status of a query object so
+ * this has to stall the channel.
+ */
+ nouveauWaitQueryResult(ctx, target, q);
+
+ BEGIN_RING_CACHE(NvSub3D, 0x17cc, 1);
+ OUT_RING_CACHE (0);
+}
+
+void
+nouveauQueryInitFuncs(GLcontext *ctx)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ if (nmesa->screen->card->type < NV_20)
+ return;
+
+ nmesa->query_object_max = (0x4000 / 32);
+ nmesa->queryNotifier =
+ nouveau_notifier_new(ctx, NvQueryNotify,
+ nmesa->query_object_max);
+ nmesa->query_alloc = calloc(nmesa->query_object_max, sizeof(GLboolean));
+
+ switch (nmesa->screen->card->type) {
+ case NV_20:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SET_OBJECT8, 1);
+ OUT_RING_CACHE (NvQueryNotify);
+ break;
+ case NV_30:
+ case NV_40:
+ case NV_44:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT7, 1);
+ OUT_RING_CACHE (NvQueryNotify);
+ break;
+ default:
+ break;
+ };
+
+ ctx->Driver.NewQueryObject = nouveauNewQueryObject;
+ ctx->Driver.BeginQuery = nouveauBeginQuery;
+ ctx->Driver.EndQuery = nouveauEndQuery;
+#if 0
+ ctx->Driver.UpdateQuery = nouveauUpdateQuery;
+ ctx->Driver.WaitQueryResult = nouveauWaitQueryResult;
+#endif
+}
+
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_query.h b/src/mesa/drivers/dri/nouveau/nouveau_query.h
new file mode 100644
index 00000000000..3ded41417e1
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_query.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __NOUVEAU_QUERY_H__
+#define __NOUVEAU_QUERY_H__
+
+typedef struct nouveau_query_object_t {
+ struct gl_query_object mesa;
+
+ int notifier_id;
+} nouveau_query_object;
+
+extern void nouveauQueryInitFuncs(GLcontext *ctx);
+#endif
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_reg.h b/src/mesa/drivers/dri/nouveau/nouveau_reg.h
new file mode 100644
index 00000000000..8758b538c85
--- /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 00000000000..881b20149f0
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c
@@ -0,0 +1,380 @@
+/**************************************************************************
+
+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, 3 };
+
+ dri_interface = interface;
+
+ if (!driCheckDriDdxDrmVersions2("nouveau",
+ dri_version, & dri_expected,
+ ddx_version, & ddx_expected,
+ drm_version, & drm_expected)) {
+ return NULL;
+ }
+
+ // temporary lock step versioning
+ if (drm_expected.patch!=drm_version->patch) {
+ __driUtilMessage("%s: wrong DRM version, expected %d, got %d\n",
+ __func__,
+ drm_expected.patch, drm_version->patch);
+ return NULL;
+ }
+
+ psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
+ ddx_version, dri_version, drm_version,
+ frame_buffer, pSAREA, fd,
+ internal_api_version, &nouveauAPI);
+ if ( psp != NULL ) {
+ NOUVEAUDRIPtr dri_priv = (NOUVEAUDRIPtr)psp->pDevPriv;
+
+ *driver_modes = nouveauFillInModes(dri_priv->bpp,
+ (dri_priv->bpp == 16) ? 16 : 24,
+ (dri_priv->bpp == 16) ? 0 : 8,
+ 1
+ );
+
+ /* Calling driInitExtensions here, with a NULL context pointer, does not actually
+ * enable the extensions. It just makes sure that all the dispatch offsets for all
+ * the extensions that *might* be enables are known. This is needed because the
+ * dispatch offsets need to be known when _mesa_context_create is called, but we can't
+ * enable the extensions until we have a context pointer.
+ *
+ * Hello chicken. Hello egg. How are you two today?
+ */
+ driInitExtensions( NULL, common_extensions, GL_FALSE );
+ driInitExtensions( NULL, nv10_extensions, GL_FALSE );
+ driInitExtensions( NULL, nv10_extensions, GL_FALSE );
+ driInitExtensions( NULL, nv30_extensions, GL_FALSE );
+ driInitExtensions( NULL, nv40_extensions, GL_FALSE );
+ driInitExtensions( NULL, nv50_extensions, GL_FALSE );
+ }
+
+ return (void *) psp;
+}
+
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.h b/src/mesa/drivers/dri/nouveau/nouveau_screen.h
new file mode 100644
index 00000000000..decdafa86d5
--- /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 00000000000..ba471325aaa
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.c
@@ -0,0 +1,818 @@
+/*
+ * 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 <[email protected]>
+ */
+
+#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(ctx, nvs))
+ return GL_FALSE;
+ /* Basic dead code elimination + register usage info */
+ if (!nouveau_shader_pass1(nvs))
+ return GL_FALSE;
+ /* nouveauShader -> HW bytecode, HW register alloc */
+ if (!nouveau_shader_pass2(nvs))
+ return GL_FALSE;
+ assert(nvs->translated);
+ assert(nvs->program);
+ }
+
+ /* Update state parameters */
+ plist = nvs->mesa.vp.Base.Parameters;
+ _mesa_load_state_parameters(ctx, plist);
+ for (i=0; i<nvs->param_high; i++) {
+ if (!nvs->params[i].in_use)
+ continue;
+
+ if (!nvs->on_hardware) {
+ /* if we've been kicked off the hardware there's no guarantee our
+ * consts are still there.. reupload them all
+ */
+ nvs->func->UpdateConst(ctx, nvs, i);
+ } else if (nvs->params[i].source_val) {
+ /* update any changed state parameters */
+ if (!TEST_EQ_4V(nvs->params[i].val, nvs->params[i].source_val))
+ nvs->func->UpdateConst(ctx, nvs, i);
+ }
+ }
+
+ /* Upload program to hardware, this must come after state param update
+ * as >=NV30 fragprogs inline consts into the bytecode.
+ */
+ if (!nvs->on_hardware) {
+ nouveauShader **current;
+
+ if (nvs->mesa.vp.Base.Target == GL_VERTEX_PROGRAM_ARB)
+ current = &nmesa->current_vertprog;
+ else
+ current = &nmesa->current_fragprog;
+ if (*current) (*current)->on_hardware = 0;
+
+ nvs->func->UploadToHW(ctx, nvs);
+ nvs->on_hardware = 1;
+
+ *current = nvs;
+ }
+
+ return GL_TRUE;
+}
+
+nouveauShader *
+nvsBuildTextShader(GLcontext *ctx, GLenum target, const char *text)
+{
+ nouveauShader *nvs;
+
+ nvs = CALLOC_STRUCT(_nouveauShader);
+ if (!nvs)
+ return NULL;
+
+ if (target == GL_VERTEX_PROGRAM_ARB) {
+ _mesa_init_vertex_program(ctx, &nvs->mesa.vp, GL_VERTEX_PROGRAM_ARB, 0);
+ _mesa_parse_arb_vertex_program(ctx,
+ GL_VERTEX_PROGRAM_ARB,
+ text,
+ strlen(text),
+ &nvs->mesa.vp);
+ } else if (target == GL_FRAGMENT_PROGRAM_ARB) {
+ _mesa_init_fragment_program(ctx, &nvs->mesa.fp, GL_FRAGMENT_PROGRAM_ARB, 0);
+ _mesa_parse_arb_fragment_program(ctx,
+ GL_FRAGMENT_PROGRAM_ARB,
+ text,
+ strlen(text),
+ &nvs->mesa.fp);
+ }
+
+ nouveau_shader_pass0(ctx, nvs);
+ nouveau_shader_pass1(nvs);
+ nouveau_shader_pass2(nvs);
+
+ return nvs;
+}
+
+static void
+nvsBuildPassthroughVP(GLcontext *ctx)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ const char *vp_text =
+ "!!ARBvp1.0\n"
+ "OPTION ARB_position_invariant;"
+ ""
+ "MOV result.color, vertex.color;\n"
+ "MOV result.texcoord[0], vertex.texcoord[0];\n"
+ "MOV result.texcoord[1], vertex.texcoord[1];\n"
+ "MOV result.texcoord[2], vertex.texcoord[2];\n"
+ "MOV result.texcoord[3], vertex.texcoord[3];\n"
+ "MOV result.texcoord[4], vertex.texcoord[4];\n"
+ "MOV result.texcoord[5], vertex.texcoord[5];\n"
+ "MOV result.texcoord[6], vertex.texcoord[6];\n"
+ "MOV result.texcoord[7], vertex.texcoord[7];\n"
+ "END";
+
+ nmesa->passthrough_vp = nvsBuildTextShader(ctx,
+ GL_VERTEX_PROGRAM_ARB,
+ vp_text);
+}
+
+static void
+nvsBuildPassthroughFP(GLcontext *ctx)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ const char *fp_text =
+ "!!ARBfp1.0\n"
+ "MOV result.color, fragment.color;\n"
+ "END";
+
+ nmesa->passthrough_fp = nvsBuildTextShader(ctx,
+ GL_FRAGMENT_PROGRAM_ARB,
+ fp_text);
+}
+
+void
+nouveauShaderInitFuncs(GLcontext * ctx)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ switch (nmesa->screen->card->type) {
+ case NV_20:
+ NV20VPInitShaderFuncs(&nmesa->VPfunc);
+ break;
+ case NV_30:
+ NV30VPInitShaderFuncs(&nmesa->VPfunc);
+ NV30FPInitShaderFuncs(&nmesa->FPfunc);
+ break;
+ case NV_40:
+ case NV_44:
+ NV40VPInitShaderFuncs(&nmesa->VPfunc);
+ NV40FPInitShaderFuncs(&nmesa->FPfunc);
+ break;
+ case NV_50:
+ default:
+ return;
+ }
+
+ /* Build a vertex program that simply passes through all attribs.
+ * Needed to do swtcl on nv40
+ */
+ if (nmesa->screen->card->type >= NV_40)
+ nvsBuildPassthroughVP(ctx);
+
+ /* Needed on NV30, even when using swtcl, if you want to get colours */
+ if (nmesa->screen->card->type >= NV_30)
+ nvsBuildPassthroughFP(ctx);
+
+ ctx->Const.VertexProgram.MaxNativeInstructions = nmesa->VPfunc.MaxInst;
+ ctx->Const.VertexProgram.MaxNativeAluInstructions = nmesa->VPfunc.MaxInst;
+ ctx->Const.VertexProgram.MaxNativeTexInstructions = nmesa->VPfunc.MaxInst;
+ ctx->Const.VertexProgram.MaxNativeTexIndirections =
+ ctx->Const.VertexProgram.MaxNativeTexInstructions;
+ ctx->Const.VertexProgram.MaxNativeAttribs = nmesa->VPfunc.MaxAttrib;
+ ctx->Const.VertexProgram.MaxNativeTemps = nmesa->VPfunc.MaxTemp;
+ ctx->Const.VertexProgram.MaxNativeAddressRegs = nmesa->VPfunc.MaxAddress;
+ ctx->Const.VertexProgram.MaxNativeParameters = nmesa->VPfunc.MaxConst;
+
+ if (nmesa->screen->card->type >= NV_30) {
+ ctx->Const.FragmentProgram.MaxNativeInstructions = nmesa->FPfunc.MaxInst;
+ ctx->Const.FragmentProgram.MaxNativeAluInstructions = nmesa->FPfunc.MaxInst;
+ ctx->Const.FragmentProgram.MaxNativeTexInstructions = nmesa->FPfunc.MaxInst;
+ ctx->Const.FragmentProgram.MaxNativeTexIndirections =
+ ctx->Const.FragmentProgram.MaxNativeTexInstructions;
+ ctx->Const.FragmentProgram.MaxNativeAttribs = nmesa->FPfunc.MaxAttrib;
+ ctx->Const.FragmentProgram.MaxNativeTemps = nmesa->FPfunc.MaxTemp;
+ ctx->Const.FragmentProgram.MaxNativeAddressRegs = nmesa->FPfunc.MaxAddress;
+ ctx->Const.FragmentProgram.MaxNativeParameters = nmesa->FPfunc.MaxConst;
+ }
+
+ ctx->Driver.NewProgram = nouveauNewProgram;
+ ctx->Driver.BindProgram = nouveauBindProgram;
+ ctx->Driver.DeleteProgram = nouveauDeleteProgram;
+ ctx->Driver.ProgramStringNotify = nouveauProgramStringNotify;
+ ctx->Driver.IsProgramNative = nouveauIsProgramNative;
+}
+
+
+/*****************************************************************************
+ * Disassembly support structs
+ */
+#define CHECK_RANGE(idx, arr) ((idx)<sizeof(_##arr)/sizeof(const char *)) \
+ ? _##arr[(idx)] : #arr"_OOB"
+
+#define NODS (1<<0)
+#define BRANCH_TR (1<<1)
+#define BRANCH_EL (1<<2)
+#define BRANCH_EN (1<<3)
+#define BRANCH_RE (1<<4)
+#define BRANCH_ALL (BRANCH_TR|BRANCH_EL|BRANCH_EN)
+#define COUNT_INC (1<<4)
+#define COUNT_IND (1<<5)
+#define COUNT_NUM (1<<6)
+#define COUNT_ALL (COUNT_INC|COUNT_IND|COUNT_NUM)
+#define TI_UNIT (1<<7)
+struct _opcode_info
+{
+ const char *name;
+ int numsrc;
+ int flags;
+};
+
+static struct _opcode_info ops[] = {
+ [NVS_OP_ABS] = {"ABS", 1, 0},
+ [NVS_OP_ADD] = {"ADD", 2, 0},
+ [NVS_OP_ARA] = {"ARA", 1, 0},
+ [NVS_OP_ARL] = {"ARL", 1, 0},
+ [NVS_OP_ARR] = {"ARR", 1, 0},
+ [NVS_OP_BRA] = {"BRA", 0, NODS | BRANCH_TR},
+ [NVS_OP_BRK] = {"BRK", 0, NODS},
+ [NVS_OP_CAL] = {"CAL", 0, NODS | BRANCH_TR},
+ [NVS_OP_CMP] = {"CMP", 2, 0},
+ [NVS_OP_COS] = {"COS", 1, 0},
+ [NVS_OP_DIV] = {"DIV", 2, 0},
+ [NVS_OP_DDX] = {"DDX", 1, 0},
+ [NVS_OP_DDY] = {"DDY", 1, 0},
+ [NVS_OP_DP2] = {"DP2", 2, 0},
+ [NVS_OP_DP2A] = {"DP2A", 3, 0},
+ [NVS_OP_DP3] = {"DP3", 2, 0},
+ [NVS_OP_DP4] = {"DP4", 2, 0},
+ [NVS_OP_DPH] = {"DPH", 2, 0},
+ [NVS_OP_DST] = {"DST", 2, 0},
+ [NVS_OP_EX2] = {"EX2", 1, 0},
+ [NVS_OP_EXP] = {"EXP", 1, 0},
+ [NVS_OP_FLR] = {"FLR", 1, 0},
+ [NVS_OP_FRC] = {"FRC", 1, 0},
+ [NVS_OP_IF] = {"IF", 0, NODS | BRANCH_EL | BRANCH_EN},
+ [NVS_OP_KIL] = {"KIL", 1, 0},
+ [NVS_OP_LG2] = {"LG2", 1, 0},
+ [NVS_OP_LIT] = {"LIT", 1, 0},
+ [NVS_OP_LOG] = {"LOG", 1, 0},
+ [NVS_OP_LOOP] = {"LOOP", 0, NODS | COUNT_ALL | BRANCH_EN},
+ [NVS_OP_LRP] = {"LRP", 3, 0},
+ [NVS_OP_MAD] = {"MAD", 3, 0},
+ [NVS_OP_MAX] = {"MAX", 2, 0},
+ [NVS_OP_MIN] = {"MIN", 2, 0},
+ [NVS_OP_MOV] = {"MOV", 1, 0},
+ [NVS_OP_MUL] = {"MUL", 2, 0},
+ [NVS_OP_NRM] = {"NRM", 1, 0},
+ [NVS_OP_PK2H] = {"PK2H", 1, 0},
+ [NVS_OP_PK2US] = {"PK2US", 1, 0},
+ [NVS_OP_PK4B] = {"PK4B", 1, 0},
+ [NVS_OP_PK4UB] = {"PK4UB", 1, 0},
+ [NVS_OP_POW] = {"POW", 2, 0},
+ [NVS_OP_POPA] = {"POPA", 0, 0},
+ [NVS_OP_PUSHA] = {"PUSHA", 1, NODS},
+ [NVS_OP_RCC] = {"RCC", 1, 0},
+ [NVS_OP_RCP] = {"RCP", 1, 0},
+ [NVS_OP_REP] = {"REP", 0, NODS | BRANCH_EN | COUNT_NUM},
+ [NVS_OP_RET] = {"RET", 0, NODS},
+ [NVS_OP_RFL] = {"RFL", 1, 0},
+ [NVS_OP_RSQ] = {"RSQ", 1, 0},
+ [NVS_OP_SCS] = {"SCS", 1, 0},
+ [NVS_OP_SEQ] = {"SEQ", 2, 0},
+ [NVS_OP_SFL] = {"SFL", 2, 0},
+ [NVS_OP_SGE] = {"SGE", 2, 0},
+ [NVS_OP_SGT] = {"SGT", 2, 0},
+ [NVS_OP_SIN] = {"SIN", 1, 0},
+ [NVS_OP_SLE] = {"SLE", 2, 0},
+ [NVS_OP_SLT] = {"SLT", 2, 0},
+ [NVS_OP_SNE] = {"SNE", 2, 0},
+ [NVS_OP_SSG] = {"SSG", 1, 0},
+ [NVS_OP_STR] = {"STR", 2, 0},
+ [NVS_OP_SUB] = {"SUB", 2, 0},
+ [NVS_OP_TEX] = {"TEX", 1, TI_UNIT},
+ [NVS_OP_TXB] = {"TXB", 1, TI_UNIT},
+ [NVS_OP_TXD] = {"TXD", 3, TI_UNIT},
+ [NVS_OP_TXL] = {"TXL", 1, TI_UNIT},
+ [NVS_OP_TXP] = {"TXP", 1, TI_UNIT},
+ [NVS_OP_UP2H] = {"UP2H", 1, 0},
+ [NVS_OP_UP2US] = {"UP2US", 1, 0},
+ [NVS_OP_UP4B] = {"UP4B", 1, 0},
+ [NVS_OP_UP4UB] = {"UP4UB", 1, 0},
+ [NVS_OP_X2D] = {"X2D", 3, 0},
+ [NVS_OP_XPD] = {"XPD", 2, 0},
+ [NVS_OP_NOP] = {"NOP", 0, NODS},
+};
+
+static struct _opcode_info *
+_get_op_info(int op)
+{
+ if (op >= (sizeof(ops) / sizeof(struct _opcode_info)))
+ return NULL;
+ if (ops[op].name == NULL)
+ return NULL;
+ return &ops[op];
+}
+
+static const char *_SFR_STRING[] = {
+ [NVS_FR_POSITION] = "position",
+ [NVS_FR_WEIGHT] = "weight",
+ [NVS_FR_NORMAL] = "normal",
+ [NVS_FR_COL0] = "color",
+ [NVS_FR_COL1] = "color.secondary",
+ [NVS_FR_BFC0] = "bfc",
+ [NVS_FR_BFC1] = "bfc.secondary",
+ [NVS_FR_FOGCOORD] = "fogcoord",
+ [NVS_FR_POINTSZ] = "pointsize",
+ [NVS_FR_TEXCOORD0] = "texcoord[0]",
+ [NVS_FR_TEXCOORD1] = "texcoord[1]",
+ [NVS_FR_TEXCOORD2] = "texcoord[2]",
+ [NVS_FR_TEXCOORD3] = "texcoord[3]",
+ [NVS_FR_TEXCOORD4] = "texcoord[4]",
+ [NVS_FR_TEXCOORD5] = "texcoord[5]",
+ [NVS_FR_TEXCOORD6] = "texcoord[6]",
+ [NVS_FR_TEXCOORD7] = "texcoord[7]",
+ [NVS_FR_FRAGDATA0] = "data[0]",
+ [NVS_FR_FRAGDATA1] = "data[1]",
+ [NVS_FR_FRAGDATA2] = "data[2]",
+ [NVS_FR_FRAGDATA3] = "data[3]",
+ [NVS_FR_CLIP0] = "clip_plane[0]",
+ [NVS_FR_CLIP1] = "clip_plane[1]",
+ [NVS_FR_CLIP2] = "clip_plane[2]",
+ [NVS_FR_CLIP3] = "clip_plane[3]",
+ [NVS_FR_CLIP4] = "clip_plane[4]",
+ [NVS_FR_CLIP5] = "clip_plane[5]",
+ [NVS_FR_CLIP6] = "clip_plane[6]",
+ [NVS_FR_FACING] = "facing",
+};
+
+#define SFR_STRING(idx) CHECK_RANGE((idx), SFR_STRING)
+
+static const char *_SWZ_STRING[] = {
+ [NVS_SWZ_X] = "x",
+ [NVS_SWZ_Y] = "y",
+ [NVS_SWZ_Z] = "z",
+ [NVS_SWZ_W] = "w"
+};
+
+#define SWZ_STRING(idx) CHECK_RANGE((idx), SWZ_STRING)
+
+static const char *_NVS_PREC_STRING[] = {
+ [NVS_PREC_FLOAT32] = "R",
+ [NVS_PREC_FLOAT16] = "H",
+ [NVS_PREC_FIXED12] = "X",
+ [NVS_PREC_UNKNOWN] = "?"
+};
+
+#define NVS_PREC_STRING(idx) CHECK_RANGE((idx), NVS_PREC_STRING)
+
+static const char *_NVS_COND_STRING[] = {
+ [NVS_COND_FL] = "FL",
+ [NVS_COND_LT] = "LT",
+ [NVS_COND_EQ] = "EQ",
+ [NVS_COND_LE] = "LE",
+ [NVS_COND_GT] = "GT",
+ [NVS_COND_NE] = "NE",
+ [NVS_COND_GE] = "GE",
+ [NVS_COND_TR] = "TR",
+ [NVS_COND_UNKNOWN] = "??"
+};
+
+#define NVS_COND_STRING(idx) CHECK_RANGE((idx), NVS_COND_STRING)
+
+/*****************************************************************************
+ * ShaderFragment dumping
+ */
+static void
+nvsDumpIndent(int lvl)
+{
+ while (lvl--)
+ printf(" ");
+}
+
+static void
+nvsDumpSwizzle(nvsSwzComp *swz)
+{
+ printf(".%s%s%s%s",
+ SWZ_STRING(swz[0]),
+ SWZ_STRING(swz[1]), SWZ_STRING(swz[2]), SWZ_STRING(swz[3])
+ );
+}
+
+static void
+nvsDumpReg(nvsInstruction * inst, nvsRegister * reg)
+{
+ if (reg->negate)
+ printf("-");
+ if (reg->abs)
+ printf("abs(");
+
+ switch (reg->file) {
+ case NVS_FILE_TEMP:
+ printf("R%d", reg->index);
+ nvsDumpSwizzle(reg->swizzle);
+ break;
+ case NVS_FILE_ATTRIB:
+ printf("attrib.%s", SFR_STRING(reg->index));
+ nvsDumpSwizzle(reg->swizzle);
+ break;
+ case NVS_FILE_ADDRESS:
+ printf("A%d", reg->index);
+ break;
+ case NVS_FILE_CONST:
+ if (reg->indexed)
+ printf("const[A%d.%s + %d]",
+ reg->addr_reg, SWZ_STRING(reg->addr_comp), reg->index);
+ else
+ printf("const[%d]", reg->index);
+ nvsDumpSwizzle(reg->swizzle);
+ break;
+ default:
+ printf("UNKNOWN_FILE");
+ break;
+ }
+
+ if (reg->abs)
+ printf(")");
+}
+
+static void
+nvsDumpInstruction(nvsInstruction * inst, int slot, int lvl)
+{
+ struct _opcode_info *opr = &ops[inst->op];
+ int i;
+
+ nvsDumpIndent(lvl);
+ printf("%s ", opr->name);
+
+ if (!opr->flags & NODS) {
+ switch (inst->dest.file) {
+ case NVS_FILE_RESULT:
+ printf("result.%s", SFR_STRING(inst->dest.index));
+ break;
+ case NVS_FILE_TEMP:
+ printf("R%d", inst->dest.index);
+ break;
+ case NVS_FILE_ADDRESS:
+ printf("A%d", inst->dest.index);
+ break;
+ default:
+ printf("UNKNOWN_DST_FILE");
+ break;
+ }
+
+ if (inst->mask != SMASK_ALL) {
+ printf(".");
+ if (inst->mask & SMASK_X)
+ printf("x");
+ if (inst->mask & SMASK_Y)
+ printf("y");
+ if (inst->mask & SMASK_Z)
+ printf("z");
+ if (inst->mask & SMASK_W)
+ printf("w");
+ }
+
+ if (opr->numsrc)
+ printf(", ");
+ }
+
+ for (i = 0; i < opr->numsrc; i++) {
+ nvsDumpReg(inst, &inst->src[i]);
+ if (i != opr->numsrc - 1)
+ printf(", ");
+ }
+ if (opr->flags & TI_UNIT)
+ printf(", texture[%d]", inst->tex_unit);
+
+ printf("\n");
+}
+
+void
+nvsDumpFragmentList(nvsFragmentHeader *f, int lvl)
+{
+ while (f) {
+ switch (f->type) {
+ case NVS_INSTRUCTION:
+ nvsDumpInstruction((nvsInstruction*)f, 0, lvl);
+ break;
+ default:
+ fprintf(stderr, "%s: Only NVS_INSTRUCTION fragments can be in"
+ "nvsFragmentList!\n", __func__);
+ return;
+ }
+ f = f->next;
+ }
+}
+
+/*****************************************************************************
+ * HW shader disassembly
+ */
+static void
+nvsDisasmHWShaderOp(nvsFunc * shader, int merged)
+{
+ struct _opcode_info *opi;
+ nvsOpcode op;
+ nvsRegFile file;
+ nvsSwzComp swz[4];
+ int i;
+
+ op = shader->GetOpcode(shader, merged);
+ opi = _get_op_info(op);
+ if (!opi) {
+ printf("NO OPINFO!");
+ return;
+ }
+
+ printf("%s", opi->name);
+ if (shader->GetPrecision &&
+ (!(opi->flags & BRANCH_ALL)) && (!(opi->flags * NODS)) &&
+ (op != NVS_OP_NOP))
+ printf("%s", NVS_PREC_STRING(shader->GetPrecision(shader)));
+ if (shader->SupportsConditional && shader->SupportsConditional(shader)) {
+ if (shader->GetConditionUpdate(shader)) {
+ printf("C%d", shader->GetCondRegID(shader));
+ }
+ }
+ if (shader->GetSaturate && shader->GetSaturate(shader))
+ printf("_SAT");
+
+ if (!(opi->flags & NODS)) {
+ int mask = shader->GetDestMask(shader, merged);
+
+ switch (shader->GetDestFile(shader, merged)) {
+ case NVS_FILE_ADDRESS:
+ printf(" A%d", shader->GetDestID(shader, merged));
+ break;
+ case NVS_FILE_TEMP:
+ printf(" R%d", shader->GetDestID(shader, merged));
+ break;
+ case NVS_FILE_RESULT:
+ printf(" result.%s", (SFR_STRING(shader->GetDestID(shader, merged))));
+ break;
+ default:
+ printf(" BAD_RESULT_FILE");
+ break;
+ }
+
+ if (mask != SMASK_ALL) {
+ printf(".");
+ if (mask & SMASK_X) printf("x");
+ if (mask & SMASK_Y) printf("y");
+ if (mask & SMASK_Z) printf("z");
+ if (mask & SMASK_W) printf("w");
+ }
+ }
+
+ if (shader->SupportsConditional && shader->SupportsConditional(shader) &&
+ shader->GetConditionTest(shader)) {
+ shader->GetCondRegSwizzle(shader, swz);
+
+ printf(" (%s%d.%s%s%s%s)",
+ NVS_COND_STRING(shader->GetCondition(shader)),
+ shader->GetCondRegID(shader),
+ SWZ_STRING(swz[NVS_SWZ_X]),
+ SWZ_STRING(swz[NVS_SWZ_Y]),
+ SWZ_STRING(swz[NVS_SWZ_Z]),
+ SWZ_STRING(swz[NVS_SWZ_W])
+ );
+ }
+
+ /* looping */
+ if (opi->flags & COUNT_ALL) {
+ printf(" { ");
+ if (opi->flags & COUNT_NUM) {
+ printf("%d", shader->GetLoopCount(shader));
+ }
+ if (opi->flags & COUNT_IND) {
+ printf(", %d", shader->GetLoopInitial(shader));
+ }
+ if (opi->flags & COUNT_INC) {
+ printf(", %d", shader->GetLoopIncrement(shader));
+ }
+ printf(" }");
+ }
+
+ /* branching */
+ if (opi->flags & BRANCH_TR)
+ printf(" %d", shader->GetBranch(shader));
+ if (opi->flags & BRANCH_EL)
+ printf(" ELSE %d", shader->GetBranchElse(shader));
+ if (opi->flags & BRANCH_EN)
+ printf(" END %d", shader->GetBranchEnd(shader));
+
+ if (!(opi->flags & NODS) && opi->numsrc)
+ printf(",");
+ printf(" ");
+
+ for (i = 0; i < opi->numsrc; i++) {
+ if (shader->GetSourceAbs(shader, merged, i))
+ printf("abs(");
+ if (shader->GetSourceNegate(shader, merged, i))
+ printf("-");
+
+ file = shader->GetSourceFile(shader, merged, i);
+ switch (file) {
+ case NVS_FILE_TEMP:
+ printf("R%d", shader->GetSourceID(shader, merged, i));
+ break;
+ case NVS_FILE_CONST:
+ if (shader->GetSourceIndexed(shader, merged, i)) {
+ printf("c[A%d.%s + 0x%x]",
+ shader->GetRelAddressRegID(shader),
+ SWZ_STRING(shader->GetRelAddressSwizzle(shader)),
+ shader->GetSourceID(shader, merged, i)
+ );
+ } else {
+ float val[4];
+
+ if (shader->GetSourceConstVal) {
+ shader->GetSourceConstVal(shader, merged, i, val);
+ printf("{ %.02f, %.02f, %.02f, %.02f }",
+ val[0], val[1], val[2], val[3]);
+ } else {
+ printf("c[0x%x]", shader->GetSourceID(shader, merged, i));
+ }
+ }
+ break;
+ case NVS_FILE_ATTRIB:
+ if (shader->GetSourceIndexed(shader, merged, i)) {
+ printf("attrib[A%d.%s + %d]",
+ shader->GetRelAddressRegID(shader),
+ SWZ_STRING(shader->GetRelAddressSwizzle(shader)),
+ shader->GetSourceID(shader, merged, i)
+ );
+ }
+ else {
+ printf("attrib.%s",
+ SFR_STRING(shader->GetSourceID(shader, merged, i))
+ );
+ }
+ break;
+ case NVS_FILE_ADDRESS:
+ printf("A%d", shader->GetRelAddressRegID(shader));
+ break;
+ default:
+ printf("UNKNOWN_SRC_FILE");
+ break;
+ }
+
+ shader->GetSourceSwizzle(shader, merged, i, swz);
+ if (file != NVS_FILE_ADDRESS &&
+ (swz[NVS_SWZ_X] != NVS_SWZ_X || swz[NVS_SWZ_Y] != NVS_SWZ_Y ||
+ swz[NVS_SWZ_Z] != NVS_SWZ_Z || swz[NVS_SWZ_W] != NVS_SWZ_W)) {
+ printf(".%s%s%s%s", SWZ_STRING(swz[NVS_SWZ_X]),
+ SWZ_STRING(swz[NVS_SWZ_Y]),
+ SWZ_STRING(swz[NVS_SWZ_Z]),
+ SWZ_STRING(swz[NVS_SWZ_W]));
+ }
+
+ if (shader->GetSourceAbs(shader, merged, i))
+ printf(")");
+ if (shader->GetSourceScale) {
+ int scale = shader->GetSourceScale(shader, merged, i);
+ if (scale > 1)
+ printf("{scaled %dx}", scale);
+ }
+ if (i < (opi->numsrc - 1))
+ printf(", ");
+ }
+
+ if (shader->IsLastInst(shader))
+ printf(" + END");
+}
+
+void
+nvsDisasmHWShader(nvsPtr nvs)
+{
+ nvsFunc *shader = nvs->func;
+ unsigned int iaddr = 0;
+
+ if (!nvs->program) {
+ fprintf(stderr, "No HW program present");
+ return;
+ }
+
+ shader->inst = nvs->program;
+ while (1) {
+ if (shader->inst >= (nvs->program + nvs->program_size)) {
+ fprintf(stderr, "Reached end of program, but HW inst has no END");
+ break;
+ }
+
+ printf("\t0x%08x:\n", shader->inst[0]);
+ printf("\t0x%08x:\n", shader->inst[1]);
+ printf("\t0x%08x:\n", shader->inst[2]);
+ printf("\t0x%08x:", shader->inst[3]);
+
+ printf("\n\t\tINST %d.0: ", iaddr);
+ nvsDisasmHWShaderOp(shader, 0);
+ if (shader->HasMergedInst(shader)) {
+ printf("\n\t\tINST %d.1: ", iaddr);
+ nvsDisasmHWShaderOp(shader, 1);
+ }
+ printf("\n");
+
+ if (shader->IsLastInst(shader))
+ break;
+
+ shader->inst += shader->GetOffsetNext(shader);
+ iaddr++;
+ }
+
+ printf("\n");
+}
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h
new file mode 100644
index 00000000000..b2df3546f62
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h
@@ -0,0 +1,441 @@
+#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 _nvs_fragment_header {
+ struct _nvs_fragment_header *parent;
+ struct _nvs_fragment_header *prev;
+ struct _nvs_fragment_header *next;
+ enum {
+ NVS_INSTRUCTION,
+ NVS_BRANCH,
+ NVS_LOOP,
+ NVS_SUBROUTINE
+ } type;
+} nvsFragmentHeader;
+
+typedef union {
+ struct {
+ GLboolean uses_kil;
+ GLuint num_regs;
+ } NV30FP;
+ struct {
+ uint32_t vp_in_reg;
+ uint32_t vp_out_reg;
+ uint32_t clip_enables;
+ } NV30VP;
+} nvsCardPriv;
+
+typedef struct _nouveauShader {
+ union {
+ struct gl_vertex_program vp;
+ struct gl_fragment_program fp;
+ } mesa;
+ GLcontext *ctx;
+ nvsFunc *func;
+
+ /* State of the final program */
+ GLboolean translated;
+ GLboolean on_hardware;
+ unsigned int *program;
+ unsigned int program_size;
+ unsigned int program_alloc_size;
+ unsigned int program_start_id;
+ unsigned int program_current;
+ struct gl_buffer_object *program_buffer;
+ int inst_count;
+
+ nvsCardPriv card_priv;
+ int vp_attrib_map[NVS_MAX_ATTRIBS];
+
+ struct {
+ GLboolean in_use;
+
+ GLfloat *source_val; /* NULL if invariant */
+ float val[4];
+ /* Hardware-specific tracking, currently only nv30_fragprog
+ * makes use of it.
+ */
+ int *hw_index;
+ int hw_index_cnt;
+ } params[NVS_MAX_CONSTS];
+ int param_high;
+
+ /* Pass-private data */
+ void *pass_rec;
+
+ nvsFragmentHeader *program_tree;
+} nouveauShader, *nvsPtr;
+
+typedef enum {
+ NVS_FILE_NONE,
+ NVS_FILE_TEMP,
+ NVS_FILE_ATTRIB,
+ NVS_FILE_CONST,
+ NVS_FILE_RESULT,
+ NVS_FILE_ADDRESS,
+ NVS_FILE_UNKNOWN
+} nvsRegFile;
+
+typedef enum {
+ NVS_OP_UNKNOWN = 0,
+ NVS_OP_NOP,
+ NVS_OP_ABS, NVS_OP_ADD, NVS_OP_ARA, NVS_OP_ARL, NVS_OP_ARR,
+ NVS_OP_BRA, NVS_OP_BRK,
+ NVS_OP_CAL, NVS_OP_CMP, NVS_OP_COS,
+ NVS_OP_DDX, NVS_OP_DDY, NVS_OP_DIV, NVS_OP_DP2, NVS_OP_DP2A, NVS_OP_DP3,
+ NVS_OP_DP4, NVS_OP_DPH, NVS_OP_DST,
+ NVS_OP_EX2, NVS_OP_EXP,
+ NVS_OP_FLR, NVS_OP_FRC,
+ NVS_OP_IF,
+ NVS_OP_KIL,
+ NVS_OP_LG2, NVS_OP_LIT, NVS_OP_LOG, NVS_OP_LOOP, NVS_OP_LRP,
+ NVS_OP_MAD, NVS_OP_MAX, NVS_OP_MIN, NVS_OP_MOV, NVS_OP_MUL,
+ NVS_OP_NRM,
+ NVS_OP_PK2H, NVS_OP_PK2US, NVS_OP_PK4B, NVS_OP_PK4UB, NVS_OP_POW,
+ NVS_OP_POPA, NVS_OP_PUSHA,
+ NVS_OP_RCC, NVS_OP_RCP, NVS_OP_REP, NVS_OP_RET, NVS_OP_RFL, NVS_OP_RSQ,
+ NVS_OP_SCS, NVS_OP_SEQ, NVS_OP_SFL, NVS_OP_SGE, NVS_OP_SGT, NVS_OP_SIN,
+ NVS_OP_SLE, NVS_OP_SLT, NVS_OP_SNE, NVS_OP_SSG, NVS_OP_STR, NVS_OP_SUB,
+ NVS_OP_SWZ,
+ NVS_OP_TEX, NVS_OP_TXB, NVS_OP_TXD, NVS_OP_TXL, NVS_OP_TXP,
+ NVS_OP_UP2H, NVS_OP_UP2US, NVS_OP_UP4B, NVS_OP_UP4UB,
+ NVS_OP_X2D, NVS_OP_XPD,
+ NVS_OP_EMUL
+} nvsOpcode;
+
+typedef enum {
+ NVS_PREC_FLOAT32,
+ NVS_PREC_FLOAT16,
+ NVS_PREC_FIXED12,
+ NVS_PREC_UNKNOWN
+} nvsPrecision;
+
+typedef enum {
+ NVS_SWZ_X = 0,
+ NVS_SWZ_Y = 1,
+ NVS_SWZ_Z = 2,
+ NVS_SWZ_W = 3
+} nvsSwzComp;
+
+typedef enum {
+ NVS_FR_POSITION = 0,
+ NVS_FR_WEIGHT = 1,
+ NVS_FR_NORMAL = 2,
+ NVS_FR_COL0 = 3,
+ NVS_FR_COL1 = 4,
+ NVS_FR_FOGCOORD = 5,
+ NVS_FR_TEXCOORD0 = 8,
+ NVS_FR_TEXCOORD1 = 9,
+ NVS_FR_TEXCOORD2 = 10,
+ NVS_FR_TEXCOORD3 = 11,
+ NVS_FR_TEXCOORD4 = 12,
+ NVS_FR_TEXCOORD5 = 13,
+ NVS_FR_TEXCOORD6 = 14,
+ NVS_FR_TEXCOORD7 = 15,
+ NVS_FR_BFC0 = 16,
+ NVS_FR_BFC1 = 17,
+ NVS_FR_POINTSZ = 18,
+ NVS_FR_FRAGDATA0 = 19,
+ NVS_FR_FRAGDATA1 = 20,
+ NVS_FR_FRAGDATA2 = 21,
+ NVS_FR_FRAGDATA3 = 22,
+ NVS_FR_CLIP0 = 23,
+ NVS_FR_CLIP1 = 24,
+ NVS_FR_CLIP2 = 25,
+ NVS_FR_CLIP3 = 26,
+ NVS_FR_CLIP4 = 27,
+ NVS_FR_CLIP5 = 28,
+ NVS_FR_CLIP6 = 29,
+ NVS_FR_FACING = 30,
+ NVS_FR_UNKNOWN
+} nvsFixedReg;
+
+typedef enum {
+ NVS_COND_FL, NVS_COND_LT, NVS_COND_EQ, NVS_COND_LE, NVS_COND_GT,
+ NVS_COND_NE, NVS_COND_GE, NVS_COND_TR, NVS_COND_UN,
+ NVS_COND_UNKNOWN
+} nvsCond;
+
+typedef struct {
+ nvsRegFile file;
+ unsigned int index;
+
+ unsigned int indexed;
+ unsigned int addr_reg;
+ nvsSwzComp addr_comp;
+
+ nvsSwzComp swizzle[4];
+ int negate;
+ int abs;
+} nvsRegister;
+
+static const nvsRegister nvr_unused = {
+ .file = NVS_FILE_ATTRIB,
+ .index = 0,
+ .indexed = 0,
+ .addr_reg = 0,
+ .addr_comp = NVS_SWZ_X,
+ .swizzle = {NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W},
+ .negate = 0,
+ .abs = 0,
+};
+
+typedef enum {
+ NVS_TEX_TARGET_1D,
+ NVS_TEX_TARGET_2D,
+ NVS_TEX_TARGET_3D,
+ NVS_TEX_TARGET_CUBE,
+ NVS_TEX_TARGET_RECT,
+ NVS_TEX_TARGET_UNKNOWN = 0
+} nvsTexTarget;
+
+typedef enum {
+ NVS_SCALE_1X = 0,
+ NVS_SCALE_2X = 1,
+ NVS_SCALE_4X = 2,
+ NVS_SCALE_8X = 3,
+ NVS_SCALE_INV_2X = 5,
+ NVS_SCALE_INV_4X = 6,
+ NVS_SCALE_INV_8X = 7,
+} nvsScale;
+
+/* Arith/TEX instructions */
+typedef struct nvs_instruction {
+ nvsFragmentHeader header;
+
+ nvsOpcode op;
+ unsigned int saturate;
+
+ nvsRegister dest;
+ unsigned int mask;
+ nvsScale dest_scale;
+
+ nvsRegister src[3];
+
+ unsigned int tex_unit;
+ nvsTexTarget tex_target;
+
+ nvsCond cond;
+ nvsSwzComp cond_swizzle[4];
+ int cond_reg;
+ int cond_test;
+ int cond_update;
+} nvsInstruction;
+
+/* BRA, CAL, IF */
+typedef struct nvs_branch {
+ nvsFragmentHeader header;
+
+ nvsOpcode op;
+
+ nvsCond cond;
+ nvsSwzComp cond_swizzle[4];
+ int cond_test;
+
+ nvsFragmentHeader *target_head;
+ nvsFragmentHeader *target_tail;
+ nvsFragmentHeader *else_head;
+ nvsFragmentHeader *else_tail;
+} nvsBranch;
+
+/* LOOP+ENDLOOP */
+typedef struct {
+ nvsFragmentHeader header;
+
+ int count;
+ int initial;
+ int increment;
+
+ nvsFragmentHeader *insn_head;
+ nvsFragmentHeader *insn_tail;
+} nvsLoop;
+
+/* label+following instructions */
+typedef struct nvs_subroutine {
+ nvsFragmentHeader header;
+
+ char * label;
+ nvsFragmentHeader *insn_head;
+ nvsFragmentHeader *insn_tail;
+} nvsSubroutine;
+
+#define SMASK_X (1<<0)
+#define SMASK_Y (1<<1)
+#define SMASK_Z (1<<2)
+#define SMASK_W (1<<3)
+#define SMASK_ALL (SMASK_X|SMASK_Y|SMASK_Z|SMASK_W)
+
+#define SPOS_ADDRESS 3
+struct _op_xlat {
+ unsigned int NV;
+ nvsOpcode SOP;
+ int srcpos[3];
+};
+#define MOD_OPCODE(t,hw,sop,s0,s1,s2) do { \
+ t[hw].NV = hw; \
+ t[hw].SOP = sop; \
+ t[hw].srcpos[0] = s0; \
+ t[hw].srcpos[1] = s1; \
+ t[hw].srcpos[2] = s2; \
+} while(0)
+
+extern unsigned int NVVP_TX_VOP_COUNT;
+extern unsigned int NVVP_TX_NVS_OP_COUNT;
+extern struct _op_xlat NVVP_TX_VOP[];
+extern struct _op_xlat NVVP_TX_SOP[];
+
+extern unsigned int NVFP_TX_AOP_COUNT;
+extern unsigned int NVFP_TX_BOP_COUNT;
+extern struct _op_xlat NVFP_TX_AOP[];
+extern struct _op_xlat NVFP_TX_BOP[];
+
+extern void NV20VPTXSwizzle(int hwswz, nvsSwzComp *swz);
+extern nvsSwzComp NV20VP_TX_SWIZZLE[4];
+
+#define SCAP_SRC_ABS (1<<0)
+
+struct _nvsFunc {
+ nvsCardPriv *card_priv;
+
+ unsigned int MaxInst;
+ unsigned int MaxAttrib;
+ unsigned int MaxTemp;
+ unsigned int MaxAddress;
+ unsigned int MaxConst;
+ unsigned int caps;
+
+ unsigned int *inst;
+ void (*UploadToHW) (GLcontext *, nouveauShader *);
+ void (*UpdateConst) (GLcontext *, nouveauShader *, int);
+
+ struct _op_xlat*(*GetOPTXRec) (nvsFunc *, int merged);
+ struct _op_xlat*(*GetOPTXFromSOP) (nvsOpcode, int *id);
+
+ void (*InitInstruction) (nvsFunc *);
+ int (*SupportsOpcode) (nvsFunc *, nvsOpcode);
+ int (*SupportsResultScale) (nvsFunc *, nvsScale);
+ void (*SetOpcode) (nvsFunc *, unsigned int opcode,
+ int slot);
+ void (*SetCCUpdate) (nvsFunc *);
+ void (*SetCondition) (nvsFunc *, int on, nvsCond, int reg,
+ nvsSwzComp *swizzle);
+ void (*SetResult) (nvsFunc *, nvsRegister *,
+ unsigned int mask, int slot);
+ void (*SetResultScale) (nvsFunc *, nvsScale);
+ void (*SetSource) (nvsFunc *, nvsRegister *, int pos);
+ void (*SetTexImageUnit) (nvsFunc *, int unit);
+ void (*SetSaturate) (nvsFunc *);
+ void (*SetLastInst) (nvsFunc *);
+
+ void (*SetBranchTarget) (nvsFunc *, int addr);
+ void (*SetBranchElse) (nvsFunc *, int addr);
+ void (*SetBranchEnd) (nvsFunc *, int addr);
+ void (*SetLoopParams) (nvsFunc *, int cnt, int init, int inc);
+
+ int (*HasMergedInst) (nvsFunc *);
+ int (*IsLastInst) (nvsFunc *);
+ int (*GetOffsetNext) (nvsFunc *);
+
+ int (*GetOpcodeSlot) (nvsFunc *, int merged);
+ unsigned int (*GetOpcodeHW) (nvsFunc *, int slot);
+ nvsOpcode (*GetOpcode) (nvsFunc *, int merged);
+
+ nvsPrecision (*GetPrecision) (nvsFunc *);
+ int (*GetSaturate) (nvsFunc *);
+
+ nvsRegFile (*GetDestFile) (nvsFunc *, int merged);
+ unsigned int (*GetDestID) (nvsFunc *, int merged);
+ unsigned int (*GetDestMask) (nvsFunc *, int merged);
+
+ unsigned int (*GetSourceHW) (nvsFunc *, int merged, int pos);
+ nvsRegFile (*GetSourceFile) (nvsFunc *, int merged, int pos);
+ int (*GetSourceID) (nvsFunc *, int merged, int pos);
+ int (*GetTexImageUnit) (nvsFunc *);
+ int (*GetSourceNegate) (nvsFunc *, int merged, int pos);
+ int (*GetSourceAbs) (nvsFunc *, int merged, int pos);
+ void (*GetSourceSwizzle) (nvsFunc *, int merged, int pos,
+ nvsSwzComp *swz);
+ int (*GetSourceIndexed) (nvsFunc *, int merged, int pos);
+ void (*GetSourceConstVal) (nvsFunc *, int merged, int pos,
+ float *val);
+ int (*GetSourceScale) (nvsFunc *, int merged, int pos);
+
+ int (*GetRelAddressRegID) (nvsFunc *);
+ nvsSwzComp (*GetRelAddressSwizzle) (nvsFunc *);
+
+ int (*SupportsConditional) (nvsFunc *);
+ int (*GetConditionUpdate) (nvsFunc *);
+ int (*GetConditionTest) (nvsFunc *);
+ nvsCond (*GetCondition) (nvsFunc *);
+ void (*GetCondRegSwizzle) (nvsFunc *, nvsSwzComp *swz);
+ int (*GetCondRegID) (nvsFunc *);
+ int (*GetBranch) (nvsFunc *);
+ int (*GetBranchElse) (nvsFunc *);
+ int (*GetBranchEnd) (nvsFunc *);
+
+ int (*GetLoopCount) (nvsFunc *);
+ int (*GetLoopInitial) (nvsFunc *);
+ int (*GetLoopIncrement) (nvsFunc *);
+};
+
+static inline nvsRegister
+nvsNegate(nvsRegister reg)
+{
+ reg.negate = !reg.negate;
+ return reg;
+}
+
+static inline nvsRegister
+nvsAbs(nvsRegister reg)
+{
+ reg.abs = 1;
+ return reg;
+}
+
+static inline nvsRegister
+nvsSwizzle(nvsRegister reg, nvsSwzComp x, nvsSwzComp y,
+ nvsSwzComp z, nvsSwzComp w)
+{
+ nvsSwzComp sc[4] = { x, y, z, w };
+ nvsSwzComp oc[4];
+ int i;
+
+ for (i=0;i<4;i++)
+ oc[i] = reg.swizzle[i];
+ for (i=0;i<4;i++)
+ reg.swizzle[i] = oc[sc[i]];
+ return reg;
+}
+
+extern GLboolean nvsUpdateShader(GLcontext *ctx, nouveauShader *nvs);
+extern void nvsDisasmHWShader(nvsPtr);
+extern void nvsDumpFragmentList(nvsFragmentHeader *f, int lvl);
+extern nouveauShader *nvsBuildTextShader(GLcontext *ctx, GLenum target,
+ const char *text);
+
+extern void NV20VPInitShaderFuncs(nvsFunc *);
+extern void NV30VPInitShaderFuncs(nvsFunc *);
+extern void NV40VPInitShaderFuncs(nvsFunc *);
+
+extern void NV30FPInitShaderFuncs(nvsFunc *);
+extern void NV40FPInitShaderFuncs(nvsFunc *);
+
+extern void nouveauShaderInitFuncs(GLcontext *ctx);
+
+extern GLboolean nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs);
+extern GLboolean nouveau_shader_pass1(nvsPtr nvs);
+extern GLboolean nouveau_shader_pass2(nvsPtr nvs);
+
+#endif
+
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c
new file mode 100644
index 00000000000..73c1f7c2a53
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c
@@ -0,0 +1,1006 @@
+/*
+ * 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 <[email protected]>
+ */
+
+#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"
+#include "nouveau_msg.h"
+
+static nvsFixedReg _tx_mesa_vp_dst_reg[VERT_RESULT_MAX] = {
+ NVS_FR_POSITION, NVS_FR_COL0, NVS_FR_COL1, NVS_FR_FOGCOORD,
+ NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3,
+ NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7,
+ NVS_FR_POINTSZ, NVS_FR_BFC0, NVS_FR_BFC1, NVS_FR_UNKNOWN /* EDGE */
+};
+
+static nvsFixedReg _tx_mesa_fp_dst_reg[FRAG_RESULT_MAX] = {
+ NVS_FR_FRAGDATA0 /* COLR */, NVS_FR_FRAGDATA0 /* COLH */,
+ NVS_FR_UNKNOWN /* DEPR */
+};
+
+static nvsFixedReg _tx_mesa_fp_src_reg[FRAG_ATTRIB_MAX] = {
+ NVS_FR_POSITION, NVS_FR_COL0, NVS_FR_COL1, NVS_FR_FOGCOORD,
+ NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3,
+ NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7
+};
+
+static nvsSwzComp _tx_mesa_swizzle[4] = {
+ NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W
+};
+
+static nvsOpcode _tx_mesa_opcode[] = {
+ [OPCODE_ABS] = NVS_OP_ABS, [OPCODE_ADD] = NVS_OP_ADD,
+ [OPCODE_ARA] = NVS_OP_ARA, [OPCODE_ARL] = NVS_OP_ARL,
+ [OPCODE_ARL_NV] = NVS_OP_ARL, [OPCODE_ARR] = NVS_OP_ARR,
+ [OPCODE_CMP] = NVS_OP_CMP, [OPCODE_COS] = NVS_OP_COS,
+ [OPCODE_DDX] = NVS_OP_DDX, [OPCODE_DDY] = NVS_OP_DDY,
+ [OPCODE_DP3] = NVS_OP_DP3, [OPCODE_DP4] = NVS_OP_DP4,
+ [OPCODE_DPH] = NVS_OP_DPH, [OPCODE_DST] = NVS_OP_DST,
+ [OPCODE_EX2] = NVS_OP_EX2, [OPCODE_EXP] = NVS_OP_EXP,
+ [OPCODE_FLR] = NVS_OP_FLR, [OPCODE_FRC] = NVS_OP_FRC,
+ [OPCODE_KIL] = NVS_OP_EMUL, [OPCODE_KIL_NV] = NVS_OP_KIL,
+ [OPCODE_LG2] = NVS_OP_LG2, [OPCODE_LIT] = NVS_OP_LIT,
+ [OPCODE_LOG] = NVS_OP_LOG,
+ [OPCODE_LRP] = NVS_OP_LRP,
+ [OPCODE_MAD] = NVS_OP_MAD, [OPCODE_MAX] = NVS_OP_MAX,
+ [OPCODE_MIN] = NVS_OP_MIN, [OPCODE_MOV] = NVS_OP_MOV,
+ [OPCODE_MUL] = NVS_OP_MUL,
+ [OPCODE_PK2H] = NVS_OP_PK2H, [OPCODE_PK2US] = NVS_OP_PK2US,
+ [OPCODE_PK4B] = NVS_OP_PK4B, [OPCODE_PK4UB] = NVS_OP_PK4UB,
+ [OPCODE_POW] = NVS_OP_POW, [OPCODE_POPA] = NVS_OP_POPA,
+ [OPCODE_PUSHA] = NVS_OP_PUSHA,
+ [OPCODE_RCC] = NVS_OP_RCC, [OPCODE_RCP] = NVS_OP_RCP,
+ [OPCODE_RFL] = NVS_OP_RFL, [OPCODE_RSQ] = NVS_OP_RSQ,
+ [OPCODE_SCS] = NVS_OP_SCS, [OPCODE_SEQ] = NVS_OP_SEQ,
+ [OPCODE_SFL] = NVS_OP_SFL, [OPCODE_SGE] = NVS_OP_SGE,
+ [OPCODE_SGT] = NVS_OP_SGT, [OPCODE_SIN] = NVS_OP_SIN,
+ [OPCODE_SLE] = NVS_OP_SLE, [OPCODE_SLT] = NVS_OP_SLT,
+ [OPCODE_SNE] = NVS_OP_SNE, [OPCODE_SSG] = NVS_OP_SSG,
+ [OPCODE_STR] = NVS_OP_STR, [OPCODE_SUB] = NVS_OP_SUB,
+ [OPCODE_SWZ] = NVS_OP_MOV,
+ [OPCODE_TEX] = NVS_OP_TEX, [OPCODE_TXB] = NVS_OP_TXB,
+ [OPCODE_TXD] = NVS_OP_TXD,
+ [OPCODE_TXL] = NVS_OP_TXL, [OPCODE_TXP] = NVS_OP_TXP,
+ [OPCODE_TXP_NV] = NVS_OP_TXP,
+ [OPCODE_UP2H] = NVS_OP_UP2H, [OPCODE_UP2US] = NVS_OP_UP2US,
+ [OPCODE_UP4B] = NVS_OP_UP4B, [OPCODE_UP4UB] = NVS_OP_UP4UB,
+ [OPCODE_X2D] = NVS_OP_X2D,
+ [OPCODE_XPD] = NVS_OP_XPD
+};
+
+static nvsCond _tx_mesa_condmask[] = {
+ NVS_COND_TR, /* workaround mesa not filling a valid value */
+ NVS_COND_GT, NVS_COND_LT, NVS_COND_UN, NVS_COND_GE,
+ NVS_COND_LE, NVS_COND_NE, NVS_COND_NE, NVS_COND_TR, NVS_COND_FL
+};
+
+struct pass0_rec {
+ int nvs_ipos;
+ int next_temp;
+
+ int mesa_const_base;
+ int mesa_const_last;
+
+ int swzconst_done;
+ int swzconst_id;
+ nvsRegister const_half;
+};
+
+#define X NVS_SWZ_X
+#define Y NVS_SWZ_Y
+#define Z NVS_SWZ_Z
+#define W NVS_SWZ_W
+
+#define FILL_CONDITION_FLAGS(fragment) do { \
+ (fragment)->cond = \
+ pass0_make_condmask(inst->DstReg.CondMask); \
+ if ((fragment)->cond != NVS_COND_TR) \
+ (fragment)->cond_test = 1; \
+ (fragment)->cond_reg = inst->CondDst; \
+ pass0_make_swizzle((fragment)->cond_swizzle, inst->DstReg.CondSwizzle);\
+} while(0)
+
+#define ARITH(op,dest,mask,sat,s0,s1,s2) do { \
+ nvsinst = pass0_emit(nvs, parent, fpos, (op), \
+ (dest), (mask), (sat), (s0), (s1), (s2));\
+ FILL_CONDITION_FLAGS(nvsinst); \
+} while(0)
+
+#define ARITHu(op,dest,mask,sat,s0,s1,s2) do { \
+ nvsinst = pass0_emit(nvs, parent, fpos, (op), \
+ (dest), (mask), (sat), (s0), (s1), (s2));\
+} while(0)
+
+static void
+pass0_append_fragment(nvsFragmentHeader *parent,
+ nvsFragmentHeader *fragment,
+ int pos)
+{
+ nvsFragmentHeader **head, **tail;
+ assert(parent && fragment);
+
+ switch (parent->type) {
+ case NVS_BRANCH:
+ if (pos == 0) {
+ head = &((nvsBranch *)parent)->target_head;
+ tail = &((nvsBranch *)parent)->target_tail;
+ } else {
+ head = &((nvsBranch *)parent)->else_head;
+ tail = &((nvsBranch *)parent)->else_tail;
+ }
+ break;
+ case NVS_LOOP:
+ head = &((nvsLoop *)parent)->insn_head;
+ tail = &((nvsLoop *)parent)->insn_tail;
+ break;
+ case NVS_SUBROUTINE:
+ head = &((nvsSubroutine *)parent)->insn_head;
+ tail = &((nvsSubroutine *)parent)->insn_tail;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ fragment->parent = parent;
+ fragment->prev = *tail;
+ fragment->next = NULL;
+ if (!(*head))
+ *head = fragment;
+ else
+ (*tail)->next = fragment;
+ *tail = fragment;
+
+}
+
+static nvsSubroutine *
+pass0_create_subroutine(nouveauShader *nvs, const char *label)
+{
+ nvsSubroutine *sub;
+
+ sub = CALLOC_STRUCT(nvs_subroutine);
+ if (sub) {
+ sub->header.type = NVS_SUBROUTINE;
+ sub->label = strdup(label);
+ if (!nvs->program_tree)
+ nvs->program_tree = &sub->header;
+ else
+ pass0_append_fragment(nvs->program_tree,
+ &sub->header, 0);
+ }
+
+ return sub;
+}
+
+static void
+pass0_make_reg(nouveauShader *nvs, nvsRegister *reg,
+ nvsRegFile file, unsigned int index)
+{
+ struct pass0_rec *rec = nvs->pass_rec;
+
+ /* defaults */
+ *reg = nvr_unused;
+ /* -1 == quick-and-dirty temp alloc */
+ if (file == NVS_FILE_TEMP && index == -1) {
+ index = rec->next_temp++;
+ assert(index < NVS_MAX_TEMPS);
+ }
+ reg->file = file;
+ reg->index = index;
+}
+
+static void
+pass0_make_swizzle(nvsSwzComp *swz, unsigned int mesa)
+{
+ int i;
+
+ for (i=0;i<4;i++)
+ swz[i] = _tx_mesa_swizzle[GET_SWZ(mesa, i)];
+}
+
+static nvsOpcode
+pass0_make_opcode(enum prog_opcode op)
+{
+ if (op > MAX_OPCODE)
+ return NVS_OP_UNKNOWN;
+ return _tx_mesa_opcode[op];
+}
+
+static nvsCond
+pass0_make_condmask(GLuint mesa)
+{
+ if (mesa > COND_FL)
+ return NVS_COND_UNKNOWN;
+ return _tx_mesa_condmask[mesa];
+}
+
+static unsigned int
+pass0_make_mask(GLuint mesa_mask)
+{
+ unsigned int mask = 0;
+
+ if (mesa_mask & WRITEMASK_X) mask |= SMASK_X;
+ if (mesa_mask & WRITEMASK_Y) mask |= SMASK_Y;
+ if (mesa_mask & WRITEMASK_Z) mask |= SMASK_Z;
+ if (mesa_mask & WRITEMASK_W) mask |= SMASK_W;
+
+ return mask;
+}
+
+static nvsTexTarget
+pass0_make_tex_target(GLuint mesa)
+{
+ switch (mesa) {
+ case TEXTURE_1D_INDEX: return NVS_TEX_TARGET_1D;
+ case TEXTURE_2D_INDEX: return NVS_TEX_TARGET_2D;
+ case TEXTURE_3D_INDEX: return NVS_TEX_TARGET_3D;
+ case TEXTURE_CUBE_INDEX: return NVS_TEX_TARGET_CUBE;
+ case TEXTURE_RECT_INDEX: return NVS_TEX_TARGET_RECT;
+ default:
+ return NVS_TEX_TARGET_UNKNOWN;
+ }
+}
+
+static void
+pass0_make_dst_reg(nvsPtr nvs, nvsRegister *reg,
+ struct prog_dst_register *dst)
+{
+ struct gl_program *mesa = (struct gl_program*)&nvs->mesa.vp;
+ nvsFixedReg sfr;
+
+ switch (dst->File) {
+ case PROGRAM_OUTPUT:
+ if (mesa->Target == GL_VERTEX_PROGRAM_ARB) {
+ sfr = (dst->Index < VERT_RESULT_MAX) ?
+ _tx_mesa_vp_dst_reg[dst->Index] :
+ NVS_FR_UNKNOWN;
+ } else {
+ sfr = (dst->Index < FRAG_RESULT_MAX) ?
+ _tx_mesa_fp_dst_reg[dst->Index] :
+ NVS_FR_UNKNOWN;
+ }
+ pass0_make_reg(nvs, reg, NVS_FILE_RESULT, sfr);
+ break;
+ case PROGRAM_TEMPORARY:
+ pass0_make_reg(nvs, reg, NVS_FILE_TEMP, dst->Index);
+ break;
+ case PROGRAM_ADDRESS:
+ pass0_make_reg(nvs, reg, NVS_FILE_ADDRESS, dst->Index);
+ break;
+ default:
+ fprintf(stderr, "Unknown dest file %d\n", dst->File);
+ assert(0);
+ }
+}
+
+static void
+pass0_make_src_reg(nvsPtr nvs, nvsRegister *reg, struct prog_src_register *src)
+{
+ struct pass0_rec *rec = nvs->pass_rec;
+ struct gl_program *mesa = (struct gl_program *)&nvs->mesa.vp.Base;
+ int i;
+
+ *reg = nvr_unused;
+
+ switch (src->File) {
+ case PROGRAM_INPUT:
+ reg->file = NVS_FILE_ATTRIB;
+ if (mesa->Target == GL_VERTEX_PROGRAM_ARB) {
+ for (i=0; i<NVS_MAX_ATTRIBS; i++) {
+ if (nvs->vp_attrib_map[i] == src->Index) {
+ reg->index = i;
+ break;
+ }
+ }
+ if (i==NVS_MAX_ATTRIBS)
+ reg->index = NVS_FR_UNKNOWN;
+ } else {
+ reg->index = (src->Index < FRAG_ATTRIB_MAX) ?
+ _tx_mesa_fp_src_reg[src->Index] :
+ NVS_FR_UNKNOWN;
+ }
+ break;
+ case PROGRAM_STATE_VAR:
+ case PROGRAM_NAMED_PARAM:
+ case PROGRAM_CONSTANT:
+ reg->file = NVS_FILE_CONST;
+ reg->index = src->Index + rec->mesa_const_base;
+ reg->indexed = src->RelAddr;
+ if (reg->indexed) {
+ reg->addr_reg = 0;
+ reg->addr_comp = NVS_SWZ_X;
+ }
+ break;
+ case PROGRAM_TEMPORARY:
+ reg->file = NVS_FILE_TEMP;
+ reg->index = src->Index;
+ break;
+ default:
+ fprintf(stderr, "Unknown source type %d\n", src->File);
+ assert(0);
+ }
+
+ /* per-component negate handled elsewhere */
+ reg->negate = src->NegateBase != 0;
+ reg->abs = src->Abs;
+ pass0_make_swizzle(reg->swizzle, src->Swizzle);
+}
+
+static nvsInstruction *
+pass0_emit(nouveauShader *nvs, nvsFragmentHeader *parent, int fpos,
+ nvsOpcode op, nvsRegister dst,
+ unsigned int mask, int saturate,
+ nvsRegister src0, nvsRegister src1, nvsRegister src2)
+{
+ nvsInstruction *sif;
+
+ sif = CALLOC_STRUCT(nvs_instruction);
+ if (!sif)
+ return NULL;
+
+ /* Seems mesa doesn't explicitly 0 this.. */
+ if (nvs->mesa.vp.Base.Target == GL_VERTEX_PROGRAM_ARB)
+ saturate = 0;
+
+ sif->op = op;
+ sif->saturate = saturate;
+ sif->dest = dst;
+ sif->mask = mask;
+ sif->dest_scale = NVS_SCALE_1X;
+ sif->src[0] = src0;
+ sif->src[1] = src1;
+ sif->src[2] = src2;
+ sif->cond = COND_TR;
+ sif->cond_reg = 0;
+ sif->cond_test = 0;
+ sif->cond_update= 0;
+ pass0_make_swizzle(sif->cond_swizzle, SWIZZLE_NOOP);
+ pass0_append_fragment(parent, &sif->header, fpos);
+
+ return sif;
+}
+
+static void
+pass0_fixup_swizzle(nvsPtr nvs, nvsFragmentHeader *parent, int fpos,
+ struct prog_src_register *src,
+ unsigned int sm1,
+ unsigned int sm2)
+{
+ static const float sc[4] = { 1.0, 0.0, -1.0, 0.0 };
+ struct pass0_rec *rec = nvs->pass_rec;
+ int fixup_1, fixup_2;
+ nvsInstruction *nvsinst;
+ nvsRegister sr, dr = nvr_unused;
+ nvsRegister sm1const, sm2const;
+
+ if (!rec->swzconst_done) {
+ struct gl_program *prog = &nvs->mesa.vp.Base;
+ 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);
+ ARITHu(NVS_OP_MOV, dr, SMASK_ALL, 0,
+ sr, nvr_unused, nvr_unused);
+ pass0_make_reg(nvs, &sr, NVS_FILE_TEMP, dr.index);
+ } else {
+ if (fixup_1)
+ src->NegateBase = 0;
+ pass0_make_src_reg(nvs, &sr, src);
+ pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1);
+ }
+
+ pass0_make_reg(nvs, &sm1const, NVS_FILE_CONST, rec->swzconst_id);
+ pass0_make_swizzle(sm1const.swizzle, sm1);
+ if (fixup_1 && fixup_2) {
+ /* Any combination with SWIZZLE_ONE */
+ pass0_make_reg(nvs, &sm2const,
+ NVS_FILE_CONST, rec->swzconst_id);
+ pass0_make_swizzle(sm2const.swizzle, sm2);
+ ARITHu(NVS_OP_MAD, dr, SMASK_ALL, 0, sr, sm1const, sm2const);
+ } else {
+ /* SWIZZLE_ZERO || arbitrary negate */
+ ARITHu(NVS_OP_MUL, dr, SMASK_ALL, 0, sr, sm1const, nvr_unused);
+ }
+
+ src->File = PROGRAM_TEMPORARY;
+ src->Index = dr.index;
+ src->Swizzle = SWIZZLE_NOOP;
+}
+
+#define SET_SWZ(fs, cp, c) fs = (fs & ~(0x7<<(cp*3))) | (c<<(cp*3))
+static void
+pass0_check_sources(nvsPtr nvs, nvsFragmentHeader *parent, int fpos,
+ struct prog_instruction *inst)
+{
+ unsigned int insrc = -1, constsrc = -1;
+ int i;
+
+ for (i=0;i<_mesa_num_inst_src_regs(inst->Opcode);i++) {
+ struct prog_src_register *src = &inst->SrcReg[i];
+ unsigned int sm_1 = 0, sm_2 = 0;
+ nvsRegister sr, dr;
+ int do_mov = 0, c;
+
+ /* Build up swizzle masks as if we were going to use
+ * "MAD new, src, const1, const2" to support arbitrary negation
+ * and SWIZZLE_ZERO/SWIZZLE_ONE.
+ */
+ for (c=0;c<4;c++) {
+ if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ZERO) {
+ SET_SWZ(sm_1, c, SWIZZLE_Y); /* 0.0 */
+ SET_SWZ(sm_2, c, SWIZZLE_Y);
+ SET_SWZ(src->Swizzle, c, SWIZZLE_X);
+ } else if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ONE) {
+ SET_SWZ(sm_1, c, SWIZZLE_Y);
+ if (src->NegateBase & (1<<c))
+ SET_SWZ(sm_2, c, SWIZZLE_Z); /* -1.0 */
+ else
+ SET_SWZ(sm_2, c, SWIZZLE_X); /* 1.0 */
+ SET_SWZ(src->Swizzle, c, SWIZZLE_X);
+ } else {
+ if (src->NegateBase & (1<<c))
+ SET_SWZ(sm_1, c, SWIZZLE_Z); /* -[xyzw] */
+ else
+ SET_SWZ(sm_1, c, SWIZZLE_X); /*[xyzw]*/
+ SET_SWZ(sm_2, c, SWIZZLE_Y);
+ }
+ }
+
+ /* Unless we're multiplying by 1.0 or -1.0 on all components,
+ * and we're adding nothing to any component we have to
+ * emulate the swizzle.
+ */
+ if ((sm_1 != MAKE_SWIZZLE4(0,0,0,0) &&
+ sm_1 != MAKE_SWIZZLE4(2,2,2,2)) ||
+ sm_2 != MAKE_SWIZZLE4(1,1,1,1)) {
+ pass0_fixup_swizzle(nvs, parent, fpos, src, sm_1, sm_2);
+ /* The source is definitely in a temp now, so don't
+ * bother checking for multiple ATTRIB/CONST regs.
+ */
+ continue;
+ }
+
+ /* HW can't use more than one ATTRIB or PARAM in a single
+ * instruction */
+ switch (src->File) {
+ case PROGRAM_INPUT:
+ if (insrc != -1 && insrc != src->Index)
+ do_mov = 1;
+ else insrc = src->Index;
+ break;
+ case PROGRAM_STATE_VAR:
+ if (constsrc != -1 && constsrc != src->Index)
+ do_mov = 1;
+ else constsrc = src->Index;
+ break;
+ default:
+ break;
+ }
+
+ /* Emit any extra ATTRIB/CONST to a temp, and modify the Mesa
+ * instruction to point at the temp.
+ */
+ if (do_mov) {
+ pass0_make_src_reg(nvs, &sr, src);
+ pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1);
+ pass0_emit(nvs, parent, fpos, NVS_OP_MOV,
+ dr, SMASK_ALL, 0,
+ sr, nvr_unused, nvr_unused);
+
+ src->File = PROGRAM_TEMPORARY;
+ src->Index = dr.index;
+ src->Swizzle= SWIZZLE_NOOP;
+ }
+ }
+}
+
+static GLboolean
+pass0_emulate_instruction(nouveauShader *nvs,
+ nvsFragmentHeader *parent, int fpos,
+ struct prog_instruction *inst)
+{
+ nvsFunc *shader = nvs->func;
+ nvsRegister src[3], dest, temp;
+ nvsInstruction *nvsinst;
+ unsigned int mask = pass0_make_mask(inst->DstReg.WriteMask);
+ int i, sat;
+
+ sat = (inst->SaturateMode == SATURATE_ZERO_ONE);
+
+ /* Build all the "real" regs for the instruction */
+ for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++)
+ pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]);
+ if (inst->Opcode != OPCODE_KIL)
+ pass0_make_dst_reg(nvs, &dest, &inst->DstReg);
+
+ switch (inst->Opcode) {
+ case OPCODE_ABS:
+ if (shader->caps & SCAP_SRC_ABS)
+ ARITH(NVS_OP_MOV, dest, mask, sat,
+ nvsAbs(src[0]), nvr_unused, nvr_unused);
+ else
+ ARITH(NVS_OP_MAX, dest, mask, sat,
+ src[0], nvsNegate(src[0]), nvr_unused);
+ break;
+ case OPCODE_CMP:
+ /*XXX: this will clobber CC0... */
+ ARITH (NVS_OP_MOV, dest, mask, sat,
+ src[2], nvr_unused, nvr_unused);
+ pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
+ ARITHu(NVS_OP_MOV, temp, SMASK_ALL, 0,
+ src[0], nvr_unused, nvr_unused);
+ nvsinst->cond_update = 1;
+ nvsinst->cond_reg = 0;
+ ARITH (NVS_OP_MOV, dest, mask, sat,
+ src[1], nvr_unused, nvr_unused);
+ nvsinst->cond = COND_LT;
+ nvsinst->cond_reg = 0;
+ nvsinst->cond_test = 1;
+ break;
+ case OPCODE_DPH:
+ pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
+ ARITHu(NVS_OP_DP3, temp, SMASK_X, 0,
+ src[0], src[1], nvr_unused);
+ ARITH (NVS_OP_ADD, dest, mask, sat,
+ nvsSwizzle(temp, X, X, X, X),
+ nvsSwizzle(src[1], W, W, W, W),
+ nvr_unused);
+ break;
+ case OPCODE_KIL:
+ /* This is only in ARB shaders, so we don't have to worry
+ * about clobbering a CC reg as they aren't supported anyway.
+ *XXX: might have to worry with GLSL however...
+ */
+ /* MOVC0 temp, src */
+ pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
+ ARITHu(NVS_OP_MOV, temp, SMASK_ALL, 0,
+ src[0], nvr_unused, nvr_unused);
+ nvsinst->cond_update = 1;
+ nvsinst->cond_reg = 0;
+ /* KIL_NV (LT0.xyzw) temp */
+ ARITHu(NVS_OP_KIL, nvr_unused, 0, 0,
+ nvr_unused, nvr_unused, nvr_unused);
+ nvsinst->cond = COND_LT;
+ nvsinst->cond_reg = 0;
+ nvsinst->cond_test = 1;
+ pass0_make_swizzle(nvsinst->cond_swizzle, SWIZZLE_NOOP);
+ break;
+ case OPCODE_LRP:
+ pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
+ ARITHu(NVS_OP_MAD, temp, mask, 0,
+ nvsNegate(src[0]), src[2], src[2]);
+ ARITH (NVS_OP_MAD, dest, mask, sat, src[0], src[1], temp);
+ break;
+ case OPCODE_POW:
+ if (shader->SupportsOpcode(shader, NVS_OP_LG2) &&
+ shader->SupportsOpcode(shader, NVS_OP_EX2)) {
+ pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
+ /* LG2 temp.x, src0.c */
+ ARITHu(NVS_OP_LG2, temp, SMASK_X, 0,
+ nvsSwizzle(src[0], X, X, X, X),
+ nvr_unused, nvr_unused);
+ /* MUL temp.x, temp.x, src1.c */
+ ARITHu(NVS_OP_MUL, temp, SMASK_X, 0,
+ nvsSwizzle(temp, X, X, X, X),
+ nvsSwizzle(src[1], X, X, X, X),
+ nvr_unused);
+ /* EX2 dest, temp.x */
+ ARITH (NVS_OP_EX2, dest, mask, sat,
+ nvsSwizzle(temp, X, X, X, X),
+ nvr_unused, nvr_unused);
+ } else {
+ /* can we use EXP/LOG instead of EX2/LG2?? */
+ fprintf(stderr, "Implement POW for NV20 vtxprog!\n");
+ return GL_FALSE;
+ }
+ break;
+ case OPCODE_RSQ:
+ pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
+ ARITHu(NVS_OP_LG2, temp, SMASK_X, 0,
+ nvsAbs(nvsSwizzle(src[0], X, X, X, X)),
+ nvr_unused, nvr_unused);
+ nvsinst->dest_scale = NVS_SCALE_INV_2X;
+ ARITH (NVS_OP_EX2, dest, mask, sat,
+ nvsNegate(nvsSwizzle(temp, X, X, X, X)),
+ nvr_unused, nvr_unused);
+ break;
+ case OPCODE_SCS:
+ if (mask & SMASK_X)
+ ARITH(NVS_OP_COS, dest, SMASK_X, sat,
+ nvsSwizzle(src[0], X, X, X, X),
+ nvr_unused, nvr_unused);
+ if (mask & SMASK_Y)
+ ARITH(NVS_OP_SIN, dest, SMASK_Y, sat,
+ nvsSwizzle(src[0], X, X, X, X),
+ nvr_unused, nvr_unused);
+ break;
+ case OPCODE_SUB:
+ ARITH(NVS_OP_ADD, dest, mask, sat,
+ src[0], nvsNegate(src[1]), nvr_unused);
+ break;
+ case OPCODE_XPD:
+ pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1);
+ ARITHu(NVS_OP_MUL, temp, SMASK_ALL, 0,
+ nvsSwizzle(src[0], Z, X, Y, Y),
+ nvsSwizzle(src[1], Y, Z, X, X),
+ nvr_unused);
+ ARITH (NVS_OP_MAD, dest, (mask & ~SMASK_W), sat,
+ nvsSwizzle(src[0], Y, Z, X, X),
+ nvsSwizzle(src[1], Z, X, Y, Y),
+ nvsNegate(temp));
+ break;
+ default:
+ WARN_ONCE("hw doesn't support opcode \"%s\","
+ "and no emulation found\n",
+ _mesa_opcode_string(inst->Opcode));
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+static GLboolean
+pass0_translate_arith(nouveauShader *nvs, struct gl_program *prog,
+ int ipos, int fpos,
+ nvsFragmentHeader *parent)
+{
+ struct prog_instruction *inst = &prog->Instructions[ipos];
+ nvsFunc *shader = nvs->func;
+ nvsInstruction *nvsinst;
+ GLboolean ret;
+
+ /* Deal with multiple ATTRIB/PARAM in a single instruction */
+ pass0_check_sources(nvs, parent, fpos, inst);
+
+ /* Now it's safe to do the prog_instruction->nvsInstruction
+ * conversion
+ */
+ if (shader->SupportsOpcode(shader,
+ pass0_make_opcode(inst->Opcode))) {
+ nvsRegister src[3], dest;
+ int i;
+
+ for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++)
+ pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]);
+ pass0_make_dst_reg(nvs, &dest, &inst->DstReg);
+
+ ARITH(pass0_make_opcode(inst->Opcode), dest,
+ pass0_make_mask(inst->DstReg.WriteMask),
+ (inst->SaturateMode != SATURATE_OFF),
+ src[0], src[1], src[2]);
+ nvsinst->tex_unit = inst->TexSrcUnit;
+ nvsinst->tex_target = pass0_make_tex_target(inst->TexSrcTarget);
+
+ ret = GL_TRUE;
+ } else
+ ret = pass0_emulate_instruction(nvs, parent, fpos, inst);
+
+ return ret;
+}
+
+static GLboolean
+pass0_translate_instructions(nouveauShader *nvs, int ipos, int fpos,
+ nvsFragmentHeader *parent)
+{
+ struct gl_program *prog = (struct gl_program *)&nvs->mesa.vp;
+
+ while (1) {
+ struct prog_instruction *inst = &prog->Instructions[ipos];
+
+ switch (inst->Opcode) {
+ case OPCODE_END:
+ return GL_TRUE;
+ case OPCODE_BRA:
+ case OPCODE_CAL:
+ case OPCODE_RET:
+ //case OPCODE_LOOP:
+ //case OPCODE_ENDLOOP:
+ //case OPCODE_IF:
+ //case OPCODE_ELSE:
+ //case OPCODE_ENDIF:
+ WARN_ONCE("branch ops unimplemented\n");
+ return GL_FALSE;
+ break;
+ default:
+ if (!pass0_translate_arith(nvs, prog,
+ ipos, fpos, parent))
+ return GL_FALSE;
+ break;
+ }
+
+ ipos++;
+ }
+
+ return GL_TRUE;
+}
+
+static void
+pass0_build_attrib_map(nouveauShader *nvs, struct gl_vertex_program *vp)
+{
+ GLuint inputs_read = vp->Base.InputsRead;
+ GLuint input_alloc = ~0xFFFF;
+ int i;
+
+ for (i=0; i<NVS_MAX_ATTRIBS; i++)
+ nvs->vp_attrib_map[i] = -1;
+
+ while (inputs_read) {
+ int in = ffs(inputs_read) - 1;
+ int hw;
+ inputs_read &= ~(1<<in);
+
+ if (vp->IsNVProgram) {
+ /* NVvp: must alias */
+ if (in >= VERT_ATTRIB_GENERIC0)
+ hw = in - VERT_ATTRIB_GENERIC0;
+ else
+ hw = in;
+ } else {
+ /* ARBvp: may alias (but we won't)
+ * GL2.0: must not alias
+ */
+ if (in >= VERT_ATTRIB_GENERIC0)
+ hw = ffs(~input_alloc) - 1;
+ else
+ hw = in;
+ input_alloc |= (1<<hw);
+ }
+
+ nvs->vp_attrib_map[hw] = in;
+ }
+
+ if (NOUVEAU_DEBUG & DEBUG_SHADERS) {
+ printf("vtxprog attrib map:\n");
+ for (i=0; i<NVS_MAX_ATTRIBS; i++) {
+ printf(" hw:%d = attrib:%d\n",
+ i, nvs->vp_attrib_map[i]);
+ }
+ }
+}
+
+static void
+pass0_vp_insert_ff_clip_planes(GLcontext *ctx, nouveauShader *nvs)
+{
+ struct gl_program *prog = &nvs->mesa.vp.Base;
+ nvsFragmentHeader *parent = nvs->program_tree;
+ nvsInstruction *nvsinst;
+ GLuint fpos = 0;
+ nvsRegister opos, epos, eqn, mv[4];
+ GLint tokens[6] = { STATE_MATRIX, STATE_MODELVIEW, 0, 0, 0, 0 };
+ GLint id;
+ int i;
+
+ /* modelview transform */
+ pass0_make_reg(nvs, &opos, NVS_FILE_ATTRIB, NVS_FR_POSITION);
+ pass0_make_reg(nvs, &epos, NVS_FILE_TEMP , -1);
+ for (i=0; i<4; i++) {
+ tokens[3] = tokens[4] = i;
+ id = _mesa_add_state_reference(prog->Parameters, tokens);
+ pass0_make_reg(nvs, &mv[i], NVS_FILE_CONST, id);
+ }
+ ARITHu(NVS_OP_DP4, epos, SMASK_X, 0, opos, mv[0], nvr_unused);
+ ARITHu(NVS_OP_DP4, epos, SMASK_Y, 0, opos, mv[1], nvr_unused);
+ ARITHu(NVS_OP_DP4, epos, SMASK_Z, 0, opos, mv[2], nvr_unused);
+ ARITHu(NVS_OP_DP4, epos, SMASK_W, 0, opos, mv[3], nvr_unused);
+
+ /* Emit code to emulate fixed-function glClipPlane */
+ for (i=0; i<6; i++) {
+ GLuint clipmask = SMASK_X;
+ nvsRegister clip;
+
+ if (!(ctx->Transform.ClipPlanesEnabled & (1<<i)))
+ continue;
+
+ /* Point a const at a user clipping plane */
+ tokens[0] = STATE_CLIPPLANE;
+ tokens[1] = i;
+ id = _mesa_add_state_reference(prog->Parameters, tokens);
+ pass0_make_reg(nvs, &eqn , NVS_FILE_CONST , id);
+ pass0_make_reg(nvs, &clip, NVS_FILE_RESULT, NVS_FR_CLIP0 + i);
+
+ /*XXX: something else needs to take care of modifying the
+ * instructions to write to the correct hw clip register.
+ */
+ switch (i) {
+ case 0: case 3: clipmask = SMASK_Y; break;
+ case 1: case 4: clipmask = SMASK_Z; break;
+ case 2: case 5: clipmask = SMASK_W; break;
+ }
+
+ /* Emit transform */
+ ARITHu(NVS_OP_DP4, clip, clipmask, 0, epos, eqn, nvr_unused);
+ }
+}
+
+static void
+pass0_rebase_mesa_consts(nouveauShader *nvs)
+{
+ struct pass0_rec *rec = nvs->pass_rec;
+ struct gl_program *prog = &nvs->mesa.vp.Base;
+ struct prog_instruction *inst = prog->Instructions;
+ int i;
+
+ /*XXX: not a good idea, params->hw_index is malloc'd */
+ memset(nvs->params, 0x00, sizeof(nvs->params));
+
+ /* When doing relative addressing on constants, the hardware needs us
+ * to fill the "const id" field with a positive value. Determine the
+ * most negative index that is used so that all accesses to a
+ * mesa-provided constant can be rebased to a positive index.
+ */
+ while (inst->Opcode != OPCODE_END) {
+ for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++) {
+ struct prog_src_register *src = &inst->SrcReg[i];
+
+ switch (src->File) {
+ case PROGRAM_STATE_VAR:
+ case PROGRAM_CONSTANT:
+ case PROGRAM_NAMED_PARAM:
+ if (src->RelAddr && src->Index < 0) {
+ int base = src->Index * -1;
+ if (rec->mesa_const_base < base)
+ rec->mesa_const_base = base;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ inst++;
+ }
+}
+
+static void
+pass0_resolve_mesa_consts(nouveauShader *nvs)
+{
+ struct pass0_rec *rec = nvs->pass_rec;
+ struct gl_program *prog = &nvs->mesa.vp.Base;
+ struct gl_program_parameter_list *plist = prog->Parameters;
+ int i;
+
+ /* Init all const tracking/alloc info from the parameter list, rather
+ * than doing it as we translate the program. Otherwise:
+ * 1) we can't get at the correct constant info when relative
+ * addressing is being used due to src->Index not pointing
+ * at the exact const;
+ * 2) as we add extra consts to the program, mesa will call realloc()
+ * and we get invalid pointers to the const data.
+ */
+ rec->mesa_const_last = plist->NumParameters + rec->mesa_const_base;
+ nvs->param_high = rec->mesa_const_last;
+ for (i=0; i<plist->NumParameters; i++) {
+ int hw = rec->mesa_const_base + i;
+
+ switch (plist->Parameters[i].Type) {
+ case PROGRAM_NAMED_PARAM:
+ case PROGRAM_STATE_VAR:
+ nvs->params[hw].in_use = GL_TRUE;
+ nvs->params[hw].source_val = plist->ParameterValues[i];
+ COPY_4V(nvs->params[hw].val, plist->ParameterValues[i]);
+ break;
+ case PROGRAM_CONSTANT:
+ nvs->params[hw].in_use = GL_TRUE;
+ nvs->params[hw].source_val = NULL;
+ COPY_4V(nvs->params[hw].val, plist->ParameterValues[i]);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ }
+}
+
+GLboolean
+nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ struct gl_program *prog = (struct gl_program*)nvs;
+ struct gl_vertex_program *vp = (struct gl_vertex_program *)prog;
+ struct gl_fragment_program *fp = (struct gl_fragment_program *)prog;
+ struct pass0_rec *rec;
+ int ret = GL_FALSE;
+
+ rec = CALLOC_STRUCT(pass0_rec);
+ if (!rec)
+ return GL_FALSE;
+
+ rec->next_temp = prog->NumTemporaries;
+ nvs->pass_rec = rec;
+
+ nvs->program_tree = (nvsFragmentHeader*)
+ pass0_create_subroutine(nvs, "program body");
+ if (!nvs->program_tree) {
+ FREE(rec);
+ return GL_FALSE;
+ }
+
+ switch (prog->Target) {
+ case GL_VERTEX_PROGRAM_ARB:
+ nvs->func = &nmesa->VPfunc;
+
+ if (vp->IsPositionInvariant)
+ _mesa_insert_mvp_code(ctx, vp);
+ pass0_rebase_mesa_consts(nvs);
+
+ if (!prog->String && ctx->Transform.ClipPlanesEnabled)
+ pass0_vp_insert_ff_clip_planes(ctx, nvs);
+
+ pass0_build_attrib_map(nvs, vp);
+ break;
+ case GL_FRAGMENT_PROGRAM_ARB:
+ nvs->func = &nmesa->FPfunc;
+
+ if (fp->FogOption != GL_NONE)
+ _mesa_append_fog_code(ctx, fp);
+ pass0_rebase_mesa_consts(nvs);
+ break;
+ default:
+ fprintf(stderr, "Unknown program type %d", prog->Target);
+ FREE(rec);
+ /* DESTROY TREE!! */
+ return GL_FALSE;
+ }
+ nvs->func->card_priv = &nvs->card_priv;
+
+ ret = pass0_translate_instructions(nvs, 0, 0, nvs->program_tree);
+ if (ret)
+ pass0_resolve_mesa_consts(nvs);
+ /*XXX: if (!ret) DESTROY TREE!!! */
+
+ FREE(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 00000000000..90c57d38078
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_1.c
@@ -0,0 +1,14 @@
+#include "glheader.h"
+#include "macros.h"
+#include "enums.h"
+
+#include "nouveau_shader.h"
+
+GLboolean
+nouveau_shader_pass1(nvsPtr nvs)
+{
+
+ 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 00000000000..b043f877e42
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c
@@ -0,0 +1,261 @@
+/*
+ * 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 <[email protected]>
+ */
+
+#include "glheader.h"
+#include "macros.h"
+#include "enums.h"
+
+#include "program.h"
+
+#include "nouveau_context.h"
+#include "nouveau_shader.h"
+#include "nouveau_msg.h"
+
+struct pass2_rec {
+ /* Map nvsRegister temp ID onto hw temp ID */
+ unsigned int temps[NVS_MAX_TEMPS];
+ /* Track free hw registers */
+ unsigned int hw_temps[NVS_MAX_TEMPS];
+};
+
+static int
+pass2_alloc_hw_temp(nvsPtr nvs)
+{
+ struct pass2_rec *rec = nvs->pass_rec;
+ int i;
+
+ for (i=0; i<nvs->func->MaxTemp; i++) {
+ /* This is a *horrible* hack.. R0 is both temp0 and result.color
+ * in NV30/40 fragprogs, we can use R0 as a temp before result
+ * is written however..
+ */
+ if (nvs->mesa.vp.Base.Target == GL_FRAGMENT_PROGRAM_ARB && i==0)
+ continue;
+ if (rec->hw_temps[i] == 0) {
+ rec->hw_temps[i] = 1;
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+static nvsRegister
+pass2_mangle_reg(nvsPtr nvs, nvsInstruction *inst, nvsRegister reg)
+{
+ struct pass2_rec *rec = nvs->pass_rec;
+
+ if (reg.file == NVS_FILE_TEMP) {
+ if (rec->temps[reg.index] == -1)
+ rec->temps[reg.index] = pass2_alloc_hw_temp(nvs);
+ reg.index = rec->temps[reg.index];
+ }
+
+ return reg;
+}
+
+static void
+pass2_add_instruction(nvsPtr nvs, nvsInstruction *inst,
+ struct _op_xlat *op, int slot)
+{
+ nvsSwzComp default_swz[4] = { NVS_SWZ_X, NVS_SWZ_Y,
+ NVS_SWZ_Z, NVS_SWZ_W };
+ nvsFunc *shader = nvs->func;
+ nvsRegister reg;
+ int i;
+
+ shader->SetOpcode(shader, op->NV, slot);
+ if (inst->saturate ) shader->SetSaturate(shader);
+ if (inst->cond_update ) shader->SetCCUpdate(shader);
+ if (inst->cond_test ) shader->SetCondition(shader, 1, inst->cond,
+ inst->cond_reg,
+ inst->cond_swizzle);
+ else shader->SetCondition(shader, 0, NVS_COND_TR,
+ 0,
+ default_swz);
+ switch (inst->op) {
+ case NVS_OP_TEX:
+ case NVS_OP_TXB:
+ case NVS_OP_TXL:
+ case NVS_OP_TXP:
+ case NVS_OP_TXD:
+ shader->SetTexImageUnit(shader, inst->tex_unit);
+ break;
+ default:
+ break;
+ }
+
+ for (i = 0; i < 3; i++) {
+ if (op->srcpos[i] != -1) {
+ reg = pass2_mangle_reg(nvs, inst, inst->src[i]);
+
+ shader->SetSource(shader, &reg, op->srcpos[i]);
+
+ if (reg.file == NVS_FILE_CONST &&
+ shader->GetSourceConstVal) {
+ int idx_slot =
+ nvs->params[reg.index].hw_index_cnt++;
+ nvs->params[reg.index].hw_index = realloc(
+ nvs->params[reg.index].hw_index,
+ sizeof(int) * idx_slot+1);
+ nvs->params[reg.index].hw_index[idx_slot] =
+ nvs->program_current + 4;
+ }
+ }
+ }
+
+ reg = pass2_mangle_reg(nvs, inst, inst->dest);
+ shader->SetResult(shader, &reg, inst->mask, slot);
+
+ if (inst->dest_scale != NVS_SCALE_1X) {
+ shader->SetResultScale(shader, inst->dest_scale);
+ }
+}
+
+static int
+pass2_assemble_instruction(nvsPtr nvs, nvsInstruction *inst, int last)
+{
+ nvsFunc *shader = nvs->func;
+ struct _op_xlat *op;
+ unsigned int hw_inst[8];
+ int slot;
+ int instsz;
+ int i;
+
+ shader->inst = hw_inst;
+
+ /* Assemble this instruction */
+ if (!(op = shader->GetOPTXFromSOP(inst->op, &slot)))
+ return 0;
+ shader->InitInstruction(shader);
+ pass2_add_instruction(nvs, inst, op, slot);
+ if (last)
+ shader->SetLastInst(shader);
+
+ instsz = shader->GetOffsetNext(nvs->func);
+ if (nvs->program_size + instsz >= nvs->program_alloc_size) {
+ nvs->program_alloc_size *= 2;
+ nvs->program = realloc(nvs->program,
+ nvs->program_alloc_size *
+ sizeof(uint32_t));
+ }
+
+ for (i=0; i<instsz; i++)
+ nvs->program[nvs->program_current++] = hw_inst[i];
+ nvs->program_size = nvs->program_current;
+ return 1;
+}
+
+static GLboolean
+pass2_translate(nvsPtr nvs, nvsFragmentHeader *f)
+{
+ nvsFunc *shader = nvs->func;
+ GLboolean last;
+
+ while (f) {
+ last = (f == ((nvsSubroutine*)nvs->program_tree)->insn_tail);
+
+ switch (f->type) {
+ case NVS_INSTRUCTION:
+ if (!pass2_assemble_instruction(nvs,
+ (nvsInstruction *)f,
+ last))
+ return GL_FALSE;
+ break;
+ default:
+ WARN_ONCE("Unimplemented fragment type\n");
+ return GL_FALSE;
+ }
+
+ f = f->next;
+ }
+
+ return GL_TRUE;
+}
+
+/* Translate program into hardware format */
+GLboolean
+nouveau_shader_pass2(nvsPtr nvs)
+{
+ struct pass2_rec *rec;
+ int i;
+
+ rec = calloc(1, sizeof(struct pass2_rec));
+ for (i=0; i<NVS_MAX_TEMPS; i++)
+ rec->temps[i] = -1;
+ nvs->pass_rec = rec;
+
+ /* Start off with allocating 4 uint32_t's for each inst, will be grown
+ * if necessary..
+ */
+ nvs->program_alloc_size = nvs->mesa.vp.Base.NumInstructions * 4;
+ nvs->program = calloc(nvs->program_alloc_size, sizeof(uint32_t));
+ nvs->program_size = 0;
+ nvs->program_current = 0;
+
+ if (!pass2_translate(nvs,
+ ((nvsSubroutine*)nvs->program_tree)->insn_head)) {
+ free(nvs->program);
+ nvs->program = NULL;
+ return GL_FALSE;
+ }
+
+ /* Shrink allocated memory to only what we need */
+ nvs->program = realloc(nvs->program,
+ nvs->program_size * sizeof(uint32_t));
+ nvs->program_alloc_size = nvs->program_size;
+
+ nvs->translated = 1;
+ nvs->on_hardware = 0;
+
+ if (NOUVEAU_DEBUG & DEBUG_SHADERS) {
+ fflush(stdout); fflush(stderr);
+ fprintf(stderr, "-----------MESA PROGRAM target=%s, id=0x%x\n",
+ _mesa_lookup_enum_by_nr(
+ nvs->mesa.vp.Base.Target),
+ nvs->mesa.vp.Base.Id);
+ fflush(stdout); fflush(stderr);
+ _mesa_print_program(&nvs->mesa.vp.Base);
+ fflush(stdout); fflush(stderr);
+ fprintf(stderr, "^^^^^^^^^^^^^^^^MESA PROGRAM\n");
+ fflush(stdout); fflush(stderr);
+ fprintf(stderr, "----------------NV PROGRAM\n");
+ fflush(stdout); fflush(stderr);
+ nvsDisasmHWShader(nvs);
+ fflush(stdout); fflush(stderr);
+ fprintf(stderr, "^^^^^^^^^^^^^^^^NV PROGRAM\n");
+ fflush(stdout); fflush(stderr);
+ }
+
+ return GL_TRUE;
+}
+
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_span.c b/src/mesa/drivers/dri/nouveau/nouveau_span.c
new file mode 100644
index 00000000000..74dec66afcf
--- /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 00000000000..bc39ecd17b5
--- /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 00000000000..e9fd188d73e
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c
@@ -0,0 +1,345 @@
+/**************************************************************************
+
+Copyright 2006 Jeremy Kolb
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#include "nouveau_context.h"
+#include "nouveau_state.h"
+#include "nouveau_swtcl.h"
+#include "nouveau_fifo.h"
+
+#include "swrast/swrast.h"
+#include "tnl/tnl.h"
+#include "swrast_setup/swrast_setup.h"
+
+#include "tnl/t_pipeline.h"
+
+#include "mtypes.h"
+#include "colormac.h"
+
+static __inline__ GLuint nouveauPackColor(GLuint format,
+ GLubyte r, GLubyte g,
+ GLubyte b, GLubyte a)
+{
+ switch (format) {
+ case 2:
+ return PACK_COLOR_565( r, g, b );
+ case 4:
+ return PACK_COLOR_8888( r, g, b, a);
+ default:
+ fprintf(stderr, "unknown format %d\n", (int)format);
+ return 0;
+ }
+}
+
+static void nouveauCalcViewport(GLcontext *ctx)
+{
+ /* Calculate the Viewport Matrix */
+
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ const GLfloat *v = ctx->Viewport._WindowMap.m;
+ GLfloat *m = nmesa->viewport.m;
+ GLfloat xoffset = nmesa->drawX, yoffset = nmesa->drawY;
+
+ nmesa->depth_scale = 1.0 / ctx->DrawBuffer->_DepthMaxF;
+
+ m[MAT_SX] = v[MAT_SX];
+ m[MAT_TX] = v[MAT_TX] + xoffset + SUBPIXEL_X;
+ m[MAT_SY] = - v[MAT_SY];
+ m[MAT_TY] = v[MAT_TY] + yoffset + SUBPIXEL_Y;
+ m[MAT_SZ] = v[MAT_SZ] * nmesa->depth_scale;
+ m[MAT_TZ] = v[MAT_TZ] * nmesa->depth_scale;
+
+ nmesa->hw_func.WindowMoved(nmesa);
+}
+
+static void nouveauViewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+{
+ /*
+ * Need to send (at least on an nv35 the following:
+ * cons = 4 (this may be bytes per pixel)
+ *
+ * The viewport:
+ * 445 0x0000bee0 {size: 0x0 channel: 0x1 cmd: 0x00009ee0} <-- VIEWPORT_SETUP/HEADER ?
+ * 446 0x00000000 {size: 0x0 channel: 0x0 cmd: 0x00000000} <-- x * cons
+ * 447 0x00000c80 {size: 0x0 channel: 0x0 cmd: 0x00000c80} <-- (height + x) * cons
+ * 448 0x00000000 {size: 0x0 channel: 0x0 cmd: 0x00000000} <-- y * cons
+ * 449 0x00000960 {size: 0x0 channel: 0x0 cmd: 0x00000960} <-- (width + y) * cons
+ * 44a 0x00082a00 {size: 0x2 channel: 0x1 cmd: 0x00000a00} <-- VIEWPORT_DIMS
+ * 44b 0x04000000 <-- (Width_from_glViewport << 16) | x
+ * 44c 0x03000000 <-- (Height_from_glViewport << 16) | (win_height - height - y)
+ *
+ */
+
+ nouveauCalcViewport(ctx);
+}
+
+static void nouveauDepthRange(GLcontext *ctx, GLclampd near, GLclampd far)
+{
+ nouveauCalcViewport(ctx);
+}
+
+static void nouveauDDUpdateHWState(GLcontext *ctx)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ int new_state = nmesa->new_state;
+
+ if ( new_state || nmesa->new_render_state & _NEW_TEXTURE )
+ {
+ nmesa->new_state = 0;
+
+ /* Update the various parts of the context's state.
+ */
+ /*
+ if ( new_state & NOUVEAU_NEW_ALPHA )
+ nouveauUpdateAlphaMode( ctx );
+
+ if ( new_state & NOUVEAU_NEW_DEPTH )
+ nouveauUpdateZMode( ctx );
+
+ if ( new_state & NOUVEAU_NEW_FOG )
+ nouveauUpdateFogAttrib( ctx );
+
+ if ( new_state & NOUVEAU_NEW_CLIP )
+ nouveauUpdateClipping( ctx );
+
+ if ( new_state & NOUVEAU_NEW_CULL )
+ nouveauUpdateCull( ctx );
+
+ if ( new_state & NOUVEAU_NEW_MASKS )
+ nouveauUpdateMasks( ctx );
+
+ if ( new_state & NOUVEAU_NEW_WINDOW )
+ nouveauUpdateWindow( ctx );
+
+ if ( nmesa->new_render_state & _NEW_TEXTURE ) {
+ nouveauUpdateTextureState( ctx );
+ }*/
+ }
+}
+
+static void nouveauDDInvalidateState(GLcontext *ctx, GLuint new_state)
+{
+ _swrast_InvalidateState( ctx, new_state );
+ _swsetup_InvalidateState( ctx, new_state );
+ _vbo_InvalidateState( ctx, new_state );
+ _tnl_InvalidateState( ctx, new_state );
+ NOUVEAU_CONTEXT(ctx)->new_render_state |= new_state;
+}
+
+/* Initialize the context's hardware state. */
+void nouveauDDInitState(nouveauContextPtr nmesa)
+{
+ uint32_t type = nmesa->screen->card->type;
+ switch(type)
+ {
+ case NV_03:
+ /* Unimplemented */
+ break;
+ case NV_04:
+ case NV_05:
+ nv04InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
+ break;
+ case NV_10:
+ nv10InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
+ break;
+ case NV_20:
+ nv20InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
+ break;
+ case NV_30:
+ case NV_40:
+ case NV_44:
+ nv30InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
+ break;
+ case NV_50:
+ nv50InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
+ break;
+ default:
+ break;
+ }
+ nouveau_state_cache_init(nmesa);
+}
+
+/* Initialize the driver's state functions */
+void nouveauDDInitStateFuncs(GLcontext *ctx)
+{
+ ctx->Driver.UpdateState = nouveauDDInvalidateState;
+
+ ctx->Driver.ClearIndex = NULL;
+ ctx->Driver.ClearColor = NULL; //nouveauDDClearColor;
+ ctx->Driver.ClearStencil = NULL; //nouveauDDClearStencil;
+ ctx->Driver.DrawBuffer = NULL; //nouveauDDDrawBuffer;
+ ctx->Driver.ReadBuffer = NULL; //nouveauDDReadBuffer;
+
+ ctx->Driver.IndexMask = NULL;
+ ctx->Driver.ColorMask = NULL; //nouveauDDColorMask;
+ ctx->Driver.AlphaFunc = NULL; //nouveauDDAlphaFunc;
+ ctx->Driver.BlendEquationSeparate = NULL; //nouveauDDBlendEquationSeparate;
+ ctx->Driver.BlendFuncSeparate = NULL; //nouveauDDBlendFuncSeparate;
+ ctx->Driver.ClearDepth = NULL; //nouveauDDClearDepth;
+ ctx->Driver.CullFace = NULL; //nouveauDDCullFace;
+ ctx->Driver.FrontFace = NULL; //nouveauDDFrontFace;
+ ctx->Driver.DepthFunc = NULL; //nouveauDDDepthFunc;
+ ctx->Driver.DepthMask = NULL; //nouveauDDDepthMask;
+ ctx->Driver.Enable = NULL; //nouveauDDEnable;
+ ctx->Driver.Fogfv = NULL; //nouveauDDFogfv;
+ ctx->Driver.Hint = NULL;
+ ctx->Driver.Lightfv = NULL;
+ ctx->Driver.LightModelfv = NULL; //nouveauDDLightModelfv;
+ ctx->Driver.LogicOpcode = NULL; //nouveauDDLogicOpCode;
+ ctx->Driver.PolygonMode = NULL;
+ ctx->Driver.PolygonStipple = NULL; //nouveauDDPolygonStipple;
+ ctx->Driver.RenderMode = NULL; //nouveauDDRenderMode;
+ ctx->Driver.Scissor = NULL; //nouveauDDScissor;
+ ctx->Driver.ShadeModel = NULL; //nouveauDDShadeModel;
+ ctx->Driver.StencilFuncSeparate = NULL; //nouveauDDStencilFuncSeparate;
+ ctx->Driver.StencilMaskSeparate = NULL; //nouveauDDStencilMaskSeparate;
+ ctx->Driver.StencilOpSeparate = NULL; //nouveauDDStencilOpSeparate;
+
+ ctx->Driver.DepthRange = nouveauDepthRange;
+ ctx->Driver.Viewport = nouveauViewport;
+
+ /* Pixel path fallbacks.
+ */
+ ctx->Driver.Accum = _swrast_Accum;
+ ctx->Driver.Bitmap = _swrast_Bitmap;
+ ctx->Driver.CopyPixels = _swrast_CopyPixels;
+ ctx->Driver.DrawPixels = _swrast_DrawPixels;
+ ctx->Driver.ReadPixels = _swrast_ReadPixels;
+
+ /* Swrast hooks for imaging extensions:
+ */
+ ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
+ ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
+ ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
+ ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
+}
+
+#define STATE_INIT(a) if (ctx->Driver.a) ctx->Driver.a
+
+void nouveauInitState(GLcontext *ctx)
+{
+ /*
+ * Mesa should do this for us:
+ */
+
+ STATE_INIT(AlphaFunc)( ctx,
+ ctx->Color.AlphaFunc,
+ ctx->Color.AlphaRef);
+
+ STATE_INIT(BlendColor)( ctx,
+ ctx->Color.BlendColor );
+
+ STATE_INIT(BlendEquationSeparate)( ctx,
+ ctx->Color.BlendEquationRGB,
+ ctx->Color.BlendEquationA);
+
+ STATE_INIT(BlendFuncSeparate)( ctx,
+ ctx->Color.BlendSrcRGB,
+ ctx->Color.BlendDstRGB,
+ ctx->Color.BlendSrcA,
+ ctx->Color.BlendDstA);
+
+ STATE_INIT(ClearColor)( ctx, ctx->Color.ClearColor);
+ STATE_INIT(ClearDepth)( ctx, ctx->Depth.Clear);
+ STATE_INIT(ClearStencil)( ctx, ctx->Stencil.Clear);
+
+ STATE_INIT(ColorMask)( ctx,
+ ctx->Color.ColorMask[RCOMP],
+ ctx->Color.ColorMask[GCOMP],
+ ctx->Color.ColorMask[BCOMP],
+ ctx->Color.ColorMask[ACOMP]);
+
+ STATE_INIT(CullFace)( ctx, ctx->Polygon.CullFaceMode );
+ STATE_INIT(DepthFunc)( ctx, ctx->Depth.Func );
+ STATE_INIT(DepthMask)( ctx, ctx->Depth.Mask );
+
+ STATE_INIT(Enable)( ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled );
+ STATE_INIT(Enable)( ctx, GL_BLEND, ctx->Color.BlendEnabled );
+ STATE_INIT(Enable)( ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled );
+ STATE_INIT(Enable)( ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled );
+ STATE_INIT(Enable)( ctx, GL_CULL_FACE, ctx->Polygon.CullFlag );
+ STATE_INIT(Enable)( ctx, GL_DEPTH_TEST, ctx->Depth.Test );
+ STATE_INIT(Enable)( ctx, GL_DITHER, ctx->Color.DitherFlag );
+ STATE_INIT(Enable)( ctx, GL_FOG, ctx->Fog.Enabled );
+ STATE_INIT(Enable)( ctx, GL_LIGHTING, ctx->Light.Enabled );
+ STATE_INIT(Enable)( ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag );
+ STATE_INIT(Enable)( ctx, GL_LINE_STIPPLE, ctx->Line.StippleFlag );
+ STATE_INIT(Enable)( ctx, GL_POINT_SMOOTH, ctx->Point.SmoothFlag );
+ STATE_INIT(Enable)( ctx, GL_POLYGON_OFFSET_FILL, ctx->Polygon.OffsetFill);
+ STATE_INIT(Enable)( ctx, GL_POLYGON_OFFSET_LINE, ctx->Polygon.OffsetLine);
+ STATE_INIT(Enable)( ctx, GL_POLYGON_OFFSET_POINT, ctx->Polygon.OffsetPoint);
+ STATE_INIT(Enable)( ctx, GL_POLYGON_SMOOTH, ctx->Polygon.SmoothFlag );
+ STATE_INIT(Enable)( ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag );
+ STATE_INIT(Enable)( ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled );
+ STATE_INIT(Enable)( ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled );
+ STATE_INIT(Enable)( ctx, GL_TEXTURE_1D, GL_FALSE );
+ STATE_INIT(Enable)( ctx, GL_TEXTURE_2D, GL_FALSE );
+ STATE_INIT(Enable)( ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE );
+ STATE_INIT(Enable)( ctx, GL_TEXTURE_3D, GL_FALSE );
+ STATE_INIT(Enable)( ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE );
+
+ STATE_INIT(Fogfv)( ctx, GL_FOG_COLOR, ctx->Fog.Color );
+ STATE_INIT(Fogfv)( ctx, GL_FOG_MODE, 0 );
+ STATE_INIT(Fogfv)( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
+ STATE_INIT(Fogfv)( ctx, GL_FOG_START, &ctx->Fog.Start );
+ STATE_INIT(Fogfv)( ctx, GL_FOG_END, &ctx->Fog.End );
+
+ STATE_INIT(FrontFace)( ctx, ctx->Polygon.FrontFace );
+
+ {
+ GLfloat f = (GLfloat)ctx->Light.Model.ColorControl;
+ STATE_INIT(LightModelfv)( ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f );
+ }
+
+ STATE_INIT(LineStipple)( ctx, ctx->Line.StippleFactor, ctx->Line.StipplePattern );
+ STATE_INIT(LineWidth)( ctx, ctx->Line.Width );
+ STATE_INIT(LogicOpcode)( ctx, ctx->Color.LogicOp );
+ STATE_INIT(PointSize)( ctx, ctx->Point.Size );
+ STATE_INIT(PolygonMode)( ctx, GL_FRONT, ctx->Polygon.FrontMode );
+ STATE_INIT(PolygonMode)( ctx, GL_BACK, ctx->Polygon.BackMode );
+ STATE_INIT(PolygonOffset)( ctx,
+ ctx->Polygon.OffsetFactor,
+ ctx->Polygon.OffsetUnits );
+ STATE_INIT(PolygonStipple)( ctx, (const GLubyte *)ctx->PolygonStipple );
+ STATE_INIT(ShadeModel)( ctx, ctx->Light.ShadeModel );
+ STATE_INIT(StencilFuncSeparate)( ctx, GL_FRONT,
+ ctx->Stencil.Function[0],
+ ctx->Stencil.Ref[0],
+ ctx->Stencil.ValueMask[0] );
+ STATE_INIT(StencilFuncSeparate)( ctx, GL_BACK,
+ ctx->Stencil.Function[1],
+ ctx->Stencil.Ref[1],
+ ctx->Stencil.ValueMask[1] );
+ STATE_INIT(StencilMaskSeparate)( ctx, GL_FRONT, ctx->Stencil.WriteMask[0] );
+ STATE_INIT(StencilMaskSeparate)( ctx, GL_BACK, ctx->Stencil.WriteMask[1] );
+ STATE_INIT(StencilOpSeparate)( ctx, GL_FRONT,
+ ctx->Stencil.FailFunc[0],
+ ctx->Stencil.ZFailFunc[0],
+ ctx->Stencil.ZPassFunc[0]);
+ STATE_INIT(StencilOpSeparate)( ctx, GL_BACK,
+ ctx->Stencil.FailFunc[1],
+ ctx->Stencil.ZFailFunc[1],
+ ctx->Stencil.ZPassFunc[1]);
+}
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.h b/src/mesa/drivers/dri/nouveau/nouveau_state.h
new file mode 100644
index 00000000000..dbac71760b6
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_state.h
@@ -0,0 +1,50 @@
+/**************************************************************************
+
+Copyright 2006 Jeremy Kolb
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifndef __NOUVEAU_STATE_H__
+#define __NOUVEAU_STATE_H__
+
+#include "nouveau_context.h"
+
+extern void nouveauDDInitState(nouveauContextPtr nmesa);
+extern void nouveauDDInitStateFuncs(GLcontext *ctx);
+
+extern void nv04InitStateFuncs(GLcontext *ctx, struct dd_function_table *func);
+extern void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func);
+extern void nv20InitStateFuncs(GLcontext *ctx, struct dd_function_table *func);
+extern void nv30InitStateFuncs(GLcontext *ctx, struct dd_function_table *func);
+extern void nv50InitStateFuncs(GLcontext *ctx, struct dd_function_table *func);
+
+extern void nouveauInitState(GLcontext *ctx);
+
+/*
+extern void nouveauDDUpdateState(GLcontext *ctx);
+extern void nouveauDDUpdateHWState(GLcontext *ctx);
+
+extern void nouveauEmitHwStateLocked(nouveauContextPtr nmesa);
+*/
+#endif
+
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state_cache.c b/src/mesa/drivers/dri/nouveau/nouveau_state_cache.c
new file mode 100644
index 00000000000..cb4b9d30270
--- /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 00000000000..5f9d426450b
--- /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 00000000000..8a013bd9995
--- /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 00000000000..ba4d8725a65
--- /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 00000000000..c47ff3a985d
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "vblank.h" /* for DO_USLEEP */
+
+#include "nouveau_context.h"
+#include "nouveau_buffers.h"
+#include "nouveau_object.h"
+#include "nouveau_fifo.h"
+#include "nouveau_reg.h"
+#include "nouveau_msg.h"
+#include "nouveau_sync.h"
+
+nouveau_notifier *
+nouveau_notifier_new(GLcontext *ctx, GLuint handle, GLuint count)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nouveau_notifier *notifier;
+
+#ifdef NOUVEAU_RING_DEBUG
+ return NULL;
+#endif
+
+ notifier = CALLOC_STRUCT(nouveau_notifier_t);
+ if (!notifier)
+ return NULL;
+
+ notifier->mem = nouveau_mem_alloc(ctx,
+ NOUVEAU_MEM_FB | NOUVEAU_MEM_MAPPED,
+ count * NV_NOTIFIER_SIZE,
+ 0);
+ if (!notifier->mem) {
+ FREE(notifier);
+ return NULL;
+ }
+
+ if (!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, GLuint id)
+{
+ volatile GLuint *n = notifier->mem->map + (id * NV_NOTIFIER_SIZE);
+
+#ifdef NOUVEAU_RING_DEBUG
+ return;
+#endif
+
+ n[NV_NOTIFY_TIME_0 /4] = 0x00000000;
+ n[NV_NOTIFY_TIME_1 /4] = 0x00000000;
+ n[NV_NOTIFY_RETURN_VALUE/4] = 0x00000000;
+ n[NV_NOTIFY_STATE /4] = (NV_NOTIFY_STATE_STATUS_IN_PROCESS <<
+ NV_NOTIFY_STATE_STATUS_SHIFT);
+}
+
+GLuint
+nouveau_notifier_status(nouveau_notifier *notifier, GLuint id)
+{
+ volatile GLuint *n = notifier->mem->map + (id * NV_NOTIFIER_SIZE);
+
+ return n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT;
+}
+
+GLuint
+nouveau_notifier_return_val(nouveau_notifier *notifier, GLuint id)
+{
+ volatile GLuint *n = notifier->mem->map + (id * NV_NOTIFIER_SIZE);
+
+ return n[NV_NOTIFY_RETURN_VALUE/4];
+}
+
+GLboolean
+nouveau_notifier_wait_status(nouveau_notifier *notifier, GLuint id,
+ GLuint status, GLuint timeout)
+{
+ volatile GLuint *n = notifier->mem->map + (id * NV_NOTIFIER_SIZE);
+ unsigned int time = 0;
+
+#ifdef NOUVEAU_RING_DEBUG
+ return GL_TRUE;
+#endif
+
+ while (time <= timeout) {
+ if (n[NV_NOTIFY_STATE/4] & NV_NOTIFY_STATE_ERROR_CODE_MASK) {
+ MESSAGE("Notifier returned error: 0x%04x\n",
+ n[NV_NOTIFY_STATE] &
+ NV_NOTIFY_STATE_ERROR_CODE_MASK);
+ return GL_FALSE;
+ }
+
+ if (((n[NV_NOTIFY_STATE/4] & NV_NOTIFY_STATE_STATUS_MASK) >>
+ NV_NOTIFY_STATE_STATUS_SHIFT) == status)
+ return GL_TRUE;
+
+ if (timeout) {
+ DO_USLEEP(1);
+ time++;
+ }
+ }
+
+ MESSAGE("Notifier timed out\n");
+ return GL_FALSE;
+}
+
+void
+nouveau_notifier_wait_nop(GLcontext *ctx, nouveau_notifier *notifier,
+ GLuint subc)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLboolean ret;
+
+ nouveau_notifier_reset(notifier, 0);
+
+ BEGIN_RING_SIZE(subc, NV_NOTIFY, 1);
+ OUT_RING (NV_NOTIFY_STYLE_WRITE_ONLY);
+ BEGIN_RING_SIZE(subc, NV_NOP, 1);
+ OUT_RING (0);
+ FIRE_RING();
+
+ ret = nouveau_notifier_wait_status(notifier, 0,
+ NV_NOTIFY_STATE_STATUS_COMPLETED,
+ 0 /* no timeout */);
+ if (ret == GL_FALSE) MESSAGE("wait on notifier failed\n");
+}
+
+GLboolean nouveauSyncInitFuncs(GLcontext *ctx)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+#ifdef NOUVEAU_RING_DEBUG
+ return GL_TRUE;
+#endif
+
+ nmesa->syncNotifier = nouveau_notifier_new(ctx, NvSyncNotify, 1);
+ if (!nmesa->syncNotifier) {
+ MESSAGE("Failed to create channel sync notifier\n");
+ return GL_FALSE;
+ }
+
+ /* 0x180 is SET_DMA_NOTIFY, should be correct for all supported 3D
+ * object classes
+ */
+ BEGIN_RING_CACHE(NvSub3D, 0x180, 1);
+ OUT_RING_CACHE (NvSyncNotify);
+#ifdef ALLOW_MULTI_SUBCHANNEL
+ BEGIN_RING_SIZE(NvSubMemFormat,
+ NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
+ OUT_RING (NvSyncNotify);
+#endif
+
+ return GL_TRUE;
+}
+
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.h b/src/mesa/drivers/dri/nouveau/nouveau_sync.h
new file mode 100644
index 00000000000..019d5f6629b
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __NOUVEAU_SYNC_H__
+#define __NOUVEAU_SYNC_H__
+
+#include "nouveau_buffers.h"
+
+#define NV_NOTIFIER_SIZE 32
+#define NV_NOTIFY_TIME_0 0x00000000
+#define NV_NOTIFY_TIME_1 0x00000004
+#define NV_NOTIFY_RETURN_VALUE 0x00000008
+#define NV_NOTIFY_STATE 0x0000000C
+#define NV_NOTIFY_STATE_STATUS_MASK 0xFF000000
+#define NV_NOTIFY_STATE_STATUS_SHIFT 24
+#define NV_NOTIFY_STATE_STATUS_COMPLETED 0x00
+#define NV_NOTIFY_STATE_STATUS_IN_PROCESS 0x01
+#define NV_NOTIFY_STATE_ERROR_CODE_MASK 0x0000FFFF
+#define NV_NOTIFY_STATE_ERROR_CODE_SHIFT 0
+
+/* Methods that (hopefully) all objects have */
+#define NV_NOP 0x00000100
+#define NV_NOTIFY 0x00000104
+#define NV_NOTIFY_STYLE_WRITE_ONLY 0
+
+typedef struct nouveau_notifier_t {
+ GLuint handle;
+ nouveau_mem *mem;
+} nouveau_notifier;
+
+extern nouveau_notifier *nouveau_notifier_new(GLcontext *, GLuint handle,
+ GLuint count);
+extern void nouveau_notifier_destroy(GLcontext *, nouveau_notifier *);
+extern void nouveau_notifier_reset(nouveau_notifier *, GLuint id);
+extern GLuint nouveau_notifier_status(nouveau_notifier *, GLuint id);
+extern GLuint nouveau_notifier_return_val(nouveau_notifier *, GLuint id);
+extern GLboolean nouveau_notifier_wait_status(nouveau_notifier *r, GLuint id,
+ GLuint status, GLuint timeout);
+extern void nouveau_notifier_wait_nop(GLcontext *ctx,
+ nouveau_notifier *, GLuint subc);
+
+extern GLboolean nouveauSyncInitFuncs(GLcontext *ctx);
+#endif
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_tex.c b/src/mesa/drivers/dri/nouveau/nouveau_tex.c
new file mode 100644
index 00000000000..0a8d2796695
--- /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 00000000000..7ac71f8300b
--- /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_state.c b/src/mesa/drivers/dri/nouveau/nv04_state.c
new file mode 100644
index 00000000000..4129ecc50ea
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nv04_state.c
@@ -0,0 +1,538 @@
+/**************************************************************************
+
+Copyright 2007 Stephane Marchesin
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#include "nouveau_context.h"
+#include "nouveau_object.h"
+#include "nouveau_fifo.h"
+#include "nouveau_reg.h"
+#include "nouveau_msg.h"
+
+#include "tnl/t_pipeline.h"
+
+#include "mtypes.h"
+#include "colormac.h"
+
+static uint32_t nv04_compare_func(GLuint f)
+{
+ switch ( f ) {
+ case GL_NEVER: return 1;
+ case GL_LESS: return 2;
+ case GL_EQUAL: return 3;
+ case GL_LEQUAL: return 4;
+ case GL_GREATER: return 5;
+ case GL_NOTEQUAL: return 6;
+ case GL_GEQUAL: return 7;
+ case GL_ALWAYS: return 8;
+ }
+ WARN_ONCE("Unable to find the function\n");
+ return 0;
+}
+
+static uint32_t nv04_blend_func(GLuint f)
+{
+ switch ( f ) {
+ case GL_ZERO: return 0x1;
+ case GL_ONE: return 0x2;
+ case GL_SRC_COLOR: return 0x3;
+ case GL_ONE_MINUS_SRC_COLOR: return 0x4;
+ case GL_SRC_ALPHA: return 0x5;
+ case GL_ONE_MINUS_SRC_ALPHA: return 0x6;
+ case GL_DST_ALPHA: return 0x7;
+ case GL_ONE_MINUS_DST_ALPHA: return 0x8;
+ case GL_DST_COLOR: return 0x9;
+ case GL_ONE_MINUS_DST_COLOR: return 0xA;
+ case GL_SRC_ALPHA_SATURATE: return 0xB;
+ }
+ WARN_ONCE("Unable to find the function 0x%x\n",f);
+ return 0;
+}
+
+static void nv04_emit_control(GLcontext *ctx)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ uint32_t control,cull;
+ GLubyte alpha_ref;
+
+ CLAMPED_FLOAT_TO_UBYTE(alpha_ref, ctx->Color.AlphaRef);
+ control=alpha_ref;
+ control|=(nv04_compare_func(ctx->Color.AlphaFunc)<<8);
+ control|=(ctx->Color.AlphaEnabled<<12);
+ control|=(1<<13);
+ control|=(ctx->Depth.Test<<14);
+ control|=(nv04_compare_func(ctx->Depth.Func)<<16);
+ if ((ctx->Polygon.CullFlag)&&(ctx->Polygon.CullFaceMode!=GL_FRONT_AND_BACK))
+ {
+ if ((ctx->Polygon.FrontFace==GL_CW)&&(ctx->Polygon.CullFaceMode==GL_FRONT))
+ cull=2;
+ if ((ctx->Polygon.FrontFace==GL_CW)&&(ctx->Polygon.CullFaceMode==GL_BACK))
+ cull=3;
+ if ((ctx->Polygon.FrontFace==GL_CCW)&&(ctx->Polygon.CullFaceMode==GL_FRONT))
+ cull=3;
+ if ((ctx->Polygon.FrontFace==GL_CCW)&&(ctx->Polygon.CullFaceMode==GL_BACK))
+ cull=2;
+ }
+ else
+ if (ctx->Polygon.CullFaceMode==GL_FRONT_AND_BACK)
+ cull=0;
+ else
+ cull=1;
+ control|=(cull<<20);
+ control|=(ctx->Color.DitherFlag<<22);
+ if ((ctx->Depth.Test)&&(ctx->Depth.Mask))
+ control|=(1<<24);
+
+ control|=(1<<30); // integer zbuffer format
+
+ BEGIN_RING_CACHE(NvSub3D, NV04_DX5_TEXTURED_TRIANGLE_CONTROL, 1);
+ OUT_RING_CACHE(control);
+}
+
+static void nv04_emit_blend(GLcontext *ctx)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ uint32_t blend;
+
+ blend=0x4; // texture MODULATE_ALPHA
+ blend|=0x20; // alpha is MSB
+ switch(ctx->Light.ShadeModel) {
+ case GL_SMOOTH:blend|=(1<<6);break;
+ case GL_FLAT: blend|=(2<<6);break;
+ default:break;
+ }
+ if (ctx->Hint.PerspectiveCorrection!=GL_FASTEST)
+ blend|=(1<<8);
+ blend|=(ctx->Fog.Enabled<<16);
+ blend|=(ctx->Color.BlendEnabled<<20);
+ blend|=(nv04_blend_func(ctx->Color.BlendSrcRGB)<<24);
+ blend|=(nv04_blend_func(ctx->Color.BlendDstRGB)<<28);
+
+ BEGIN_RING_CACHE(NvSub3D, NV04_DX5_TEXTURED_TRIANGLE_BLEND, 1);
+ OUT_RING_CACHE(blend);
+}
+
+static void nv04_emit_fog_color(GLcontext *ctx)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte c[4];
+ c[0] = FLOAT_TO_UBYTE( ctx->Fog.Color[0] );
+ c[1] = FLOAT_TO_UBYTE( ctx->Fog.Color[1] );
+ c[2] = FLOAT_TO_UBYTE( ctx->Fog.Color[2] );
+ c[3] = FLOAT_TO_UBYTE( ctx->Fog.Color[3] );
+ BEGIN_RING_CACHE(NvSub3D, NV04_DX5_TEXTURED_TRIANGLE_FOG_COLOR, 1);
+ OUT_RING_CACHE(PACK_COLOR_8888_REV(c[0],c[1],c[2],c[3]));
+}
+
+static void nv04AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
+{
+ nv04_emit_control(ctx);
+}
+
+static void nv04BlendColor(GLcontext *ctx, const GLfloat color[4])
+{
+ nv04_emit_blend(ctx);
+}
+
+static void nv04BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA)
+{
+ nv04_emit_blend(ctx);
+}
+
+
+static void nv04BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB,
+ GLenum sfactorA, GLenum dfactorA)
+{
+ nv04_emit_blend(ctx);
+}
+
+static void nv04Clear(GLcontext *ctx, GLbitfield mask)
+{
+ /* TODO */
+}
+
+static void nv04ClearColor(GLcontext *ctx, const GLfloat color[4])
+{
+ /* TODO */
+}
+
+static void nv04ClearDepth(GLcontext *ctx, GLclampd d)
+{
+ /* TODO */
+}
+
+static void nv04ClearStencil(GLcontext *ctx, GLint s)
+{
+ /* TODO */
+}
+
+static void nv04ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation)
+{
+ /* TODO */
+}
+
+static void nv04ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask,
+ GLboolean bmask, GLboolean amask )
+{
+ /* TODO */
+}
+
+static void nv04ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode)
+{
+ /* TODO I need love */
+}
+
+static void nv04CullFace(GLcontext *ctx, GLenum mode)
+{
+ nv04_emit_control(ctx);
+}
+
+static void nv04FrontFace(GLcontext *ctx, GLenum mode)
+{
+ /* TODO */
+}
+
+static void nv04DepthFunc(GLcontext *ctx, GLenum func)
+{
+ nv04_emit_control(ctx);
+}
+
+static void nv04DepthMask(GLcontext *ctx, GLboolean flag)
+{
+ /* TODO */
+}
+
+static void nv04DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval)
+{
+ /* TODO */
+}
+
+/** Specify the current buffer for writing */
+//void (*DrawBuffer)( GLcontext *ctx, GLenum buffer );
+/** Specify the buffers for writing for fragment programs*/
+//void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers );
+
+static void nv04Enable(GLcontext *ctx, GLenum cap, GLboolean state)
+{
+ switch(cap)
+ {
+ case GL_ALPHA_TEST:
+ nv04_emit_control(ctx);
+ break;
+// case GL_AUTO_NORMAL:
+ case GL_BLEND:
+ nv04_emit_blend(ctx);
+ break;
+// case GL_CLIP_PLANE0:
+// case GL_CLIP_PLANE1:
+// case GL_CLIP_PLANE2:
+// case GL_CLIP_PLANE3:
+// case GL_CLIP_PLANE4:
+// case GL_CLIP_PLANE5:
+// case GL_COLOR_LOGIC_OP:
+// case GL_COLOR_MATERIAL:
+// case GL_COLOR_SUM_EXT:
+// case GL_COLOR_TABLE:
+// case GL_CONVOLUTION_1D:
+// case GL_CONVOLUTION_2D:
+ case GL_CULL_FACE:
+ nv04_emit_control(ctx);
+ break;
+ case GL_DEPTH_TEST:
+ nv04_emit_control(ctx);
+ break;
+ case GL_DITHER:
+ nv04_emit_control(ctx);
+ break;
+ case GL_FOG:
+ nv04_emit_blend(ctx);
+ nv04_emit_fog_color(ctx);
+ break;
+// case GL_HISTOGRAM:
+// case GL_INDEX_LOGIC_OP:
+// case GL_LIGHT0:
+// case GL_LIGHT1:
+// case GL_LIGHT2:
+// case GL_LIGHT3:
+// case GL_LIGHT4:
+// case GL_LIGHT5:
+// case GL_LIGHT6:
+// case GL_LIGHT7:
+// case GL_LIGHTING:
+// case GL_LINE_SMOOTH:
+// case GL_LINE_STIPPLE:
+// case GL_MAP1_COLOR_4:
+// case GL_MAP1_INDEX:
+// case GL_MAP1_NORMAL:
+// case GL_MAP1_TEXTURE_COORD_1:
+// case GL_MAP1_TEXTURE_COORD_2:
+// case GL_MAP1_TEXTURE_COORD_3:
+// case GL_MAP1_TEXTURE_COORD_4:
+// case GL_MAP1_VERTEX_3:
+// case GL_MAP1_VERTEX_4:
+// case GL_MAP2_COLOR_4:
+// case GL_MAP2_INDEX:
+// case GL_MAP2_NORMAL:
+// case GL_MAP2_TEXTURE_COORD_1:
+// case GL_MAP2_TEXTURE_COORD_2:
+// case GL_MAP2_TEXTURE_COORD_3:
+// case GL_MAP2_TEXTURE_COORD_4:
+// case GL_MAP2_VERTEX_3:
+// case GL_MAP2_VERTEX_4:
+// case GL_MINMAX:
+// case GL_NORMALIZE:
+// case GL_POINT_SMOOTH:
+// case GL_POLYGON_OFFSET_POINT:
+// case GL_POLYGON_OFFSET_LINE:
+// case GL_POLYGON_OFFSET_FILL:
+// case GL_POLYGON_SMOOTH:
+// case GL_POLYGON_STIPPLE:
+// case GL_POST_COLOR_MATRIX_COLOR_TABLE:
+// case GL_POST_CONVOLUTION_COLOR_TABLE:
+// case GL_RESCALE_NORMAL:
+// case GL_SCISSOR_TEST:
+// case GL_SEPARABLE_2D:
+// case GL_STENCIL_TEST:
+// case GL_TEXTURE_GEN_Q:
+// case GL_TEXTURE_GEN_R:
+// case GL_TEXTURE_GEN_S:
+// case GL_TEXTURE_GEN_T:
+// case GL_TEXTURE_1D:
+// case GL_TEXTURE_2D:
+// case GL_TEXTURE_3D:
+ }
+}
+
+static void nv04Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
+{
+ nv04_emit_blend(ctx);
+ nv04_emit_fog_color(ctx);
+}
+
+static void nv04Hint(GLcontext *ctx, GLenum target, GLenum mode)
+{
+ switch(target)
+ {
+ case GL_PERSPECTIVE_CORRECTION_HINT:nv04_emit_blend(ctx);break;
+ default:break;
+ }
+}
+
+static void nv04LineStipple(GLcontext *ctx, GLint factor, GLushort pattern )
+{
+ /* TODO not even in your dreams */
+}
+
+static void nv04LineWidth(GLcontext *ctx, GLfloat width)
+{
+ /* TODO */
+}
+
+static void nv04LogicOpcode(GLcontext *ctx, GLenum opcode)
+{
+ /* TODO */
+}
+
+static void nv04PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
+{
+ /* TODO */
+}
+
+static void nv04PointSize(GLcontext *ctx, GLfloat size)
+{
+ /* TODO */
+}
+
+static void nv04PolygonMode(GLcontext *ctx, GLenum face, GLenum mode)
+{
+ /* TODO */
+}
+
+/** Set the scale and units used to calculate depth values */
+static void nv04PolygonOffset(GLcontext *ctx, GLfloat factor, GLfloat units)
+{
+ /* TODO */
+}
+
+/** Set the polygon stippling pattern */
+static void nv04PolygonStipple(GLcontext *ctx, const GLubyte *mask )
+{
+ /* TODO */
+}
+
+/* Specifies the current buffer for reading */
+void (*ReadBuffer)( GLcontext *ctx, GLenum buffer );
+/** Set rasterization mode */
+void (*RenderMode)(GLcontext *ctx, GLenum mode );
+
+/** Define the scissor box */
+static void nv04Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+{
+ /* TODO */
+}
+
+/** Select flat or smooth shading */
+static void nv04ShadeModel(GLcontext *ctx, GLenum mode)
+{
+ nv04_emit_blend(ctx);
+}
+
+/** OpenGL 2.0 two-sided StencilFunc */
+static void nv04StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func,
+ GLint ref, GLuint mask)
+{
+ /* TODO */
+}
+
+/** OpenGL 2.0 two-sided StencilMask */
+static void nv04StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask)
+{
+ /* TODO */
+}
+
+/** OpenGL 2.0 two-sided StencilOp */
+static void nv04StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail,
+ GLenum zfail, GLenum zpass)
+{
+ /* TODO */
+}
+
+/** Control the generation of texture coordinates */
+void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname,
+ const GLfloat *params);
+/** Set texture environment parameters */
+void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname,
+ const GLfloat *param);
+/** Set texture parameters */
+void (*TexParameter)(GLcontext *ctx, GLenum target,
+ struct gl_texture_object *texObj,
+ GLenum pname, const GLfloat *params);
+
+/* Update anything that depends on the window position/size */
+static void nv04WindowMoved(nouveauContextPtr nmesa)
+{
+}
+
+/* Initialise any card-specific non-GL related state */
+static GLboolean nv04InitCard(nouveauContextPtr nmesa)
+{
+ nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D);
+ nouveauObjectOnSubchannel(nmesa, NvSubCtxSurf3D, NvCtxSurf3D);
+
+ BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_DMA_NOTIFY, 3);
+ OUT_RING(NvDmaFB);
+ OUT_RING(NvDmaFB);
+ OUT_RING(NvDmaFB);
+ BEGIN_RING_SIZE(NvSub3D, NV04_DX5_TEXTURED_TRIANGLE_SURFACE, 1);
+ OUT_RING(NvCtxSurf3D);
+ return GL_TRUE;
+}
+
+/* Update buffer offset/pitch/format */
+static GLboolean nv04BindBuffers(nouveauContextPtr nmesa, int num_color,
+ nouveau_renderbuffer **color,
+ nouveau_renderbuffer *depth)
+{
+ GLuint x, y, w, h;
+
+ w = color[0]->mesa.Width;
+ h = color[0]->mesa.Height;
+ x = nmesa->drawX;
+ y = nmesa->drawY;
+
+ /* FIXME pitches have to be aligned ! */
+ BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_PITCH, 2);
+ OUT_RING(color[0]->pitch|(depth?(depth->pitch<<16):0));
+ OUT_RING(color[0]->offset);
+
+ if (depth) {
+ BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1);
+ OUT_RING(depth->offset);
+ }
+
+ BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_CLIP_HORIZONTAL, 2);
+ OUT_RING((w<<16)|x);
+ OUT_RING((h<<16)|y);
+
+ /* FIXME not sure... */
+ BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_CLIP_SIZE, 1);
+ OUT_RING((h<<16)|w);
+
+ BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_FORMAT, 1);
+ if (color[0]->mesa._ActualFormat == GL_RGBA8)
+ OUT_RING(108/*A8R8G8B8*/);
+ else
+ OUT_RING(103/*R5G6B5*/);
+
+ return GL_TRUE;
+}
+
+void nv04InitStateFuncs(GLcontext *ctx, struct dd_function_table *func)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ func->AlphaFunc = nv04AlphaFunc;
+ func->BlendColor = nv04BlendColor;
+ func->BlendEquationSeparate = nv04BlendEquationSeparate;
+ func->BlendFuncSeparate = nv04BlendFuncSeparate;
+ func->Clear = nv04Clear;
+ func->ClearColor = nv04ClearColor;
+ func->ClearDepth = nv04ClearDepth;
+ func->ClearStencil = nv04ClearStencil;
+ func->ClipPlane = nv04ClipPlane;
+ func->ColorMask = nv04ColorMask;
+ func->ColorMaterial = nv04ColorMaterial;
+ func->CullFace = nv04CullFace;
+ func->FrontFace = nv04FrontFace;
+ func->DepthFunc = nv04DepthFunc;
+ func->DepthMask = nv04DepthMask;
+ func->DepthRange = nv04DepthRange;
+ func->Enable = nv04Enable;
+ func->Fogfv = nv04Fogfv;
+ func->Hint = nv04Hint;
+/* func->Lightfv = nv04Lightfv;*/
+/* func->LightModelfv = nv04LightModelfv; */
+ func->LineStipple = nv04LineStipple; /* Not for NV04 */
+ func->LineWidth = nv04LineWidth;
+ func->LogicOpcode = nv04LogicOpcode;
+ func->PointParameterfv = nv04PointParameterfv;
+ func->PointSize = nv04PointSize;
+ func->PolygonMode = nv04PolygonMode;
+ func->PolygonOffset = nv04PolygonOffset;
+ func->PolygonStipple = nv04PolygonStipple; /* Not for NV04 */
+/* func->ReadBuffer = nv04ReadBuffer;*/
+/* func->RenderMode = nv04RenderMode;*/
+ func->Scissor = nv04Scissor;
+ func->ShadeModel = nv04ShadeModel;
+ func->StencilFuncSeparate = nv04StencilFuncSeparate;
+ func->StencilMaskSeparate = nv04StencilMaskSeparate;
+ func->StencilOpSeparate = nv04StencilOpSeparate;
+/* func->TexGen = nv04TexGen;*/
+/* func->TexParameter = nv04TexParameter;*/
+/* func->TextureMatrix = nv04TextureMatrix;*/
+
+ nmesa->hw_func.InitCard = nv04InitCard;
+ nmesa->hw_func.BindBuffers = nv04BindBuffers;
+ nmesa->hw_func.WindowMoved = nv04WindowMoved;
+}
diff --git a/src/mesa/drivers/dri/nouveau/nv04_swtcl.c b/src/mesa/drivers/dri/nouveau/nv04_swtcl.c
new file mode 100644
index 00000000000..9b5332b77a7
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nv04_swtcl.c
@@ -0,0 +1,618 @@
+/*
+ * Copyright 2007 Stephane Marchesin. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/* Software TCL for NV04, NV05, NV06 */
+
+#include <stdio.h>
+#include <math.h>
+
+#include "glheader.h"
+#include "context.h"
+#include "mtypes.h"
+#include "macros.h"
+#include "colormac.h"
+#include "enums.h"
+
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "tnl/t_context.h"
+#include "tnl/t_pipeline.h"
+
+#include "nouveau_swtcl.h"
+#include "nv04_swtcl.h"
+#include "nouveau_context.h"
+#include "nouveau_span.h"
+#include "nouveau_reg.h"
+#include "nouveau_tex.h"
+#include "nouveau_fifo.h"
+#include "nouveau_msg.h"
+#include "nouveau_object.h"
+
+static void nv04RasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim );
+static void nv04RenderPrimitive( GLcontext *ctx, GLenum prim );
+static void nv04ResetLineStipple( GLcontext *ctx );
+
+
+static inline void nv04_2triangles(struct nouveau_context *nmesa,nouveauVertex* v0,nouveauVertex* v1,nouveauVertex* v2,nouveauVertex* v3,nouveauVertex* v4,nouveauVertex* v5)
+{
+ BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0xA),49);
+ OUT_RINGp(v0,8);
+ OUT_RINGp(v1,8);
+ OUT_RINGp(v2,8);
+ OUT_RINGp(v3,8);
+ OUT_RINGp(v4,8);
+ OUT_RINGp(v5,8);
+ OUT_RING(0xFEDCBA);
+}
+
+static inline void nv04_1triangle(struct nouveau_context *nmesa,nouveauVertex* v0,nouveauVertex* v1,nouveauVertex* v2)
+{
+ BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0xD),25);
+ OUT_RINGp(v0,8);
+ OUT_RINGp(v1,8);
+ OUT_RINGp(v2,8);
+ OUT_RING(0xFED);
+}
+
+static inline void nv04_1quad(struct nouveau_context *nmesa,nouveauVertex* v0,nouveauVertex* v1,nouveauVertex* v2,nouveauVertex* v3)
+{
+ BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0xC),33);
+ OUT_RINGp(v0,8);
+ OUT_RINGp(v1,8);
+ OUT_RINGp(v2,8);
+ OUT_RINGp(v3,8);
+ OUT_RING(0xFECEDC);
+}
+
+static inline void nv04_render_points(GLcontext *ctx,GLuint first,GLuint last)
+{
+ WARN_ONCE("Unimplemented\n");
+}
+
+static inline void nv04_render_line(GLcontext *ctx,GLuint v1,GLuint v2)
+{
+ WARN_ONCE("Unimplemented\n");
+}
+
+static inline void nv04_render_triangle(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3)
+{
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte *vertptr = (GLubyte *)nmesa->verts;
+ GLuint vertsize = nmesa->vertex_size;
+
+ nv04_1triangle(nmesa,
+ (nouveauVertex*)(vertptr+v1*vertsize),
+ (nouveauVertex*)(vertptr+v2*vertsize),
+ (nouveauVertex*)(vertptr+v3*vertsize)
+ );
+}
+
+static inline void nv04_render_quad(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3,GLuint v4)
+{
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte *vertptr = (GLubyte *)nmesa->verts;
+ GLuint vertsize = nmesa->vertex_size;
+
+ nv04_1quad(nmesa,
+ (nouveauVertex*)(vertptr+v1*vertsize),
+ (nouveauVertex*)(vertptr+v2*vertsize),
+ (nouveauVertex*)(vertptr+v3*vertsize),
+ (nouveauVertex*)(vertptr+v4*vertsize)
+ );
+}
+
+/**********************************************************************/
+/* Render unclipped begin/end objects */
+/**********************************************************************/
+
+static void nv04_render_points_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ // erm
+}
+
+static void nv04_render_lines_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ // umm
+}
+
+static void nv04_render_line_strip_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ // yeah
+}
+
+static void nv04_render_line_loop_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ // right
+}
+
+static void nv04_render_triangles_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte *vertptr = (GLubyte *)nmesa->verts;
+ GLuint vertsize = nmesa->vertex_size;
+ int i;
+
+ for(i=start;i<count-5;i+=6)
+ nv04_2triangles(nmesa,
+ (nouveauVertex*)(vertptr+(i+0)*vertsize),
+ (nouveauVertex*)(vertptr+(i+1)*vertsize),
+ (nouveauVertex*)(vertptr+(i+2)*vertsize),
+ (nouveauVertex*)(vertptr+(i+3)*vertsize),
+ (nouveauVertex*)(vertptr+(i+4)*vertsize),
+ (nouveauVertex*)(vertptr+(i+5)*vertsize)
+ );
+ if (i!=count)
+ {
+ nv04_1triangle(nmesa,
+ (nouveauVertex*)(vertptr+(i+0)*vertsize),
+ (nouveauVertex*)(vertptr+(i+1)*vertsize),
+ (nouveauVertex*)(vertptr+(i+2)*vertsize)
+ );
+ i+=3;
+ }
+ if (i!=count)
+ printf("oops\n");
+}
+
+static void nv04_render_tri_strip_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte *vertptr = (GLubyte *)nmesa->verts;
+ GLuint vertsize = nmesa->vertex_size;
+ uint32_t striptbl[]={0x321210,0x543432,0x765654,0x987876,0xBA9A98,0xDCBCBA,0xFEDEDC};
+ int i,j;
+
+ for(i=start;i<count;i+=14)
+ {
+ int numvert=MIN2(16,count-i);
+ int numtri=numvert-2;
+ if (numvert<3)
+ break;
+
+ BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0),numvert*8);
+ for(j=0;j<numvert;j++)
+ OUT_RINGp((nouveauVertex*)(vertptr+(i+j)*vertsize),8);
+
+ BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_DRAW|NONINC_METHOD,(numtri+1)/2);
+ for(j=0;j<numtri/2;j++)
+ OUT_RING(striptbl[j]);
+ if (numtri%2)
+ OUT_RING(striptbl[numtri/2]&0xFFF);
+ }
+}
+
+static void nv04_render_tri_fan_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte *vertptr = (GLubyte *)nmesa->verts;
+ GLuint vertsize = nmesa->vertex_size;
+ uint32_t fantbl[]={0x320210,0x540430,0x760650,0x980870,0xBA0A90,0xDC0CB0,0xFE0ED0};
+ int i,j;
+
+ BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0),8);
+ OUT_RINGp((nouveauVertex*)(vertptr+start*vertsize),8);
+
+ for(i=start+1;i<count;i+=14)
+ {
+ int numvert=MIN2(15,count-i);
+ int numtri=numvert-1;
+ if (numvert<3)
+ break;
+
+ BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x1),numvert*8);
+
+ for(j=0;j<numvert;j++)
+ OUT_RINGp((nouveauVertex*)(vertptr+(i+j)*vertsize),8);
+
+ BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_DRAW|NONINC_METHOD,(numtri+1)/2);
+ for(j=0;j<numtri/2;j++)
+ OUT_RING(fantbl[j]);
+ if (numtri%2)
+ OUT_RING(fantbl[numtri/2]&0xFFF);
+ }
+}
+
+static void nv04_render_quads_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte *vertptr = (GLubyte *)nmesa->verts;
+ GLuint vertsize = nmesa->vertex_size;
+ int i;
+
+ for(i=start;i<count;i+=4)
+ nv04_1quad(nmesa,
+ (nouveauVertex*)(vertptr+(i+0)*vertsize),
+ (nouveauVertex*)(vertptr+(i+1)*vertsize),
+ (nouveauVertex*)(vertptr+(i+2)*vertsize),
+ (nouveauVertex*)(vertptr+(i+3)*vertsize)
+ );
+}
+
+static void nv04_render_noop_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+}
+
+static void (*nv04_render_tab_verts[GL_POLYGON+2])(GLcontext *,
+ GLuint,
+ GLuint,
+ GLuint) =
+{
+ nv04_render_points_verts,
+ nv04_render_lines_verts,
+ nv04_render_line_loop_verts,
+ nv04_render_line_strip_verts,
+ nv04_render_triangles_verts,
+ nv04_render_tri_strip_verts,
+ nv04_render_tri_fan_verts,
+ nv04_render_quads_verts,
+ nv04_render_tri_strip_verts, //nv04_render_quad_strip_verts
+ nv04_render_tri_fan_verts, //nv04_render_poly_verts
+ nv04_render_noop_verts,
+};
+
+
+static void nv04_render_points_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ // erm
+}
+
+static void nv04_render_lines_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ // umm
+}
+
+static void nv04_render_line_strip_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ // yeah
+}
+
+static void nv04_render_line_loop_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ // right
+}
+
+static void nv04_render_triangles_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte *vertptr = (GLubyte *)nmesa->verts;
+ GLuint vertsize = nmesa->vertex_size;
+ const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts;
+ int i;
+
+ for(i=start;i<count-5;i+=6)
+ nv04_2triangles(nmesa,
+ (nouveauVertex*)(vertptr+elt[i+0]*vertsize),
+ (nouveauVertex*)(vertptr+elt[i+1]*vertsize),
+ (nouveauVertex*)(vertptr+elt[i+2]*vertsize),
+ (nouveauVertex*)(vertptr+elt[i+3]*vertsize),
+ (nouveauVertex*)(vertptr+elt[i+4]*vertsize),
+ (nouveauVertex*)(vertptr+elt[i+5]*vertsize)
+ );
+ if (i!=count)
+ {
+ nv04_1triangle(nmesa,
+ (nouveauVertex*)(vertptr+elt[i+0]*vertsize),
+ (nouveauVertex*)(vertptr+elt[i+1]*vertsize),
+ (nouveauVertex*)(vertptr+elt[i+2]*vertsize)
+ );
+ i+=3;
+ }
+ if (i!=count)
+ printf("oops\n");
+}
+
+static void nv04_render_tri_strip_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte *vertptr = (GLubyte *)nmesa->verts;
+ GLuint vertsize = nmesa->vertex_size;
+ uint32_t striptbl[]={0x321210,0x543432,0x765654,0x987876,0xBA9A98,0xDCBCBA,0xFEDEDC};
+ const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts;
+ int i,j;
+
+ for(i=start;i<count;i+=14)
+ {
+ int numvert=MIN2(16,count-i);
+ int numtri=numvert-2;
+ if (numvert<3)
+ break;
+
+ BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0),numvert*8);
+ for(j=0;j<numvert;j++)
+ OUT_RINGp((nouveauVertex*)(vertptr+elt[i+j]*vertsize),8);
+
+ BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_DRAW|NONINC_METHOD,(numtri+1)/2);
+ for(j=0;j<numtri/2;j++)
+ OUT_RING(striptbl[j]);
+ if (numtri%2)
+ OUT_RING(striptbl[numtri/2]&0xFFF);
+ }
+}
+
+static void nv04_render_tri_fan_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte *vertptr = (GLubyte *)nmesa->verts;
+ GLuint vertsize = nmesa->vertex_size;
+ uint32_t fantbl[]={0x320210,0x540430,0x760650,0x980870,0xBA0A90,0xDC0CB0,0xFE0ED0};
+ const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts;
+ int i,j;
+
+ BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0),8);
+ OUT_RINGp((nouveauVertex*)(vertptr+elt[start]*vertsize),8);
+
+ for(i=start+1;i<count;i+=14)
+ {
+ int numvert=MIN2(15,count-i);
+ int numtri=numvert-2;
+ if (numvert<3)
+ break;
+
+ BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x1),numvert*8);
+
+ for(j=0;j<numvert;j++)
+ OUT_RINGp((nouveauVertex*)(vertptr+elt[i+j]*vertsize),8);
+
+ BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_DRAW|NONINC_METHOD,(numtri+1)/2);
+ for(j=0;j<numtri/2;j++)
+ OUT_RING(fantbl[j]);
+ if (numtri%2)
+ OUT_RING(fantbl[numtri/2]&0xFFF);
+ }
+}
+
+static void nv04_render_quads_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte *vertptr = (GLubyte *)nmesa->verts;
+ GLuint vertsize = nmesa->vertex_size;
+ const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts;
+ int i;
+
+ for(i=start;i<count;i+=4)
+ nv04_1quad(nmesa,
+ (nouveauVertex*)(vertptr+elt[i+0]*vertsize),
+ (nouveauVertex*)(vertptr+elt[i+1]*vertsize),
+ (nouveauVertex*)(vertptr+elt[i+2]*vertsize),
+ (nouveauVertex*)(vertptr+elt[i+3]*vertsize)
+ );
+}
+
+static void nv04_render_noop_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+}
+
+static void (*nv04_render_tab_elts[GL_POLYGON+2])(GLcontext *,
+ GLuint,
+ GLuint,
+ GLuint) =
+{
+ nv04_render_points_elts,
+ nv04_render_lines_elts,
+ nv04_render_line_loop_elts,
+ nv04_render_line_strip_elts,
+ nv04_render_triangles_elts,
+ nv04_render_tri_strip_elts,
+ nv04_render_tri_fan_elts,
+ nv04_render_quads_elts,
+ nv04_render_tri_strip_elts, // nv04_render_quad_strip_elts,
+ nv04_render_tri_fan_elts, // nv04_render_poly_elts,
+ nv04_render_noop_elts,
+};
+
+
+/**********************************************************************/
+/* Choose render functions */
+/**********************************************************************/
+
+
+#define EMIT_ATTR( ATTR, STYLE ) \
+do { \
+ nmesa->vertex_attrs[nmesa->vertex_attr_count].attrib = (ATTR); \
+ nmesa->vertex_attrs[nmesa->vertex_attr_count].format = (STYLE); \
+ nmesa->vertex_attr_count++; \
+} while (0)
+
+#define EMIT_PAD( N ) \
+do { \
+ nmesa->vertex_attrs[nmesa->vertex_attr_count].attrib = 0; \
+ nmesa->vertex_attrs[nmesa->vertex_attr_count].format = EMIT_PAD; \
+ nmesa->vertex_attrs[nmesa->vertex_attr_count].offset = (N); \
+ nmesa->vertex_attr_count++; \
+} while (0)
+
+static void nv04_render_clipped_line(GLcontext *ctx,GLuint ii,GLuint jj)
+{
+}
+
+static void nv04_render_clipped_poly(GLcontext *ctx,const GLuint *elts,GLuint n)
+{
+}
+
+static void nv04ChooseRenderState(GLcontext *ctx)
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+
+ tnl->Driver.Render.PrimTabVerts = nv04_render_tab_verts;
+ tnl->Driver.Render.PrimTabElts = nv04_render_tab_elts;
+ tnl->Driver.Render.ClippedLine = nv04_render_clipped_line;
+ tnl->Driver.Render.ClippedPolygon = nv04_render_clipped_poly;
+ tnl->Driver.Render.Points = nv04_render_points;
+ tnl->Driver.Render.Line = nv04_render_line;
+ tnl->Driver.Render.Triangle = nv04_render_triangle;
+ tnl->Driver.Render.Quad = nv04_render_quad;
+}
+
+
+
+static inline void nv04OutputVertexFormat(struct nouveau_context* nmesa)
+{
+ GLcontext* ctx=nmesa->glCtx;
+ DECLARE_RENDERINPUTS(index);
+
+ /*
+ * Tell t_vertex about the vertex format
+ */
+ 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 00000000000..42dde5383eb
--- /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 00000000000..5f304ccab92
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nv10_state.c
@@ -0,0 +1,798 @@
+/**************************************************************************
+
+Copyright 2006 Nouveau
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#include "nouveau_context.h"
+#include "nouveau_object.h"
+#include "nouveau_fifo.h"
+#include "nouveau_reg.h"
+
+#include "tnl/t_pipeline.h"
+
+#include "mtypes.h"
+#include "colormac.h"
+
+static void nv10ViewportScale(nouveauContextPtr nmesa)
+{
+ GLcontext *ctx = nmesa->glCtx;
+ GLuint w = ctx->Viewport.Width;
+ GLuint h = ctx->Viewport.Height;
+
+ GLfloat max_depth = (ctx->Viewport.Near + ctx->Viewport.Far) * 0.5;
+/* if (ctx->DrawBuffer) {
+ switch (ctx->DrawBuffer->_DepthBuffer->DepthBits) {
+ case 16:
+ max_depth *= 32767.0;
+ break;
+ case 24:
+ max_depth *= 16777215.0;
+ break;
+ }
+ } else {*/
+ /* Default to 24 bits range */
+ max_depth *= 16777215.0;
+/* }*/
+
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X, 4);
+ OUT_RING_CACHEf ((((GLfloat) w) * 0.5) - 2048.0);
+ OUT_RING_CACHEf ((((GLfloat) h) * 0.5) - 2048.0);
+ OUT_RING_CACHEf (max_depth);
+ OUT_RING_CACHEf (0.0);
+}
+
+static void nv10AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte ubRef;
+ CLAMPED_FLOAT_TO_UBYTE(ubRef, ref);
+
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC, 2);
+ OUT_RING_CACHE(func);
+ OUT_RING_CACHE(ubRef);
+}
+
+static void nv10BlendColor(GLcontext *ctx, const GLfloat color[4])
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte cf[4];
+
+ CLAMPED_FLOAT_TO_UBYTE(cf[0], color[0]);
+ CLAMPED_FLOAT_TO_UBYTE(cf[1], color[1]);
+ CLAMPED_FLOAT_TO_UBYTE(cf[2], color[2]);
+ CLAMPED_FLOAT_TO_UBYTE(cf[3], color[3]);
+
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_COLOR, 1);
+ OUT_RING_CACHE(PACK_COLOR_8888(cf[3], cf[1], cf[2], cf[0]));
+}
+
+static void nv10BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ assert( modeRGB == modeA );
+
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_EQUATION, 1);
+ OUT_RING_CACHE(modeRGB);
+}
+
+
+static void nv10BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB,
+ GLenum sfactorA, GLenum dfactorA)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ assert( sfactorRGB == sfactorA );
+ assert( dfactorRGB == dfactorA );
+
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2);
+ OUT_RING_CACHE(sfactorRGB);
+ OUT_RING_CACHE(dfactorRGB);
+}
+
+static void nv10Clear(GLcontext *ctx, GLbitfield mask)
+{
+ /* TODO */
+}
+
+static void nv10ClearColor(GLcontext *ctx, const GLfloat color[4])
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte c[4];
+ UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,color);
+ nmesa->clear_color_value = PACK_COLOR_8888(c[3],c[0],c[1],c[2]);
+}
+
+static void nv10ClearDepth(GLcontext *ctx, GLclampd d)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+/* switch (ctx->DrawBuffer->_DepthBuffer->DepthBits) {
+ case 16:
+ nmesa->clear_value = (uint32_t)(d*0x7FFF);
+ break;
+ case 24:*/
+ nmesa->clear_value = ((nmesa->clear_value&0x000000FF) |
+ (((uint32_t)(d*0xFFFFFF))<<8));
+/* break;
+ }*/
+}
+
+static void nv10ClearStencil(GLcontext *ctx, GLint s)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+/* if (ctx->DrawBuffer->_DepthBuffer->DepthBits == 24) {*/
+ nmesa->clear_value = ((nmesa->clear_value&0xFFFFFF00)|
+ (s&0x000000FF));
+/* }*/
+}
+
+static void nv10ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4);
+ OUT_RING_CACHEf(equation[0]);
+ OUT_RING_CACHEf(equation[1]);
+ OUT_RING_CACHEf(equation[2]);
+ OUT_RING_CACHEf(equation[3]);
+}
+
+static void nv10ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask,
+ GLboolean bmask, GLboolean amask )
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_COLOR_MASK, 1);
+ OUT_RING_CACHE(((amask && 0x01) << 24) | ((rmask && 0x01) << 16) | ((gmask && 0x01)<< 8) | ((bmask && 0x01) << 0));
+}
+
+static void nv10ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode)
+{
+ /* TODO I need love */
+}
+
+static void nv10CullFace(GLcontext *ctx, GLenum mode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CULL_FACE, 1);
+ OUT_RING_CACHE(mode);
+}
+
+static void nv10FrontFace(GLcontext *ctx, GLenum mode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FRONT_FACE, 1);
+ OUT_RING_CACHE(mode);
+}
+
+static void nv10DepthFunc(GLcontext *ctx, GLenum func)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1);
+ OUT_RING_CACHE(func);
+}
+
+static void nv10DepthMask(GLcontext *ctx, GLboolean flag)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1);
+ OUT_RING_CACHE(flag);
+}
+
+static void nv10DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ GLfloat depth_scale = 16777216.0;
+ if (ctx->DrawBuffer->_DepthBuffer->DepthBits == 16) {
+ depth_scale = 32768.0;
+ }
+
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2);
+ OUT_RING_CACHEf(nearval * depth_scale);
+ OUT_RING_CACHEf(farval * depth_scale);
+
+ nv10ViewportScale(nmesa);
+}
+
+/** Specify the current buffer for writing */
+//void (*DrawBuffer)( GLcontext *ctx, GLenum buffer );
+/** Specify the buffers for writing for fragment programs*/
+//void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers );
+
+static void nv10Enable(GLcontext *ctx, GLenum cap, GLboolean state)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ switch(cap)
+ {
+ case GL_ALPHA_TEST:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_AUTO_NORMAL:
+ case GL_BLEND:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_CLIP_PLANE0:
+ case GL_CLIP_PLANE1:
+ case GL_CLIP_PLANE2:
+ case GL_CLIP_PLANE3:
+ case GL_CLIP_PLANE4:
+ case GL_CLIP_PLANE5:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_COLOR_LOGIC_OP:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_COLOR_MATERIAL:
+// case GL_COLOR_SUM_EXT:
+// case GL_COLOR_TABLE:
+// case GL_CONVOLUTION_1D:
+// case GL_CONVOLUTION_2D:
+ case GL_CULL_FACE:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_DEPTH_TEST:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_DITHER:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DITHER_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_FOG:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FOG_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_HISTOGRAM:
+// case GL_INDEX_LOGIC_OP:
+ case GL_LIGHT0:
+ case GL_LIGHT1:
+ case GL_LIGHT2:
+ case GL_LIGHT3:
+ case GL_LIGHT4:
+ case GL_LIGHT5:
+ case GL_LIGHT6:
+ case GL_LIGHT7:
+ {
+ uint32_t mask=1<<(2*(cap-GL_LIGHT0));
+ nmesa->enabled_lights=((nmesa->enabled_lights&mask)|(mask*state));
+ if (nmesa->lighting_enabled)
+ {
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1);
+ OUT_RING_CACHE(nmesa->enabled_lights);
+ }
+ break;
+ }
+ case GL_LIGHTING:
+ nmesa->lighting_enabled=state;
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1);
+ if (nmesa->lighting_enabled)
+ OUT_RING_CACHE(nmesa->enabled_lights);
+ else
+ OUT_RING_CACHE(0x0);
+ break;
+ case GL_LINE_SMOOTH:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_LINE_STIPPLE:
+// case GL_MAP1_COLOR_4:
+// case GL_MAP1_INDEX:
+// case GL_MAP1_NORMAL:
+// case GL_MAP1_TEXTURE_COORD_1:
+// case GL_MAP1_TEXTURE_COORD_2:
+// case GL_MAP1_TEXTURE_COORD_3:
+// case GL_MAP1_TEXTURE_COORD_4:
+// case GL_MAP1_VERTEX_3:
+// case GL_MAP1_VERTEX_4:
+// case GL_MAP2_COLOR_4:
+// case GL_MAP2_INDEX:
+// case GL_MAP2_NORMAL:
+// case GL_MAP2_TEXTURE_COORD_1:
+// case GL_MAP2_TEXTURE_COORD_2:
+// case GL_MAP2_TEXTURE_COORD_3:
+// case GL_MAP2_TEXTURE_COORD_4:
+// case GL_MAP2_VERTEX_3:
+// case GL_MAP2_VERTEX_4:
+// case GL_MINMAX:
+ case GL_NORMALIZE:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_POINT_SMOOTH:
+ case GL_POLYGON_OFFSET_POINT:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_POLYGON_OFFSET_LINE:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_POLYGON_OFFSET_FILL:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_POLYGON_SMOOTH:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_POLYGON_STIPPLE:
+// case GL_POST_COLOR_MATRIX_COLOR_TABLE:
+// case GL_POST_CONVOLUTION_COLOR_TABLE:
+// case GL_RESCALE_NORMAL:
+// case GL_SCISSOR_TEST:
+// case GL_SEPARABLE_2D:
+ case GL_STENCIL_TEST:
+ // TODO BACK and FRONT ?
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_TEXTURE_GEN_Q:
+// case GL_TEXTURE_GEN_R:
+// case GL_TEXTURE_GEN_S:
+// case GL_TEXTURE_GEN_T:
+// case GL_TEXTURE_1D:
+// case GL_TEXTURE_2D:
+// case GL_TEXTURE_3D:
+ }
+}
+
+static void nv10Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ switch(pname)
+ {
+ case GL_FOG_MODE:
+ //BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FOG_MODE, 1);
+ //OUT_RING_CACHE (params);
+ break;
+ /* TODO: unsure about the rest.*/
+ default:
+ break;
+ }
+
+}
+
+static void nv10Hint(GLcontext *ctx, GLenum target, GLenum mode)
+{
+ /* TODO I need love (fog and line_smooth hints) */
+}
+
+// void (*IndexMask)(GLcontext *ctx, GLuint mask);
+
+enum {
+ SPOTLIGHT_NO_UPDATE,
+ SPOTLIGHT_UPDATE_EXPONENT,
+ SPOTLIGHT_UPDATE_DIRECTION,
+ SPOTLIGHT_UPDATE_ALL
+};
+
+static void nv10Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params )
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLint p = light - GL_LIGHT0;
+ struct gl_light *l = &ctx->Light.Light[p];
+ int spotlight_update = SPOTLIGHT_NO_UPDATE;
+
+ switch(pname)
+ {
+ case GL_AMBIENT:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(p), 3);
+ OUT_RING_CACHEf(params[0]);
+ OUT_RING_CACHEf(params[1]);
+ OUT_RING_CACHEf(params[2]);
+ break;
+ case GL_DIFFUSE:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(p), 3);
+ OUT_RING_CACHEf(params[0]);
+ OUT_RING_CACHEf(params[1]);
+ OUT_RING_CACHEf(params[2]);
+ break;
+ case GL_SPECULAR:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(p), 3);
+ OUT_RING_CACHEf(params[0]);
+ OUT_RING_CACHEf(params[1]);
+ OUT_RING_CACHEf(params[2]);
+ break;
+ case GL_POSITION:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(p), 3);
+ OUT_RING_CACHEf(params[0]);
+ OUT_RING_CACHEf(params[1]);
+ OUT_RING_CACHEf(params[2]);
+ break;
+ case GL_SPOT_DIRECTION:
+ spotlight_update = SPOTLIGHT_UPDATE_DIRECTION;
+ break;
+ case GL_SPOT_EXPONENT:
+ spotlight_update = SPOTLIGHT_UPDATE_EXPONENT;
+ break;
+ case GL_SPOT_CUTOFF:
+ spotlight_update = SPOTLIGHT_UPDATE_ALL;
+ break;
+ case GL_CONSTANT_ATTENUATION:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(p), 1);
+ OUT_RING_CACHEf(*params);
+ break;
+ case GL_LINEAR_ATTENUATION:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(p), 1);
+ OUT_RING_CACHEf(*params);
+ break;
+ case GL_QUADRATIC_ATTENUATION:
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(p), 1);
+ OUT_RING_CACHEf(*params);
+ break;
+ default:
+ break;
+ }
+
+ switch(spotlight_update) {
+ case SPOTLIGHT_UPDATE_DIRECTION:
+ {
+ GLfloat x,y,z;
+ GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0);
+ x = spot_light_coef_a * l->_NormDirection[0];
+ y = spot_light_coef_a * l->_NormDirection[1];
+ z = spot_light_coef_a * l->_NormDirection[2];
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p), 3);
+ OUT_RING_CACHEf(x);
+ OUT_RING_CACHEf(y);
+ OUT_RING_CACHEf(z);
+ }
+ break;
+ case SPOTLIGHT_UPDATE_EXPONENT:
+ {
+ GLfloat cc,lc,qc;
+ cc = 1.0; /* FIXME: These need to be correctly computed */
+ lc = 0.0;
+ qc = 2.0;
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 3);
+ OUT_RING_CACHEf(cc);
+ OUT_RING_CACHEf(lc);
+ OUT_RING_CACHEf(qc);
+ }
+ break;
+ case SPOTLIGHT_UPDATE_ALL:
+ {
+ GLfloat cc,lc,qc, x,y,z, c;
+ GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0);
+ cc = 1.0; /* FIXME: These need to be correctly computed */
+ lc = 0.0;
+ qc = 2.0;
+ x = spot_light_coef_a * l->_NormDirection[0];
+ y = spot_light_coef_a * l->_NormDirection[1];
+ z = spot_light_coef_a * l->_NormDirection[2];
+ c = spot_light_coef_a + 1.0;
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 7);
+ OUT_RING_CACHEf(cc);
+ OUT_RING_CACHEf(lc);
+ OUT_RING_CACHEf(qc);
+ OUT_RING_CACHEf(x);
+ OUT_RING_CACHEf(y);
+ OUT_RING_CACHEf(z);
+ OUT_RING_CACHEf(c);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/** Set the lighting model parameters */
+static void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params);
+
+
+static void nv10LineStipple(GLcontext *ctx, GLint factor, GLushort pattern )
+{
+ /* Not for NV10 */
+}
+
+static void nv10LineWidth(GLcontext *ctx, GLfloat width)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LINE_WIDTH, 1);
+ OUT_RING_CACHE(((int) (width * 8.0)) & -4);
+}
+
+static void nv10LogicOpcode(GLcontext *ctx, GLenum opcode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP, 1);
+ OUT_RING_CACHE(opcode);
+}
+
+static void nv10PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
+{
+ /*TODO: not sure what goes here. */
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+}
+
+static void nv10PointSize(GLcontext *ctx, GLfloat size)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POINT_SIZE, 1);
+ OUT_RING_CACHE(((int) (size * 8.0)) & -4);
+}
+
+static void nv10PolygonMode(GLcontext *ctx, GLenum face, GLenum mode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 1);
+ OUT_RING_CACHE(mode);
+ }
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK, 1);
+ OUT_RING_CACHE(mode);
+ }
+}
+
+/** Set the scale and units used to calculate depth values */
+static void nv10PolygonOffset(GLcontext *ctx, GLfloat factor, GLfloat units)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR, 2);
+ OUT_RING_CACHEf(factor);
+ OUT_RING_CACHEf(units);
+}
+
+/** Set the polygon stippling pattern */
+static void nv10PolygonStipple(GLcontext *ctx, const GLubyte *mask )
+{
+ /* Not for NV10 */
+}
+
+/* Specifies the current buffer for reading */
+void (*ReadBuffer)( GLcontext *ctx, GLenum buffer );
+/** Set rasterization mode */
+void (*RenderMode)(GLcontext *ctx, GLenum mode );
+
+/** Define the scissor box */
+static void nv10Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+{
+}
+
+/** Select flat or smooth shading */
+static void nv10ShadeModel(GLcontext *ctx, GLenum mode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_SHADE_MODEL, 1);
+ OUT_RING_CACHE(mode);
+}
+
+/** OpenGL 2.0 two-sided StencilFunc */
+static void nv10StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func,
+ GLint ref, GLuint mask)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ /* NV10 do not have separate FRONT and BACK stencils */
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC, 3);
+ OUT_RING_CACHE(func);
+ OUT_RING_CACHE(ref);
+ OUT_RING_CACHE(mask);
+}
+
+/** OpenGL 2.0 two-sided StencilMask */
+static void nv10StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ /* NV10 do not have separate FRONT and BACK stencils */
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_MASK, 1);
+ OUT_RING_CACHE(mask);
+}
+
+/** OpenGL 2.0 two-sided StencilOp */
+static void nv10StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail,
+ GLenum zfail, GLenum zpass)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ /* NV10 do not have separate FRONT and BACK stencils */
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_OP_FAIL, 3);
+ OUT_RING_CACHE(fail);
+ OUT_RING_CACHE(zfail);
+ OUT_RING_CACHE(zpass);
+}
+
+/** Control the generation of texture coordinates */
+void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname,
+ const GLfloat *params);
+/** Set texture environment parameters */
+void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname,
+ const GLfloat *param);
+/** Set texture parameters */
+void (*TexParameter)(GLcontext *ctx, GLenum target,
+ struct gl_texture_object *texObj,
+ GLenum pname, const GLfloat *params);
+
+static void nv10TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16);
+ /*XXX: This SHOULD work.*/
+ OUT_RING_CACHEp(mat->m, 16);
+}
+
+/* Update anything that depends on the window position/size */
+static void nv10WindowMoved(nouveauContextPtr nmesa)
+{
+ GLcontext *ctx = nmesa->glCtx;
+ GLfloat *v = nmesa->viewport.m;
+ GLuint w = ctx->Viewport.Width;
+ GLuint h = ctx->Viewport.Height;
+ GLuint x = ctx->Viewport.X + nmesa->drawX;
+ GLuint y = ctx->Viewport.Y + nmesa->drawY;
+ int i;
+
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2);
+ OUT_RING_CACHE((w << 16) | x);
+ OUT_RING_CACHE((h << 16) | y);
+
+ /* something to do with clears, possibly doesn't belong here */
+ BEGIN_RING_SIZE(NvSub3D, 0x02b4, 1);
+ OUT_RING(0);
+
+ BEGIN_RING_CACHE(NvSub3D,
+ NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 1);
+ OUT_RING_CACHE(((w+x-1) << 16) | x | 0x08000800);
+ BEGIN_RING_CACHE(NvSub3D,
+ NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(0), 1);
+ OUT_RING_CACHE(((h+y-1) << 16) | y | 0x08000800);
+ for (i=1; i<8; i++) {
+ BEGIN_RING_CACHE(NvSub3D,
+ NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 1);
+ OUT_RING_CACHE(0);
+ BEGIN_RING_CACHE(NvSub3D,
+ NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(i), 1);
+ OUT_RING_CACHE(0);
+ }
+
+ nv10ViewportScale(nmesa);
+}
+
+/* Initialise any card-specific non-GL related state */
+static GLboolean nv10InitCard(nouveauContextPtr nmesa)
+{
+ nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D);
+
+ BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY0, 2);
+ OUT_RING(NvDmaFB); /* 184 dma_in_memory0 */
+ OUT_RING(NvDmaFB); /* 188 dma_in_memory1 */
+ BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY2, 2);
+ OUT_RING(NvDmaFB); /* 194 dma_in_memory2 */
+ OUT_RING(NvDmaFB); /* 198 dma_in_memory3 */
+
+ BEGIN_RING_SIZE(NvSub3D, 0x0290, 1);
+ OUT_RING(0x00100001);
+ BEGIN_RING_SIZE(NvSub3D, 0x03f4, 1);
+ OUT_RING(0);
+
+ /* not for nv10, only for >= nv11 */
+ if ((nmesa->screen->card->id>>4) >= 0x11) {
+ BEGIN_RING_SIZE(NvSub3D, 0x120, 3);
+ OUT_RING(0);
+ OUT_RING(1);
+ OUT_RING(2);
+ }
+
+ return GL_TRUE;
+}
+
+/* Update buffer offset/pitch/format */
+static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color,
+ nouveau_renderbuffer **color,
+ nouveau_renderbuffer *depth)
+{
+ GLuint x, y, w, h;
+ GLuint pitch, format, depth_pitch;
+
+ w = color[0]->mesa.Width;
+ h = color[0]->mesa.Height;
+ x = nmesa->drawX;
+ y = nmesa->drawY;
+
+ if (num_color != 1)
+ return GL_FALSE;
+
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 6);
+ OUT_RING_CACHE((w << 16) | x);
+ OUT_RING_CACHE((h << 16) | y);
+ depth_pitch = (depth ? depth->pitch : color[0]->pitch);
+ pitch = (depth_pitch<<16) | color[0]->pitch;
+ format = 0x108;
+ if (color[0]->mesa._ActualFormat != GL_RGBA8) {
+ format = 0x103; /* R5G6B5 color buffer */
+ }
+ OUT_RING_CACHE(format);
+ OUT_RING_CACHE(pitch);
+ OUT_RING_CACHE(color[0]->offset);
+ OUT_RING_CACHE(depth ? depth->offset : color[0]->offset);
+
+ /* Always set to bottom left of buffer */
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X, 4);
+ OUT_RING_CACHEf (0.0);
+ OUT_RING_CACHEf ((GLfloat) h);
+ OUT_RING_CACHEf (0.0);
+ OUT_RING_CACHEf (0.0);
+
+ return GL_TRUE;
+}
+
+void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ func->AlphaFunc = nv10AlphaFunc;
+ func->BlendColor = nv10BlendColor;
+ func->BlendEquationSeparate = nv10BlendEquationSeparate;
+ func->BlendFuncSeparate = nv10BlendFuncSeparate;
+ func->Clear = nv10Clear;
+ func->ClearColor = nv10ClearColor;
+ func->ClearDepth = nv10ClearDepth;
+ func->ClearStencil = nv10ClearStencil;
+ func->ClipPlane = nv10ClipPlane;
+ func->ColorMask = nv10ColorMask;
+ func->ColorMaterial = nv10ColorMaterial;
+ func->CullFace = nv10CullFace;
+ func->FrontFace = nv10FrontFace;
+ func->DepthFunc = nv10DepthFunc;
+ func->DepthMask = nv10DepthMask;
+ func->DepthRange = nv10DepthRange;
+ func->Enable = nv10Enable;
+ func->Fogfv = nv10Fogfv;
+ func->Hint = nv10Hint;
+ func->Lightfv = nv10Lightfv;
+/* func->LightModelfv = nv10LightModelfv; */
+ func->LineStipple = nv10LineStipple; /* Not for NV10 */
+ func->LineWidth = nv10LineWidth;
+ func->LogicOpcode = nv10LogicOpcode;
+ func->PointParameterfv = nv10PointParameterfv;
+ func->PointSize = nv10PointSize;
+ func->PolygonMode = nv10PolygonMode;
+ func->PolygonOffset = nv10PolygonOffset;
+ func->PolygonStipple = nv10PolygonStipple; /* Not for NV10 */
+/* func->ReadBuffer = nv10ReadBuffer;*/
+/* func->RenderMode = nv10RenderMode;*/
+ func->Scissor = nv10Scissor;
+ func->ShadeModel = nv10ShadeModel;
+ func->StencilFuncSeparate = nv10StencilFuncSeparate;
+ func->StencilMaskSeparate = nv10StencilMaskSeparate;
+ func->StencilOpSeparate = nv10StencilOpSeparate;
+/* func->TexGen = nv10TexGen;*/
+/* func->TexParameter = nv10TexParameter;*/
+ func->TextureMatrix = nv10TextureMatrix;
+
+ nmesa->hw_func.InitCard = nv10InitCard;
+ nmesa->hw_func.BindBuffers = nv10BindBuffers;
+ nmesa->hw_func.WindowMoved = nv10WindowMoved;
+}
diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c
new file mode 100644
index 00000000000..32da40661b4
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c
@@ -0,0 +1,647 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ * Copyright 2006 Stephane Marchesin. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/* Software TCL for NV10, NV20, NV30, NV40, NV50 */
+
+#include <stdio.h>
+#include <math.h>
+
+#include "glheader.h"
+#include "context.h"
+#include "mtypes.h"
+#include "macros.h"
+#include "colormac.h"
+#include "enums.h"
+
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "tnl/t_context.h"
+#include "tnl/t_pipeline.h"
+
+#include "nouveau_swtcl.h"
+#include "nv10_swtcl.h"
+#include "nouveau_context.h"
+#include "nouveau_span.h"
+#include "nouveau_reg.h"
+#include "nouveau_tex.h"
+#include "nouveau_fifo.h"
+#include "nouveau_msg.h"
+#include "nouveau_object.h"
+
+static void nv10RasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim );
+static void nv10RenderPrimitive( GLcontext *ctx, GLenum prim );
+static void nv10ResetLineStipple( GLcontext *ctx );
+
+
+
+static inline void nv10StartPrimitive(struct nouveau_context* nmesa,uint32_t primitive,uint32_t size)
+{
+ if (nmesa->screen->card->type==NV_10)
+ BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_BEGIN_END,1);
+ else if (nmesa->screen->card->type==NV_20)
+ BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_BEGIN_END,1);
+ else
+ BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_BEGIN_END,1);
+ OUT_RING(primitive);
+
+ if (nmesa->screen->card->type==NV_10)
+ BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_DATA|NONINC_METHOD,size);
+ else if (nmesa->screen->card->type==NV_20)
+ BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_VERTEX_DATA|NONINC_METHOD,size);
+ else
+ BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_DATA|NONINC_METHOD,size);
+}
+
+inline void nv10FinishPrimitive(struct nouveau_context *nmesa)
+{
+ if (nmesa->screen->card->type==NV_10)
+ BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_BEGIN_END,1);
+ else if (nmesa->screen->card->type==NV_20)
+ BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_BEGIN_END,1);
+ else
+ BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_BEGIN_END,1);
+ OUT_RING(0x0);
+ FIRE_RING();
+}
+
+
+static inline void nv10ExtendPrimitive(struct nouveau_context* nmesa, int size)
+{
+ /* make sure there's enough room. if not, wait */
+ if (RING_AVAILABLE()<size)
+ {
+ WAIT_RING(nmesa,size);
+ }
+}
+
+/**********************************************************************/
+/* Render unclipped begin/end objects */
+/**********************************************************************/
+
+static inline void nv10_render_generic_primitive_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags,GLuint prim)
+{
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte *vertptr = (GLubyte *)nmesa->verts;
+ GLuint vertsize = nmesa->vertex_size;
+ GLuint size_dword = vertsize*(count-start)/4;
+
+ nv10ExtendPrimitive(nmesa, size_dword);
+ nv10StartPrimitive(nmesa,prim+1,size_dword);
+ OUT_RINGp((nouveauVertex*)(vertptr+(start*vertsize)),size_dword);
+ nv10FinishPrimitive(nmesa);
+}
+
+static void nv10_render_points_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_POINTS);
+}
+
+static void nv10_render_lines_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_LINES);
+}
+
+static void nv10_render_line_strip_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_LINE_STRIP);
+}
+
+static void nv10_render_line_loop_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_LINE_LOOP);
+}
+
+static void nv10_render_triangles_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_TRIANGLES);
+}
+
+static void nv10_render_tri_strip_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_TRIANGLE_STRIP);
+}
+
+static void nv10_render_tri_fan_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_TRIANGLE_FAN);
+}
+
+static void nv10_render_quads_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_QUADS);
+}
+
+static void nv10_render_quad_strip_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_QUAD_STRIP);
+}
+
+static void nv10_render_poly_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_POLYGON);
+}
+
+static void nv10_render_noop_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+}
+
+static void (*nv10_render_tab_verts[GL_POLYGON+2])(GLcontext *,
+ GLuint,
+ GLuint,
+ GLuint) =
+{
+ nv10_render_points_verts,
+ nv10_render_lines_verts,
+ nv10_render_line_loop_verts,
+ nv10_render_line_strip_verts,
+ nv10_render_triangles_verts,
+ nv10_render_tri_strip_verts,
+ nv10_render_tri_fan_verts,
+ nv10_render_quads_verts,
+ nv10_render_quad_strip_verts,
+ nv10_render_poly_verts,
+ nv10_render_noop_verts,
+};
+
+
+static inline void nv10_render_generic_primitive_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags,GLuint prim)
+{
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte *vertptr = (GLubyte *)nmesa->verts;
+ GLuint vertsize = nmesa->vertex_size;
+ GLuint size_dword = vertsize*(count-start)/4;
+ const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts;
+ GLuint j;
+
+ nv10ExtendPrimitive(nmesa, size_dword);
+ nv10StartPrimitive(nmesa,prim+1,size_dword);
+ for (j=start; j<count; j++ ) {
+ OUT_RINGp((nouveauVertex*)(vertptr+(elt[j]*vertsize)),vertsize/4);
+ }
+ nv10FinishPrimitive(nmesa);
+}
+
+static void nv10_render_points_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_POINTS);
+}
+
+static void nv10_render_lines_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_LINES);
+}
+
+static void nv10_render_line_strip_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_LINE_STRIP);
+}
+
+static void nv10_render_line_loop_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_LINE_LOOP);
+}
+
+static void nv10_render_triangles_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_TRIANGLES);
+}
+
+static void nv10_render_tri_strip_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_TRIANGLE_STRIP);
+}
+
+static void nv10_render_tri_fan_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_TRIANGLE_FAN);
+}
+
+static void nv10_render_quads_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_QUADS);
+}
+
+static void nv10_render_quad_strip_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_QUAD_STRIP);
+}
+
+static void nv10_render_poly_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+ nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_POLYGON);
+}
+
+static void nv10_render_noop_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
+{
+}
+
+static void (*nv10_render_tab_elts[GL_POLYGON+2])(GLcontext *,
+ GLuint,
+ GLuint,
+ GLuint) =
+{
+ nv10_render_points_elts,
+ nv10_render_lines_elts,
+ nv10_render_line_loop_elts,
+ nv10_render_line_strip_elts,
+ nv10_render_triangles_elts,
+ nv10_render_tri_strip_elts,
+ nv10_render_tri_fan_elts,
+ nv10_render_quads_elts,
+ nv10_render_quad_strip_elts,
+ nv10_render_poly_elts,
+ nv10_render_noop_elts,
+};
+
+
+/**********************************************************************/
+/* Choose render functions */
+/**********************************************************************/
+
+
+#define EMIT_ATTR( ATTR, STYLE ) \
+do { \
+ nmesa->vertex_attrs[nmesa->vertex_attr_count].attrib = (ATTR); \
+ nmesa->vertex_attrs[nmesa->vertex_attr_count].format = (STYLE); \
+ nmesa->vertex_attr_count++; \
+} while (0)
+
+static void nv10_render_clipped_line(GLcontext *ctx,GLuint ii,GLuint jj)
+{
+
+}
+
+static void nv10_render_clipped_poly(GLcontext *ctx,const GLuint *elts,GLuint n)
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ struct vertex_buffer *VB = &tnl->vb;
+ GLuint *tmp = VB->Elts;
+ VB->Elts = (GLuint *)elts;
+ nv10_render_generic_primitive_elts( ctx, 0, n, PRIM_BEGIN|PRIM_END,GL_POLYGON );
+ VB->Elts = tmp;
+}
+
+static inline void nv10_render_points(GLcontext *ctx,GLuint first,GLuint last)
+{
+ WARN_ONCE("Unimplemented\n");
+}
+
+static inline void nv10_render_line(GLcontext *ctx,GLuint v1,GLuint v2)
+{
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte *vertptr = (GLubyte *)nmesa->verts;
+ GLuint vertsize = nmesa->vertex_size;
+ GLuint size_dword = vertsize*(2)/4;
+
+ nv10ExtendPrimitive(nmesa, size_dword);
+ nv10StartPrimitive(nmesa,GL_LINES+1,size_dword);
+ OUT_RINGp((nouveauVertex*)(vertptr+(v1*vertsize)),vertsize);
+ OUT_RINGp((nouveauVertex*)(vertptr+(v2*vertsize)),vertsize);
+ nv10FinishPrimitive(nmesa);
+}
+
+static inline void nv10_render_triangle(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3)
+{
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte *vertptr = (GLubyte *)nmesa->verts;
+ GLuint vertsize = nmesa->vertex_size;
+ GLuint size_dword = vertsize*(3)/4;
+
+ nv10ExtendPrimitive(nmesa, size_dword);
+ nv10StartPrimitive(nmesa,GL_TRIANGLES+1,size_dword);
+ OUT_RINGp((nouveauVertex*)(vertptr+(v1*vertsize)),vertsize);
+ OUT_RINGp((nouveauVertex*)(vertptr+(v2*vertsize)),vertsize);
+ OUT_RINGp((nouveauVertex*)(vertptr+(v3*vertsize)),vertsize);
+ nv10FinishPrimitive(nmesa);
+}
+
+static inline void nv10_render_quad(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3,GLuint v4)
+{
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte *vertptr = (GLubyte *)nmesa->verts;
+ GLuint vertsize = nmesa->vertex_size;
+ GLuint size_dword = vertsize*(4)/4;
+
+ nv10ExtendPrimitive(nmesa, size_dword);
+ nv10StartPrimitive(nmesa,GL_QUADS+1,size_dword);
+ OUT_RINGp((nouveauVertex*)(vertptr+(v1*vertsize)),vertsize);
+ OUT_RINGp((nouveauVertex*)(vertptr+(v2*vertsize)),vertsize);
+ OUT_RINGp((nouveauVertex*)(vertptr+(v3*vertsize)),vertsize);
+ OUT_RINGp((nouveauVertex*)(vertptr+(v4*vertsize)),vertsize);
+ nv10FinishPrimitive(nmesa);
+}
+
+
+
+static void nv10ChooseRenderState(GLcontext *ctx)
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+
+ tnl->Driver.Render.PrimTabVerts = nv10_render_tab_verts;
+ tnl->Driver.Render.PrimTabElts = nv10_render_tab_elts;
+ tnl->Driver.Render.ClippedLine = nv10_render_clipped_line;
+ tnl->Driver.Render.ClippedPolygon = nv10_render_clipped_poly;
+ tnl->Driver.Render.Points = nv10_render_points;
+ tnl->Driver.Render.Line = nv10_render_line;
+ tnl->Driver.Render.Triangle = nv10_render_triangle;
+ tnl->Driver.Render.Quad = nv10_render_quad;
+}
+
+
+
+static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa)
+{
+ GLcontext* ctx=nmesa->glCtx;
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ DECLARE_RENDERINPUTS(index);
+ struct vertex_buffer *VB = &tnl->vb;
+ int attr_size[16];
+ int default_attr_size[8]={3,3,3,4,3,1,4,4};
+ int i;
+ int slots=0;
+ int total_size=0;
+ /* t_vertex_generic dereferences a NULL pointer if we
+ * pass NULL as the vp transform...
+ */
+ const GLfloat ident_vp[16] = {
+ 1.0, 0.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0, 0.0,
+ 0.0, 0.0, 1.0, 0.0,
+ 0.0, 0.0, 0.0, 1.0
+ };
+
+ nmesa->vertex_attr_count = 0;
+ RENDERINPUTS_COPY(index, nmesa->render_inputs_bitset);
+
+ /*
+ * Determine attribute sizes
+ */
+ for(i=0;i<8;i++)
+ {
+ if (RENDERINPUTS_TEST(index, i))
+ attr_size[i]=default_attr_size[i];
+ else
+ attr_size[i]=0;
+ }
+ for(i=8;i<16;i++)
+ {
+ if (RENDERINPUTS_TEST(index, i))
+ attr_size[i]=VB->TexCoordPtr[i-8]->size;
+ else
+ attr_size[i]=0;
+ }
+
+ /*
+ * Tell t_vertex about the vertex format
+ */
+ for(i=0;i<16;i++)
+ {
+ if (RENDERINPUTS_TEST(index, i))
+ {
+ slots=i+1;
+ if (i==_TNL_ATTRIB_POS)
+ {
+ /* special-case POS */
+ EMIT_ATTR(_TNL_ATTRIB_POS,EMIT_3F_VIEWPORT);
+ }
+ else
+ {
+ switch(attr_size[i])
+ {
+ case 1:
+ EMIT_ATTR(i,EMIT_1F);
+ break;
+ case 2:
+ EMIT_ATTR(i,EMIT_2F);
+ break;
+ case 3:
+ EMIT_ATTR(i,EMIT_3F);
+ break;
+ case 4:
+ EMIT_ATTR(i,EMIT_4F);
+ break;
+ }
+ }
+ if (i==_TNL_ATTRIB_COLOR0)
+ nmesa->color_offset=total_size;
+ if (i==_TNL_ATTRIB_COLOR1)
+ nmesa->specular_offset=total_size;
+ total_size+=attr_size[i];
+ }
+ }
+
+ nmesa->vertex_size=_tnl_install_attrs( ctx,
+ nmesa->vertex_attrs,
+ nmesa->vertex_attr_count,
+ ident_vp, 0 );
+ assert(nmesa->vertex_size==total_size*4);
+
+ /*
+ * Tell the hardware about the vertex format
+ */
+ if (nmesa->screen->card->type==NV_10) {
+ int size;
+
+#define NV_VERTEX_ATTRIBUTE_TYPE_FLOAT 2
+
+#define NV10_SET_VERTEX_ATTRIB(i,j) \
+ do { \
+ size = attr_size[j] << 4; \
+ size |= (attr_size[j]*4) << 8; \
+ size |= NV_VERTEX_ATTRIBUTE_TYPE_FLOAT; \
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_ATTR(i),1); \
+ OUT_RING_CACHE(size); \
+ } while (0)
+
+ NV10_SET_VERTEX_ATTRIB(0, _TNL_ATTRIB_POS);
+ NV10_SET_VERTEX_ATTRIB(1, _TNL_ATTRIB_COLOR0);
+ NV10_SET_VERTEX_ATTRIB(2, _TNL_ATTRIB_COLOR1);
+ NV10_SET_VERTEX_ATTRIB(3, _TNL_ATTRIB_TEX0);
+ NV10_SET_VERTEX_ATTRIB(4, _TNL_ATTRIB_TEX1);
+ NV10_SET_VERTEX_ATTRIB(5, _TNL_ATTRIB_NORMAL);
+ NV10_SET_VERTEX_ATTRIB(6, _TNL_ATTRIB_WEIGHT);
+ NV10_SET_VERTEX_ATTRIB(7, _TNL_ATTRIB_FOG);
+
+ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_VALIDATE,1);
+ OUT_RING_CACHE(0);
+ } else if (nmesa->screen->card->type==NV_20) {
+ for(i=0;i<16;i++)
+ {
+ int size=attr_size[i];
+ BEGIN_RING_CACHE(NvSub3D,NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR(i),1);
+ OUT_RING_CACHE(NV_VERTEX_ATTRIBUTE_TYPE_FLOAT|(size*0x10));
+ }
+ } else {
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DO_VERTICES, 1);
+ OUT_RING(0);
+ BEGIN_RING_CACHE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR0_POS,slots);
+ for(i=0;i<slots;i++)
+ {
+ int size=attr_size[i];
+ OUT_RING_CACHE(NV_VERTEX_ATTRIBUTE_TYPE_FLOAT|(size*0x10));
+ }
+ // FIXME this is probably not needed
+ BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_UNK_0,1);
+ OUT_RING(0);
+ BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_UNK_0,1);
+ OUT_RING(0);
+ BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_UNK_0,1);
+ OUT_RING(0);
+ }
+}
+
+
+static void nv10ChooseVertexState( GLcontext *ctx )
+{
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ DECLARE_RENDERINPUTS(index);
+
+ RENDERINPUTS_COPY(index, tnl->render_inputs_bitset);
+ if (!RENDERINPUTS_EQUAL(index, nmesa->render_inputs_bitset))
+ {
+ RENDERINPUTS_COPY(nmesa->render_inputs_bitset, index);
+ nv10OutputVertexFormat(nmesa);
+ }
+
+ if (nmesa->screen->card->type == NV_30) {
+ nouveauShader *fp;
+
+ if (ctx->FragmentProgram.Enabled) {
+ fp = (nouveauShader *) ctx->FragmentProgram.Current;
+ nvsUpdateShader(ctx, fp);
+ } else
+ nvsUpdateShader(ctx, nmesa->passthrough_fp);
+ }
+
+ if (nmesa->screen->card->type >= NV_40) {
+ /* Ensure passthrough shader is being used, and mvp matrix
+ * is up to date
+ */
+ nvsUpdateShader(ctx, nmesa->passthrough_vp);
+
+ /* Update texenv shader / user fragprog */
+ nvsUpdateShader(ctx, (nouveauShader*)ctx->FragmentProgram._Current);
+ }
+}
+
+
+/**********************************************************************/
+/* High level hooks for t_vb_render.c */
+/**********************************************************************/
+
+
+static void nv10RenderStart(GLcontext *ctx)
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+
+ if (nmesa->new_state) {
+ nmesa->new_render_state |= nmesa->new_state;
+ }
+
+ if (nmesa->new_render_state) {
+ nv10ChooseVertexState(ctx);
+ nv10ChooseRenderState(ctx);
+ nmesa->new_render_state = 0;
+ }
+}
+
+static void nv10RenderFinish(GLcontext *ctx)
+{
+}
+
+
+/* System to flush dma and emit state changes based on the rasterized
+ * primitive.
+ */
+void nv10RasterPrimitive(GLcontext *ctx,
+ GLenum glprim,
+ GLuint hwprim)
+{
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+
+ assert (!nmesa->new_state);
+
+ if (hwprim != nmesa->current_primitive)
+ {
+ nmesa->current_primitive=hwprim;
+
+ }
+}
+
+static const GLuint hw_prim[GL_POLYGON+1] = {
+ GL_POINTS+1,
+ GL_LINES+1,
+ GL_LINE_STRIP+1,
+ GL_LINE_LOOP+1,
+ GL_TRIANGLES+1,
+ GL_TRIANGLE_STRIP+1,
+ GL_TRIANGLE_FAN+1,
+ GL_QUADS+1,
+ GL_QUAD_STRIP+1,
+ GL_POLYGON+1
+};
+
+/* Callback for mesa:
+ */
+static void nv10RenderPrimitive( GLcontext *ctx, GLuint prim )
+{
+ nv10RasterPrimitive( ctx, prim, hw_prim[prim] );
+}
+
+static void nv10ResetLineStipple( GLcontext *ctx )
+{
+ /* FIXME do something here */
+ WARN_ONCE("Unimplemented nv10ResetLineStipple\n");
+}
+
+
+/**********************************************************************/
+/* Initialization. */
+/**********************************************************************/
+
+void nv10TriInitFunctions(GLcontext *ctx)
+{
+ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+
+ tnl->Driver.RunPipeline = nouveauRunPipeline;
+ tnl->Driver.Render.Start = nv10RenderStart;
+ tnl->Driver.Render.Finish = nv10RenderFinish;
+ tnl->Driver.Render.PrimitiveNotify = nv10RenderPrimitive;
+ tnl->Driver.Render.ResetLineStipple = nv10ResetLineStipple;
+ tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
+ tnl->Driver.Render.CopyPV = _tnl_copy_pv;
+ tnl->Driver.Render.Interp = _tnl_interp;
+
+ _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12,
+ 64 * sizeof(GLfloat) );
+
+ nmesa->verts = (GLubyte *)tnl->clipspace.vertex_buf;
+}
+
+
diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.h b/src/mesa/drivers/dri/nouveau/nv10_swtcl.h
new file mode 100644
index 00000000000..7c854addd2d
--- /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 00000000000..7d2e29db668
--- /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 00000000000..030713c0dbb
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nv20_state.c
@@ -0,0 +1,811 @@
+/**************************************************************************
+
+Copyright 2006 Nouveau
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#include "nouveau_context.h"
+#include "nouveau_object.h"
+#include "nouveau_fifo.h"
+#include "nouveau_reg.h"
+
+#include "tnl/t_pipeline.h"
+
+#include "mtypes.h"
+#include "colormac.h"
+
+static void nv20AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte ubRef;
+ CLAMPED_FLOAT_TO_UBYTE(ubRef, ref);
+
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC, 2);
+ OUT_RING_CACHE(func);
+ OUT_RING_CACHE(ubRef);
+}
+
+static void nv20BlendColor(GLcontext *ctx, const GLfloat color[4])
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte cf[4];
+
+ CLAMPED_FLOAT_TO_UBYTE(cf[0], color[0]);
+ CLAMPED_FLOAT_TO_UBYTE(cf[1], color[1]);
+ CLAMPED_FLOAT_TO_UBYTE(cf[2], color[2]);
+ CLAMPED_FLOAT_TO_UBYTE(cf[3], color[3]);
+
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_BLEND_COLOR, 1);
+ OUT_RING_CACHE(PACK_COLOR_8888(cf[3], cf[1], cf[2], cf[0]));
+}
+
+static void nv20BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_BLEND_EQUATION, 1);
+ OUT_RING_CACHE((modeA<<16) | modeRGB);
+}
+
+
+static void nv20BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB,
+ GLenum sfactorA, GLenum dfactorA)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2);
+ OUT_RING_CACHE((sfactorA<<16) | sfactorRGB);
+ OUT_RING_CACHE((dfactorA<<16) | dfactorRGB);
+}
+
+static void nv20Clear(GLcontext *ctx, GLbitfield mask)
+{
+ /* TODO */
+}
+
+static void nv20ClearColor(GLcontext *ctx, const GLfloat color[4])
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte c[4];
+ UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,color);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB, 1);
+ OUT_RING_CACHE(PACK_COLOR_8888(c[3],c[0],c[1],c[2]));
+}
+
+static void nv20ClearDepth(GLcontext *ctx, GLclampd d)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nmesa->clear_value=((nmesa->clear_value&0x000000FF)|(((uint32_t)(d*0xFFFFFF))<<8));
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1);
+ OUT_RING_CACHE(nmesa->clear_value);
+}
+
+/* we're don't support indexed buffers
+ void (*ClearIndex)(GLcontext *ctx, GLuint index)
+ */
+
+static void nv20ClearStencil(GLcontext *ctx, GLint s)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nmesa->clear_value=((nmesa->clear_value&0xFFFFFF00)|(s&0x000000FF));
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1);
+ OUT_RING_CACHE(nmesa->clear_value);
+}
+
+static void nv20ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4);
+ OUT_RING_CACHEf(equation[0]);
+ OUT_RING_CACHEf(equation[1]);
+ OUT_RING_CACHEf(equation[2]);
+ OUT_RING_CACHEf(equation[3]);
+}
+
+static void nv20ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask,
+ GLboolean bmask, GLboolean amask )
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_COLOR_MASK, 1);
+ OUT_RING_CACHE(((amask && 0x01) << 24) | ((rmask && 0x01) << 16) | ((gmask && 0x01)<< 8) | ((bmask && 0x01) << 0));
+}
+
+static void nv20ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode)
+{
+ // TODO I need love
+}
+
+static void nv20CullFace(GLcontext *ctx, GLenum mode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CULL_FACE, 1);
+ OUT_RING_CACHE(mode);
+}
+
+static void nv20FrontFace(GLcontext *ctx, GLenum mode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_FRONT_FACE, 1);
+ OUT_RING_CACHE(mode);
+}
+
+static void nv20DepthFunc(GLcontext *ctx, GLenum func)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1);
+ OUT_RING_CACHE(func);
+}
+
+static void nv20DepthMask(GLcontext *ctx, GLboolean flag)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1);
+ OUT_RING_CACHE(flag);
+}
+
+static void nv20DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2);
+ OUT_RING_CACHEf(nearval);
+ OUT_RING_CACHEf(farval);
+}
+
+/** Specify the current buffer for writing */
+//void (*DrawBuffer)( GLcontext *ctx, GLenum buffer );
+/** Specify the buffers for writing for fragment programs*/
+//void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers );
+
+static void nv20Enable(GLcontext *ctx, GLenum cap, GLboolean state)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ switch(cap)
+ {
+ case GL_ALPHA_TEST:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_AUTO_NORMAL:
+ case GL_BLEND:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_CLIP_PLANE0:
+ case GL_CLIP_PLANE1:
+ case GL_CLIP_PLANE2:
+ case GL_CLIP_PLANE3:
+ case GL_CLIP_PLANE4:
+ case GL_CLIP_PLANE5:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_COLOR_LOGIC_OP:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_COLOR_MATERIAL:
+// case GL_COLOR_SUM_EXT:
+// case GL_COLOR_TABLE:
+// case GL_CONVOLUTION_1D:
+// case GL_CONVOLUTION_2D:
+ case GL_CULL_FACE:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_DEPTH_TEST:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_DITHER:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DITHER_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_FOG:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_FOG_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_HISTOGRAM:
+// case GL_INDEX_LOGIC_OP:
+ case GL_LIGHT0:
+ case GL_LIGHT1:
+ case GL_LIGHT2:
+ case GL_LIGHT3:
+ case GL_LIGHT4:
+ case GL_LIGHT5:
+ case GL_LIGHT6:
+ case GL_LIGHT7:
+ {
+ uint32_t mask=0x11<<(2*(cap-GL_LIGHT0));
+ nmesa->enabled_lights=((nmesa->enabled_lights&mask)|(mask*state));
+ if (nmesa->lighting_enabled)
+ {
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1);
+ OUT_RING_CACHE(nmesa->enabled_lights);
+ }
+ break;
+ }
+ case GL_LIGHTING:
+ nmesa->lighting_enabled=state;
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1);
+ if (nmesa->lighting_enabled)
+ OUT_RING_CACHE(nmesa->enabled_lights);
+ else
+ OUT_RING_CACHE(0x0);
+ break;
+ case GL_LINE_SMOOTH:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_LINE_STIPPLE:
+// case GL_MAP1_COLOR_4:
+// case GL_MAP1_INDEX:
+// case GL_MAP1_NORMAL:
+// case GL_MAP1_TEXTURE_COORD_1:
+// case GL_MAP1_TEXTURE_COORD_2:
+// case GL_MAP1_TEXTURE_COORD_3:
+// case GL_MAP1_TEXTURE_COORD_4:
+// case GL_MAP1_VERTEX_3:
+// case GL_MAP1_VERTEX_4:
+// case GL_MAP2_COLOR_4:
+// case GL_MAP2_INDEX:
+// case GL_MAP2_NORMAL:
+// case GL_MAP2_TEXTURE_COORD_1:
+// case GL_MAP2_TEXTURE_COORD_2:
+// case GL_MAP2_TEXTURE_COORD_3:
+// case GL_MAP2_TEXTURE_COORD_4:
+// case GL_MAP2_VERTEX_3:
+// case GL_MAP2_VERTEX_4:
+// case GL_MINMAX:
+ case GL_NORMALIZE:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_POINT_SMOOTH:
+ case GL_POLYGON_OFFSET_POINT:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_POLYGON_OFFSET_LINE:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_POLYGON_OFFSET_FILL:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_POLYGON_SMOOTH:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_POLYGON_STIPPLE:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_POST_COLOR_MATRIX_COLOR_TABLE:
+// case GL_POST_CONVOLUTION_COLOR_TABLE:
+// case GL_RESCALE_NORMAL:
+ case GL_SCISSOR_TEST:
+ /* No enable bit, nv20Scissor will adjust to max range */
+ ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
+ ctx->Scissor.Width, ctx->Scissor.Height);
+ break;
+// case GL_SEPARABLE_2D:
+ case GL_STENCIL_TEST:
+ // TODO BACK and FRONT ?
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_TEXTURE_GEN_Q:
+// case GL_TEXTURE_GEN_R:
+// case GL_TEXTURE_GEN_S:
+// case GL_TEXTURE_GEN_T:
+// case GL_TEXTURE_1D:
+// case GL_TEXTURE_2D:
+// case GL_TEXTURE_3D:
+ }
+}
+
+static void nv20Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ switch(pname)
+ {
+ case GL_FOG_MODE:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_FOG_MODE, 1);
+ //OUT_RING_CACHE (params);
+ break;
+ /* TODO: unsure about the rest.*/
+ default:
+ break;
+ }
+
+}
+
+static void nv20Hint(GLcontext *ctx, GLenum target, GLenum mode)
+{
+ // TODO I need love (fog and line_smooth hints)
+}
+
+// void (*IndexMask)(GLcontext *ctx, GLuint mask);
+
+enum {
+ SPOTLIGHT_NO_UPDATE,
+ SPOTLIGHT_UPDATE_EXPONENT,
+ SPOTLIGHT_UPDATE_DIRECTION,
+ SPOTLIGHT_UPDATE_ALL
+};
+
+static void nv20Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params )
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLint p = light - GL_LIGHT0;
+ struct gl_light *l = &ctx->Light.Light[p];
+ int spotlight_update = SPOTLIGHT_NO_UPDATE;
+
+ /* not sure where the fourth param value goes...*/
+ switch(pname)
+ {
+ case GL_AMBIENT:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(p), 3);
+ OUT_RING_CACHEf(params[0]);
+ OUT_RING_CACHEf(params[1]);
+ OUT_RING_CACHEf(params[2]);
+ break;
+ case GL_DIFFUSE:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(p), 3);
+ OUT_RING_CACHEf(params[0]);
+ OUT_RING_CACHEf(params[1]);
+ OUT_RING_CACHEf(params[2]);
+ break;
+ case GL_SPECULAR:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(p), 3);
+ OUT_RING_CACHEf(params[0]);
+ OUT_RING_CACHEf(params[1]);
+ OUT_RING_CACHEf(params[2]);
+ break;
+ case GL_POSITION:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(p), 3);
+ OUT_RING_CACHEf(params[0]);
+ OUT_RING_CACHEf(params[1]);
+ OUT_RING_CACHEf(params[2]);
+ break;
+ case GL_SPOT_DIRECTION:
+ spotlight_update = SPOTLIGHT_UPDATE_DIRECTION;
+ break;
+ case GL_SPOT_EXPONENT:
+ spotlight_update = SPOTLIGHT_UPDATE_EXPONENT;
+ break;
+ case GL_SPOT_CUTOFF:
+ spotlight_update = SPOTLIGHT_UPDATE_ALL;
+ break;
+ case GL_CONSTANT_ATTENUATION:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(p), 1);
+ OUT_RING_CACHEf(*params);
+ break;
+ case GL_LINEAR_ATTENUATION:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(p), 1);
+ OUT_RING_CACHEf(*params);
+ break;
+ case GL_QUADRATIC_ATTENUATION:
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(p), 1);
+ OUT_RING_CACHEf(*params);
+ break;
+ default:
+ break;
+ }
+
+ switch(spotlight_update) {
+ case SPOTLIGHT_UPDATE_DIRECTION:
+ {
+ GLfloat x,y,z;
+ GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0);
+ x = spot_light_coef_a * l->_NormDirection[0];
+ y = spot_light_coef_a * l->_NormDirection[1];
+ z = spot_light_coef_a * l->_NormDirection[2];
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p), 3);
+ OUT_RING_CACHEf(x);
+ OUT_RING_CACHEf(y);
+ OUT_RING_CACHEf(z);
+ }
+ break;
+ case SPOTLIGHT_UPDATE_EXPONENT:
+ {
+ GLfloat cc,lc,qc;
+ cc = 1.0; /* FIXME: These need to be correctly computed */
+ lc = 0.0;
+ qc = 2.0;
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 3);
+ OUT_RING_CACHEf(cc);
+ OUT_RING_CACHEf(lc);
+ OUT_RING_CACHEf(qc);
+ }
+ break;
+ case SPOTLIGHT_UPDATE_ALL:
+ {
+ GLfloat cc,lc,qc, x,y,z, c;
+ GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0);
+ cc = 1.0; /* FIXME: These need to be correctly computed */
+ lc = 0.0;
+ qc = 2.0;
+ x = spot_light_coef_a * l->_NormDirection[0];
+ y = spot_light_coef_a * l->_NormDirection[1];
+ z = spot_light_coef_a * l->_NormDirection[2];
+ c = spot_light_coef_a + 1.0;
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 7);
+ OUT_RING_CACHEf(cc);
+ OUT_RING_CACHEf(lc);
+ OUT_RING_CACHEf(qc);
+ OUT_RING_CACHEf(x);
+ OUT_RING_CACHEf(y);
+ OUT_RING_CACHEf(z);
+ OUT_RING_CACHEf(c);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/** Set the lighting model parameters */
+static void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params);
+
+
+static void nv20LineStipple(GLcontext *ctx, GLint factor, GLushort pattern )
+{
+/* nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN, 1);
+ OUT_RING_CACHE((pattern << 16) | factor);*/
+}
+
+static void nv20LineWidth(GLcontext *ctx, GLfloat width)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LINE_WIDTH, 1);
+ OUT_RING_CACHEf(width);
+}
+
+static void nv20LogicOpcode(GLcontext *ctx, GLenum opcode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP, 1);
+ OUT_RING_CACHE(opcode);
+}
+
+static void nv20PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
+{
+ /*TODO: not sure what goes here. */
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+}
+
+/** Specify the diameter of rasterized points */
+static void nv20PointSize(GLcontext *ctx, GLfloat size)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POINT_SIZE, 1);
+ OUT_RING_CACHEf(size);
+}
+
+/** Select a polygon rasterization mode */
+static void nv20PolygonMode(GLcontext *ctx, GLenum face, GLenum mode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 1);
+ OUT_RING_CACHE(mode);
+ }
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK, 1);
+ OUT_RING_CACHE(mode);
+ }
+}
+
+/** Set the scale and units used to calculate depth values */
+static void nv20PolygonOffset(GLcontext *ctx, GLfloat factor, GLfloat units)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR, 2);
+ OUT_RING_CACHEf(factor);
+ OUT_RING_CACHEf(units);
+}
+
+/** Set the polygon stippling pattern */
+static void nv20PolygonStipple(GLcontext *ctx, const GLubyte *mask )
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(0), 32);
+ OUT_RING_CACHEp(mask, 32);
+}
+
+/* Specifies the current buffer for reading */
+void (*ReadBuffer)( GLcontext *ctx, GLenum buffer );
+/** Set rasterization mode */
+void (*RenderMode)(GLcontext *ctx, GLenum mode );
+
+/** Define the scissor box */
+static void nv20Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ /* There's no scissor enable bit, so adjust the scissor to cover the
+ * maximum draw buffer bounds
+ */
+ if (!ctx->Scissor.Enabled) {
+ x = y = 0;
+ w = h = 4095;
+ } else {
+ x += nmesa->drawX;
+ y += nmesa->drawY;
+ }
+
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SCISSOR_X2_X1, 2);
+ OUT_RING_CACHE(((x+w-1) << 16) | x);
+ OUT_RING_CACHE(((y+h-1) << 16) | y);
+}
+
+/** Select flat or smooth shading */
+static void nv20ShadeModel(GLcontext *ctx, GLenum mode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SHADE_MODEL, 1);
+ OUT_RING_CACHE(mode);
+}
+
+/** OpenGL 2.0 two-sided StencilFunc */
+static void nv20StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func,
+ GLint ref, GLuint mask)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC, 3);
+ OUT_RING_CACHE(func);
+ OUT_RING_CACHE(ref);
+ OUT_RING_CACHE(mask);
+}
+
+/** OpenGL 2.0 two-sided StencilMask */
+static void nv20StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_MASK, 1);
+ OUT_RING_CACHE(mask);
+}
+
+/** OpenGL 2.0 two-sided StencilOp */
+static void nv20StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail,
+ GLenum zfail, GLenum zpass)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_OP_FAIL, 1);
+ OUT_RING_CACHE(fail);
+ OUT_RING_CACHE(zfail);
+ OUT_RING_CACHE(zpass);
+}
+
+/** Control the generation of texture coordinates */
+void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname,
+ const GLfloat *params);
+/** Set texture environment parameters */
+void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname,
+ const GLfloat *param);
+/** Set texture parameters */
+void (*TexParameter)(GLcontext *ctx, GLenum target,
+ struct gl_texture_object *texObj,
+ GLenum pname, const GLfloat *params);
+
+static void nv20TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16);
+ /*XXX: This SHOULD work.*/
+ OUT_RING_CACHEp(mat->m, 16);
+}
+
+/* Update anything that depends on the window position/size */
+static void nv20WindowMoved(nouveauContextPtr nmesa)
+{
+ GLcontext *ctx = nmesa->glCtx;
+ GLfloat *v = nmesa->viewport.m;
+ GLuint w = ctx->Viewport.Width;
+ GLuint h = ctx->Viewport.Height;
+ GLuint x = ctx->Viewport.X + nmesa->drawX;
+ GLuint y = ctx->Viewport.Y + nmesa->drawY;
+ int i;
+
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2);
+ OUT_RING_CACHE((w << 16) | x);
+ OUT_RING_CACHE((h << 16) | y);
+
+ BEGIN_RING_SIZE(NvSub3D, 0x02b4, 1);
+ OUT_RING(0);
+
+ BEGIN_RING_CACHE(NvSub3D,
+ NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 1);
+ OUT_RING_CACHE((4095 << 16) | 0);
+ BEGIN_RING_CACHE(NvSub3D,
+ NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(0), 1);
+ OUT_RING_CACHE((4095 << 16) | 0);
+ for (i=1; i<8; i++) {
+ BEGIN_RING_CACHE(NvSub3D,
+ NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 1);
+ OUT_RING_CACHE(0);
+ BEGIN_RING_CACHE(NvSub3D,
+ NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(i), 1);
+ OUT_RING_CACHE(0);
+ }
+
+ ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
+ ctx->Scissor.Width, ctx->Scissor.Height);
+
+ /* TODO: recalc viewport scale coefs */
+}
+
+/* Initialise any card-specific non-GL related state */
+static GLboolean nv20InitCard(nouveauContextPtr nmesa)
+{
+ nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D);
+
+ BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SET_OBJECT1, 2);
+ OUT_RING(NvDmaFB); /* 184 dma_object1 */
+ OUT_RING(NvDmaFB); /* 188 dma_object2 */
+ BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SET_OBJECT3, 2);
+ OUT_RING(NvDmaFB); /* 194 dma_object3 */
+ OUT_RING(NvDmaFB); /* 198 dma_object4 */
+ BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SET_OBJECT8, 1);
+ OUT_RING(NvDmaFB); /* 1a8 dma_object8 */
+
+ BEGIN_RING_SIZE(NvSub3D, 0x17e0, 3);
+ OUT_RINGf(0.0);
+ OUT_RINGf(0.0);
+ OUT_RINGf(1.0);
+
+ BEGIN_RING_SIZE(NvSub3D, 0x1e6c, 1);
+ OUT_RING(0x0db6);
+ BEGIN_RING_SIZE(NvSub3D, 0x0290, 1);
+ OUT_RING(0x00100001);
+ BEGIN_RING_SIZE(NvSub3D, 0x09fc, 1);
+ OUT_RING(0);
+ BEGIN_RING_SIZE(NvSub3D, 0x1d80, 1);
+ OUT_RING(1);
+ BEGIN_RING_SIZE(NvSub3D, 0x09f8, 1);
+ OUT_RING(4);
+
+ BEGIN_RING_SIZE(NvSub3D, 0x17ec, 3);
+ OUT_RINGf(0.0);
+ OUT_RINGf(1.0);
+ OUT_RINGf(0.0);
+
+ BEGIN_RING_SIZE(NvSub3D, 0x1d88, 1);
+ OUT_RING(3);
+
+ /* FIXME: More dma objects to setup ? */
+
+ BEGIN_RING_SIZE(NvSub3D, 0x1e98, 1);
+ OUT_RING(0);
+
+ BEGIN_RING_SIZE(NvSub3D, 0x120, 3);
+ OUT_RING(0);
+ OUT_RING(1);
+ OUT_RING(2);
+
+ return GL_TRUE;
+}
+
+/* Update buffer offset/pitch/format */
+static GLboolean nv20BindBuffers(nouveauContextPtr nmesa, int num_color,
+ nouveau_renderbuffer **color,
+ nouveau_renderbuffer *depth)
+{
+ GLuint x, y, w, h;
+ GLuint pitch, format, depth_pitch;
+
+ w = color[0]->mesa.Width;
+ h = color[0]->mesa.Height;
+ x = nmesa->drawX;
+ y = nmesa->drawY;
+
+ if (num_color != 1)
+ return GL_FALSE;
+
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 6);
+ OUT_RING_CACHE((w << 16) | x);
+ OUT_RING_CACHE((h << 16) | y);
+ depth_pitch = (depth ? depth->pitch : color[0]->pitch);
+ pitch = (depth_pitch<<16) | color[0]->pitch;
+ format = 0x128;
+ if (color[0]->mesa._ActualFormat != GL_RGBA8) {
+ format = 0x123; /* R5G6B5 color buffer */
+ }
+ OUT_RING_CACHE(format);
+ OUT_RING_CACHE(pitch);
+ OUT_RING_CACHE(color[0]->offset);
+ OUT_RING_CACHE(depth ? depth->offset : color[0]->offset);
+
+ if (depth) {
+ BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH, 2);
+ /* TODO: use a different buffer */
+ OUT_RING(depth->pitch);
+ OUT_RING(depth->offset);
+ }
+
+ /* Always set to bottom left of buffer */
+ BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X, 4);
+ OUT_RING_CACHEf (0.0);
+ OUT_RING_CACHEf ((GLfloat) h);
+ OUT_RING_CACHEf (0.0);
+ OUT_RING_CACHEf (0.0);
+
+ return GL_TRUE;
+}
+
+void nv20InitStateFuncs(GLcontext *ctx, struct dd_function_table *func)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ func->AlphaFunc = nv20AlphaFunc;
+ func->BlendColor = nv20BlendColor;
+ func->BlendEquationSeparate = nv20BlendEquationSeparate;
+ func->BlendFuncSeparate = nv20BlendFuncSeparate;
+ func->Clear = nv20Clear;
+ func->ClearColor = nv20ClearColor;
+ func->ClearDepth = nv20ClearDepth;
+ func->ClearStencil = nv20ClearStencil;
+ func->ClipPlane = nv20ClipPlane;
+ func->ColorMask = nv20ColorMask;
+ func->ColorMaterial = nv20ColorMaterial;
+ func->CullFace = nv20CullFace;
+ func->FrontFace = nv20FrontFace;
+ func->DepthFunc = nv20DepthFunc;
+ func->DepthMask = nv20DepthMask;
+ func->DepthRange = nv20DepthRange;
+ func->Enable = nv20Enable;
+ func->Fogfv = nv20Fogfv;
+ func->Hint = nv20Hint;
+ func->Lightfv = nv20Lightfv;
+/* func->LightModelfv = nv20LightModelfv; */
+ func->LineStipple = nv20LineStipple;
+ func->LineWidth = nv20LineWidth;
+ func->LogicOpcode = nv20LogicOpcode;
+ func->PointParameterfv = nv20PointParameterfv;
+ func->PointSize = nv20PointSize;
+ func->PolygonMode = nv20PolygonMode;
+ func->PolygonOffset = nv20PolygonOffset;
+ func->PolygonStipple = nv20PolygonStipple;
+/* func->ReadBuffer = nv20ReadBuffer;*/
+/* func->RenderMode = nv20RenderMode;*/
+ func->Scissor = nv20Scissor;
+ func->ShadeModel = nv20ShadeModel;
+ func->StencilFuncSeparate = nv20StencilFuncSeparate;
+ func->StencilMaskSeparate = nv20StencilMaskSeparate;
+ func->StencilOpSeparate = nv20StencilOpSeparate;
+/* func->TexGen = nv20TexGen;*/
+/* func->TexParameter = nv20TexParameter;*/
+ func->TextureMatrix = nv20TextureMatrix;
+
+ nmesa->hw_func.InitCard = nv20InitCard;
+ nmesa->hw_func.BindBuffers = nv20BindBuffers;
+ nmesa->hw_func.WindowMoved = nv20WindowMoved;
+}
+
diff --git a/src/mesa/drivers/dri/nouveau/nv20_vertprog.c b/src/mesa/drivers/dri/nouveau/nv20_vertprog.c
new file mode 100644
index 00000000000..60cfcd70561
--- /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 00000000000..e32452361e8
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c
@@ -0,0 +1,742 @@
+#include <stdint.h>
+
+#include "glheader.h"
+#include "macros.h"
+
+#include "nouveau_context.h"
+#include "nouveau_fifo.h"
+#include "nouveau_reg.h"
+#include "nouveau_drm.h"
+#include "nouveau_shader.h"
+#include "nouveau_object.h"
+#include "nouveau_msg.h"
+#include "nouveau_bufferobj.h"
+#include "nv30_shader.h"
+
+unsigned int NVFP_TX_AOP_COUNT = 64;
+struct _op_xlat NVFP_TX_AOP[64];
+
+/*******************************************************************************
+ * Support routines
+ */
+
+static void
+NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nvsCardPriv *priv = &nvs->card_priv;
+ uint32_t offset;
+
+ if (!nvs->program_buffer)
+ nvs->program_buffer = ctx->Driver.NewBufferObject(ctx, 0,
+ GL_ARRAY_BUFFER_ARB);
+
+ /* Should use STATIC_DRAW_ARB if shader doesn't use changable params */
+ nouveau_bo_init_storage(ctx, NOUVEAU_BO_VRAM_OK,
+ nvs->program_size * sizeof(uint32_t),
+ (const GLvoid *)nvs->program,
+ GL_DYNAMIC_DRAW_ARB,
+ nvs->program_buffer);
+
+ offset = nouveau_bo_gpu_ref(ctx, nvs->program_buffer);
+
+ /* Not using state cache here, updated programs at the same address don't
+ * seem to take effect unless the ACTIVE_PROGRAM method is called again.
+ * HW caches the program somewhere?
+ */
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM, 1);
+ OUT_RING (offset | 1);
+ if (nmesa->screen->card->type == NV_30) {
+ BEGIN_RING_SIZE(NvSub3D,
+ 0x1d60 /*NV30_TCL_PRIMITIVE_3D_FP_CONTROL*/, 1);
+ OUT_RING ((priv->NV30FP.uses_kil << 7));
+ BEGIN_RING_SIZE(NvSub3D, 0x1450, 1);
+ OUT_RING (priv->NV30FP.num_regs << 16);
+ } else {
+ BEGIN_RING_SIZE(NvSub3D,
+ 0x1d60 /*NV30_TCL_PRIMITIVE_3D_FP_CONTROL*/, 1);
+ OUT_RING ((priv->NV30FP.uses_kil << 7) |
+ (priv->NV30FP.num_regs << 24));
+ }
+}
+
+static void
+NV30FPUpdateConst(GLcontext *ctx, nouveauShader *nvs, int id)
+{
+ uint32_t *new = nvs->params[id].source_val ?
+ (uint32_t*)nvs->params[id].source_val : (uint32_t*)nvs->params[id].val;
+ uint32_t *current;
+ int i;
+
+ for (i=0; i<nvs->params[id].hw_index_cnt; i++) {
+ current = nvs->program + nvs->params[id].hw_index[i];
+ COPY_4V(current, new);
+ }
+ nvs->on_hardware = 0;
+}
+
+/*******************************************************************************
+ * Assembly helpers
+ */
+static struct _op_xlat *
+NV30FPGetOPTXFromSOP(nvsOpcode op, int *id)
+{
+ int i;
+
+ for (i=0; i<NVFP_TX_AOP_COUNT; i++) {
+ if (NVFP_TX_AOP[i].SOP == op) {
+ if (id) *id = 0;
+ return &NVFP_TX_AOP[i];
+ }
+ }
+
+ return NULL;
+}
+
+static int
+NV30FPSupportsOpcode(nvsFunc *shader, nvsOpcode op)
+{
+ if (shader->GetOPTXFromSOP(op, NULL))
+ return 1;
+ return 0;
+}
+
+static void
+NV30FPSetOpcode(nvsFunc *shader, unsigned int opcode, int slot)
+{
+ if (opcode == NV30_FP_OP_OPCODE_KIL)
+ shader->card_priv->NV30FP.uses_kil = GL_TRUE;
+ shader->inst[0] &= ~NV30_FP_OP_OPCODE_MASK;
+ shader->inst[0] |= (opcode << NV30_FP_OP_OPCODE_SHIFT);
+}
+
+static void
+NV30FPSetCCUpdate(nvsFunc *shader)
+{
+ shader->inst[0] |= NV30_FP_OP_COND_WRITE_ENABLE;
+}
+
+static void
+NV30FPSetCondition(nvsFunc *shader, int on, nvsCond cond, int reg,
+ nvsSwzComp *swz)
+{
+ nvsSwzComp default_swz[4] = { NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W };
+ unsigned int hwcond;
+
+ /* cond masking is always enabled */
+ if (!on) {
+ cond = NVS_COND_TR;
+ reg = 0;
+ swz = default_swz;
+ }
+
+ switch (cond) {
+ case NVS_COND_TR: hwcond = NV30_FP_OP_COND_TR; break;
+ case NVS_COND_FL: hwcond = NV30_FP_OP_COND_FL; break;
+ case NVS_COND_LT: hwcond = NV30_FP_OP_COND_LT; break;
+ case NVS_COND_GT: hwcond = NV30_FP_OP_COND_GT; break;
+ case NVS_COND_LE: hwcond = NV30_FP_OP_COND_LE; break;
+ case NVS_COND_GE: hwcond = NV30_FP_OP_COND_GE; break;
+ case NVS_COND_EQ: hwcond = NV30_FP_OP_COND_EQ; break;
+ case NVS_COND_NE: hwcond = NV30_FP_OP_COND_NE; break;
+ default:
+ WARN_ONCE("unknown fp condmask=%d\n", cond);
+ hwcond = NV30_FP_OP_COND_TR;
+ break;
+ }
+
+ shader->inst[1] &= ~NV30_FP_OP_COND_MASK;
+ shader->inst[1] |= (hwcond << NV30_FP_OP_COND_SHIFT);
+
+ shader->inst[1] &= ~NV30_FP_OP_COND_SWZ_ALL_MASK;
+ shader->inst[1] |= (swz[NVS_SWZ_X] << NV30_FP_OP_COND_SWZ_X_SHIFT);
+ shader->inst[1] |= (swz[NVS_SWZ_Y] << NV30_FP_OP_COND_SWZ_Y_SHIFT);
+ shader->inst[1] |= (swz[NVS_SWZ_Z] << NV30_FP_OP_COND_SWZ_Z_SHIFT);
+ shader->inst[1] |= (swz[NVS_SWZ_W] << NV30_FP_OP_COND_SWZ_W_SHIFT);
+}
+
+static void
+NV30FPSetHighReg(nvsFunc *shader, int id)
+{
+ if (shader->card_priv->NV30FP.num_regs < (id+1)) {
+ if (id == 0)
+ id = 1; /* necessary? */
+ shader->card_priv->NV30FP.num_regs = (id+1);
+ }
+}
+
+static void
+NV30FPSetResult(nvsFunc *shader, nvsRegister *reg, unsigned int mask, int slot)
+{
+ unsigned int hwreg;
+
+ if (mask & SMASK_X) shader->inst[0] |= NV30_FP_OP_OUT_X;
+ if (mask & SMASK_Y) shader->inst[0] |= NV30_FP_OP_OUT_Y;
+ if (mask & SMASK_Z) shader->inst[0] |= NV30_FP_OP_OUT_Z;
+ if (mask & SMASK_W) shader->inst[0] |= NV30_FP_OP_OUT_W;
+
+ if (reg->file == NVS_FILE_RESULT) {
+ hwreg = 0; /* FIXME: this is only fragment.color */
+ /* This is *not* correct, I have no idea what it is either */
+ shader->inst[0] |= NV30_FP_OP_UNK0_7;
+ } else {
+ shader->inst[0] &= ~NV30_FP_OP_UNK0_7;
+ hwreg = reg->index;
+ }
+ NV30FPSetHighReg(shader, hwreg);
+ shader->inst[0] &= ~NV30_FP_OP_OUT_REG_SHIFT;
+ shader->inst[0] |= (hwreg << NV30_FP_OP_OUT_REG_SHIFT);
+}
+
+static void
+NV30FPSetSource(nvsFunc *shader, nvsRegister *reg, int pos)
+{
+ unsigned int hwsrc = 0;
+
+ switch (reg->file) {
+ case NVS_FILE_TEMP:
+ hwsrc |= (NV30_FP_REG_TYPE_TEMP << NV30_FP_REG_TYPE_SHIFT);
+ hwsrc |= (reg->index << NV30_FP_REG_SRC_SHIFT);
+ NV30FPSetHighReg(shader, reg->index);
+ break;
+ case NVS_FILE_ATTRIB:
+ {
+ unsigned int hwin;
+
+ switch (reg->index) {
+ case NVS_FR_POSITION : hwin = NV30_FP_OP_INPUT_SRC_POSITION; break;
+ case NVS_FR_COL0 : hwin = NV30_FP_OP_INPUT_SRC_COL0; break;
+ case NVS_FR_COL1 : hwin = NV30_FP_OP_INPUT_SRC_COL1; break;
+ case NVS_FR_FOGCOORD : hwin = NV30_FP_OP_INPUT_SRC_FOGC; break;
+ case NVS_FR_TEXCOORD0: hwin = NV30_FP_OP_INPUT_SRC_TC(0); break;
+ case NVS_FR_TEXCOORD1: hwin = NV30_FP_OP_INPUT_SRC_TC(1); break;
+ case NVS_FR_TEXCOORD2: hwin = NV30_FP_OP_INPUT_SRC_TC(2); break;
+ case NVS_FR_TEXCOORD3: hwin = NV30_FP_OP_INPUT_SRC_TC(3); break;
+ case NVS_FR_TEXCOORD4: hwin = NV30_FP_OP_INPUT_SRC_TC(4); break;
+ case NVS_FR_TEXCOORD5: hwin = NV30_FP_OP_INPUT_SRC_TC(5); break;
+ case NVS_FR_TEXCOORD6: hwin = NV30_FP_OP_INPUT_SRC_TC(6); break;
+ case NVS_FR_TEXCOORD7: hwin = NV30_FP_OP_INPUT_SRC_TC(7); break;
+ default:
+ WARN_ONCE("unknown fp input %d\n", reg->index);
+ hwin = NV30_FP_OP_INPUT_SRC_COL0;
+ break;
+ }
+ shader->inst[0] &= ~NV30_FP_OP_INPUT_SRC_MASK;
+ shader->inst[0] |= (hwin << NV30_FP_OP_INPUT_SRC_SHIFT);
+ hwsrc |= (hwin << NV30_FP_REG_SRC_SHIFT);
+ }
+ hwsrc |= (NV30_FP_REG_TYPE_INPUT << NV30_FP_REG_TYPE_SHIFT);
+ break;
+ case NVS_FILE_CONST:
+ /* consts are inlined after the inst */
+ hwsrc |= (NV30_FP_REG_TYPE_CONST << NV30_FP_REG_TYPE_SHIFT);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ if (reg->negate)
+ hwsrc |= NV30_FP_REG_NEGATE;
+ if (reg->abs)
+ shader->inst[1] |= (1 << (29+pos));
+ hwsrc |= (reg->swizzle[NVS_SWZ_X] << NV30_FP_REG_SWZ_X_SHIFT);
+ hwsrc |= (reg->swizzle[NVS_SWZ_Y] << NV30_FP_REG_SWZ_Y_SHIFT);
+ hwsrc |= (reg->swizzle[NVS_SWZ_Z] << NV30_FP_REG_SWZ_Z_SHIFT);
+ hwsrc |= (reg->swizzle[NVS_SWZ_W] << NV30_FP_REG_SWZ_W_SHIFT);
+
+ shader->inst[pos+1] &= ~NV30_FP_REG_ALL_MASK;
+ shader->inst[pos+1] |= hwsrc;
+}
+
+static void
+NV30FPSetTexImageUnit(nvsFunc *shader, int unit)
+{
+ shader->inst[0] &= ~NV30_FP_OP_TEX_UNIT_SHIFT;
+ shader->inst[0] |= (unit << NV30_FP_OP_TEX_UNIT_SHIFT);
+}
+
+static void
+NV30FPSetSaturate(nvsFunc *shader)
+{
+ shader->inst[0] |= NV30_FP_OP_OUT_SAT;
+}
+
+static void
+NV30FPInitInstruction(nvsFunc *shader)
+{
+ unsigned int hwsrc;
+
+ shader->inst[0] = 0;
+
+ hwsrc = (NV30_FP_REG_TYPE_INPUT << NV30_FP_REG_TYPE_SHIFT) |
+ (NVS_SWZ_X << NV30_FP_REG_SWZ_X_SHIFT) |
+ (NVS_SWZ_Y << NV30_FP_REG_SWZ_Y_SHIFT) |
+ (NVS_SWZ_Z << NV30_FP_REG_SWZ_Z_SHIFT) |
+ (NVS_SWZ_W << NV30_FP_REG_SWZ_W_SHIFT);
+ shader->inst[1] = hwsrc;
+ shader->inst[2] = hwsrc;
+ shader->inst[3] = hwsrc;
+}
+
+static void
+NV30FPSetLastInst(nvsFunc *shader)
+{
+ shader->inst[0] |= 1;
+}
+
+/*******************************************************************************
+ * Disassembly helpers
+ */
+static struct _op_xlat *
+NV30FPGetOPTXRec(nvsFunc * shader, int merged)
+{
+ int op;
+
+ op = shader->GetOpcodeHW(shader, 0);
+ if (op > NVFP_TX_AOP_COUNT)
+ return NULL;
+ if (NVFP_TX_AOP[op].SOP == NVS_OP_UNKNOWN)
+ return NULL;
+ return &NVFP_TX_AOP[op];
+}
+
+static int
+NV30FPHasMergedInst(nvsFunc * shader)
+{
+ return 0;
+}
+
+static int
+NV30FPIsLastInst(nvsFunc * shader)
+{
+ return ((shader->inst[0] & NV30_FP_OP_PROGRAM_END) ? 1 : 0);
+}
+
+static int
+NV30FPGetOffsetNext(nvsFunc * shader)
+{
+ int i;
+
+ for (i = 0; i < 3; i++)
+ if (shader->GetSourceFile(shader, 0, i) == NVS_FILE_CONST)
+ return 8;
+ return 4;
+}
+
+static nvsOpcode
+NV30FPGetOpcode(nvsFunc * shader, int merged)
+{
+ struct _op_xlat *opr;
+
+ opr = shader->GetOPTXRec(shader, merged);
+ if (!opr)
+ return NVS_OP_UNKNOWN;
+
+ return opr->SOP;
+}
+
+static unsigned int
+NV30FPGetOpcodeHW(nvsFunc * shader, int slot)
+{
+ int op;
+
+ op = (shader->inst[0] & NV30_FP_OP_OPCODE_MASK) >> NV30_FP_OP_OPCODE_SHIFT;
+
+ return op;
+}
+
+static nvsRegFile
+NV30FPGetDestFile(nvsFunc * shader, int merged)
+{
+ /* Result regs overlap temporary regs */
+ return NVS_FILE_TEMP;
+}
+
+static unsigned int
+NV30FPGetDestID(nvsFunc * shader, int merged)
+{
+ int id;
+
+ switch (shader->GetDestFile(shader, merged)) {
+ case NVS_FILE_TEMP:
+ id = ((shader->inst[0] & NV30_FP_OP_OUT_REG_MASK)
+ >> NV30_FP_OP_OUT_REG_SHIFT);
+ return id;
+ default:
+ return -1;
+ }
+}
+
+static unsigned int
+NV30FPGetDestMask(nvsFunc * shader, int merged)
+{
+ unsigned int mask = 0;
+
+ if (shader->inst[0] & NV30_FP_OP_OUT_X) mask |= SMASK_X;
+ if (shader->inst[0] & NV30_FP_OP_OUT_Y) mask |= SMASK_Y;
+ if (shader->inst[0] & NV30_FP_OP_OUT_Z) mask |= SMASK_Z;
+ if (shader->inst[0] & NV30_FP_OP_OUT_W) mask |= SMASK_W;
+
+ return mask;
+}
+
+static unsigned int
+NV30FPGetSourceHW(nvsFunc * shader, int merged, int pos)
+{
+ struct _op_xlat *opr;
+
+ opr = shader->GetOPTXRec(shader, merged);
+ if (!opr || opr->srcpos[pos] == -1)
+ return -1;
+
+ return shader->inst[opr->srcpos[pos] + 1];
+}
+
+static nvsRegFile
+NV30FPGetSourceFile(nvsFunc * shader, int merged, int pos)
+{
+ unsigned int src;
+ struct _op_xlat *opr;
+ int file;
+
+ opr = shader->GetOPTXRec(shader, merged);
+ if (!opr || opr->srcpos[pos] == -1)
+ return NVS_FILE_UNKNOWN;
+
+ switch (opr->srcpos[pos]) {
+ case SPOS_ADDRESS: return NVS_FILE_ADDRESS;
+ default:
+ src = shader->GetSourceHW(shader, merged, pos);
+ file = (src & NV30_FP_REG_TYPE_MASK) >> NV30_FP_REG_TYPE_SHIFT;
+
+ switch (file) {
+ case NV30_FP_REG_TYPE_TEMP : return NVS_FILE_TEMP;
+ case NV30_FP_REG_TYPE_INPUT: return NVS_FILE_ATTRIB;
+ case NV30_FP_REG_TYPE_CONST: return NVS_FILE_CONST;
+ default:
+ return NVS_FILE_UNKNOWN;
+ }
+ }
+}
+
+static int
+NV30FPGetSourceID(nvsFunc * shader, int merged, int pos)
+{
+ switch (shader->GetSourceFile(shader, merged, pos)) {
+ case NVS_FILE_ATTRIB:
+ switch ((shader->inst[0] & NV30_FP_OP_INPUT_SRC_MASK)
+ >> NV30_FP_OP_INPUT_SRC_SHIFT) {
+ case NV30_FP_OP_INPUT_SRC_POSITION: return NVS_FR_POSITION;
+ case NV30_FP_OP_INPUT_SRC_COL0 : return NVS_FR_COL0;
+ case NV30_FP_OP_INPUT_SRC_COL1 : return NVS_FR_COL1;
+ case NV30_FP_OP_INPUT_SRC_FOGC : return NVS_FR_FOGCOORD;
+ case NV30_FP_OP_INPUT_SRC_TC(0) : return NVS_FR_TEXCOORD0;
+ case NV30_FP_OP_INPUT_SRC_TC(1) : return NVS_FR_TEXCOORD1;
+ case NV30_FP_OP_INPUT_SRC_TC(2) : return NVS_FR_TEXCOORD2;
+ case NV30_FP_OP_INPUT_SRC_TC(3) : return NVS_FR_TEXCOORD3;
+ case NV30_FP_OP_INPUT_SRC_TC(4) : return NVS_FR_TEXCOORD4;
+ case NV30_FP_OP_INPUT_SRC_TC(5) : return NVS_FR_TEXCOORD5;
+ case NV30_FP_OP_INPUT_SRC_TC(6) : return NVS_FR_TEXCOORD6;
+ case NV30_FP_OP_INPUT_SRC_TC(7) : return NVS_FR_TEXCOORD7;
+ default:
+ return -1;
+ }
+ break;
+ case NVS_FILE_TEMP:
+ {
+ unsigned int src;
+
+ src = shader->GetSourceHW(shader, merged, pos);
+ return ((src & NV30_FP_REG_SRC_MASK) >> NV30_FP_REG_SRC_SHIFT);
+ }
+ case NVS_FILE_CONST: /* inlined into fragprog */
+ default:
+ return -1;
+ }
+}
+
+static int
+NV30FPGetTexImageUnit(nvsFunc *shader)
+{
+ return ((shader->inst[0] & NV30_FP_OP_TEX_UNIT_MASK)
+ >> NV30_FP_OP_TEX_UNIT_SHIFT);
+}
+
+static int
+NV30FPGetSourceNegate(nvsFunc * shader, int merged, int pos)
+{
+ unsigned int src;
+
+ src = shader->GetSourceHW(shader, merged, pos);
+
+ if (src == -1)
+ return -1;
+ return ((src & NV30_FP_REG_NEGATE) ? 1 : 0);
+}
+
+static int
+NV30FPGetSourceAbs(nvsFunc * shader, int merged, int pos)
+{
+ struct _op_xlat *opr;
+ static unsigned int abspos[3] = {
+ NV30_FP_OP_OUT_ABS,
+ (1 << 30), /* guess */
+ (1 << 31) /* guess */
+ };
+
+ opr = shader->GetOPTXRec(shader, merged);
+ if (!opr || opr->srcpos[pos] == -1)
+ return -1;
+
+ return ((shader->inst[1] & abspos[opr->srcpos[pos]]) ? 1 : 0);
+}
+
+nvsSwzComp NV30FP_TX_SWIZZLE[4] = {NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W };
+
+static void
+NV30FPTXSwizzle(int hwswz, nvsSwzComp *swz)
+{
+ swz[NVS_SWZ_W] = NV30FP_TX_SWIZZLE[(hwswz & 0xC0) >> 6];
+ swz[NVS_SWZ_Z] = NV30FP_TX_SWIZZLE[(hwswz & 0x30) >> 4];
+ swz[NVS_SWZ_Y] = NV30FP_TX_SWIZZLE[(hwswz & 0x0C) >> 2];
+ swz[NVS_SWZ_X] = NV30FP_TX_SWIZZLE[(hwswz & 0x03) >> 0];
+}
+
+static void
+NV30FPGetSourceSwizzle(nvsFunc * shader, int merged, int pos, nvsSwzComp *swz)
+{
+ unsigned int src;
+ int swzbits;
+
+ src = shader->GetSourceHW(shader, merged, pos);
+ swzbits = (src & NV30_FP_REG_SWZ_ALL_MASK) >> NV30_FP_REG_SWZ_ALL_SHIFT;
+ NV30FPTXSwizzle(swzbits, swz);
+}
+
+static int
+NV30FPGetSourceIndexed(nvsFunc * shader, int merged, int pos)
+{
+ switch (shader->GetSourceFile(shader, merged, pos)) {
+ case NVS_FILE_ATTRIB:
+ return ((shader->inst[3] & NV30_FP_OP_INDEX_INPUT) ? 1 : 0);
+ default:
+ return 0;
+ }
+}
+
+static void
+NV30FPGetSourceConstVal(nvsFunc * shader, int merged, int pos, float *val)
+{
+ val[0] = *(float *) &(shader->inst[4]);
+ val[1] = *(float *) &(shader->inst[5]);
+ val[2] = *(float *) &(shader->inst[6]);
+ val[3] = *(float *) &(shader->inst[7]);
+}
+
+static int
+NV30FPGetSourceScale(nvsFunc * shader, int merged, int pos)
+{
+/*FIXME: is this per-source, only for a specific source, or all sources??*/
+ return (1 << ((shader->inst[2] & NV30_FP_OP_SRC_SCALE_MASK)
+ >> NV30_FP_OP_SRC_SCALE_SHIFT));
+}
+
+static int
+NV30FPGetAddressRegID(nvsFunc * shader)
+{
+ return 0;
+}
+
+static nvsSwzComp
+NV30FPGetAddressRegSwizzle(nvsFunc * shader)
+{
+ return NVS_SWZ_X;
+}
+
+static int
+NV30FPSupportsConditional(nvsFunc * shader)
+{
+ /*FIXME: Is this true of all ops? */
+ return 1;
+}
+
+static int
+NV30FPGetConditionUpdate(nvsFunc * shader)
+{
+ return ((shader->inst[0] & NV30_FP_OP_COND_WRITE_ENABLE) ? 1 : 0);
+}
+
+static int
+NV30FPGetConditionTest(nvsFunc * shader)
+{
+ /*FIXME: always? */
+ return 1;
+}
+
+static nvsCond
+NV30FPGetCondition(nvsFunc * shader)
+{
+ int cond;
+
+ cond = ((shader->inst[1] & NV30_FP_OP_COND_MASK)
+ >> NV30_FP_OP_COND_SHIFT);
+
+ switch (cond) {
+ case NV30_FP_OP_COND_FL: return NVS_COND_FL;
+ case NV30_FP_OP_COND_LT: return NVS_COND_LT;
+ case NV30_FP_OP_COND_EQ: return NVS_COND_EQ;
+ case NV30_FP_OP_COND_LE: return NVS_COND_LE;
+ case NV30_FP_OP_COND_GT: return NVS_COND_GT;
+ case NV30_FP_OP_COND_NE: return NVS_COND_NE;
+ case NV30_FP_OP_COND_GE: return NVS_COND_GE;
+ case NV30_FP_OP_COND_TR: return NVS_COND_TR;
+ default:
+ return NVS_COND_UNKNOWN;
+ }
+}
+
+static void
+NV30FPGetCondRegSwizzle(nvsFunc * shader, nvsSwzComp *swz)
+{
+ int swzbits;
+
+ swzbits = (shader->inst[1] & NV30_FP_OP_COND_SWZ_ALL_MASK)
+ >> NV30_FP_OP_COND_SWZ_ALL_SHIFT;
+ NV30FPTXSwizzle(swzbits, swz);
+}
+
+static int
+NV30FPGetCondRegID(nvsFunc * shader)
+{
+ return 0;
+}
+
+static nvsPrecision
+NV30FPGetPrecision(nvsFunc * shader)
+{
+ int p;
+
+ p = (shader->inst[0] & NV30_FP_OP_PRECISION_MASK)
+ >> NV30_FP_OP_PRECISION_SHIFT;
+
+ switch (p) {
+ case NV30_FP_PRECISION_FP32: return NVS_PREC_FLOAT32;
+ case NV30_FP_PRECISION_FP16: return NVS_PREC_FLOAT16;
+ case NV30_FP_PRECISION_FX12: return NVS_PREC_FIXED12;
+ default:
+ return NVS_PREC_UNKNOWN;
+ }
+}
+
+static int
+NV30FPGetSaturate(nvsFunc * shader)
+{
+ return ((shader->inst[0] & NV30_FP_OP_OUT_SAT) ? 1 : 0);
+}
+
+/*******************************************************************************
+ * Init
+ */
+void
+NV30FPInitShaderFuncs(nvsFunc * shader)
+{
+ /* These are probably bogus, I made them up... */
+ shader->MaxInst = 1024;
+ shader->MaxAttrib = 16;
+ shader->MaxTemp = 32;
+ shader->MaxAddress = 1;
+ shader->MaxConst = 256;
+ shader->caps = SCAP_SRC_ABS;
+
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MOV, NVS_OP_MOV, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MUL, NVS_OP_MUL, 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_ADD, NVS_OP_ADD, 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MAD, NVS_OP_MAD, 0, 1, 2);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DP3, NVS_OP_DP3, 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DP4, NVS_OP_DP4, 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DST, NVS_OP_DST, 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MIN, NVS_OP_MIN, 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MAX, NVS_OP_MAX, 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SLT, NVS_OP_SLT, 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SGE, NVS_OP_SGE, 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_FRC, NVS_OP_FRC, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_FLR, NVS_OP_FLR, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_TEX, NVS_OP_TEX, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_TXD, NVS_OP_TXD, 0, 1, 2);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_TXP, NVS_OP_TXP, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_TXB, NVS_OP_TXB, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SEQ, NVS_OP_SEQ, 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SGT, NVS_OP_SGT, 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SLE, NVS_OP_SLE, 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SNE, NVS_OP_SNE, 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_RCP, NVS_OP_RCP, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_LG2, NVS_OP_LG2, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_EX2, NVS_OP_EX2, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_COS, NVS_OP_COS, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SIN, NVS_OP_SIN, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_NOP, NVS_OP_NOP, -1, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DDX, NVS_OP_DDX, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DDY, NVS_OP_DDY, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_KIL, NVS_OP_KIL, -1, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_PK4B, NVS_OP_PK4B, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_UP4B, NVS_OP_UP4B, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_PK2H, NVS_OP_PK2H, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_UP2H, NVS_OP_UP2H, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_PK4UB, NVS_OP_PK4UB, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_UP4UB, NVS_OP_UP4UB, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_PK2US, NVS_OP_PK2US, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_UP2US, NVS_OP_UP2US, 0, -1, -1);
+ /*FIXME: Haven't confirmed the source positions for the below opcodes */
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_LIT, NVS_OP_LIT, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_LRP, NVS_OP_LRP, 0, 1, 2);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_POW, NVS_OP_POW, 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_RSQ, NVS_OP_RSQ, 0, -1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_RFL, NVS_OP_RFL, 0, 1, -1);
+
+ shader->GetOPTXRec = NV30FPGetOPTXRec;
+ shader->GetOPTXFromSOP = NV30FPGetOPTXFromSOP;
+
+ shader->UploadToHW = NV30FPUploadToHW;
+ shader->UpdateConst = NV30FPUpdateConst;
+
+ shader->InitInstruction = NV30FPInitInstruction;
+ shader->SupportsOpcode = NV30FPSupportsOpcode;
+ shader->SetOpcode = NV30FPSetOpcode;
+ shader->SetCCUpdate = NV30FPSetCCUpdate;
+ shader->SetCondition = NV30FPSetCondition;
+ shader->SetResult = NV30FPSetResult;
+ shader->SetSource = NV30FPSetSource;
+ shader->SetTexImageUnit = NV30FPSetTexImageUnit;
+ shader->SetSaturate = NV30FPSetSaturate;
+ shader->SetLastInst = NV30FPSetLastInst;
+
+ shader->HasMergedInst = NV30FPHasMergedInst;
+ shader->IsLastInst = NV30FPIsLastInst;
+ shader->GetOffsetNext = NV30FPGetOffsetNext;
+ shader->GetOpcode = NV30FPGetOpcode;
+ shader->GetOpcodeHW = NV30FPGetOpcodeHW;
+ shader->GetDestFile = NV30FPGetDestFile;
+ shader->GetDestID = NV30FPGetDestID;
+ shader->GetDestMask = NV30FPGetDestMask;
+ shader->GetSourceHW = NV30FPGetSourceHW;
+ shader->GetSourceFile = NV30FPGetSourceFile;
+ shader->GetSourceID = NV30FPGetSourceID;
+ shader->GetTexImageUnit = NV30FPGetTexImageUnit;
+ shader->GetSourceNegate = NV30FPGetSourceNegate;
+ shader->GetSourceAbs = NV30FPGetSourceAbs;
+ shader->GetSourceSwizzle = NV30FPGetSourceSwizzle;
+ shader->GetSourceIndexed = NV30FPGetSourceIndexed;
+ shader->GetSourceConstVal = NV30FPGetSourceConstVal;
+ shader->GetSourceScale = NV30FPGetSourceScale;
+ shader->GetRelAddressRegID = NV30FPGetAddressRegID;
+ shader->GetRelAddressSwizzle = NV30FPGetAddressRegSwizzle;
+ shader->GetPrecision = NV30FPGetPrecision;
+ shader->GetSaturate = NV30FPGetSaturate;
+ shader->SupportsConditional = NV30FPSupportsConditional;
+ shader->GetConditionUpdate = NV30FPGetConditionUpdate;
+ shader->GetConditionTest = NV30FPGetConditionTest;
+ shader->GetCondition = NV30FPGetCondition;
+ shader->GetCondRegSwizzle = NV30FPGetCondRegSwizzle;
+ shader->GetCondRegID = NV30FPGetCondRegID;
+}
diff --git a/src/mesa/drivers/dri/nouveau/nv30_shader.h b/src/mesa/drivers/dri/nouveau/nv30_shader.h
new file mode 100644
index 00000000000..7a027dd4273
--- /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 00000000000..ad21fa27302
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nv30_state.c
@@ -0,0 +1,980 @@
+/**************************************************************************
+
+Copyright 2006 Nouveau
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#include "nouveau_context.h"
+#include "nouveau_object.h"
+#include "nouveau_fifo.h"
+#include "nouveau_reg.h"
+#include "nouveau_state.h"
+
+#include "tnl/t_pipeline.h"
+
+#include "mtypes.h"
+#include "colormac.h"
+
+#define NOUVEAU_CARD_USING_SHADERS (nmesa->screen->card->type >= NV_40)
+
+static void nv30AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte ubRef;
+ CLAMPED_FLOAT_TO_UBYTE(ubRef, ref);
+
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC, 2);
+ OUT_RING_CACHE(func); /* NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC */
+ OUT_RING_CACHE(ubRef); /* NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF */
+}
+
+static void nv30BlendColor(GLcontext *ctx, const GLfloat color[4])
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte cf[4];
+
+ CLAMPED_FLOAT_TO_UBYTE(cf[0], color[0]);
+ CLAMPED_FLOAT_TO_UBYTE(cf[1], color[1]);
+ CLAMPED_FLOAT_TO_UBYTE(cf[2], color[2]);
+ CLAMPED_FLOAT_TO_UBYTE(cf[3], color[3]);
+
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_COLOR, 1);
+ OUT_RING_CACHE(PACK_COLOR_8888(cf[3], cf[1], cf[2], cf[0]));
+}
+
+static void nv30BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_EQUATION, 1);
+ OUT_RING_CACHE((modeA<<16) | modeRGB);
+}
+
+
+static void nv30BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB,
+ GLenum sfactorA, GLenum dfactorA)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2);
+ OUT_RING_CACHE((sfactorA<<16) | sfactorRGB);
+ OUT_RING_CACHE((dfactorA<<16) | dfactorRGB);
+}
+
+static void nv30Clear(GLcontext *ctx, GLbitfield mask)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLuint hw_bufs = 0;
+
+ if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT))
+ hw_bufs |= 0xf0;
+ if (mask & (BUFFER_BIT_DEPTH))
+ hw_bufs |= 0x03;
+
+ if (hw_bufs) {
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_WHICH_BUFFERS, 1);
+ OUT_RING(hw_bufs);
+ }
+}
+
+static void nv30ClearColor(GLcontext *ctx, const GLfloat color[4])
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte c[4];
+ UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,color);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB, 1);
+ OUT_RING_CACHE(PACK_COLOR_8888(c[3],c[0],c[1],c[2]));
+}
+
+static void nv30ClearDepth(GLcontext *ctx, GLclampd d)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nmesa->clear_value=((nmesa->clear_value&0x000000FF)|(((uint32_t)(d*0xFFFFFF))<<8));
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1);
+ OUT_RING_CACHE(nmesa->clear_value);
+}
+
+/* we're don't support indexed buffers
+ void (*ClearIndex)(GLcontext *ctx, GLuint index)
+ */
+
+static void nv30ClearStencil(GLcontext *ctx, GLint s)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ nmesa->clear_value=((nmesa->clear_value&0xFFFFFF00)|(s&0x000000FF));
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1);
+ OUT_RING_CACHE(nmesa->clear_value);
+}
+
+static void nv30ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ if (NOUVEAU_CARD_USING_SHADERS)
+ return;
+
+ plane -= GL_CLIP_PLANE0;
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4);
+ OUT_RING_CACHEf(equation[0]);
+ OUT_RING_CACHEf(equation[1]);
+ OUT_RING_CACHEf(equation[2]);
+ OUT_RING_CACHEf(equation[3]);
+}
+
+static void nv30ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask,
+ GLboolean bmask, GLboolean amask )
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_MASK, 1);
+ OUT_RING_CACHE(((amask && 0x01) << 24) | ((rmask && 0x01) << 16) | ((gmask && 0x01)<< 8) | ((bmask && 0x01) << 0));
+}
+
+static void nv30ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode)
+{
+ // TODO I need love
+}
+
+static void nv30CullFace(GLcontext *ctx, GLenum mode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CULL_FACE, 1);
+ OUT_RING_CACHE(mode);
+}
+
+static void nv30FrontFace(GLcontext *ctx, GLenum mode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FRONT_FACE, 1);
+ OUT_RING_CACHE(mode);
+}
+
+static void nv30DepthFunc(GLcontext *ctx, GLenum func)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1);
+ OUT_RING_CACHE(func);
+}
+
+static void nv30DepthMask(GLcontext *ctx, GLboolean flag)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1);
+ OUT_RING_CACHE(flag);
+}
+
+static void nv30DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2);
+ OUT_RING_CACHEf(nearval);
+ OUT_RING_CACHEf(farval);
+}
+
+/** Specify the current buffer for writing */
+//void (*DrawBuffer)( GLcontext *ctx, GLenum buffer );
+/** Specify the buffers for writing for fragment programs*/
+//void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers );
+
+static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ switch(cap)
+ {
+ case GL_ALPHA_TEST:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_AUTO_NORMAL:
+ case GL_BLEND:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_CLIP_PLANE0:
+ case GL_CLIP_PLANE1:
+ case GL_CLIP_PLANE2:
+ case GL_CLIP_PLANE3:
+ case GL_CLIP_PLANE4:
+ case GL_CLIP_PLANE5:
+ if (NOUVEAU_CARD_USING_SHADERS) {
+ nouveauShader *nvs = (nouveauShader *)ctx->VertexProgram._Current;
+ if (nvs)
+ nvs->translated = GL_FALSE;
+ } else {
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1);
+ OUT_RING_CACHE(state);
+ }
+ break;
+ case GL_COLOR_LOGIC_OP:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_COLOR_MATERIAL:
+// case GL_COLOR_SUM_EXT:
+// case GL_COLOR_TABLE:
+// case GL_CONVOLUTION_1D:
+// case GL_CONVOLUTION_2D:
+ case GL_CULL_FACE:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_DEPTH_TEST:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_DITHER:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DITHER_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_FOG:
+ if (NOUVEAU_CARD_USING_SHADERS)
+ break;
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_HISTOGRAM:
+// case GL_INDEX_LOGIC_OP:
+ case GL_LIGHT0:
+ case GL_LIGHT1:
+ case GL_LIGHT2:
+ case GL_LIGHT3:
+ case GL_LIGHT4:
+ case GL_LIGHT5:
+ case GL_LIGHT6:
+ case GL_LIGHT7:
+ {
+ uint32_t mask=0x11<<(2*(cap-GL_LIGHT0));
+
+ if (NOUVEAU_CARD_USING_SHADERS)
+ break;
+
+ nmesa->enabled_lights=((nmesa->enabled_lights&mask)|(mask*state));
+ if (nmesa->lighting_enabled)
+ {
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1);
+ OUT_RING_CACHE(nmesa->enabled_lights);
+ }
+ break;
+ }
+ case GL_LIGHTING:
+ if (NOUVEAU_CARD_USING_SHADERS)
+ break;
+
+ nmesa->lighting_enabled=state;
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1);
+ if (nmesa->lighting_enabled)
+ OUT_RING_CACHE(nmesa->enabled_lights);
+ else
+ OUT_RING_CACHE(0x0);
+ break;
+// case GL_LINE_SMOOTH:
+// case GL_LINE_STIPPLE:
+// case GL_MAP1_COLOR_4:
+// case GL_MAP1_INDEX:
+// case GL_MAP1_NORMAL:
+// case GL_MAP1_TEXTURE_COORD_1:
+// case GL_MAP1_TEXTURE_COORD_2:
+// case GL_MAP1_TEXTURE_COORD_3:
+// case GL_MAP1_TEXTURE_COORD_4:
+// case GL_MAP1_VERTEX_3:
+// case GL_MAP1_VERTEX_4:
+// case GL_MAP2_COLOR_4:
+// case GL_MAP2_INDEX:
+// case GL_MAP2_NORMAL:
+// case GL_MAP2_TEXTURE_COORD_1:
+// case GL_MAP2_TEXTURE_COORD_2:
+// case GL_MAP2_TEXTURE_COORD_3:
+// case GL_MAP2_TEXTURE_COORD_4:
+// case GL_MAP2_VERTEX_3:
+// case GL_MAP2_VERTEX_4:
+// case GL_MINMAX:
+ case GL_NORMALIZE:
+ if (nmesa->screen->card->type != NV_44) {
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ }
+ break;
+// case GL_POINT_SMOOTH:
+ case GL_POLYGON_OFFSET_POINT:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_POLYGON_OFFSET_LINE:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_POLYGON_OFFSET_FILL:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_POLYGON_SMOOTH:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_POLYGON_STIPPLE:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_POST_COLOR_MATRIX_COLOR_TABLE:
+// case GL_POST_CONVOLUTION_COLOR_TABLE:
+// case GL_RESCALE_NORMAL:
+ case GL_SCISSOR_TEST:
+ /* No enable bit, nv30Scissor will adjust to max range */
+ ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
+ ctx->Scissor.Width, ctx->Scissor.Height);
+ break;
+// case GL_SEPARABLE_2D:
+ case GL_STENCIL_TEST:
+ // TODO BACK and FRONT ?
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_TEXTURE_GEN_Q:
+// case GL_TEXTURE_GEN_R:
+// case GL_TEXTURE_GEN_S:
+// case GL_TEXTURE_GEN_T:
+// case GL_TEXTURE_1D:
+// case GL_TEXTURE_2D:
+// case GL_TEXTURE_3D:
+ }
+}
+
+static void nv30Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ if (NOUVEAU_CARD_USING_SHADERS)
+ return;
+
+ switch(pname)
+ {
+ case GL_FOG_MODE:
+ {
+ int mode = 0;
+ /* The modes are different in GL and the card. */
+ switch(ctx->Fog.Mode)
+ {
+ case GL_LINEAR:
+ mode = 0x804;
+ break;
+ case GL_EXP:
+ mode = 0x802;
+ break;
+ case GL_EXP2:
+ mode = 0x803;
+ break;
+ }
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_MODE, 1);
+ OUT_RING_CACHE (mode);
+ break;
+ }
+ case GL_FOG_COLOR:
+ {
+ GLubyte c[4];
+ UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,params);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_COLOR, 1);
+ /* nvidia ignores the alpha channel */
+ OUT_RING_CACHE(PACK_COLOR_8888_REV(c[0],c[1],c[2],c[3]));
+ break;
+ }
+ case GL_FOG_DENSITY:
+ case GL_FOG_START:
+ case GL_FOG_END:
+ {
+ GLfloat f=0., c=0.;
+ switch(ctx->Fog.Mode)
+ {
+ case GL_LINEAR:
+ f = -1.0/(ctx->Fog.End - ctx->Fog.Start);
+ c = ctx->Fog.Start/(ctx->Fog.End - ctx->Fog.Start) + 2.001953;
+ break;
+ case GL_EXP:
+ f = -0.090168*ctx->Fog.Density;
+ c = 1.5;
+ case GL_EXP2:
+ f = -0.212330*ctx->Fog.Density;
+ c = 1.5;
+ }
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_LINEAR, 1);
+ OUT_RING_CACHE(f);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT, 1);
+ OUT_RING_CACHE(c);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_QUADRATIC, 1);
+ OUT_RING_CACHE(0); /* Is this always the same? */
+ break;
+ }
+// case GL_FOG_COORD_SRC:
+ default:
+ break;
+ }
+}
+
+static void nv30Hint(GLcontext *ctx, GLenum target, GLenum mode)
+{
+ // TODO I need love (fog and line_smooth hints)
+}
+
+// void (*IndexMask)(GLcontext *ctx, GLuint mask);
+
+enum {
+ SPOTLIGHT_NO_UPDATE,
+ SPOTLIGHT_UPDATE_EXPONENT,
+ SPOTLIGHT_UPDATE_DIRECTION,
+ SPOTLIGHT_UPDATE_ALL
+};
+
+static void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params )
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLint p = light - GL_LIGHT0;
+ struct gl_light *l = &ctx->Light.Light[p];
+ int spotlight_update = SPOTLIGHT_NO_UPDATE;
+
+ if (NOUVEAU_CARD_USING_SHADERS)
+ return;
+
+ /* not sure where the fourth param value goes...*/
+ switch(pname)
+ {
+ case GL_AMBIENT:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(p), 3);
+ OUT_RING_CACHEf(params[0]);
+ OUT_RING_CACHEf(params[1]);
+ OUT_RING_CACHEf(params[2]);
+ break;
+ case GL_DIFFUSE:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(p), 3);
+ OUT_RING_CACHEf(params[0]);
+ OUT_RING_CACHEf(params[1]);
+ OUT_RING_CACHEf(params[2]);
+ break;
+ case GL_SPECULAR:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(p), 3);
+ OUT_RING_CACHEf(params[0]);
+ OUT_RING_CACHEf(params[1]);
+ OUT_RING_CACHEf(params[2]);
+ break;
+ case GL_POSITION:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(p), 3);
+ OUT_RING_CACHEf(params[0]);
+ OUT_RING_CACHEf(params[1]);
+ OUT_RING_CACHEf(params[2]);
+ break;
+ case GL_SPOT_DIRECTION:
+ spotlight_update = SPOTLIGHT_UPDATE_DIRECTION;
+ break;
+ case GL_SPOT_EXPONENT:
+ spotlight_update = SPOTLIGHT_UPDATE_EXPONENT;
+ break;
+ case GL_SPOT_CUTOFF:
+ spotlight_update = SPOTLIGHT_UPDATE_ALL;
+ break;
+ case GL_CONSTANT_ATTENUATION:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(p), 1);
+ OUT_RING_CACHEf(*params);
+ break;
+ case GL_LINEAR_ATTENUATION:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(p), 1);
+ OUT_RING_CACHEf(*params);
+ break;
+ case GL_QUADRATIC_ATTENUATION:
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(p), 1);
+ OUT_RING_CACHEf(*params);
+ break;
+ default:
+ break;
+ }
+
+ switch(spotlight_update) {
+ case SPOTLIGHT_UPDATE_DIRECTION:
+ {
+ GLfloat x,y,z;
+ GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0);
+ x = spot_light_coef_a * l->_NormDirection[0];
+ y = spot_light_coef_a * l->_NormDirection[1];
+ z = spot_light_coef_a * l->_NormDirection[2];
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p), 3);
+ OUT_RING_CACHEf(x);
+ OUT_RING_CACHEf(y);
+ OUT_RING_CACHEf(z);
+ }
+ break;
+ case SPOTLIGHT_UPDATE_EXPONENT:
+ {
+ GLfloat cc,lc,qc;
+ cc = 1.0; /* FIXME: These need to be correctly computed */
+ lc = 0.0;
+ qc = 2.0;
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 3);
+ OUT_RING_CACHEf(cc);
+ OUT_RING_CACHEf(lc);
+ OUT_RING_CACHEf(qc);
+ }
+ break;
+ case SPOTLIGHT_UPDATE_ALL:
+ {
+ GLfloat cc,lc,qc, x,y,z, c;
+ GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0);
+ cc = 1.0; /* FIXME: These need to be correctly computed */
+ lc = 0.0;
+ qc = 2.0;
+ x = spot_light_coef_a * l->_NormDirection[0];
+ y = spot_light_coef_a * l->_NormDirection[1];
+ z = spot_light_coef_a * l->_NormDirection[2];
+ c = spot_light_coef_a + 1.0;
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 7);
+ OUT_RING_CACHEf(cc);
+ OUT_RING_CACHEf(lc);
+ OUT_RING_CACHEf(qc);
+ OUT_RING_CACHEf(x);
+ OUT_RING_CACHEf(y);
+ OUT_RING_CACHEf(z);
+ OUT_RING_CACHEf(c);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/** Set the lighting model parameters */
+void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params);
+
+
+static void nv30LineStipple(GLcontext *ctx, GLint factor, GLushort pattern )
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN, 1);
+ OUT_RING_CACHE((pattern << 16) | factor);
+}
+
+static void nv30LineWidth(GLcontext *ctx, GLfloat width)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte ubWidth;
+
+ ubWidth = (GLubyte)(width * 8.0) & 0xFF;
+
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_WIDTH_SMOOTH, 1);
+ OUT_RING_CACHE(ubWidth);
+}
+
+static void nv30LogicOpcode(GLcontext *ctx, GLenum opcode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP, 1);
+ OUT_RING_CACHE(opcode);
+}
+
+static void nv30PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
+{
+ /*TODO: not sure what goes here. */
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+}
+
+/** Specify the diameter of rasterized points */
+static void nv30PointSize(GLcontext *ctx, GLfloat size)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POINT_SIZE, 1);
+ OUT_RING_CACHEf(size);
+}
+
+/** Select a polygon rasterization mode */
+static void nv30PolygonMode(GLcontext *ctx, GLenum face, GLenum mode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 1);
+ OUT_RING_CACHE(mode);
+ }
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK, 1);
+ OUT_RING_CACHE(mode);
+ }
+}
+
+/** Set the scale and units used to calculate depth values */
+static void nv30PolygonOffset(GLcontext *ctx, GLfloat factor, GLfloat units)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR, 2);
+ OUT_RING_CACHEf(factor);
+
+ /* Looks like we always multiply units by 2.0... according to the dumps.*/
+ OUT_RING_CACHEf(units * 2.0);
+}
+
+/** Set the polygon stippling pattern */
+static void nv30PolygonStipple(GLcontext *ctx, const GLubyte *mask )
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(0), 32);
+ OUT_RING_CACHEp(mask, 32);
+}
+
+/* Specifies the current buffer for reading */
+void (*ReadBuffer)( GLcontext *ctx, GLenum buffer );
+/** Set rasterization mode */
+void (*RenderMode)(GLcontext *ctx, GLenum mode );
+
+/** Define the scissor box */
+static void nv30Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ /* There's no scissor enable bit, so adjust the scissor to cover the
+ * maximum draw buffer bounds
+ */
+ if (!ctx->Scissor.Enabled) {
+ x = y = 0;
+ w = h = 4095;
+ } else {
+ x += nmesa->drawX;
+ y += nmesa->drawY;
+ }
+
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS, 2);
+ OUT_RING_CACHE(((w) << 16) | x);
+ OUT_RING_CACHE(((h) << 16) | y);
+}
+
+/** Select flat or smooth shading */
+static void nv30ShadeModel(GLcontext *ctx, GLenum mode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SHADE_MODEL, 1);
+ OUT_RING_CACHE(mode);
+}
+
+/** OpenGL 2.0 two-sided StencilFunc */
+static void nv30StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func,
+ GLint ref, GLuint mask)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_FUNC, 3);
+ OUT_RING_CACHE(func);
+ OUT_RING_CACHE(ref);
+ OUT_RING_CACHE(mask);
+ }
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_FUNC, 3);
+ OUT_RING_CACHE(func);
+ OUT_RING_CACHE(ref);
+ OUT_RING_CACHE(mask);
+ }
+}
+
+/** OpenGL 2.0 two-sided StencilMask */
+static void nv30StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_MASK, 1);
+ OUT_RING_CACHE(mask);
+ }
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_MASK, 1);
+ OUT_RING_CACHE(mask);
+ }
+}
+
+/** OpenGL 2.0 two-sided StencilOp */
+static void nv30StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail,
+ GLenum zfail, GLenum zpass)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_FAIL, 3);
+ OUT_RING_CACHE(fail);
+ OUT_RING_CACHE(zfail);
+ OUT_RING_CACHE(zpass);
+ }
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_FAIL, 3);
+ OUT_RING_CACHE(fail);
+ OUT_RING_CACHE(zfail);
+ OUT_RING_CACHE(zpass);
+ }
+}
+
+/** Control the generation of texture coordinates */
+void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname,
+ const GLfloat *params);
+/** Set texture environment parameters */
+void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname,
+ const GLfloat *param);
+/** Set texture parameters */
+void (*TexParameter)(GLcontext *ctx, GLenum target,
+ struct gl_texture_object *texObj,
+ GLenum pname, const GLfloat *params);
+
+static void nv30TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ if (!NOUVEAU_CARD_USING_SHADERS) {
+ BEGIN_RING_CACHE(NvSub3D,
+ NV30_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16);
+ /*XXX: This SHOULD work.*/
+ OUT_RING_CACHEp(mat->m, 16);
+ }
+}
+
+static void nv30WindowMoved(nouveauContextPtr nmesa)
+{
+ GLcontext *ctx = nmesa->glCtx;
+ GLfloat *v = nmesa->viewport.m;
+ GLuint w = ctx->Viewport.Width;
+ GLuint h = ctx->Viewport.Height;
+ GLuint x = ctx->Viewport.X + nmesa->drawX;
+ GLuint y = ctx->Viewport.Y + nmesa->drawY;
+
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_0, 2);
+ OUT_RING_CACHE((w << 16) | x);
+ OUT_RING_CACHE((h << 16) | y);
+ /* something to do with clears, possibly doesn't belong here */
+ BEGIN_RING_CACHE(NvSub3D,
+ NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_OFS0, 2);
+ OUT_RING_CACHE(((w+x) << 16) | x);
+ OUT_RING_CACHE(((h+y) << 16) | y);
+ /* viewport transform */
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_OX, 8);
+ OUT_RING_CACHEf (v[MAT_TX]);
+ OUT_RING_CACHEf (v[MAT_TY]);
+ OUT_RING_CACHEf (v[MAT_TZ]);
+ OUT_RING_CACHEf (0.0);
+ OUT_RING_CACHEf (v[MAT_SX]);
+ OUT_RING_CACHEf (v[MAT_SY]);
+ OUT_RING_CACHEf (v[MAT_SZ]);
+ OUT_RING_CACHEf (0.0);
+
+ ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
+ ctx->Scissor.Width, ctx->Scissor.Height);
+}
+
+static GLboolean nv30InitCard(nouveauContextPtr nmesa)
+{
+ int i;
+ nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D);
+
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT1, 3);
+ OUT_RING(NvDmaFB);
+ OUT_RING(NvDmaAGP);
+ OUT_RING(NvDmaFB);
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT8, 1);
+ OUT_RING(NvDmaFB);
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT4, 2);
+ OUT_RING(NvDmaFB);
+ OUT_RING(NvDmaFB);
+ BEGIN_RING_SIZE(NvSub3D, 0x1b0, 1); /* SET_OBJECT8B*/
+ OUT_RING(NvDmaFB);
+
+ for(i = 0x2c8; i <= 0x2fc; i += 4)
+ {
+ BEGIN_RING_SIZE(NvSub3D, i, 1);
+ OUT_RING(0x0);
+ }
+
+ BEGIN_RING_SIZE(NvSub3D, 0x0220, 1);
+ OUT_RING(1);
+
+ BEGIN_RING_SIZE(NvSub3D, 0x03b0, 1);
+ OUT_RING(0x00100000);
+ BEGIN_RING_SIZE(NvSub3D, 0x1454, 1);
+ OUT_RING(0);
+ BEGIN_RING_SIZE(NvSub3D, 0x1d80, 1);
+ OUT_RING(3);
+
+ /* NEW */
+ BEGIN_RING_SIZE(NvSub3D, 0x1e98, 1);
+ OUT_RING(0);
+ BEGIN_RING_SIZE(NvSub3D, 0x17e0, 3);
+ OUT_RING(0);
+ OUT_RING(0);
+ OUT_RING(0x3f800000);
+ BEGIN_RING_SIZE(NvSub3D, 0x1f80, 16);
+ OUT_RING(0); OUT_RING(0); OUT_RING(0); OUT_RING(0);
+ OUT_RING(0); OUT_RING(0); OUT_RING(0); OUT_RING(0);
+ OUT_RING(0x0000ffff);
+ OUT_RING(0); OUT_RING(0); OUT_RING(0); OUT_RING(0);
+ OUT_RING(0); OUT_RING(0); OUT_RING(0);
+/*
+ BEGIN_RING_SIZE(NvSub3D, 0x100, 2);
+ OUT_RING(0);
+ OUT_RING(0);
+*/
+ BEGIN_RING_SIZE(NvSub3D, 0x120, 3);
+ OUT_RING(0);
+ OUT_RING(1);
+ OUT_RING(2);
+
+ BEGIN_RING_SIZE(NvSub3D, 0x1d88, 1);
+ OUT_RING(0x00001200);
+
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_RC_ENABLE, 1);
+ OUT_RING (0);
+
+ return GL_TRUE;
+}
+
+static GLboolean nv40InitCard(nouveauContextPtr nmesa)
+{
+ nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D);
+
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT1, 2);
+ OUT_RING(NvDmaFB);
+ OUT_RING(NvDmaFB);
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT8, 1);
+ OUT_RING(NvDmaFB);
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT4, 2);
+ OUT_RING(NvDmaFB);
+ OUT_RING(NvDmaFB);
+ BEGIN_RING_SIZE(NvSub3D, 0x0220, 1);
+ OUT_RING(1);
+
+ BEGIN_RING_SIZE(NvSub3D, 0x1ea4, 3);
+ OUT_RING(0x00000010);
+ OUT_RING(0x01000100);
+ OUT_RING(0xff800006);
+ BEGIN_RING_SIZE(NvSub3D, 0x1fc4, 1);
+ OUT_RING(0x06144321);
+ BEGIN_RING_SIZE(NvSub3D, 0x1fc8, 2);
+ OUT_RING(0xedcba987);
+ OUT_RING(0x00000021);
+ BEGIN_RING_SIZE(NvSub3D, 0x1fd0, 1);
+ OUT_RING(0x00171615);
+ BEGIN_RING_SIZE(NvSub3D, 0x1fd4, 1);
+ OUT_RING(0x001b1a19);
+
+ BEGIN_RING_SIZE(NvSub3D, 0x1ef8, 1);
+ OUT_RING(0x0020ffff);
+ BEGIN_RING_SIZE(NvSub3D, 0x1d64, 1);
+ OUT_RING(0x00d30000);
+ BEGIN_RING_SIZE(NvSub3D, 0x1e94, 1);
+ OUT_RING(0x00000001);
+
+ return GL_TRUE;
+}
+
+static GLboolean nv30BindBuffers(nouveauContextPtr nmesa, int num_color,
+ nouveau_renderbuffer **color,
+ nouveau_renderbuffer *depth)
+{
+ GLuint x, y, w, h;
+
+ w = color[0]->mesa.Width;
+ h = color[0]->mesa.Height;
+ x = nmesa->drawX;
+ y = nmesa->drawY;
+
+ if (num_color != 1)
+ return GL_FALSE;
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_DIM0, 5);
+ OUT_RING (((w+x)<<16)|x);
+ OUT_RING (((h+y)<<16)|y);
+ if (color[0]->mesa._ActualFormat == GL_RGBA8)
+ OUT_RING (0x148);
+ else
+ OUT_RING (0x143);
+ if (nmesa->screen->card->type >= NV_40)
+ OUT_RING (color[0]->pitch);
+ else
+ OUT_RING (color[0]->pitch | (depth ? (depth->pitch << 16): 0));
+ OUT_RING (color[0]->offset);
+
+ if (depth) {
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_OFFSET, 1);
+ OUT_RING (depth->offset);
+ if (nmesa->screen->card->type >= NV_40) {
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH, 1);
+ OUT_RING (depth->pitch);
+ }
+ }
+
+ return GL_TRUE;
+}
+
+void nv30InitStateFuncs(GLcontext *ctx, struct dd_function_table *func)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ func->AlphaFunc = nv30AlphaFunc;
+ func->BlendColor = nv30BlendColor;
+ func->BlendEquationSeparate = nv30BlendEquationSeparate;
+ func->BlendFuncSeparate = nv30BlendFuncSeparate;
+ func->Clear = nv30Clear;
+ func->ClearColor = nv30ClearColor;
+ func->ClearDepth = nv30ClearDepth;
+ func->ClearStencil = nv30ClearStencil;
+ func->ClipPlane = nv30ClipPlane;
+ func->ColorMask = nv30ColorMask;
+ func->ColorMaterial = nv30ColorMaterial;
+ func->CullFace = nv30CullFace;
+ func->FrontFace = nv30FrontFace;
+ func->DepthFunc = nv30DepthFunc;
+ func->DepthMask = nv30DepthMask;
+ func->DepthRange = nv30DepthRange;
+ func->Enable = nv30Enable;
+ func->Fogfv = nv30Fogfv;
+ func->Hint = nv30Hint;
+ func->Lightfv = nv30Lightfv;
+/* func->LightModelfv = nv30LightModelfv; */
+ func->LineStipple = nv30LineStipple;
+ func->LineWidth = nv30LineWidth;
+ func->LogicOpcode = nv30LogicOpcode;
+ func->PointParameterfv = nv30PointParameterfv;
+ func->PointSize = nv30PointSize;
+ func->PolygonMode = nv30PolygonMode;
+ func->PolygonOffset = nv30PolygonOffset;
+ func->PolygonStipple = nv30PolygonStipple;
+#if 0
+ func->ReadBuffer = nv30ReadBuffer;
+ func->RenderMode = nv30RenderMode;
+#endif
+ func->Scissor = nv30Scissor;
+ func->ShadeModel = nv30ShadeModel;
+ func->StencilFuncSeparate = nv30StencilFuncSeparate;
+ func->StencilMaskSeparate = nv30StencilMaskSeparate;
+ func->StencilOpSeparate = nv30StencilOpSeparate;
+#if 0
+ func->TexGen = nv30TexGen;
+ func->TexParameter = nv30TexParameter;
+#endif
+ func->TextureMatrix = nv30TextureMatrix;
+
+
+ if (nmesa->screen->card->type >= NV_40)
+ nmesa->hw_func.InitCard = nv40InitCard;
+ else
+ nmesa->hw_func.InitCard = nv30InitCard;
+ nmesa->hw_func.BindBuffers = nv30BindBuffers;
+ nmesa->hw_func.WindowMoved = nv30WindowMoved;
+}
+
diff --git a/src/mesa/drivers/dri/nouveau/nv30_vertprog.c b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c
new file mode 100644
index 00000000000..d023e8439e3
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c
@@ -0,0 +1,367 @@
+#include "nouveau_context.h"
+#include "nouveau_object.h"
+#include "nouveau_fifo.h"
+#include "nouveau_reg.h"
+
+#include "nouveau_shader.h"
+#include "nv30_shader.h"
+
+/*****************************************************************************
+ * Support routines
+ */
+static void
+NV30VPUploadToHW(GLcontext *ctx, nouveauShader *nvs)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ int i;
+
+ /* We can do better here and keep more than one VP on the hardware, and
+ * switch between them with PROGRAM_START_ID..
+ */
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_FROM_ID, 1);
+ OUT_RING(0);
+ for (i=0; i<nvs->program_size; i+=4) {
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_INST0, 4);
+ OUT_RING(nvs->program[i + 0]);
+ OUT_RING(nvs->program[i + 1]);
+ OUT_RING(nvs->program[i + 2]);
+ OUT_RING(nvs->program[i + 3]);
+ }
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_PROGRAM_START_ID, 1);
+ OUT_RING(0);
+
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_IN_REG, 2);
+ OUT_RING(nvs->card_priv.NV30VP.vp_in_reg);
+ OUT_RING(nvs->card_priv.NV30VP.vp_out_reg);
+
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_CLIPPING_PLANES, 1);
+ OUT_RING_CACHE (nvs->card_priv.NV30VP.clip_enables);
+}
+
+static void
+NV30VPUpdateConst(GLcontext *ctx, nouveauShader *nvs, int id)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLfloat *val;
+
+ val = nvs->params[id].source_val ?
+ nvs->params[id].source_val : nvs->params[id].val;
+
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_ID, 5);
+ OUT_RING (id);
+ OUT_RINGp(val, 4);
+}
+
+/*****************************************************************************
+ * Assembly routines
+ */
+static void
+NV30VPSetBranchTarget(nvsFunc *shader, int addr)
+{
+ shader->inst[2] &= ~NV30_VP_INST_IADDR_MASK;
+ shader->inst[2] |= (addr << NV30_VP_INST_IADDR_SHIFT);
+}
+
+/*****************************************************************************
+ * Disassembly routines
+ */
+static unsigned int
+NV30VPGetOpcodeHW(nvsFunc * shader, int slot)
+{
+ int op;
+
+ if (slot) {
+ op = (shader->inst[1] & NV30_VP_INST_SCA_OPCODEL_MASK)
+ >> NV30_VP_INST_SCA_OPCODEL_SHIFT;
+ op |= ((shader->inst[0] & NV30_VP_INST_SCA_OPCODEH_MASK)
+ >> NV30_VP_INST_SCA_OPCODEH_SHIFT) << 4;
+ }
+ else {
+ op = (shader->inst[1] & NV30_VP_INST_VEC_OPCODE_MASK)
+ >> NV30_VP_INST_VEC_OPCODE_SHIFT;
+ }
+
+ return op;
+}
+
+static nvsRegFile
+NV30VPGetDestFile(nvsFunc * shader, int merged)
+{
+ switch (shader->GetOpcode(shader, merged)) {
+ case NVS_OP_ARL:
+ case NVS_OP_ARR:
+ case NVS_OP_ARA:
+ return NVS_FILE_ADDRESS;
+ default:
+ /*FIXME: This probably isn't correct.. */
+ if ((shader->inst[3] & NV30_VP_INST_VDEST_WRITEMASK_MASK) != 0)
+ return NVS_FILE_RESULT;
+ if ((shader->inst[3] & NV30_VP_INST_SDEST_WRITEMASK_MASK) != 0)
+ return NVS_FILE_RESULT;
+ return NVS_FILE_TEMP;
+ }
+}
+
+static unsigned int
+NV30VPGetDestID(nvsFunc * shader, int merged)
+{
+ int id;
+
+ switch (shader->GetDestFile(shader, merged)) {
+ case NVS_FILE_RESULT:
+ id = ((shader->inst[3] & NV30_VP_INST_DEST_ID_MASK)
+ >> NV30_VP_INST_DEST_ID_SHIFT);
+ switch (id) {
+ case NV30_VP_INST_DEST_POS : return NVS_FR_POSITION;
+ case NV30_VP_INST_DEST_COL0 : return NVS_FR_COL0;
+ case NV30_VP_INST_DEST_COL1 : return NVS_FR_COL1;
+ case NV30_VP_INST_DEST_TC(0): return NVS_FR_TEXCOORD0;
+ case NV30_VP_INST_DEST_TC(1): return NVS_FR_TEXCOORD1;
+ case NV30_VP_INST_DEST_TC(2): return NVS_FR_TEXCOORD2;
+ case NV30_VP_INST_DEST_TC(3): return NVS_FR_TEXCOORD3;
+ case NV30_VP_INST_DEST_TC(4): return NVS_FR_TEXCOORD4;
+ case NV30_VP_INST_DEST_TC(5): return NVS_FR_TEXCOORD5;
+ case NV30_VP_INST_DEST_TC(6): return NVS_FR_TEXCOORD6;
+ case NV30_VP_INST_DEST_TC(7): return NVS_FR_TEXCOORD7;
+ default:
+ return -1;
+ }
+ case NVS_FILE_ADDRESS:
+ case NVS_FILE_TEMP:
+ return (shader->inst[0] & NV30_VP_INST_DEST_TEMP_ID_MASK)
+ >> NV30_VP_INST_DEST_TEMP_ID_SHIFT;
+ default:
+ return -1;
+ }
+}
+
+static unsigned int
+NV30VPGetDestMask(nvsFunc * shader, int merged)
+{
+ int hwmask, mask = 0;
+
+ if (shader->GetDestFile(shader, merged) == NVS_FILE_RESULT)
+ if (shader->GetOpcodeSlot(shader, merged))
+ hwmask = (shader->inst[3] & NV30_VP_INST_SDEST_WRITEMASK_MASK)
+ >> NV30_VP_INST_SDEST_WRITEMASK_SHIFT;
+ else
+ hwmask = (shader->inst[3] & NV30_VP_INST_VDEST_WRITEMASK_MASK)
+ >> NV30_VP_INST_VDEST_WRITEMASK_SHIFT;
+ else if (shader->GetOpcodeSlot(shader, merged))
+ hwmask = (shader->inst[3] & NV30_VP_INST_STEMP_WRITEMASK_MASK)
+ >> NV30_VP_INST_STEMP_WRITEMASK_SHIFT;
+ else
+ hwmask = (shader->inst[3] & NV30_VP_INST_VTEMP_WRITEMASK_MASK)
+ >> NV30_VP_INST_VTEMP_WRITEMASK_SHIFT;
+
+ if (hwmask & (1 << 3)) mask |= SMASK_X;
+ if (hwmask & (1 << 2)) mask |= SMASK_Y;
+ if (hwmask & (1 << 1)) mask |= SMASK_Z;
+ if (hwmask & (1 << 0)) mask |= SMASK_W;
+
+ return mask;
+}
+
+static int
+NV30VPGetSourceID(nvsFunc * shader, int merged, int pos)
+{
+ unsigned int src;
+
+ switch (shader->GetSourceFile(shader, merged, pos)) {
+ case NVS_FILE_TEMP:
+ src = shader->GetSourceHW(shader, merged, pos);
+ return ((src & NV30_VP_SRC_REG_TEMP_ID_MASK) >>
+ NV30_VP_SRC_REG_TEMP_ID_SHIFT);
+ case NVS_FILE_CONST:
+ return ((shader->inst[1] & NV30_VP_INST_CONST_SRC_MASK)
+ >> NV30_VP_INST_CONST_SRC_SHIFT);
+ case NVS_FILE_ATTRIB:
+ src = ((shader->inst[1] & NV30_VP_INST_INPUT_SRC_MASK)
+ >> NV30_VP_INST_INPUT_SRC_SHIFT);
+ switch (src) {
+ case NV30_VP_INST_IN_POS : return NVS_FR_POSITION;
+ case NV30_VP_INST_IN_COL0 : return NVS_FR_COL0;
+ case NV30_VP_INST_IN_COL1 : return NVS_FR_COL1;
+ case NV30_VP_INST_IN_TC(0): return NVS_FR_TEXCOORD0;
+ case NV30_VP_INST_IN_TC(1): return NVS_FR_TEXCOORD1;
+ case NV30_VP_INST_IN_TC(2): return NVS_FR_TEXCOORD2;
+ case NV30_VP_INST_IN_TC(3): return NVS_FR_TEXCOORD3;
+ case NV30_VP_INST_IN_TC(4): return NVS_FR_TEXCOORD4;
+ case NV30_VP_INST_IN_TC(5): return NVS_FR_TEXCOORD5;
+ case NV30_VP_INST_IN_TC(6): return NVS_FR_TEXCOORD6;
+ case NV30_VP_INST_IN_TC(7): return NVS_FR_TEXCOORD7;
+ default:
+ return NVS_FR_UNKNOWN;
+ }
+ default:
+ return -1;
+ }
+}
+
+static int
+NV30VPGetSourceAbs(nvsFunc * shader, int merged, int pos)
+{
+ struct _op_xlat *opr;
+ static unsigned int abspos[3] = {
+ NV30_VP_INST_SRC0_ABS,
+ NV30_VP_INST_SRC1_ABS,
+ NV30_VP_INST_SRC2_ABS,
+ };
+
+ opr = shader->GetOPTXRec(shader, merged);
+ if (!opr || opr->srcpos[pos] == -1 || opr->srcpos[pos] > 2)
+ return 0;
+
+ return ((shader->inst[0] & abspos[opr->srcpos[pos]]) ? 1 : 0);
+}
+
+static int
+NV30VPGetRelAddressRegID(nvsFunc * shader)
+{
+ return ((shader->inst[0] & NV30_VP_INST_ADDR_REG_SELECT_1) ? 1 : 0);
+}
+
+static nvsSwzComp
+NV30VPGetRelAddressSwizzle(nvsFunc * shader)
+{
+ nvsSwzComp swz;
+
+ swz = NV20VP_TX_SWIZZLE[(shader->inst[0] & NV30_VP_INST_ADDR_SWZ_MASK)
+ >> NV30_VP_INST_ADDR_SWZ_SHIFT];
+ return swz;
+}
+
+static int
+NV30VPSupportsConditional(nvsFunc * shader)
+{
+ /*FIXME: Is this true of all ops? */
+ return 1;
+}
+
+static int
+NV30VPGetConditionUpdate(nvsFunc * shader)
+{
+ return ((shader->inst[0] & NV30_VP_INST_COND_UPDATE_ENABLE) ? 1 : 0);
+}
+
+static int
+NV30VPGetConditionTest(nvsFunc * shader)
+{
+ int op;
+
+ /* The condition test is unconditionally enabled on some
+ * instructions. ie: the condition test bit does *NOT* have
+ * to be set.
+ *
+ * FIXME: check other relevant ops for this situation.
+ */
+ op = shader->GetOpcodeHW(shader, 1);
+ switch (op) {
+ case NV30_VP_INST_OP_BRA:
+ return 1;
+ default:
+ return ((shader->inst[0] & NV30_VP_INST_COND_TEST_ENABLE) ? 1 : 0);
+ }
+}
+
+static nvsCond
+NV30VPGetCondition(nvsFunc * shader)
+{
+ int cond;
+
+ cond = ((shader->inst[0] & NV30_VP_INST_COND_MASK)
+ >> NV30_VP_INST_COND_SHIFT);
+
+ switch (cond) {
+ case NV30_VP_INST_COND_FL: return NVS_COND_FL;
+ case NV30_VP_INST_COND_LT: return NVS_COND_LT;
+ case NV30_VP_INST_COND_EQ: return NVS_COND_EQ;
+ case NV30_VP_INST_COND_LE: return NVS_COND_LE;
+ case NV30_VP_INST_COND_GT: return NVS_COND_GT;
+ case NV30_VP_INST_COND_NE: return NVS_COND_NE;
+ case NV30_VP_INST_COND_GE: return NVS_COND_GE;
+ case NV30_VP_INST_COND_TR: return NVS_COND_TR;
+ default:
+ return NVS_COND_UNKNOWN;
+ }
+}
+
+static void
+NV30VPGetCondRegSwizzle(nvsFunc * shader, nvsSwzComp *swz)
+{
+ int swzbits;
+
+ swzbits = (shader->inst[0] & NV30_VP_INST_COND_SWZ_ALL_MASK)
+ >> NV30_VP_INST_COND_SWZ_ALL_SHIFT;
+ NV20VPTXSwizzle(swzbits, swz);
+}
+
+static int
+NV30VPGetCondRegID(nvsFunc * shader)
+{
+ return 0;
+}
+
+
+static int
+NV30VPGetBranch(nvsFunc * shader)
+{
+ return ((shader->inst[2] & NV30_VP_INST_IADDR_MASK)
+ >> NV30_VP_INST_IADDR_SHIFT);
+}
+
+void
+NV30VPInitShaderFuncs(nvsFunc * shader)
+{
+ /* Inherit NV20 code, a lot of it is the same */
+ NV20VPInitShaderFuncs(shader);
+
+ /* Increase max valid opcode ID, and add new instructions */
+ NVVP_TX_VOP_COUNT = NVVP_TX_NVS_OP_COUNT = 32;
+
+ MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_FRC, NVS_OP_FRC, 0, -1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_FLR, NVS_OP_FLR, 0, -1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SEQ, NVS_OP_SEQ, 0, 1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SFL, NVS_OP_SFL, 0, 1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SGT, NVS_OP_SGT, 0, 1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SLE, NVS_OP_SLE, 0, 1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SNE, NVS_OP_SNE, 0, 1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_STR, NVS_OP_STR, 0, 1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SSG, NVS_OP_SSG, 0, -1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_ARR, NVS_OP_ARR, 0, -1, -1);
+ MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_ARA, NVS_OP_ARA, 3, -1, -1);
+
+ MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_BRA, NVS_OP_BRA, -1, -1, -1);
+ MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_CAL, NVS_OP_CAL, -1, -1, -1);
+ MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_RET, NVS_OP_RET, -1, -1, -1);
+ MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_LG2, NVS_OP_LG2, 2, -1, -1);
+ MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_EX2, NVS_OP_EX2, 2, -1, -1);
+ MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_SIN, NVS_OP_SIN, 2, -1, -1);
+ MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_COS, NVS_OP_COS, 2, -1, -1);
+
+ shader->UploadToHW = NV30VPUploadToHW;
+ shader->UpdateConst = NV30VPUpdateConst;
+
+ shader->GetOpcodeHW = NV30VPGetOpcodeHW;
+
+ shader->GetDestFile = NV30VPGetDestFile;
+ shader->GetDestID = NV30VPGetDestID;
+ shader->GetDestMask = NV30VPGetDestMask;
+
+ shader->GetSourceID = NV30VPGetSourceID;
+ shader->GetSourceAbs = NV30VPGetSourceAbs;
+
+ shader->GetRelAddressRegID = NV30VPGetRelAddressRegID;
+ shader->GetRelAddressSwizzle = NV30VPGetRelAddressSwizzle;
+
+ shader->SupportsConditional = NV30VPSupportsConditional;
+ shader->GetConditionUpdate = NV30VPGetConditionUpdate;
+ shader->GetConditionTest = NV30VPGetConditionTest;
+ shader->GetCondition = NV30VPGetCondition;
+ shader->GetCondRegSwizzle = NV30VPGetCondRegSwizzle;
+ shader->GetCondRegID = NV30VPGetCondRegID;
+
+ shader->GetBranch = NV30VPGetBranch;
+ shader->SetBranchTarget = NV30VPSetBranchTarget;
+}
+
diff --git a/src/mesa/drivers/dri/nouveau/nv40_fragprog.c b/src/mesa/drivers/dri/nouveau/nv40_fragprog.c
new file mode 100644
index 00000000000..3e4ae0496e4
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nv40_fragprog.c
@@ -0,0 +1,224 @@
+#include "nouveau_shader.h"
+#include "nv40_shader.h"
+
+/* branching ops */
+unsigned int NVFP_TX_BOP_COUNT = 5;
+struct _op_xlat NVFP_TX_BOP[64];
+
+
+/*****************************************************************************
+ * Assembly routines
+ * - These extend the NV30 routines, which are almost identical. NV40
+ * just has branching hacked into the instruction set.
+ */
+static int
+NV40FPSupportsResultScale(nvsFunc *shader, nvsScale scale)
+{
+ switch (scale) {
+ case NVS_SCALE_1X:
+ case NVS_SCALE_2X:
+ case NVS_SCALE_4X:
+ case NVS_SCALE_8X:
+ case NVS_SCALE_INV_2X:
+ case NVS_SCALE_INV_4X:
+ case NVS_SCALE_INV_8X:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static void
+NV40FPSetResultScale(nvsFunc *shader, nvsScale scale)
+{
+ shader->inst[2] &= ~NV40_FP_OP_DST_SCALE_MASK;
+ shader->inst[2] |= ((unsigned int)scale << NV40_FP_OP_DST_SCALE_SHIFT);
+}
+
+static void
+NV40FPSetBranchTarget(nvsFunc *shader, int addr)
+{
+ shader->inst[2] &= ~NV40_FP_OP_IADDR_MASK;
+ shader->inst[2] |= (addr << NV40_FP_OP_IADDR_SHIFT);
+}
+
+static void
+NV40FPSetBranchElse(nvsFunc *shader, int addr)
+{
+ shader->inst[2] &= ~NV40_FP_OP_ELSE_ID_MASK;
+ shader->inst[2] |= (addr << NV40_FP_OP_ELSE_ID_SHIFT);
+}
+
+static void
+NV40FPSetBranchEnd(nvsFunc *shader, int addr)
+{
+ shader->inst[3] &= ~NV40_FP_OP_END_ID_MASK;
+ shader->inst[3] |= (addr << NV40_FP_OP_END_ID_SHIFT);
+}
+
+static void
+NV40FPSetLoopParams(nvsFunc *shader, int count, int initial, int increment)
+{
+ shader->inst[2] &= ~(NV40_FP_OP_LOOP_COUNT_MASK |
+ NV40_FP_OP_LOOP_INDEX_MASK |
+ NV40_FP_OP_LOOP_INCR_MASK);
+ shader->inst[2] |= ((count << NV40_FP_OP_LOOP_COUNT_SHIFT) |
+ (initial << NV40_FP_OP_LOOP_INDEX_SHIFT) |
+ (increment << NV40_FP_OP_LOOP_INCR_SHIFT));
+}
+
+/*****************************************************************************
+ * Disassembly routines
+ */
+static struct _op_xlat *
+NV40FPGetOPTXRec(nvsFunc * shader, int merged)
+{
+ struct _op_xlat *opr;
+ int op;
+
+ op = shader->GetOpcodeHW(shader, 0);
+ if (shader->inst[2] & NV40_FP_OP_OPCODE_IS_BRANCH) {
+ opr = NVFP_TX_BOP;
+ op &= ~NV40_FP_OP_OPCODE_IS_BRANCH;
+ if (op > NVFP_TX_BOP_COUNT)
+ return NULL;
+ }
+ else {
+ opr = NVFP_TX_AOP;
+ if (op > NVFP_TX_AOP_COUNT)
+ return NULL;
+ }
+
+ if (opr[op].SOP == NVS_OP_UNKNOWN)
+ return NULL;
+ return &opr[op];
+}
+
+static int
+NV40FPGetSourceID(nvsFunc * shader, int merged, int pos)
+{
+ switch (shader->GetSourceFile(shader, merged, pos)) {
+ case NVS_FILE_ATTRIB:
+ switch ((shader->inst[0] & NV40_FP_OP_INPUT_SRC_MASK)
+ >> NV40_FP_OP_INPUT_SRC_SHIFT) {
+ case NV40_FP_OP_INPUT_SRC_POSITION: return NVS_FR_POSITION;
+ case NV40_FP_OP_INPUT_SRC_COL0 : return NVS_FR_COL0;
+ case NV40_FP_OP_INPUT_SRC_COL1 : return NVS_FR_COL1;
+ case NV40_FP_OP_INPUT_SRC_FOGC : return NVS_FR_FOGCOORD;
+ case NV40_FP_OP_INPUT_SRC_TC(0) : return NVS_FR_TEXCOORD0;
+ case NV40_FP_OP_INPUT_SRC_TC(1) : return NVS_FR_TEXCOORD1;
+ case NV40_FP_OP_INPUT_SRC_TC(2) : return NVS_FR_TEXCOORD2;
+ case NV40_FP_OP_INPUT_SRC_TC(3) : return NVS_FR_TEXCOORD3;
+ case NV40_FP_OP_INPUT_SRC_TC(4) : return NVS_FR_TEXCOORD4;
+ case NV40_FP_OP_INPUT_SRC_TC(5) : return NVS_FR_TEXCOORD5;
+ case NV40_FP_OP_INPUT_SRC_TC(6) : return NVS_FR_TEXCOORD6;
+ case NV40_FP_OP_INPUT_SRC_TC(7) : return NVS_FR_TEXCOORD7;
+ case NV40_FP_OP_INPUT_SRC_FACING : return NVS_FR_FACING;
+ default:
+ return -1;
+ }
+ break;
+ case NVS_FILE_TEMP:
+ {
+ unsigned int src;
+
+ src = shader->GetSourceHW(shader, merged, pos);
+ return ((src & NV40_FP_REG_SRC_MASK) >> NV40_FP_REG_SRC_SHIFT);
+ }
+ case NVS_FILE_CONST: /* inlined into fragprog */
+ default:
+ return -1;
+ }
+}
+
+static int
+NV40FPGetBranch(nvsFunc * shader)
+{
+ return ((shader->inst[2] & NV40_FP_OP_IADDR_MASK)
+ >> NV40_FP_OP_IADDR_SHIFT);;
+}
+
+static int
+NV40FPGetBranchElse(nvsFunc * shader)
+{
+ return ((shader->inst[2] & NV40_FP_OP_ELSE_ID_MASK)
+ >> NV40_FP_OP_ELSE_ID_SHIFT);
+}
+
+static int
+NV40FPGetBranchEnd(nvsFunc * shader)
+{
+ return ((shader->inst[3] & NV40_FP_OP_END_ID_MASK)
+ >> NV40_FP_OP_END_ID_SHIFT);
+}
+
+static int
+NV40FPGetLoopCount(nvsFunc * shader)
+{
+ return ((shader->inst[2] & NV40_FP_OP_LOOP_COUNT_MASK)
+ >> NV40_FP_OP_LOOP_COUNT_SHIFT);
+}
+
+static int
+NV40FPGetLoopInitial(nvsFunc * shader)
+{
+ return ((shader->inst[2] & NV40_FP_OP_LOOP_INDEX_MASK)
+ >> NV40_FP_OP_LOOP_INDEX_SHIFT);
+}
+
+static int
+NV40FPGetLoopIncrement(nvsFunc * shader)
+{
+ return ((shader->inst[2] & NV40_FP_OP_LOOP_INCR_MASK)
+ >> NV40_FP_OP_LOOP_INCR_SHIFT);
+}
+
+void
+NV40FPInitShaderFuncs(nvsFunc * shader)
+{
+ /* Inherit NV30 FP code, it's mostly the same */
+ NV30FPInitShaderFuncs(shader);
+
+ /* Kill off opcodes seen on NV30, but not seen on NV40 - need to find
+ * out if these actually work or not.
+ *
+ * update: either LIT/RSQ don't work on nv40, or I generate bad code for
+ * them. haven't tested the others yet
+ */
+ MOD_OPCODE(NVFP_TX_AOP, 0x1B, NVS_OP_UNKNOWN, -1, -1, -1); /* NV30 RSQ */
+ MOD_OPCODE(NVFP_TX_AOP, 0x1E, NVS_OP_UNKNOWN, -1, -1, -1); /* NV30 LIT */
+ MOD_OPCODE(NVFP_TX_AOP, 0x1F, NVS_OP_UNKNOWN, -1, -1, -1); /* NV30 LRP */
+ MOD_OPCODE(NVFP_TX_AOP, 0x26, NVS_OP_UNKNOWN, -1, -1, -1); /* NV30 POW */
+ MOD_OPCODE(NVFP_TX_AOP, 0x36, NVS_OP_UNKNOWN, -1, -1, -1); /* NV30 RFL */
+
+ /* Extra opcodes supported on NV40 */
+ MOD_OPCODE(NVFP_TX_AOP, NV40_FP_OP_OPCODE_DIV , NVS_OP_DIV , 0, 1, -1);
+ MOD_OPCODE(NVFP_TX_AOP, NV40_FP_OP_OPCODE_DP2A , NVS_OP_DP2A, 0, 1, 2);
+ MOD_OPCODE(NVFP_TX_AOP, NV40_FP_OP_OPCODE_TXL , NVS_OP_TXL , 0, -1, -1);
+
+ MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_BRK , NVS_OP_BRK , -1, -1, -1);
+ MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_CAL , NVS_OP_CAL , -1, -1, -1);
+ MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_IF , NVS_OP_IF , -1, -1, -1);
+ MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_LOOP, NVS_OP_LOOP, -1, -1, -1);
+ MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_REP , NVS_OP_REP , -1, -1, -1);
+ MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_RET , NVS_OP_RET , -1, -1, -1);
+
+ shader->SupportsResultScale = NV40FPSupportsResultScale;
+ shader->SetResultScale = NV40FPSetResultScale;
+
+ /* fragment.facing */
+ shader->GetSourceID = NV40FPGetSourceID;
+
+ /* branching */
+ shader->GetOPTXRec = NV40FPGetOPTXRec;
+ shader->GetBranch = NV40FPGetBranch;
+ shader->GetBranchElse = NV40FPGetBranchElse;
+ shader->GetBranchEnd = NV40FPGetBranchEnd;
+ shader->GetLoopCount = NV40FPGetLoopCount;
+ shader->GetLoopInitial = NV40FPGetLoopInitial;
+ shader->GetLoopIncrement = NV40FPGetLoopIncrement;
+ shader->SetBranchTarget = NV40FPSetBranchTarget;
+ shader->SetBranchElse = NV40FPSetBranchElse;
+ shader->SetBranchEnd = NV40FPSetBranchEnd;
+ shader->SetLoopParams = NV40FPSetLoopParams;
+}
diff --git a/src/mesa/drivers/dri/nouveau/nv40_shader.h b/src/mesa/drivers/dri/nouveau/nv40_shader.h
new file mode 100644
index 00000000000..584f4c23e08
--- /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_DST_SCALE_SHIFT 28
+#define NV40_FP_OP_DST_SCALE_MASK (3 << 28)
+
+/* SRC1 LOOP */
+#define NV40_FP_OP_LOOP_INCR_SHIFT 19
+#define NV40_FP_OP_LOOP_INCR_MASK (0xFF << 19)
+#define NV40_FP_OP_LOOP_INDEX_SHIFT 10
+#define NV40_FP_OP_LOOP_INDEX_MASK (0xFF << 10)
+#define NV40_FP_OP_LOOP_COUNT_SHIFT 2
+#define NV40_FP_OP_LOOP_COUNT_MASK (0xFF << 2)
+
+/* SRC1 IF */
+#define NV40_FP_OP_ELSE_ID_SHIFT 2
+#define NV40_FP_OP_ELSE_ID_MASK (0xFF << 2)
+
+/* SRC1 CAL */
+#define NV40_FP_OP_IADDR_SHIFT 2
+#define NV40_FP_OP_IADDR_MASK (0xFF << 2)
+
+/* SRC1 REP
+ * I have no idea why there are 3 count values here.. but they
+ * have always been filled with the same value in my tests so
+ * far..
+ */
+#define NV40_FP_OP_REP_COUNT1_SHIFT 2
+#define NV40_FP_OP_REP_COUNT1_MASK (0xFF << 2)
+#define NV40_FP_OP_REP_COUNT2_SHIFT 10
+#define NV40_FP_OP_REP_COUNT2_MASK (0xFF << 10)
+#define NV40_FP_OP_REP_COUNT3_SHIFT 19
+#define NV40_FP_OP_REP_COUNT3_MASK (0xFF << 19)
+
+/* SRC2 REP/IF */
+#define NV40_FP_OP_END_ID_SHIFT 2
+#define NV40_FP_OP_END_ID_MASK (0xFF << 2)
+
+// SRC2 high-order
+#define NV40_FP_OP_INDEX_INPUT (1 << 30)
+#define NV40_FP_OP_ADDR_INDEX_SHIFT 19
+#define NV40_FP_OP_ADDR_INDEX_MASK (0xF << 19)
+
+//== Register selection ==
+#define NV40_FP_REG_TYPE_SHIFT 0
+#define NV40_FP_REG_TYPE_MASK (3 << 0)
+# define NV40_FP_REG_TYPE_TEMP 0
+# define NV40_FP_REG_TYPE_INPUT 1
+# define NV40_FP_REG_TYPE_CONST 2
+#define NV40_FP_REG_SRC_SHIFT 2
+#define NV40_FP_REG_SRC_MASK (31 << 2)
+#define NV40_FP_REG_UNK_0 (1 << 8)
+#define NV40_FP_REG_SWZ_ALL_SHIFT 9
+#define NV40_FP_REG_SWZ_ALL_MASK (255 << 9)
+#define NV40_FP_REG_SWZ_X_SHIFT 9
+#define NV40_FP_REG_SWZ_X_MASK (3 << 9)
+#define NV40_FP_REG_SWZ_Y_SHIFT 11
+#define NV40_FP_REG_SWZ_Y_MASK (3 << 11)
+#define NV40_FP_REG_SWZ_Z_SHIFT 13
+#define NV40_FP_REG_SWZ_Z_MASK (3 << 13)
+#define NV40_FP_REG_SWZ_W_SHIFT 15
+#define NV40_FP_REG_SWZ_W_MASK (3 << 15)
+# define NV40_FP_SWIZZLE_X 0
+# define NV40_FP_SWIZZLE_Y 1
+# define NV40_FP_SWIZZLE_Z 2
+# define NV40_FP_SWIZZLE_W 3
+#define NV40_FP_REG_NEGATE (1 << 17)
+
+#endif
diff --git a/src/mesa/drivers/dri/nouveau/nv40_vertprog.c b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c
new file mode 100644
index 00000000000..d054140bcd0
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c
@@ -0,0 +1,778 @@
+#include "nouveau_shader.h"
+#include "nouveau_msg.h"
+#include "nv40_shader.h"
+
+/*****************************************************************************
+ * Assembly routines
+ */
+static int
+NV40VPSupportsOpcode(nvsFunc * shader, nvsOpcode op)
+{
+ if (shader->GetOPTXFromSOP(op, NULL))
+ return 1;
+ return 0;
+}
+
+static void
+NV40VPSetOpcode(nvsFunc *shader, unsigned int opcode, int slot)
+{
+ if (slot) {
+ shader->inst[1] &= ~NV40_VP_INST_SCA_OPCODE_MASK;
+ shader->inst[1] |= (opcode << NV40_VP_INST_SCA_OPCODE_SHIFT);
+ } else {
+ shader->inst[1] &= ~NV40_VP_INST_VEC_OPCODE_MASK;
+ shader->inst[1] |= (opcode << NV40_VP_INST_VEC_OPCODE_SHIFT);
+ }
+}
+
+static void
+NV40VPSetCCUpdate(nvsFunc *shader)
+{
+ shader->inst[0] |= NV40_VP_INST_COND_UPDATE_ENABLE;
+}
+
+static void
+NV40VPSetCondition(nvsFunc *shader, int on, nvsCond cond, int reg,
+ nvsSwzComp *swizzle)
+{
+ unsigned int hwcond;
+
+ if (on ) shader->inst[0] |= NV40_VP_INST_COND_TEST_ENABLE;
+ else shader->inst[0] &= ~NV40_VP_INST_COND_TEST_ENABLE;
+ if (reg) shader->inst[0] |= NV40_VP_INST_COND_REG_SELECT_1;
+ else shader->inst[0] &= ~NV40_VP_INST_COND_REG_SELECT_1;
+
+ switch (cond) {
+ case NVS_COND_TR: hwcond = NV40_VP_INST_COND_TR; break;
+ case NVS_COND_FL: hwcond = NV40_VP_INST_COND_FL; break;
+ case NVS_COND_LT: hwcond = NV40_VP_INST_COND_LT; break;
+ case NVS_COND_GT: hwcond = NV40_VP_INST_COND_GT; break;
+ case NVS_COND_NE: hwcond = NV40_VP_INST_COND_NE; break;
+ case NVS_COND_EQ: hwcond = NV40_VP_INST_COND_EQ; break;
+ case NVS_COND_GE: hwcond = NV40_VP_INST_COND_GE; break;
+ case NVS_COND_LE: hwcond = NV40_VP_INST_COND_LE; break;
+ default:
+ WARN_ONCE("unknown vp cond %d\n", cond);
+ hwcond = NV40_VP_INST_COND_TR;
+ break;
+ }
+ shader->inst[0] &= ~NV40_VP_INST_COND_MASK;
+ shader->inst[0] |= (hwcond << NV40_VP_INST_COND_SHIFT);
+
+ shader->inst[0] &= ~NV40_VP_INST_COND_SWZ_ALL_MASK;
+ shader->inst[0] |= (swizzle[NVS_SWZ_X] << NV40_VP_INST_COND_SWZ_X_SHIFT);
+ shader->inst[0] |= (swizzle[NVS_SWZ_Y] << NV40_VP_INST_COND_SWZ_Y_SHIFT);
+ shader->inst[0] |= (swizzle[NVS_SWZ_Z] << NV40_VP_INST_COND_SWZ_Z_SHIFT);
+ shader->inst[0] |= (swizzle[NVS_SWZ_W] << NV40_VP_INST_COND_SWZ_W_SHIFT);
+}
+
+/* these just exist here until nouveau_reg.h has them. */
+#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_COL0 (1<<0)
+#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_COL1 (1<<1)
+#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_BFC0 (1<<2)
+#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_BFC1 (1<<3)
+#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_FOGC (1<<4)
+#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_PSZ (1<<5)
+#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP0 (1<<6)
+#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP1 (1<<7)
+#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP2 (1<<8)
+#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP3 (1<<9)
+#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP4 (1<<10)
+#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP5 (1<<11)
+#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_TEX0 (1<<14)
+
+static unsigned int
+NV40VPTranslateResultReg(nvsFunc *shader, nvsFixedReg result,
+ unsigned int *mask_ret)
+{
+ unsigned int *out_reg = &shader->card_priv->NV30VP.vp_out_reg;
+ unsigned int *clip_en = &shader->card_priv->NV30VP.clip_enables;
+
+ *mask_ret = 0xf;
+
+ switch (result) {
+ case NVS_FR_POSITION:
+ /* out_reg POS implied */
+ return NV40_VP_INST_DEST_POS;
+ case NVS_FR_COL0:
+ (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_COL0;
+ return NV40_VP_INST_DEST_COL0;
+ case NVS_FR_COL1:
+ (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_COL1;
+ return NV40_VP_INST_DEST_COL1;
+ case NVS_FR_BFC0:
+ (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_BFC0;
+ return NV40_VP_INST_DEST_BFC0;
+ case NVS_FR_BFC1:
+ (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_BFC1;
+ return NV40_VP_INST_DEST_BFC1;
+ case NVS_FR_FOGCOORD:
+ (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_FOGC;
+ *mask_ret = 0x8;
+ return NV40_VP_INST_DEST_FOGC;
+ case NVS_FR_CLIP0:
+ (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP0;
+ (*clip_en) |= 0x00000002;
+ *mask_ret = 0x4;
+ return NV40_VP_INST_DEST_FOGC;
+ case NVS_FR_CLIP1:
+ (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP1;
+ (*clip_en) |= 0x00000020;
+ *mask_ret = 0x2;
+ return NV40_VP_INST_DEST_FOGC;
+ case NVS_FR_CLIP2:
+ (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP2;
+ (*clip_en) |= 0x00000200;
+ *mask_ret = 0x1;
+ return NV40_VP_INST_DEST_FOGC;
+ case NVS_FR_POINTSZ:
+ (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_PSZ;
+ *mask_ret = 0x8;
+ return NV40_VP_INST_DEST_PSZ;
+ case NVS_FR_CLIP3:
+ (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP3;
+ (*clip_en) |= 0x00002000;
+ *mask_ret = 0x4;
+ return NV40_VP_INST_DEST_PSZ;
+ case NVS_FR_CLIP4:
+ (*clip_en) |= 0x00020000;
+ (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP4;
+ *mask_ret = 0x2;
+ return NV40_VP_INST_DEST_PSZ;
+ case NVS_FR_CLIP5:
+ (*clip_en) |= 0x00200000;
+ (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP5;
+ *mask_ret = 0x1;
+ return NV40_VP_INST_DEST_PSZ;
+ case NVS_FR_TEXCOORD0:
+ case NVS_FR_TEXCOORD1:
+ case NVS_FR_TEXCOORD2:
+ case NVS_FR_TEXCOORD3:
+ case NVS_FR_TEXCOORD4:
+ case NVS_FR_TEXCOORD5:
+ case NVS_FR_TEXCOORD6:
+ case NVS_FR_TEXCOORD7:
+ {
+ int unit = result - NVS_FR_TEXCOORD0;
+ (*out_reg) |= (NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_TEX0 << unit);
+ return NV40_VP_INST_DEST_TC(unit);
+ }
+ default:
+ WARN_ONCE("unknown vp output %d\n", result);
+ return NV40_VP_INST_DEST_POS;
+ }
+}
+
+static void
+NV40VPSetResult(nvsFunc *shader, nvsRegister * dest, unsigned int mask,
+ int slot)
+{
+ unsigned int hwmask = 0;
+
+ if (mask & SMASK_X) hwmask |= (1 << 3);
+ if (mask & SMASK_Y) hwmask |= (1 << 2);
+ if (mask & SMASK_Z) hwmask |= (1 << 1);
+ if (mask & SMASK_W) hwmask |= (1 << 0);
+
+ if (dest->file == NVS_FILE_RESULT) {
+ unsigned int valid_mask;
+ int hwidx;
+
+ hwidx = NV40VPTranslateResultReg(shader, dest->index, &valid_mask);
+ if (hwmask & ~valid_mask)
+ WARN_ONCE("writing invalid components of result reg\n");
+ hwmask &= valid_mask;
+
+ shader->inst[3] &= ~NV40_VP_INST_DEST_MASK;
+ shader->inst[3] |= (hwidx << NV40_VP_INST_DEST_SHIFT);
+
+ if (slot) shader->inst[3] |= NV40_VP_INST_SCA_RESULT;
+ else shader->inst[0] |= NV40_VP_INST_VEC_RESULT;
+ } else {
+ /* NVS_FILE_TEMP || NVS_FILE_ADDRESS */
+ if (slot) {
+ shader->inst[3] &= ~NV40_VP_INST_SCA_RESULT;
+ shader->inst[3] &= ~NV40_VP_INST_SCA_DEST_TEMP_MASK;
+ shader->inst[3] |= (dest->index << NV40_VP_INST_SCA_DEST_TEMP_SHIFT);
+ } else {
+ shader->inst[0] &= ~NV40_VP_INST_VEC_RESULT;
+ shader->inst[0] &= ~(NV40_VP_INST_VEC_DEST_TEMP_MASK | (1<<20));
+ shader->inst[0] |= (dest->index << NV40_VP_INST_VEC_DEST_TEMP_SHIFT);
+ }
+ }
+
+ if (slot) {
+ shader->inst[3] &= ~NV40_VP_INST_SCA_WRITEMASK_MASK;
+ shader->inst[3] |= (hwmask << NV40_VP_INST_SCA_WRITEMASK_SHIFT);
+ } else {
+ shader->inst[3] &= ~NV40_VP_INST_VEC_WRITEMASK_MASK;
+ shader->inst[3] |= (hwmask << NV40_VP_INST_VEC_WRITEMASK_SHIFT);
+ }
+}
+
+static void
+NV40VPInsertSource(nvsFunc *shader, unsigned int hw, int pos)
+{
+ switch (pos) {
+ case 0:
+ shader->inst[1] &= ~NV40_VP_INST_SRC0H_MASK;
+ shader->inst[2] &= ~NV40_VP_INST_SRC0L_MASK;
+ shader->inst[1] |= ((hw & NV40_VP_SRC0_HIGH_MASK) >>
+ NV40_VP_SRC0_HIGH_SHIFT)
+ << NV40_VP_INST_SRC0H_SHIFT;
+ shader->inst[2] |= (hw & NV40_VP_SRC0_LOW_MASK)
+ << NV40_VP_INST_SRC0L_SHIFT;
+ break;
+ case 1:
+ shader->inst[2] &= ~NV40_VP_INST_SRC1_MASK;
+ shader->inst[2] |= hw
+ << NV40_VP_INST_SRC1_SHIFT;
+ break;
+ case 2:
+ shader->inst[2] &= ~NV40_VP_INST_SRC2H_MASK;
+ shader->inst[3] &= ~NV40_VP_INST_SRC2L_MASK;
+ shader->inst[2] |= ((hw & NV40_VP_SRC2_HIGH_MASK) >>
+ NV40_VP_SRC2_HIGH_SHIFT)
+ << NV40_VP_INST_SRC2H_SHIFT;
+ shader->inst[3] |= (hw & NV40_VP_SRC2_LOW_MASK)
+ << NV40_VP_INST_SRC2L_SHIFT;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+}
+
+static void
+NV40VPSetSource(nvsFunc *shader, nvsRegister * src, int pos)
+{
+ unsigned int hw = 0;
+
+ switch (src->file) {
+ case NVS_FILE_ADDRESS:
+ break;
+ case NVS_FILE_ATTRIB:
+ hw |= (NV40_VP_SRC_REG_TYPE_INPUT << NV40_VP_SRC_REG_TYPE_SHIFT);
+
+ shader->inst[1] &= ~NV40_VP_INST_INPUT_SRC_MASK;
+ shader->inst[1] |= (src->index << NV40_VP_INST_INPUT_SRC_SHIFT);
+ shader->card_priv->NV30VP.vp_in_reg |= (1 << src->index);
+ if (src->indexed) {
+ shader->inst[0] |= NV40_VP_INST_INDEX_INPUT;
+ if (src->addr_reg)
+ shader->inst[0] |= NV40_VP_INST_ADDR_REG_SELECT_1;
+ else
+ shader->inst[0] &= ~NV40_VP_INST_ADDR_REG_SELECT_1;
+ shader->inst[0] &= ~NV40_VP_INST_ADDR_SWZ_SHIFT;
+ shader->inst[0] |= (src->addr_comp << NV40_VP_INST_ADDR_SWZ_SHIFT);
+ } else
+ shader->inst[0] &= ~NV40_VP_INST_INDEX_INPUT;
+ break;
+ case NVS_FILE_CONST:
+ hw |= (NV40_VP_SRC_REG_TYPE_CONST << NV40_VP_SRC_REG_TYPE_SHIFT);
+
+ shader->inst[1] &= ~NV40_VP_INST_CONST_SRC_MASK;
+ shader->inst[1] |= (src->index << NV40_VP_INST_CONST_SRC_SHIFT);
+ if (src->indexed) {
+ shader->inst[3] |= NV40_VP_INST_INDEX_CONST;
+ if (src->addr_reg)
+ shader->inst[0] |= NV40_VP_INST_ADDR_REG_SELECT_1;
+ else
+ shader->inst[0] &= ~NV40_VP_INST_ADDR_REG_SELECT_1;
+ shader->inst[0] &= ~NV40_VP_INST_ADDR_SWZ_MASK;
+ shader->inst[0] |= (src->addr_comp << NV40_VP_INST_ADDR_SWZ_SHIFT);
+ } else
+ shader->inst[3] &= ~NV40_VP_INST_INDEX_CONST;
+ break;
+ case NVS_FILE_TEMP:
+ hw |= (NV40_VP_SRC_REG_TYPE_TEMP << NV40_VP_SRC_REG_TYPE_SHIFT);
+ hw |= (src->index << NV40_VP_SRC_TEMP_SRC_SHIFT);
+ break;
+ default:
+ fprintf(stderr, "unknown source file %d\n", src->file);
+ assert(0);
+ break;
+ }
+
+ if (src->file != NVS_FILE_ADDRESS) {
+ if (src->negate)
+ hw |= NV40_VP_SRC_NEGATE;
+ if (src->abs)
+ shader->inst[0] |= (1 << (21 + pos));
+ else
+ shader->inst[0] &= ~(1 << (21 + pos));
+ hw |= (src->swizzle[0] << NV40_VP_SRC_SWZ_X_SHIFT);
+ hw |= (src->swizzle[1] << NV40_VP_SRC_SWZ_Y_SHIFT);
+ hw |= (src->swizzle[2] << NV40_VP_SRC_SWZ_Z_SHIFT);
+ hw |= (src->swizzle[3] << NV40_VP_SRC_SWZ_W_SHIFT);
+
+ NV40VPInsertSource(shader, hw, pos);
+ }
+}
+
+static void
+NV40VPSetBranchTarget(nvsFunc *shader, int addr)
+{
+ shader->inst[2] &= ~NV40_VP_INST_IADDRH_MASK;
+ shader->inst[2] |= ((addr & 0xf8) >> 3) << NV40_VP_INST_IADDRH_SHIFT;
+ shader->inst[3] &= ~NV40_VP_INST_IADDRL_MASK;
+ shader->inst[3] |= ((addr & 0x07) << NV40_VP_INST_IADDRL_SHIFT);
+}
+
+static void
+NV40VPInitInstruction(nvsFunc *shader)
+{
+ unsigned int hwsrc = 0;
+
+ shader->inst[0] = /*NV40_VP_INST_VEC_RESULT | */
+ NV40_VP_INST_VEC_DEST_TEMP_MASK | (1<<20);
+ shader->inst[1] = 0;
+ shader->inst[2] = 0;
+ shader->inst[3] = NV40_VP_INST_SCA_RESULT |
+ NV40_VP_INST_SCA_DEST_TEMP_MASK |
+ NV40_VP_INST_DEST_MASK;
+
+ hwsrc = (NV40_VP_SRC_REG_TYPE_INPUT << NV40_VP_SRC_REG_TYPE_SHIFT) |
+ (NVS_SWZ_X << NV40_VP_SRC_SWZ_X_SHIFT) |
+ (NVS_SWZ_Y << NV40_VP_SRC_SWZ_Y_SHIFT) |
+ (NVS_SWZ_Z << NV40_VP_SRC_SWZ_Z_SHIFT) |
+ (NVS_SWZ_W << NV40_VP_SRC_SWZ_W_SHIFT);
+ NV40VPInsertSource(shader, hwsrc, 0);
+ NV40VPInsertSource(shader, hwsrc, 1);
+ NV40VPInsertSource(shader, hwsrc, 2);
+}
+
+static void
+NV40VPSetLastInst(nvsFunc *shader)
+{
+ shader->inst[3] |= 1;
+}
+
+/*****************************************************************************
+ * Disassembly routines
+ */
+static int
+NV40VPHasMergedInst(nvsFunc * shader)
+{
+ if (shader->GetOpcodeHW(shader, 0) != NV40_VP_INST_OP_NOP &&
+ shader->GetOpcodeHW(shader, 1) != NV40_VP_INST_OP_NOP)
+ return 1;
+ return 0;
+}
+
+static unsigned int
+NV40VPGetOpcodeHW(nvsFunc * shader, int slot)
+{
+ int op;
+
+ if (slot)
+ op = (shader->inst[1] & NV40_VP_INST_SCA_OPCODE_MASK)
+ >> NV40_VP_INST_SCA_OPCODE_SHIFT;
+ else
+ op = (shader->inst[1] & NV40_VP_INST_VEC_OPCODE_MASK)
+ >> NV40_VP_INST_VEC_OPCODE_SHIFT;
+
+ return op;
+}
+
+static nvsRegFile
+NV40VPGetDestFile(nvsFunc * shader, int merged)
+{
+ nvsOpcode op;
+
+ op = shader->GetOpcode(shader, merged);
+ switch (op) {
+ case NVS_OP_ARL:
+ case NVS_OP_ARR:
+ case NVS_OP_ARA:
+ case NVS_OP_POPA:
+ return NVS_FILE_ADDRESS;
+ default:
+ if (shader->GetOpcodeSlot(shader, merged)) {
+ if (shader->inst[3] & NV40_VP_INST_SCA_RESULT)
+ return NVS_FILE_RESULT;
+ }
+ else {
+ if (shader->inst[0] & NV40_VP_INST_VEC_RESULT)
+ return NVS_FILE_RESULT;
+ }
+ return NVS_FILE_TEMP;
+ }
+
+}
+
+static unsigned int
+NV40VPGetDestID(nvsFunc * shader, int merged)
+{
+ int id;
+
+ switch (shader->GetDestFile(shader, merged)) {
+ case NVS_FILE_RESULT:
+ id = ((shader->inst[3] & NV40_VP_INST_DEST_MASK)
+ >> NV40_VP_INST_DEST_SHIFT);
+ switch (id) {
+ case NV40_VP_INST_DEST_POS : return NVS_FR_POSITION;
+ case NV40_VP_INST_DEST_COL0: return NVS_FR_COL0;
+ case NV40_VP_INST_DEST_COL1: return NVS_FR_COL1;
+ case NV40_VP_INST_DEST_BFC0: return NVS_FR_BFC0;
+ case NV40_VP_INST_DEST_BFC1: return NVS_FR_BFC1;
+ case NV40_VP_INST_DEST_FOGC: {
+ int mask = shader->GetDestMask(shader, merged);
+ switch (mask) {
+ case SMASK_X: return NVS_FR_FOGCOORD;
+ case SMASK_Y: return NVS_FR_CLIP0;
+ case SMASK_Z: return NVS_FR_CLIP1;
+ case SMASK_W: return NVS_FR_CLIP2;
+ default:
+ printf("more than 1 mask component set in FOGC writemask!\n");
+ return NVS_FR_UNKNOWN;
+ }
+ }
+ case NV40_VP_INST_DEST_PSZ:
+ {
+ int mask = shader->GetDestMask(shader, merged);
+ switch (mask) {
+ case SMASK_X: return NVS_FR_POINTSZ;
+ case SMASK_Y: return NVS_FR_CLIP3;
+ case SMASK_Z: return NVS_FR_CLIP4;
+ case SMASK_W: return NVS_FR_CLIP5;
+ default:
+ printf("more than 1 mask component set in PSZ writemask!\n");
+ return NVS_FR_UNKNOWN;
+ }
+ }
+ case NV40_VP_INST_DEST_TC(0): return NVS_FR_TEXCOORD0;
+ case NV40_VP_INST_DEST_TC(1): return NVS_FR_TEXCOORD1;
+ case NV40_VP_INST_DEST_TC(2): return NVS_FR_TEXCOORD2;
+ case NV40_VP_INST_DEST_TC(3): return NVS_FR_TEXCOORD3;
+ case NV40_VP_INST_DEST_TC(4): return NVS_FR_TEXCOORD4;
+ case NV40_VP_INST_DEST_TC(5): return NVS_FR_TEXCOORD5;
+ case NV40_VP_INST_DEST_TC(6): return NVS_FR_TEXCOORD6;
+ case NV40_VP_INST_DEST_TC(7): return NVS_FR_TEXCOORD7;
+ default:
+ return -1;
+ }
+ case NVS_FILE_ADDRESS:
+ /* Instructions that write address regs are encoded as if
+ * they would write temps.
+ */
+ case NVS_FILE_TEMP:
+ if (shader->GetOpcodeSlot(shader, merged))
+ id = ((shader->inst[3] & NV40_VP_INST_SCA_DEST_TEMP_MASK)
+ >> NV40_VP_INST_SCA_DEST_TEMP_SHIFT);
+ else
+ id = ((shader->inst[0] & NV40_VP_INST_VEC_DEST_TEMP_MASK)
+ >> NV40_VP_INST_VEC_DEST_TEMP_SHIFT);
+ return id;
+ default:
+ return -1;
+ }
+}
+
+static unsigned int
+NV40VPGetDestMask(nvsFunc * shader, int merged)
+{
+ unsigned int mask = 0;
+
+ if (shader->GetOpcodeSlot(shader, merged)) {
+ if (shader->inst[3] & NV40_VP_INST_SCA_WRITEMASK_X) mask |= SMASK_X;
+ if (shader->inst[3] & NV40_VP_INST_SCA_WRITEMASK_Y) mask |= SMASK_Y;
+ if (shader->inst[3] & NV40_VP_INST_SCA_WRITEMASK_Z) mask |= SMASK_Z;
+ if (shader->inst[3] & NV40_VP_INST_SCA_WRITEMASK_W) mask |= SMASK_W;
+ } else {
+ if (shader->inst[3] & NV40_VP_INST_VEC_WRITEMASK_X) mask |= SMASK_X;
+ if (shader->inst[3] & NV40_VP_INST_VEC_WRITEMASK_Y) mask |= SMASK_Y;
+ if (shader->inst[3] & NV40_VP_INST_VEC_WRITEMASK_Z) mask |= SMASK_Z;
+ if (shader->inst[3] & NV40_VP_INST_VEC_WRITEMASK_W) mask |= SMASK_W;
+ }
+
+ return mask;
+}
+
+static unsigned int
+NV40VPGetSourceHW(nvsFunc * shader, int merged, int pos)
+{
+ struct _op_xlat *opr;
+ unsigned int src;
+
+ opr = shader->GetOPTXRec(shader, merged);
+ if (!opr)
+ return -1;
+
+ switch (opr->srcpos[pos]) {
+ case 0:
+ src = ((shader->inst[1] & NV40_VP_INST_SRC0H_MASK)
+ >> NV40_VP_INST_SRC0H_SHIFT)
+ << NV40_VP_SRC0_HIGH_SHIFT;
+ src |= ((shader->inst[2] & NV40_VP_INST_SRC0L_MASK)
+ >> NV40_VP_INST_SRC0L_SHIFT);
+ break;
+ case 1:
+ src = ((shader->inst[2] & NV40_VP_INST_SRC1_MASK)
+ >> NV40_VP_INST_SRC1_SHIFT);
+ break;
+ case 2:
+ src = ((shader->inst[2] & NV40_VP_INST_SRC2H_MASK)
+ >> NV40_VP_INST_SRC2H_SHIFT)
+ << NV40_VP_SRC2_HIGH_SHIFT;
+ src |= ((shader->inst[3] & NV40_VP_INST_SRC2L_MASK)
+ >> NV40_VP_INST_SRC2L_SHIFT);
+ break;
+ default:
+ src = -1;
+ }
+
+ return src;
+}
+
+static nvsRegFile
+NV40VPGetSourceFile(nvsFunc * shader, int merged, int pos)
+{
+ unsigned int src;
+ struct _op_xlat *opr;
+ int file;
+
+ opr = shader->GetOPTXRec(shader, merged);
+ if (!opr || opr->srcpos[pos] == -1)
+ return -1;
+
+ switch (opr->srcpos[pos]) {
+ case SPOS_ADDRESS: return NVS_FILE_ADDRESS;
+ default:
+ src = shader->GetSourceHW(shader, merged, pos);
+ file = (src & NV40_VP_SRC_REG_TYPE_MASK) >> NV40_VP_SRC_REG_TYPE_SHIFT;
+
+ switch (file) {
+ case NV40_VP_SRC_REG_TYPE_TEMP : return NVS_FILE_TEMP;
+ case NV40_VP_SRC_REG_TYPE_INPUT: return NVS_FILE_ATTRIB;
+ case NV40_VP_SRC_REG_TYPE_CONST: return NVS_FILE_CONST;
+ default:
+ return NVS_FILE_UNKNOWN;
+ }
+ }
+}
+
+static int
+NV40VPGetSourceID(nvsFunc * shader, int merged, int pos)
+{
+ switch (shader->GetSourceFile(shader, merged, pos)) {
+ case NVS_FILE_ATTRIB:
+ switch ((shader->inst[1] & NV40_VP_INST_INPUT_SRC_MASK)
+ >> NV40_VP_INST_INPUT_SRC_SHIFT) {
+ case NV40_VP_INST_IN_POS: return NVS_FR_POSITION;
+ case NV40_VP_INST_IN_WEIGHT: return NVS_FR_WEIGHT;
+ case NV40_VP_INST_IN_NORMAL: return NVS_FR_NORMAL;
+ case NV40_VP_INST_IN_COL0: return NVS_FR_COL0;
+ case NV40_VP_INST_IN_COL1: return NVS_FR_COL1;
+ case NV40_VP_INST_IN_FOGC: return NVS_FR_FOGCOORD;
+ case NV40_VP_INST_IN_TC(0): return NVS_FR_TEXCOORD0;
+ case NV40_VP_INST_IN_TC(1): return NVS_FR_TEXCOORD1;
+ case NV40_VP_INST_IN_TC(2): return NVS_FR_TEXCOORD2;
+ case NV40_VP_INST_IN_TC(3): return NVS_FR_TEXCOORD3;
+ case NV40_VP_INST_IN_TC(4): return NVS_FR_TEXCOORD4;
+ case NV40_VP_INST_IN_TC(5): return NVS_FR_TEXCOORD5;
+ case NV40_VP_INST_IN_TC(6): return NVS_FR_TEXCOORD6;
+ case NV40_VP_INST_IN_TC(7): return NVS_FR_TEXCOORD7;
+ default:
+ return -1;
+ }
+ break;
+ case NVS_FILE_CONST:
+ return ((shader->inst[1] & NV40_VP_INST_CONST_SRC_MASK)
+ >> NV40_VP_INST_CONST_SRC_SHIFT);
+ case NVS_FILE_TEMP:
+ {
+ unsigned int src;
+
+ src = shader->GetSourceHW(shader, merged, pos);
+ return ((src & NV40_VP_SRC_TEMP_SRC_MASK) >>
+ NV40_VP_SRC_TEMP_SRC_SHIFT);
+ }
+ default:
+ return -1;
+ }
+}
+
+static int
+NV40VPGetSourceNegate(nvsFunc * shader, int merged, int pos)
+{
+ unsigned int src;
+
+ src = shader->GetSourceHW(shader, merged, pos);
+
+ if (src == -1)
+ return -1;
+ return ((src & NV40_VP_SRC_NEGATE) ? 1 : 0);
+}
+
+static void
+NV40VPGetSourceSwizzle(nvsFunc * shader, int merged, int pos, nvsSwzComp *swz)
+{
+ unsigned int src;
+ int swzbits;
+
+ src = shader->GetSourceHW(shader, merged, pos);
+ swzbits = (src & NV40_VP_SRC_SWZ_ALL_MASK) >> NV40_VP_SRC_SWZ_ALL_SHIFT;
+ NV20VPTXSwizzle(swzbits, swz);
+}
+
+static int
+NV40VPGetSourceIndexed(nvsFunc * shader, int merged, int pos)
+{
+ switch (shader->GetSourceFile(shader, merged, pos)) {
+ case NVS_FILE_ATTRIB:
+ return ((shader->inst[0] & NV40_VP_INST_INDEX_INPUT) ? 1 : 0);
+ case NVS_FILE_CONST:
+ return ((shader->inst[3] & NV40_VP_INST_INDEX_CONST) ? 1 : 0);
+ default:
+ return 0;
+ }
+}
+
+static nvsSwzComp
+NV40VPGetAddressRegSwizzle(nvsFunc * shader)
+{
+ nvsSwzComp swz;
+
+ swz = NV20VP_TX_SWIZZLE[(shader->inst[0] & NV40_VP_INST_ADDR_SWZ_MASK)
+ >> NV40_VP_INST_ADDR_SWZ_SHIFT];
+ return swz;
+}
+
+static int
+NV40VPSupportsConditional(nvsFunc * shader)
+{
+ /*FIXME: Is this true of all ops? */
+ return 1;
+}
+
+static int
+NV40VPGetConditionUpdate(nvsFunc * shader)
+{
+ return ((shader->inst[0] & NV40_VP_INST_COND_UPDATE_ENABLE) ? 1 : 0);
+}
+
+static int
+NV40VPGetConditionTest(nvsFunc * shader)
+{
+ int op;
+
+ /* The condition test is unconditionally enabled on some
+ * instructions. ie: the condition test bit does *NOT* have
+ * to be set.
+ *
+ * FIXME: check other relevant ops for this situation.
+ */
+ op = shader->GetOpcodeHW(shader, 1);
+ switch (op) {
+ case NV40_VP_INST_OP_BRA:
+ return 1;
+ default:
+ return ((shader->inst[0] & NV40_VP_INST_COND_TEST_ENABLE) ? 1 : 0);
+ }
+}
+
+static nvsCond
+NV40VPGetCondition(nvsFunc * shader)
+{
+ int cond;
+
+ cond = ((shader->inst[0] & NV40_VP_INST_COND_MASK)
+ >> NV40_VP_INST_COND_SHIFT);
+
+ switch (cond) {
+ case NV40_VP_INST_COND_FL: return NVS_COND_FL;
+ case NV40_VP_INST_COND_LT: return NVS_COND_LT;
+ case NV40_VP_INST_COND_EQ: return NVS_COND_EQ;
+ case NV40_VP_INST_COND_LE: return NVS_COND_LE;
+ case NV40_VP_INST_COND_GT: return NVS_COND_GT;
+ case NV40_VP_INST_COND_NE: return NVS_COND_NE;
+ case NV40_VP_INST_COND_GE: return NVS_COND_GE;
+ case NV40_VP_INST_COND_TR: return NVS_COND_TR;
+ default:
+ return NVS_COND_UNKNOWN;
+ }
+}
+
+static void
+NV40VPGetCondRegSwizzle(nvsFunc * shader, nvsSwzComp *swz)
+{
+ int swzbits;
+
+ swzbits = (shader->inst[0] & NV40_VP_INST_COND_SWZ_ALL_MASK)
+ >> NV40_VP_INST_COND_SWZ_ALL_SHIFT;
+ NV20VPTXSwizzle(swzbits, swz);
+}
+
+static int
+NV40VPGetCondRegID(nvsFunc * shader)
+{
+ return ((shader->inst[0] & NV40_VP_INST_COND_REG_SELECT_1) ? 1 : 0);
+}
+
+static int
+NV40VPGetBranch(nvsFunc * shader)
+{
+ int addr;
+
+ addr = ((shader->inst[2] & NV40_VP_INST_IADDRH_MASK)
+ >> NV40_VP_INST_IADDRH_SHIFT) << 3;
+ addr |= ((shader->inst[3] & NV40_VP_INST_IADDRL_MASK)
+ >> NV40_VP_INST_IADDRL_SHIFT);
+ return addr;
+}
+
+void
+NV40VPInitShaderFuncs(nvsFunc * shader)
+{
+ /* Inherit NV30 VP code, we share some of it */
+ NV30VPInitShaderFuncs(shader);
+
+ /* Limits */
+ shader->MaxInst = 4096;
+ shader->MaxAttrib = 16;
+ shader->MaxTemp = 32;
+ shader->MaxAddress = 2;
+ shader->MaxConst = 256;
+ shader->caps = SCAP_SRC_ABS;
+
+ /* Add extra opcodes for NV40+ */
+// MOD_OPCODE(NVVP_TX_VOP, NV40_VP_INST_OP_TXWHAT, NVS_OP_TEX , 0, 4, -1);
+ MOD_OPCODE(NVVP_TX_SOP, NV40_VP_INST_OP_PUSHA, NVS_OP_PUSHA, 3, -1, -1);
+ MOD_OPCODE(NVVP_TX_SOP, NV40_VP_INST_OP_POPA , NVS_OP_POPA , -1, -1, -1);
+
+ shader->InitInstruction = NV40VPInitInstruction;
+ shader->SupportsOpcode = NV40VPSupportsOpcode;
+ shader->SetOpcode = NV40VPSetOpcode;
+ shader->SetCCUpdate = NV40VPSetCCUpdate;
+ shader->SetCondition = NV40VPSetCondition;
+ shader->SetResult = NV40VPSetResult;
+ shader->SetSource = NV40VPSetSource;
+ shader->SetLastInst = NV40VPSetLastInst;
+ shader->SetBranchTarget = NV40VPSetBranchTarget;
+
+ shader->HasMergedInst = NV40VPHasMergedInst;
+ shader->GetOpcodeHW = NV40VPGetOpcodeHW;
+
+ shader->GetDestFile = NV40VPGetDestFile;
+ shader->GetDestID = NV40VPGetDestID;
+ shader->GetDestMask = NV40VPGetDestMask;
+
+ shader->GetSourceHW = NV40VPGetSourceHW;
+ shader->GetSourceFile = NV40VPGetSourceFile;
+ shader->GetSourceID = NV40VPGetSourceID;
+ shader->GetSourceNegate = NV40VPGetSourceNegate;
+ shader->GetSourceSwizzle = NV40VPGetSourceSwizzle;
+ shader->GetSourceIndexed = NV40VPGetSourceIndexed;
+
+ shader->GetRelAddressSwizzle = NV40VPGetAddressRegSwizzle;
+
+ shader->SupportsConditional = NV40VPSupportsConditional;
+ shader->GetConditionUpdate = NV40VPGetConditionUpdate;
+ shader->GetConditionTest = NV40VPGetConditionTest;
+ shader->GetCondition = NV40VPGetCondition;
+ shader->GetCondRegSwizzle = NV40VPGetCondRegSwizzle;
+ shader->GetCondRegID = NV40VPGetCondRegID;
+
+ shader->GetBranch = NV40VPGetBranch;
+}
diff --git a/src/mesa/drivers/dri/nouveau/nv50_state.c b/src/mesa/drivers/dri/nouveau/nv50_state.c
new file mode 100644
index 00000000000..818e268615c
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nv50_state.c
@@ -0,0 +1,641 @@
+/**************************************************************************
+
+Copyright 2006 Nouveau
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#include "nouveau_context.h"
+#include "nouveau_object.h"
+#include "nouveau_fifo.h"
+#include "nouveau_reg.h"
+#include "nouveau_state.h"
+
+#include "tnl/t_pipeline.h"
+
+#include "mtypes.h"
+#include "colormac.h"
+
+static void nv50AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte ubRef;
+ CLAMPED_FLOAT_TO_UBYTE(ubRef, ref);
+
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF, 2);
+ OUT_RING_CACHE(ubRef);
+ OUT_RING_CACHE(func);
+}
+
+static void nv50BlendColor(GLcontext *ctx, const GLfloat color[4])
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_BLEND_COLOR_R, 4);
+ OUT_RING_CACHEf(color[0]);
+ OUT_RING_CACHEf(color[1]);
+ OUT_RING_CACHEf(color[2]);
+ OUT_RING_CACHEf(color[3]);
+}
+
+static void nv50BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_BLEND_EQUATION_RGB, 1);
+ OUT_RING_CACHE(modeRGB);
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_BLEND_EQUATION_ALPHA, 1);
+ OUT_RING_CACHE(modeA);
+}
+
+
+static void nv50BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB,
+ GLenum sfactorA, GLenum dfactorA)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC_RGB, 2);
+ OUT_RING_CACHE(sfactorRGB); /* FIXME, sometimes has |0x4000 */
+ OUT_RING_CACHE(dfactorRGB); /* FIXME, sometimes has |0x4000 */
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC_ALPHA, 2);
+ OUT_RING_CACHE(sfactorA); /* FIXME, sometimes has |0x4000 */
+ OUT_RING_CACHE(dfactorA); /* FIXME, sometimes has |0x4000 */
+}
+
+static void nv50Clear(GLcontext *ctx, GLbitfield mask)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLuint hw_bufs = 0;
+
+ if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT))
+ hw_bufs |= 0x3c;
+ if (mask & (BUFFER_BIT_STENCIL))
+ hw_bufs |= 0x02;
+ if (mask & (BUFFER_BIT_DEPTH))
+ hw_bufs |= 0x01;
+
+ if (hw_bufs) {
+ BEGIN_RING_SIZE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CLEAR_BUFFERS, 1);
+ OUT_RING(hw_bufs);
+ }
+}
+
+static void nv50ClearColor(GLcontext *ctx, const GLfloat color[4])
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CLEAR_COLOR_R, 4);
+ OUT_RING_CACHEf(color[0]);
+ OUT_RING_CACHEf(color[1]);
+ OUT_RING_CACHEf(color[2]);
+ OUT_RING_CACHEf(color[3]);
+}
+
+static void nv50ClearDepth(GLcontext *ctx, GLclampd d)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CLEAR_DEPTH, 1);
+ OUT_RING_CACHEf(d);
+}
+
+/* we're don't support indexed buffers
+ void (*ClearIndex)(GLcontext *ctx, GLuint index)
+ */
+
+static void nv50ClearStencil(GLcontext *ctx, GLint s)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CLEAR_STENCIL, 1);
+ OUT_RING_CACHE(s);
+}
+
+static void nv50ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation)
+{
+ /* Only using shaders */
+}
+
+static void nv50ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask,
+ GLboolean bmask, GLboolean amask )
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ int i;
+
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_COLOR_MASK(0), 8);
+ for (i=0; i<8; i++) {
+ OUT_RING_CACHE(((amask && 0x01) << 12) | ((bmask && 0x01) << 8) | ((gmask && 0x01)<< 4) | ((rmask && 0x01) << 0));
+ }
+}
+
+static void nv50ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode)
+{
+ // TODO I need love
+}
+
+static void nv50CullFace(GLcontext *ctx, GLenum mode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CULL_FACE, 1);
+ OUT_RING_CACHE(mode);
+}
+
+static void nv50FrontFace(GLcontext *ctx, GLenum mode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_FRONT_FACE, 1);
+ OUT_RING_CACHE(mode);
+}
+
+static void nv50DepthFunc(GLcontext *ctx, GLenum func)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1);
+ OUT_RING_CACHE(func);
+}
+
+static void nv50DepthMask(GLcontext *ctx, GLboolean flag)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1);
+ OUT_RING_CACHE(flag);
+}
+
+static void nv50DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2);
+ OUT_RING_CACHEf(nearval);
+ OUT_RING_CACHEf(farval);
+}
+
+/** Specify the current buffer for writing */
+//void (*DrawBuffer)( GLcontext *ctx, GLenum buffer );
+/** Specify the buffers for writing for fragment programs*/
+//void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers );
+
+static void nv50Enable(GLcontext *ctx, GLenum cap, GLboolean state)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ switch(cap)
+ {
+ case GL_ALPHA_TEST:
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_AUTO_NORMAL:
+// case GL_BLEND:
+// case GL_CLIP_PLANE0:
+// case GL_CLIP_PLANE1:
+// case GL_CLIP_PLANE2:
+// case GL_CLIP_PLANE3:
+// case GL_CLIP_PLANE4:
+// case GL_CLIP_PLANE5:
+ case GL_COLOR_LOGIC_OP:
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LOGIC_OP_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_COLOR_MATERIAL:
+// case GL_COLOR_SUM_EXT:
+// case GL_COLOR_TABLE:
+// case GL_CONVOLUTION_1D:
+// case GL_CONVOLUTION_2D:
+ case GL_CULL_FACE:
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_DEPTH_TEST:
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_DITHER:
+// case GL_FOG:
+// case GL_HISTOGRAM:
+// case GL_INDEX_LOGIC_OP:
+// case GL_LIGHT0:
+// case GL_LIGHT1:
+// case GL_LIGHT2:
+// case GL_LIGHT3:
+// case GL_LIGHT4:
+// case GL_LIGHT5:
+// case GL_LIGHT6:
+// case GL_LIGHT7:
+// case GL_LIGHTING:
+ case GL_LINE_SMOOTH:
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_LINE_STIPPLE:
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LINE_STIPPLE_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_MAP1_COLOR_4:
+// case GL_MAP1_INDEX:
+// case GL_MAP1_NORMAL:
+// case GL_MAP1_TEXTURE_COORD_1:
+// case GL_MAP1_TEXTURE_COORD_2:
+// case GL_MAP1_TEXTURE_COORD_3:
+// case GL_MAP1_TEXTURE_COORD_4:
+// case GL_MAP1_VERTEX_3:
+// case GL_MAP1_VERTEX_4:
+// case GL_MAP2_COLOR_4:
+// case GL_MAP2_INDEX:
+// case GL_MAP2_NORMAL:
+// case GL_MAP2_TEXTURE_COORD_1:
+// case GL_MAP2_TEXTURE_COORD_2:
+// case GL_MAP2_TEXTURE_COORD_3:
+// case GL_MAP2_TEXTURE_COORD_4:
+// case GL_MAP2_VERTEX_3:
+// case GL_MAP2_VERTEX_4:
+// case GL_MINMAX:
+// case GL_NORMALIZE:
+// case GL_POINT_SMOOTH:
+ case GL_POLYGON_OFFSET_POINT:
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_POLYGON_OFFSET_LINE:
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_POLYGON_OFFSET_FILL:
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_POLYGON_SMOOTH:
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+ case GL_POLYGON_STIPPLE:
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_POST_COLOR_MATRIX_COLOR_TABLE:
+// case GL_POST_CONVOLUTION_COLOR_TABLE:
+// case GL_RESCALE_NORMAL:
+ case GL_SCISSOR_TEST:
+ /* No enable bit, nv50Scissor will adjust to max range */
+ ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
+ ctx->Scissor.Width, ctx->Scissor.Height);
+ break;
+// case GL_SEPARABLE_2D:
+ case GL_STENCIL_TEST:
+ // TODO BACK and FRONT ?
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ break;
+// case GL_TEXTURE_GEN_Q:
+// case GL_TEXTURE_GEN_R:
+// case GL_TEXTURE_GEN_S:
+// case GL_TEXTURE_GEN_T:
+// case GL_TEXTURE_1D:
+// case GL_TEXTURE_2D:
+// case GL_TEXTURE_3D:
+ }
+}
+
+static void nv50Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
+{
+ /* Only using shaders */
+}
+
+static void nv50Hint(GLcontext *ctx, GLenum target, GLenum mode)
+{
+ // TODO I need love (fog and line_smooth hints)
+}
+
+// void (*IndexMask)(GLcontext *ctx, GLuint mask);
+
+static void nv50Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params )
+{
+ /* Only with shaders */
+}
+
+/** Set the lighting model parameters */
+void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params);
+
+
+static void nv50LineStipple(GLcontext *ctx, GLint factor, GLushort pattern )
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN, 1);
+ OUT_RING_CACHE((pattern << 8) | factor);
+}
+
+static void nv50LineWidth(GLcontext *ctx, GLfloat width)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LINE_WIDTH, 1);
+ OUT_RING_CACHEf(width);
+}
+
+static void nv50LogicOpcode(GLcontext *ctx, GLenum opcode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LOGIC_OP_OP, 1);
+ OUT_RING_CACHE(opcode);
+}
+
+static void nv50PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
+{
+ /*TODO: not sure what goes here. */
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+}
+
+/** Specify the diameter of rasterized points */
+static void nv50PointSize(GLcontext *ctx, GLfloat size)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POINT_SIZE, 1);
+ OUT_RING_CACHEf(size);
+}
+
+/** Select a polygon rasterization mode */
+static void nv50PolygonMode(GLcontext *ctx, GLenum face, GLenum mode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 1);
+ OUT_RING_CACHE(mode);
+ }
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK, 1);
+ OUT_RING_CACHE(mode);
+ }
+}
+
+/** Set the scale and units used to calculate depth values */
+static void nv50PolygonOffset(GLcontext *ctx, GLfloat factor, GLfloat units)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR, 1);
+ OUT_RING_CACHEf(factor);
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_UNITS, 1);
+ OUT_RING_CACHEf(units);
+}
+
+/** Set the polygon stippling pattern */
+static void nv50PolygonStipple(GLcontext *ctx, const GLubyte *mask )
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(0), 32);
+ OUT_RING_CACHEp(mask, 32);
+}
+
+/* Specifies the current buffer for reading */
+void (*ReadBuffer)( GLcontext *ctx, GLenum buffer );
+/** Set rasterization mode */
+void (*RenderMode)(GLcontext *ctx, GLenum mode );
+
+/** Define the scissor box */
+static void nv50Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ /* There's no scissor enable bit, so adjust the scissor to cover the
+ * maximum draw buffer bounds
+ */
+ if (!ctx->Scissor.Enabled) {
+ x = y = 0;
+ w = h = 8191;
+ } else {
+ x += nmesa->drawX;
+ y += nmesa->drawY;
+ }
+
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS, 2);
+ OUT_RING_CACHE(((w) << 16) | x);
+ OUT_RING_CACHE(((h) << 16) | y);
+}
+
+/** Select flat or smooth shading */
+static void nv50ShadeModel(GLcontext *ctx, GLenum mode)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_SHADE_MODEL, 1);
+ OUT_RING_CACHE(mode);
+}
+
+/** OpenGL 2.0 two-sided StencilFunc */
+static void nv50StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func,
+ GLint ref, GLuint mask)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_FUNC, 1);
+ OUT_RING_CACHE(func);
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_REF, 1);
+ OUT_RING_CACHE(ref);
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_MASK, 1);
+ OUT_RING_CACHE(mask);
+ }
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_FUNC, 2);
+ OUT_RING_CACHE(func);
+ OUT_RING_CACHE(ref);
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_MASK, 1);
+ OUT_RING_CACHE(mask);
+ }
+}
+
+/** OpenGL 2.0 two-sided StencilMask */
+static void nv50StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_MASK, 1);
+ OUT_RING_CACHE(mask);
+ }
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_MASK, 1);
+ OUT_RING_CACHE(mask);
+ }
+}
+
+/** OpenGL 2.0 two-sided StencilOp */
+static void nv50StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail,
+ GLenum zfail, GLenum zpass)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_FAIL, 3);
+ OUT_RING_CACHE(fail);
+ OUT_RING_CACHE(zfail);
+ OUT_RING_CACHE(zpass);
+ }
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
+ BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_FAIL, 3);
+ OUT_RING_CACHE(fail);
+ OUT_RING_CACHE(zfail);
+ OUT_RING_CACHE(zpass);
+ }
+}
+
+/** Control the generation of texture coordinates */
+void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname,
+ const GLfloat *params);
+/** Set texture environment parameters */
+void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname,
+ const GLfloat *param);
+/** Set texture parameters */
+void (*TexParameter)(GLcontext *ctx, GLenum target,
+ struct gl_texture_object *texObj,
+ GLenum pname, const GLfloat *params);
+
+static void nv50TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat)
+{
+ /* Only with shaders */
+}
+
+static void nv50WindowMoved(nouveauContextPtr nmesa)
+{
+ GLcontext *ctx = nmesa->glCtx;
+ GLfloat *v = nmesa->viewport.m;
+ GLuint w = ctx->Viewport.Width;
+ GLuint h = ctx->Viewport.Height;
+ GLuint x = ctx->Viewport.X + nmesa->drawX;
+ GLuint y = ctx->Viewport.Y + nmesa->drawY;
+ int i;
+
+ BEGIN_RING_CACHE(NvSub3D,
+ NV50_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 2);
+ OUT_RING_CACHE((8191 << 16) | 0);
+ OUT_RING_CACHE((8191 << 16) | 0);
+ for (i=1; i<8; i++) {
+ BEGIN_RING_CACHE(NvSub3D,
+ NV50_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 2);
+ OUT_RING_CACHE(0);
+ OUT_RING_CACHE(0);
+ }
+
+ ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
+ ctx->Scissor.Width, ctx->Scissor.Height);
+}
+
+static GLboolean nv50InitCard(nouveauContextPtr nmesa)
+{
+ int i,j;
+
+ nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D);
+
+ BEGIN_RING_SIZE(NvSub3D, 0x1558, 1);
+ OUT_RING(1);
+
+ BEGIN_RING_SIZE(NvSub3D, NV50_TCL_PRIMITIVE_3D_SET_OBJECT_1(0), 8);
+ for (i=0; i<8; i++) {
+ OUT_RING(NvDmaFB);
+ }
+
+ BEGIN_RING_SIZE(NvSub3D, NV50_TCL_PRIMITIVE_3D_SET_OBJECT_0(0), 12);
+ for (i=0; i<12; i++) {
+ OUT_RING(NvDmaFB);
+ }
+
+ BEGIN_RING_SIZE(NvSub3D, 0x121c, 1);
+ OUT_RING(1);
+
+ for (i=0; i<8; i++) {
+ BEGIN_RING_SIZE(NvSub3D, 0x0200 + (i*0x20), 5);
+ for (j=0; j<5; j++) {
+ OUT_RING(0);
+ }
+ }
+
+ BEGIN_RING_SIZE(NvSub3D, 0x0fe0, 5);
+ OUT_RING(0);
+ OUT_RING(0);
+ OUT_RING(0x16);
+ OUT_RING(0);
+ OUT_RING(0);
+
+ return GL_FALSE;
+}
+
+static GLboolean nv50BindBuffers(nouveauContextPtr nmesa, int num_color,
+ nouveau_renderbuffer **color,
+ nouveau_renderbuffer *depth)
+{
+ return GL_FALSE;
+}
+
+void nv50InitStateFuncs(GLcontext *ctx, struct dd_function_table *func)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ func->AlphaFunc = nv50AlphaFunc;
+ func->BlendColor = nv50BlendColor;
+ func->BlendEquationSeparate = nv50BlendEquationSeparate;
+ func->BlendFuncSeparate = nv50BlendFuncSeparate;
+ func->Clear = nv50Clear;
+ func->ClearColor = nv50ClearColor;
+ func->ClearDepth = nv50ClearDepth;
+ func->ClearStencil = nv50ClearStencil;
+ func->ClipPlane = nv50ClipPlane;
+ func->ColorMask = nv50ColorMask;
+ func->ColorMaterial = nv50ColorMaterial;
+ func->CullFace = nv50CullFace;
+ func->FrontFace = nv50FrontFace;
+ func->DepthFunc = nv50DepthFunc;
+ func->DepthMask = nv50DepthMask;
+ func->DepthRange = nv50DepthRange;
+ func->Enable = nv50Enable;
+ func->Fogfv = nv50Fogfv;
+ func->Hint = nv50Hint;
+ func->Lightfv = nv50Lightfv;
+/* func->LightModelfv = nv50LightModelfv; */
+ func->LineStipple = nv50LineStipple;
+ func->LineWidth = nv50LineWidth;
+ func->LogicOpcode = nv50LogicOpcode;
+ func->PointParameterfv = nv50PointParameterfv;
+ func->PointSize = nv50PointSize;
+ func->PolygonMode = nv50PolygonMode;
+ func->PolygonOffset = nv50PolygonOffset;
+ func->PolygonStipple = nv50PolygonStipple;
+/* func->ReadBuffer = nv50ReadBuffer; */
+/* func->RenderMode = nv50RenderMode; */
+ func->Scissor = nv50Scissor;
+ func->ShadeModel = nv50ShadeModel;
+ func->StencilFuncSeparate = nv50StencilFuncSeparate;
+ func->StencilMaskSeparate = nv50StencilMaskSeparate;
+ func->StencilOpSeparate = nv50StencilOpSeparate;
+/* func->TexGen = nv50TexGen; */
+/* func->TexParameter = nv50TexParameter; */
+ func->TextureMatrix = nv50TextureMatrix;
+
+ nmesa->hw_func.InitCard = nv50InitCard;
+ nmesa->hw_func.BindBuffers = nv50BindBuffers;
+ nmesa->hw_func.WindowMoved = nv50WindowMoved;
+}
diff --git a/src/mesa/drivers/dri/r128/r128_context.c b/src/mesa/drivers/dri/r128/r128_context.c
index 8ec027542ad..89ddafa02a5 100644
--- a/src/mesa/drivers/dri/r128/r128_context.c
+++ b/src/mesa/drivers/dri/r128/r128_context.c
@@ -42,7 +42,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
@@ -235,7 +235,7 @@ GLboolean r128CreateContext( const __GLcontextModes *glVisual,
/* Initialize the software rasterizer and helper modules.
*/
_swrast_CreateContext( ctx );
- _ac_CreateContext( ctx );
+ _vbo_CreateContext( ctx );
_tnl_CreateContext( ctx );
_swsetup_CreateContext( ctx );
@@ -293,7 +293,7 @@ void r128DestroyContext( __DRIcontextPrivate *driContextPriv )
_swsetup_DestroyContext( rmesa->glCtx );
_tnl_DestroyContext( rmesa->glCtx );
- _ac_DestroyContext( rmesa->glCtx );
+ _vbo_DestroyContext( rmesa->glCtx );
_swrast_DestroyContext( rmesa->glCtx );
if ( release_texture_heaps ) {
diff --git a/src/mesa/drivers/dri/r128/r128_state.c b/src/mesa/drivers/dri/r128/r128_state.c
index 1bfd3709377..e476afa5d82 100644
--- a/src/mesa/drivers/dri/r128/r128_state.c
+++ b/src/mesa/drivers/dri/r128/r128_state.c
@@ -44,7 +44,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "enums.h"
#include "colormac.h"
#include "swrast/swrast.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "swrast_setup/swrast_setup.h"
@@ -1250,7 +1250,7 @@ static void r128DDInvalidateState( GLcontext *ctx, GLuint new_state )
{
_swrast_InvalidateState( ctx, new_state );
_swsetup_InvalidateState( ctx, new_state );
- _ac_InvalidateState( ctx, new_state );
+ _vbo_InvalidateState( ctx, new_state );
_tnl_InvalidateState( ctx, new_state );
R128_CONTEXT(ctx)->NewGLState |= new_state;
}
diff --git a/src/mesa/drivers/dri/r200/Makefile b/src/mesa/drivers/dri/r200/Makefile
index 75c09ff867e..e9144ac75ce 100644
--- a/src/mesa/drivers/dri/r200/Makefile
+++ b/src/mesa/drivers/dri/r200/Makefile
@@ -26,10 +26,6 @@ DRIVER_SOURCES = r200_context.c \
r200_span.c \
r200_maos.c \
r200_sanity.c \
- r200_vtxfmt.c \
- r200_vtxfmt_c.c \
- r200_vtxfmt_sse.c \
- r200_vtxfmt_x86.c \
r200_fragshader.c \
r200_vertprog.c \
radeon_screen.c \
@@ -37,7 +33,7 @@ DRIVER_SOURCES = r200_context.c \
C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES)
-X86_SOURCES = r200_vtxtmp_x86.S
+X86_SOURCES =
DRIVER_DEFINES = -DRADEON_COMMON=1 -DRADEON_COMMON_FOR_R200
diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c
index bb7a16c9327..fc6eb93daa8 100644
--- a/src/mesa/drivers/dri/r200/r200_context.c
+++ b/src/mesa/drivers/dri/r200/r200_context.c
@@ -45,7 +45,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
@@ -60,7 +60,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r200_tex.h"
#include "r200_swtcl.h"
#include "r200_tcl.h"
-#include "r200_vtxfmt.h"
#include "r200_maos.h"
#include "r200_vertprog.h"
@@ -415,7 +414,7 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
/* Initialize the software rasterizer and helper modules.
*/
_swrast_CreateContext( ctx );
- _ac_CreateContext( ctx );
+ _vbo_CreateContext( ctx );
_tnl_CreateContext( ctx );
_swsetup_CreateContext( ctx );
_ae_create_context( ctx );
@@ -424,11 +423,10 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
*/
_tnl_destroy_pipeline( ctx );
_tnl_install_pipeline( ctx, r200_pipeline );
- ctx->Driver.FlushVertices = r200FlushVertices;
/* Try and keep materials and vertices separate:
*/
- _tnl_isolate_materials( ctx, GL_TRUE );
+/* _tnl_isolate_materials( ctx, GL_TRUE ); */
/* Configure swrast and TNL to match hardware characteristics:
@@ -533,12 +531,6 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
TCL_FALLBACK(rmesa->glCtx, R200_TCL_FALLBACK_TCL_DISABLE, 1);
}
- if (rmesa->r200Screen->chip_flags & RADEON_CHIPSET_TCL) {
- if (tcl_mode >= DRI_CONF_TCL_VTXFMT)
- r200VtxfmtInit( ctx, tcl_mode >= DRI_CONF_TCL_CODEGEN );
-
- _tnl_need_dlist_norm_lengths( ctx, GL_FALSE );
- }
return GL_TRUE;
}
@@ -568,7 +560,7 @@ void r200DestroyContext( __DRIcontextPrivate *driContextPriv )
release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1);
_swsetup_DestroyContext( rmesa->glCtx );
_tnl_DestroyContext( rmesa->glCtx );
- _ac_DestroyContext( rmesa->glCtx );
+ _vbo_DestroyContext( rmesa->glCtx );
_swrast_DestroyContext( rmesa->glCtx );
r200DestroySwtcl( rmesa->glCtx );
@@ -579,12 +571,6 @@ void r200DestroyContext( __DRIcontextPrivate *driContextPriv )
r200FlushCmdBuf( rmesa, __FUNCTION__ );
}
- if (!(rmesa->TclFallback & R200_TCL_FALLBACK_TCL_DISABLE)) {
- int tcl_mode = driQueryOptioni(&rmesa->optionCache, "tcl_mode");
- if (tcl_mode >= DRI_CONF_TCL_VTXFMT)
- r200VtxfmtDestroy( rmesa->glCtx );
- }
-
if (rmesa->state.scissor.pClipRects) {
FREE(rmesa->state.scissor.pClipRects);
rmesa->state.scissor.pClipRects = NULL;
@@ -700,9 +686,6 @@ r200MakeCurrent( __DRIcontextPrivate *driContextPriv,
(GLframebuffer *) driDrawPriv->driverPrivate,
(GLframebuffer *) driReadPriv->driverPrivate );
- if (newCtx->vb.enabled)
- r200VtxfmtMakeCurrent( newCtx->glCtx );
-
_mesa_update_state( newCtx->glCtx );
r200ValidateState( newCtx->glCtx );
@@ -727,6 +710,5 @@ r200UnbindContext( __DRIcontextPrivate *driContextPriv )
if (R200_DEBUG & DEBUG_DRI)
fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *)rmesa->glCtx);
- r200VtxfmtUnbindContext( rmesa->glCtx );
return GL_TRUE;
}
diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h
index fa38a78e263..e840a502c0b 100644
--- a/src/mesa/drivers/dri/r200/r200_context.h
+++ b/src/mesa/drivers/dri/r200/r200_context.h
@@ -107,8 +107,7 @@ struct r200_vertex_program {
VERTEX_SHADER_INSTRUCTION instr[R200_VSF_MAX_INST + 6];
int pos_end;
int inputs[VERT_ATTRIB_MAX];
- int rev_inputs[16];
- int gen_inputs_mapped;
+ GLubyte inputmap_rev[16];
int native;
int fogpidx;
int fogmode;
@@ -724,8 +723,6 @@ struct r200_store {
/* r200_tcl.c
*/
struct r200_tcl_info {
- GLuint vertex_format;
- GLint last_offset;
GLuint hw_primitive;
/* hw can handle 12 components max */
@@ -735,13 +732,7 @@ struct r200_tcl_info {
GLuint *Elts;
struct r200_dma_region indexed_verts;
- struct r200_dma_region obj;
- struct r200_dma_region rgba;
- struct r200_dma_region spec;
- struct r200_dma_region fog;
- struct r200_dma_region tex[R200_MAX_TEXTURE_UNITS];
- struct r200_dma_region norm;
- struct r200_dma_region generic[16];
+ struct r200_dma_region vertex_data[15];
};
@@ -811,87 +802,6 @@ struct r200_ioctl {
#define R200_MAX_PRIMS 64
-/* Want to keep a cache of these around. Each is parameterized by
- * only a single value which has only a small range. Only expect a
- * few, so just rescan the list each time?
- */
-struct dynfn {
- struct dynfn *next, *prev;
- int key[2];
- char *code;
-};
-
-struct dfn_lists {
- struct dynfn Vertex2f;
- struct dynfn Vertex2fv;
- struct dynfn Vertex3f;
- struct dynfn Vertex3fv;
- struct dynfn Color4ub;
- struct dynfn Color4ubv;
- struct dynfn Color3ub;
- struct dynfn Color3ubv;
- struct dynfn Color4f;
- struct dynfn Color4fv;
- struct dynfn Color3f;
- struct dynfn Color3fv;
- struct dynfn SecondaryColor3ubEXT;
- struct dynfn SecondaryColor3ubvEXT;
- struct dynfn SecondaryColor3fEXT;
- struct dynfn SecondaryColor3fvEXT;
- struct dynfn Normal3f;
- struct dynfn Normal3fv;
- struct dynfn TexCoord3f;
- struct dynfn TexCoord3fv;
- struct dynfn TexCoord2f;
- struct dynfn TexCoord2fv;
- struct dynfn TexCoord1f;
- struct dynfn TexCoord1fv;
- struct dynfn MultiTexCoord3fARB;
- struct dynfn MultiTexCoord3fvARB;
- struct dynfn MultiTexCoord2fARB;
- struct dynfn MultiTexCoord2fvARB;
- struct dynfn MultiTexCoord1fARB;
- struct dynfn MultiTexCoord1fvARB;
- struct dynfn FogCoordfEXT;
- struct dynfn FogCoordfvEXT;
-};
-
-struct dfn_generators {
- struct dynfn *(*Vertex2f)( GLcontext *, const int * );
- struct dynfn *(*Vertex2fv)( GLcontext *, const int * );
- struct dynfn *(*Vertex3f)( GLcontext *, const int * );
- struct dynfn *(*Vertex3fv)( GLcontext *, const int * );
- struct dynfn *(*Color4ub)( GLcontext *, const int * );
- struct dynfn *(*Color4ubv)( GLcontext *, const int * );
- struct dynfn *(*Color3ub)( GLcontext *, const int * );
- struct dynfn *(*Color3ubv)( GLcontext *, const int * );
- struct dynfn *(*Color4f)( GLcontext *, const int * );
- struct dynfn *(*Color4fv)( GLcontext *, const int * );
- struct dynfn *(*Color3f)( GLcontext *, const int * );
- struct dynfn *(*Color3fv)( GLcontext *, const int * );
- struct dynfn *(*SecondaryColor3ubEXT)( GLcontext *, const int * );
- struct dynfn *(*SecondaryColor3ubvEXT)( GLcontext *, const int * );
- struct dynfn *(*SecondaryColor3fEXT)( GLcontext *, const int * );
- struct dynfn *(*SecondaryColor3fvEXT)( GLcontext *, const int * );
- struct dynfn *(*Normal3f)( GLcontext *, const int * );
- struct dynfn *(*Normal3fv)( GLcontext *, const int * );
- struct dynfn *(*TexCoord3f)( GLcontext *, const int * );
- struct dynfn *(*TexCoord3fv)( GLcontext *, const int * );
- struct dynfn *(*TexCoord2f)( GLcontext *, const int * );
- struct dynfn *(*TexCoord2fv)( GLcontext *, const int * );
- struct dynfn *(*TexCoord1f)( GLcontext *, const int * );
- struct dynfn *(*TexCoord1fv)( GLcontext *, const int * );
- struct dynfn *(*MultiTexCoord3fARB)( GLcontext *, const int * );
- struct dynfn *(*MultiTexCoord3fvARB)( GLcontext *, const int * );
- struct dynfn *(*MultiTexCoord2fARB)( GLcontext *, const int * );
- struct dynfn *(*MultiTexCoord2fvARB)( GLcontext *, const int * );
- struct dynfn *(*MultiTexCoord1fARB)( GLcontext *, const int * );
- struct dynfn *(*MultiTexCoord1fvARB)( GLcontext *, const int * );
- struct dynfn *(*FogCoordfEXT)( GLcontext *, const int * );
- struct dynfn *(*FogCoordfvEXT)( GLcontext *, const int * );
-};
-
-
struct r200_prim {
GLuint start;
@@ -912,43 +822,6 @@ struct r200_prim {
#define R200_MAX_VERTEX_SIZE ((3*6)+11)
-struct r200_vbinfo {
- GLint counter, initial_counter;
- GLint *dmaptr;
- void (*notify)( void );
- GLint vertex_size;
-
- union { float f; int i; r200_color_t color; } vertex[R200_MAX_VERTEX_SIZE];
-
- GLfloat *normalptr;
- GLfloat *floatcolorptr;
- GLfloat *fogptr;
- r200_color_t *colorptr;
- GLfloat *floatspecptr;
- r200_color_t *specptr;
- GLfloat *texcoordptr[8]; /* 6 (TMU) + 2 for r200_vtxfmt_c.c when GL_TEXTURE6/7 */
-
-
- GLenum *prim; /* &ctx->Driver.CurrentExecPrimitive */
- GLuint primflags;
- GLboolean enabled; /* *_NO_VTXFMT / *_NO_TCL env vars */
- GLboolean installed;
- GLboolean fell_back;
- GLboolean recheck;
- GLint nrverts;
- GLuint vtxfmt_0, vtxfmt_1;
-
- GLuint installed_vertex_format;
- GLuint installed_color_3f_sz;
-
- struct r200_prim primlist[R200_MAX_PRIMS];
- int nrprims;
-
- struct dfn_lists dfn_cache;
- struct dfn_generators codegen;
- GLvertexformat vtxfmt;
-};
-
struct r200_context {
GLcontext *glCtx; /* Mesa context */
@@ -1040,10 +913,6 @@ struct r200_context {
*/
struct r200_swtcl_info swtcl;
- /* r200_vtxfmt.c
- */
- struct r200_vbinfo vb;
-
/* Mirrors of some DRI state
*/
struct r200_dri_mirror dri;
diff --git a/src/mesa/drivers/dri/r200/r200_maos.h b/src/mesa/drivers/dri/r200/r200_maos.h
index b9e4d3c2392..4998f67445c 100644
--- a/src/mesa/drivers/dri/r200/r200_maos.h
+++ b/src/mesa/drivers/dri/r200/r200_maos.h
@@ -38,7 +38,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r200_context.h"
-extern void r200EmitArrays( GLcontext *ctx, GLuint inputs );
+extern void r200EmitArrays( GLcontext *ctx, GLubyte *vimap_rev );
extern void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs );
#endif
diff --git a/src/mesa/drivers/dri/r200/r200_maos_arrays.c b/src/mesa/drivers/dri/r200/r200_maos_arrays.c
index 39c1f68911f..6a6c30a2b0d 100644
--- a/src/mesa/drivers/dri/r200/r200_maos_arrays.c
+++ b/src/mesa/drivers/dri/r200/r200_maos_arrays.c
@@ -376,7 +376,7 @@ static void emit_vector( GLcontext *ctx,
/* Emit any changed arrays to new GART memory, re-emit a packet to
* update the arrays.
*/
-void r200EmitArrays( GLcontext *ctx, GLuint inputs )
+void r200EmitArrays( GLcontext *ctx, GLubyte *vimap_rev )
{
r200ContextPtr rmesa = R200_CONTEXT( ctx );
struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
@@ -384,318 +384,130 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs )
GLuint nr = 0;
GLuint vfmt0 = 0, vfmt1 = 0;
GLuint count = VB->Count;
- GLuint i;
- GLuint generic_in_mapped = 0;
- struct r200_vertex_program *vp = NULL;
-
- /* this looks way more complicated than necessary... */
- if (ctx->VertexProgram._Enabled) {
- vp = rmesa->curr_vp_hw;
- generic_in_mapped = vp->gen_inputs_mapped;
- }
-
- if (inputs & VERT_BIT_POS) {
- if (!rmesa->tcl.obj.buf)
- emit_vector( ctx,
- &rmesa->tcl.obj,
- (char *)VB->ObjPtr->data,
- VB->ObjPtr->size,
- VB->ObjPtr->stride,
- count);
-
- switch( VB->ObjPtr->size ) {
- case 4: vfmt0 |= R200_VTX_W0;
- case 3: vfmt0 |= R200_VTX_Z0;
- case 2:
- default:
- break;
- }
- component[nr++] = &rmesa->tcl.obj;
- }
- else if (generic_in_mapped & (1 << 0)) {
- int geninput = vp->rev_inputs[0] - VERT_ATTRIB_GENERIC0;
- if (!rmesa->tcl.generic[geninput].buf) {
- emit_vector( ctx,
- &(rmesa->tcl.generic[geninput]),
- (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data,
- 4,
- VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride,
- count );
- }
- component[nr++] = &rmesa->tcl.generic[geninput];
- vfmt0 |= R200_VTX_W0 | R200_VTX_Z0;
- }
-
- if (inputs & VERT_BIT_NORMAL) {
- if (!rmesa->tcl.norm.buf)
- emit_vector( ctx,
- &(rmesa->tcl.norm),
- (char *)VB->NormalPtr->data,
- 3,
- VB->NormalPtr->stride,
- count);
-
- vfmt0 |= R200_VTX_N0;
- component[nr++] = &rmesa->tcl.norm;
- }
-
- if (inputs & VERT_BIT_FOG) {
- if (!rmesa->tcl.fog.buf) {
- if (ctx->VertexProgram._Enabled)
- emit_vector( ctx,
- &(rmesa->tcl.fog),
- (char *)VB->FogCoordPtr->data,
+ GLuint i, emitsize;
+
+ for ( i = 0; i < 15; i++ ) {
+ GLubyte attrib = vimap_rev[i];
+ if (attrib != 255) {
+ switch (i) {
+ case 0:
+ emitsize = (VB->AttribPtr[attrib]->size);
+ switch (emitsize) {
+ case 4:
+ vfmt0 |= R200_VTX_W0;
+ /* fallthrough */
+ case 3:
+ vfmt0 |= R200_VTX_Z0;
+ break;
+ case 2:
+ break;
+ default: assert(0);
+ }
+ break;
+ case 1:
+ assert(attrib == VERT_ATTRIB_WEIGHT);
+ emitsize = (VB->AttribPtr[attrib]->size);
+ vfmt0 |= emitsize << R200_VTX_WEIGHT_COUNT_SHIFT;
+ break;
+ case 2:
+ assert(attrib == VERT_ATTRIB_NORMAL);
+ emitsize = 3;
+ vfmt0 |= R200_VTX_N0;
+ break;
+ case 3:
+ /* special handling to fix up fog. Will get us into trouble with vbos...*/
+ assert(attrib == VERT_ATTRIB_FOG);
+ if (!rmesa->tcl.vertex_data[i].buf) {
+ if (ctx->VertexProgram._Enabled)
+ emit_vector( ctx,
+ &(rmesa->tcl.vertex_data[attrib]),
+ (char *)VB->AttribPtr[attrib]->data,
1,
- VB->FogCoordPtr->stride,
+ VB->AttribPtr[attrib]->stride,
count);
- else
- emit_vecfog( ctx,
- &(rmesa->tcl.fog),
- (char *)VB->FogCoordPtr->data,
- VB->FogCoordPtr->stride,
+ else
+ emit_vecfog( ctx,
+ &(rmesa->tcl.vertex_data[attrib]),
+ (char *)VB->AttribPtr[attrib]->data,
+ VB->AttribPtr[attrib]->stride,
count);
- }
-
- vfmt0 |= R200_VTX_DISCRETE_FOG;
- component[nr++] = &rmesa->tcl.fog;
- }
-
- if (inputs & VERT_BIT_COLOR0) {
- int emitsize;
-
- if (VB->ColorPtr[0]->size == 4 &&
- (VB->ColorPtr[0]->stride != 0 ||
- VB->ColorPtr[0]->data[0][3] != 1.0)) {
- vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT;
- emitsize = 4;
- }
- else {
- vfmt0 |= R200_VTX_FP_RGB << R200_VTX_COLOR_0_SHIFT;
- emitsize = 3;
- }
-
- if (!rmesa->tcl.rgba.buf)
- emit_vector( ctx,
- &(rmesa->tcl.rgba),
- (char *)VB->ColorPtr[0]->data,
- emitsize,
- VB->ColorPtr[0]->stride,
- count);
-
- component[nr++] = &rmesa->tcl.rgba;
- }
-/* vfmt0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT;
- emit_ubyte_rgba( ctx, &rmesa->tcl.rgba,
- (char *)VB->ColorPtr[0]->data, 4,
- VB->ColorPtr[0]->stride, count);*/
- else if (generic_in_mapped & (1 << 2)) {
- int geninput = vp->rev_inputs[2] - VERT_ATTRIB_GENERIC0;
- if (!rmesa->tcl.generic[geninput].buf) {
- emit_vector( ctx,
- &(rmesa->tcl.generic[geninput]),
- (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data,
- 4,
- VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride,
- count );
- }
- component[nr++] = &rmesa->tcl.generic[geninput];
- vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT;
- }
-
-
- if (inputs & VERT_BIT_COLOR1) {
- if (!rmesa->tcl.spec.buf) {
- emit_vector( ctx,
- &rmesa->tcl.spec,
- (char *)VB->SecondaryColorPtr[0]->data,
- 3,
- VB->SecondaryColorPtr[0]->stride,
- count);
- }
-
- /* How does this work?
- */
- vfmt0 |= R200_VTX_FP_RGB << R200_VTX_COLOR_1_SHIFT;
- component[nr++] = &rmesa->tcl.spec;
- }
- else if (generic_in_mapped & (1 << 3)) {
- int geninput = vp->rev_inputs[3] - VERT_ATTRIB_GENERIC0;
- if (!rmesa->tcl.generic[geninput].buf) {
- emit_vector( ctx,
- &(rmesa->tcl.generic[geninput]),
- (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data,
- 4,
- VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride,
- count );
- }
- component[nr++] = &rmesa->tcl.generic[geninput];
- vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT;
- }
-
- if (generic_in_mapped & (1 << 4)) {
- int geninput = vp->rev_inputs[4] - VERT_ATTRIB_GENERIC0;
- if (!rmesa->tcl.generic[geninput].buf) {
- emit_vector( ctx,
- &(rmesa->tcl.generic[geninput]),
- (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data,
- 4,
- VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride,
- count );
- }
- component[nr++] = &rmesa->tcl.generic[geninput];
- vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_2_SHIFT;
- }
-
- if (generic_in_mapped & (1 << 5)) {
- int geninput = vp->rev_inputs[5] - VERT_ATTRIB_GENERIC0;
- if (!rmesa->tcl.generic[geninput].buf) {
- emit_vector( ctx,
- &(rmesa->tcl.generic[geninput]),
- (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data,
- 4,
- VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride,
- count );
- }
- component[nr++] = &rmesa->tcl.generic[geninput];
- vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_3_SHIFT;
- }
-
- for ( i = 0 ; i < 6 ; i++ ) {
- if (inputs & (VERT_BIT_TEX0 << i)) {
- if (!rmesa->tcl.tex[i].buf)
- emit_vector( ctx,
- &(rmesa->tcl.tex[i]),
- (char *)VB->TexCoordPtr[i]->data,
- VB->TexCoordPtr[i]->size,
- VB->TexCoordPtr[i]->stride,
- count );
-
- vfmt1 |= VB->TexCoordPtr[i]->size << (i * 3);
- component[nr++] = &rmesa->tcl.tex[i];
- }
- else if (generic_in_mapped & (1 << (i + 6))) {
- int geninput = vp->rev_inputs[i + 6] - VERT_ATTRIB_GENERIC0;
- if (!rmesa->tcl.generic[geninput].buf) {
- emit_vector( ctx,
- &(rmesa->tcl.generic[geninput]),
- (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data,
- 4,
- VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride,
- count );
- }
- component[nr++] = &rmesa->tcl.generic[geninput];
- vfmt1 |= 4 << (R200_VTX_TEX0_COMP_CNT_SHIFT + (i * 3));
- }
- }
-
- if (generic_in_mapped & (1 << 13)) {
- int geninput = vp->rev_inputs[13] - VERT_ATTRIB_GENERIC0;
- if (!rmesa->tcl.generic[geninput].buf) {
- emit_vector( ctx,
- &(rmesa->tcl.generic[geninput]),
- (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data,
- 4,
- VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride,
- count );
- }
- component[nr++] = &rmesa->tcl.generic[geninput];
- vfmt0 |= R200_VTX_XY1 | R200_VTX_Z1 | R200_VTX_W1;
- }
-
-/* doesn't work. Wrong order with mixed generic & conventional! */
-/*
- if (ctx->VertexProgram._Enabled) {
- int *vp_inputs = rmesa->curr_vp_hw->inputs;
- for ( i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++ ) {
- if (inputs & (1 << i)) {
- int geninput = i - VERT_ATTRIB_GENERIC0;
- if (!rmesa->tcl.generic[geninput].buf) {
- emit_vector( ctx,
- &(rmesa->tcl.generic[geninput]),
- (char *)VB->AttribPtr[i]->data,
- 4,
- VB->AttribPtr[i]->stride,
- count );
}
- component[nr++] = &rmesa->tcl.generic[geninput];
- switch (vp_inputs[i]) {
- case 0:
- vfmt0 |= R200_VTX_W0 | R200_VTX_Z0;
- break;
+ vfmt0 |= R200_VTX_DISCRETE_FOG;
+ goto after_emit;
+ break;
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ if (VB->AttribPtr[attrib]->size == 4 &&
+ (VB->AttribPtr[attrib]->stride != 0 ||
+ VB->AttribPtr[attrib]->data[0][3] != 1.0)) emitsize = 4;
+ else emitsize = 3;
+ if (emitsize == 4)
+ vfmt0 |= R200_VTX_FP_RGBA << (R200_VTX_COLOR_0_SHIFT + (i - 4) * 2);
+ else {
+ vfmt0 |= R200_VTX_FP_RGB << (R200_VTX_COLOR_0_SHIFT + (i - 4) * 2);
+ }
+ break;
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ emitsize = VB->AttribPtr[attrib]->size;
+ vfmt1 |= emitsize << (R200_VTX_TEX0_COMP_CNT_SHIFT + (i - 8) * 3);
+ break;
+ case 14:
+ emitsize = VB->AttribPtr[attrib]->size >= 2 ? VB->AttribPtr[attrib]->size : 2;
+ switch (emitsize) {
case 2:
+ vfmt0 |= R200_VTX_XY1;
+ /* fallthrough */
case 3:
+ vfmt0 |= R200_VTX_Z1;
+ /* fallthrough */
case 4:
- case 5:
- vfmt0 |= R200_VTX_FP_RGBA << (R200_VTX_COLOR_0_SHIFT + (vp_inputs[i] - 2) * 2);
- break;
- case 6:
- case 7:
- case 8:
- case 9:
- case 10:
- case 11:
- vfmt1 |= 4 << (R200_VTX_TEX0_COMP_CNT_SHIFT + (vp_inputs[i] - 6) * 3);
- break;
- case 13:
- vfmt0 |= R200_VTX_XY1 | R200_VTX_Z1 | R200_VTX_W1;
- break;
- case 1:
- case 12:
- default:
- assert(0);
+ vfmt0 |= R200_VTX_W1;
+ break;
}
+ default:
+ assert(0);
+ }
+ if (!rmesa->tcl.vertex_data[i].buf) {
+ emit_vector( ctx,
+ &(rmesa->tcl.vertex_data[i]),
+ (char *)VB->AttribPtr[attrib]->data,
+ emitsize,
+ VB->AttribPtr[attrib]->stride,
+ count );
}
+after_emit:
+ assert(nr < 12);
+ component[nr++] = &rmesa->tcl.vertex_data[i];
}
}
-*/
if (vfmt0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] ||
- vfmt1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) {
- R200_STATECHANGE( rmesa, vtx );
+ vfmt1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) {
+ R200_STATECHANGE( rmesa, vtx );
rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = vfmt0;
rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = vfmt1;
- }
+ }
rmesa->tcl.nr_aos_components = nr;
- rmesa->tcl.vertex_format = vfmt0;
}
void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs )
{
- GLuint unit;
r200ContextPtr rmesa = R200_CONTEXT( ctx );
-/* if (R200_DEBUG & DEBUG_VERTS) */
-/* _tnl_print_vert_flags( __FUNCTION__, newinputs ); */
-
- if (newinputs & VERT_BIT_POS)
- r200ReleaseDmaRegion( rmesa, &rmesa->tcl.obj, __FUNCTION__ );
-
- if (newinputs & VERT_BIT_NORMAL)
- r200ReleaseDmaRegion( rmesa, &rmesa->tcl.norm, __FUNCTION__ );
-
- if (newinputs & VERT_BIT_FOG)
- r200ReleaseDmaRegion( rmesa, &rmesa->tcl.fog, __FUNCTION__ );
-
- if (newinputs & VERT_BIT_COLOR0)
- r200ReleaseDmaRegion( rmesa, &rmesa->tcl.rgba, __FUNCTION__ );
-
- if (newinputs & VERT_BIT_COLOR1)
- r200ReleaseDmaRegion( rmesa, &rmesa->tcl.spec, __FUNCTION__ );
-
- for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
- if (newinputs & VERT_BIT_TEX(unit))
- r200ReleaseDmaRegion( rmesa, &rmesa->tcl.tex[unit], __FUNCTION__ );
- }
-
- if (ctx->VertexProgram._Enabled) {
- int i;
- for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) {
- if (newinputs & (1 << i))
- r200ReleaseDmaRegion( rmesa,
- &rmesa->tcl.generic[i - VERT_ATTRIB_GENERIC0], __FUNCTION__ );
- }
+ /* only do it for changed inputs ? */
+ int i;
+ for (i = 0; i < 15; i++) {
+ if (newinputs & (1 << i))
+ r200ReleaseDmaRegion( rmesa,
+ &rmesa->tcl.vertex_data[i], __FUNCTION__ );
}
-
}
diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c
index dc1fbef72ee..bdb487f2b93 100644
--- a/src/mesa/drivers/dri/r200/r200_state.c
+++ b/src/mesa/drivers/dri/r200/r200_state.c
@@ -43,7 +43,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "framebuffer.h"
#include "swrast/swrast.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
#include "swrast_setup/swrast_setup.h"
@@ -54,7 +54,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r200_tcl.h"
#include "r200_tex.h"
#include "r200_swtcl.h"
-#include "r200_vtxfmt.h"
#include "r200_vertprog.h"
#include "drirenderbuffer.h"
@@ -2536,23 +2535,24 @@ static void r200InvalidateState( GLcontext *ctx, GLuint new_state )
{
_swrast_InvalidateState( ctx, new_state );
_swsetup_InvalidateState( ctx, new_state );
- _ac_InvalidateState( ctx, new_state );
+ _vbo_InvalidateState( ctx, new_state );
_tnl_InvalidateState( ctx, new_state );
_ae_invalidate_state( ctx, new_state );
R200_CONTEXT(ctx)->NewGLState |= new_state;
- r200VtxfmtInvalidate( ctx );
}
/* A hack. The r200 can actually cope just fine with materials
- * between begin/ends, so fix this. But how ?
+ * between begin/ends, so fix this.
+ * Should map to inputs just like the generic vertex arrays for vertex progs.
+ * In theory there could still be too many and we'd still need a fallback.
*/
static GLboolean check_material( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLint i;
- for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT;
- i < _TNL_ATTRIB_MAT_BACK_INDEXES;
+ for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT;
+ i < _TNL_ATTRIB_MAT_BACK_INDEXES;
i++)
if (tnl->vb.AttribPtr[i] &&
tnl->vb.AttribPtr[i]->stride)
@@ -2560,7 +2560,7 @@ static GLboolean check_material( GLcontext *ctx )
return GL_FALSE;
}
-
+
static void r200WrapRunPipeline( GLcontext *ctx )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
@@ -2574,7 +2574,7 @@ static void r200WrapRunPipeline( GLcontext *ctx )
if (rmesa->NewGLState)
r200ValidateState( ctx );
- has_material = (ctx->Light.Enabled && check_material( ctx ));
+ has_material = !ctx->VertexProgram._Enabled && ctx->Light.Enabled && check_material( ctx );
if (has_material) {
TCL_FALLBACK( ctx, R200_TCL_FALLBACK_MATERIAL, GL_TRUE );
diff --git a/src/mesa/drivers/dri/r200/r200_state_init.c b/src/mesa/drivers/dri/r200/r200_state_init.c
index d95a80c7bbc..b40d0bdcb7c 100644
--- a/src/mesa/drivers/dri/r200/r200_state_init.c
+++ b/src/mesa/drivers/dri/r200/r200_state_init.c
@@ -39,7 +39,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "api_arrayelt.h"
#include "swrast/swrast.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
#include "swrast_setup/swrast_setup.h"
@@ -50,7 +50,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r200_tcl.h"
#include "r200_tex.h"
#include "r200_swtcl.h"
-#include "r200_vtxfmt.h"
#include "xmlpool.h"
diff --git a/src/mesa/drivers/dri/r200/r200_swtcl.c b/src/mesa/drivers/dri/r200/r200_swtcl.c
index c14a275f7a3..25d229d8ed6 100644
--- a/src/mesa/drivers/dri/r200/r200_swtcl.c
+++ b/src/mesa/drivers/dri/r200/r200_swtcl.c
@@ -48,7 +48,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "tnl/tnl.h"
#include "tnl/t_context.h"
#include "tnl/t_pipeline.h"
-#include "tnl/t_vtx_api.h"
#include "r200_context.h"
#include "r200_ioctl.h"
@@ -936,13 +935,6 @@ r200PointsBitmap( GLcontext *ctx, GLint px, GLint py,
}
-void r200FlushVertices( GLcontext *ctx, GLuint flags )
-{
- _tnl_FlushVertices( ctx, flags );
-
- if (flags & FLUSH_STORED_VERTICES)
- R200_NEWPRIM( R200_CONTEXT( ctx ) );
-}
/**********************************************************************/
/* Initialization. */
diff --git a/src/mesa/drivers/dri/r200/r200_swtcl.h b/src/mesa/drivers/dri/r200/r200_swtcl.h
index ce2b6b5f06b..ccf817988c5 100644
--- a/src/mesa/drivers/dri/r200/r200_swtcl.h
+++ b/src/mesa/drivers/dri/r200/r200_swtcl.h
@@ -42,7 +42,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
extern void r200InitSwtcl( GLcontext *ctx );
extern void r200DestroySwtcl( GLcontext *ctx );
-extern void r200FlushVertices( GLcontext *ctx, GLuint flags );
extern void r200ChooseRenderState( GLcontext *ctx );
extern void r200ChooseVertexState( GLcontext *ctx );
diff --git a/src/mesa/drivers/dri/r200/r200_tcl.c b/src/mesa/drivers/dri/r200/r200_tcl.c
index 86edf7132ce..e0c32b26d92 100644
--- a/src/mesa/drivers/dri/r200/r200_tcl.c
+++ b/src/mesa/drivers/dri/r200/r200_tcl.c
@@ -40,7 +40,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "colormac.h"
#include "light.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
@@ -384,8 +384,14 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx,
r200ContextPtr rmesa = R200_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
- GLuint inputs = 0;
GLuint i;
+ GLubyte *vimap_rev;
+/* use hw fixed order for simplicity, pos 0, weight 1, normal 2, fog 3,
+ color0 - color3 4-7, texcoord0 - texcoord5 8-13, pos 1 14. Must not use
+ more than 12 of those at the same time. */
+ GLubyte map_rev_fixed[15] = {255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255};
+
/* TODO: separate this from the swtnl pipeline
*/
@@ -404,30 +410,40 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx,
r200ValidateState( ctx );
if (!ctx->VertexProgram._Enabled) {
- inputs = VERT_BIT_POS | VERT_BIT_COLOR0;
/* NOTE: inputs != tnl->render_inputs - these are the untransformed
* inputs.
*/
+ map_rev_fixed[0] = VERT_ATTRIB_POS;
+ /* technically there is no reason we always need VA_COLOR0. In theory
+ could disable it depending on lighting, color materials, texturing... */
+ map_rev_fixed[4] = VERT_ATTRIB_COLOR0;
+
if (ctx->Light.Enabled) {
- inputs |= VERT_BIT_NORMAL;
+ map_rev_fixed[2] = VERT_ATTRIB_NORMAL;
}
+ /* this also enables VA_COLOR1 when using separate specular
+ lighting model, which is unnecessary.
+ FIXME: OTOH, we're missing the case where a ATI_fragment_shader accesses
+ the secondary color (if lighting is disabled). The chip seems
+ misconfigured for that though elsewhere (tcl output, might lock up) */
if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
- inputs |= VERT_BIT_COLOR1;
+ map_rev_fixed[5] = VERT_ATTRIB_COLOR1;
}
if ( (ctx->Fog.FogCoordinateSource == GL_FOG_COORD) && ctx->Fog.Enabled ) {
- inputs |= VERT_BIT_FOG;
+ map_rev_fixed[3] = VERT_ATTRIB_FOG;
}
for (i = 0 ; i < ctx->Const.MaxTextureUnits; i++) {
if (ctx->Texture.Unit[i]._ReallyEnabled) {
if (rmesa->TexGenNeedNormals[i]) {
- inputs |= VERT_BIT_NORMAL;
+ map_rev_fixed[2] = VERT_ATTRIB_NORMAL;
}
- inputs |= VERT_BIT_TEX(i);
+ map_rev_fixed[8 + i] = VERT_ATTRIB_TEX0 + i;
}
}
+ vimap_rev = &map_rev_fixed[0];
}
else {
/* vtx_tcl_output_vtxfmt_0/1 need to match configuration of "fragment
@@ -437,14 +453,8 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx,
We only need to change compsel. */
GLuint out_compsel = 0;
GLuint vp_out = rmesa->curr_vp_hw->mesa_program.Base.OutputsWritten;
-#if 0
- /* can't handle other inputs, generic attribs etc. currently - should never arrive here */
- assert ((rmesa->curr_vp_hw->mesa_program.Base.InputsRead &
- ~(VERT_BIT_POS | VERT_BIT_NORMAL | VERT_BIT_COLOR0 | VERT_BIT_COLOR1 |
- VERT_BIT_FOG | VERT_BIT_TEX0 | VERT_BIT_TEX1 | VERT_BIT_TEX2 |
- VERT_BIT_TEX3 | VERT_BIT_TEX4 | VERT_BIT_TEX5)) == 0);
-#endif
- inputs |= rmesa->curr_vp_hw->mesa_program.Base.InputsRead;
+
+ vimap_rev = &rmesa->curr_vp_hw->inputmap_rev[0];
assert(vp_out & (1 << VERT_RESULT_HPOS));
out_compsel = R200_OUTPUT_XYZW;
if (vp_out & (1 << VERT_RESULT_COL0)) {
@@ -473,7 +483,7 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx,
/* Do the actual work:
*/
r200ReleaseArrays( ctx, ~0 /* stage->changed_inputs */ );
- r200EmitArrays( ctx, inputs );
+ r200EmitArrays( ctx, vimap_rev );
rmesa->tcl.Elts = VB->Elts;
diff --git a/src/mesa/drivers/dri/r200/r200_vertprog.c b/src/mesa/drivers/dri/r200/r200_vertprog.c
index 899e84caa0f..4960d481d5d 100644
--- a/src/mesa/drivers/dri/r200/r200_vertprog.c
+++ b/src/mesa/drivers/dri/r200/r200_vertprog.c
@@ -405,7 +405,6 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte
int dofogfix = 0;
int fog_temp_i = 0;
int free_inputs;
- int free_inputs_conv;
int array_count = 0;
vp->native = GL_FALSE;
@@ -461,7 +460,7 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte
/* for fogc, can't change mesa_vp, as it would hose swtnl, and exp with
base e isn't directly available neither. */
- if (mesa_vp->Base.OutputsWritten & VERT_RESULT_FOGC && !vp->fogpidx) {
+ if ((mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_FOGC)) && !vp->fogpidx) {
struct gl_program_parameter_list *paramList;
GLint tokens[6] = { STATE_FOG_PARAMS, 0, 0, 0, 0, 0 };
paramList = mesa_vp->Base.Parameters;
@@ -477,6 +476,8 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte
for(i = 0; i < VERT_ATTRIB_MAX; i++)
vp->inputs[i] = -1;
+ for(i = 0; i < 15; i++)
+ vp->inputmap_rev[i] = 255;
free_inputs = 0x2ffd;
/* fglrx uses fixed inputs as follows for conventional attribs.
@@ -499,39 +500,45 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte
/* may look different when using idx buf / input_route instead of se_vtx_fmt? */
if (mesa_vp->Base.InputsRead & VERT_BIT_POS) {
vp->inputs[VERT_ATTRIB_POS] = 0;
+ vp->inputmap_rev[0] = VERT_ATTRIB_POS;
free_inputs &= ~(1 << 0);
array_count++;
}
if (mesa_vp->Base.InputsRead & VERT_BIT_WEIGHT) {
- /* we don't actually handle that later. Then again, we don't have to... */
vp->inputs[VERT_ATTRIB_WEIGHT] = 12;
+ vp->inputmap_rev[1] = VERT_ATTRIB_WEIGHT;
array_count++;
}
if (mesa_vp->Base.InputsRead & VERT_BIT_NORMAL) {
vp->inputs[VERT_ATTRIB_NORMAL] = 1;
+ vp->inputmap_rev[2] = VERT_ATTRIB_NORMAL;
array_count++;
}
if (mesa_vp->Base.InputsRead & VERT_BIT_COLOR0) {
vp->inputs[VERT_ATTRIB_COLOR0] = 2;
+ vp->inputmap_rev[4] = VERT_ATTRIB_COLOR0;
free_inputs &= ~(1 << 2);
array_count++;
}
if (mesa_vp->Base.InputsRead & VERT_BIT_COLOR1) {
vp->inputs[VERT_ATTRIB_COLOR1] = 3;
+ vp->inputmap_rev[5] = VERT_ATTRIB_COLOR1;
free_inputs &= ~(1 << 3);
array_count++;
}
if (mesa_vp->Base.InputsRead & VERT_BIT_FOG) {
vp->inputs[VERT_ATTRIB_FOG] = 15; array_count++;
+ vp->inputmap_rev[3] = VERT_ATTRIB_FOG;
+ array_count++;
}
for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX5; i++) {
if (mesa_vp->Base.InputsRead & (1 << i)) {
vp->inputs[i] = i - VERT_ATTRIB_TEX0 + 6;
+ vp->inputmap_rev[8 + i - VERT_ATTRIB_TEX0] = i;
free_inputs &= ~(1 << (i - VERT_ATTRIB_TEX0 + 6));
array_count++;
}
}
- free_inputs_conv = free_inputs;
/* using VERT_ATTRIB_TEX6/7 would be illegal */
/* completely ignore aliasing? */
for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) {
@@ -550,13 +557,14 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte
if (free_inputs & (1 << j)) {
free_inputs &= ~(1 << j);
vp->inputs[i] = j;
- vp->rev_inputs[j] = i;
+ if (j == 0) vp->inputmap_rev[j] = i; /* mapped to pos */
+ else if (j < 12) vp->inputmap_rev[j + 2] = i; /* mapped to col/tex */
+ else vp->inputmap_rev[j + 1] = i; /* mapped to pos1 */
break;
}
}
}
}
- vp->gen_inputs_mapped = free_inputs ^ free_inputs_conv;
if (!(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS))) {
if (R200_DEBUG & DEBUG_FALLBACKS) {
diff --git a/src/mesa/drivers/dri/r200/r200_vtxfmt.c b/src/mesa/drivers/dri/r200/r200_vtxfmt.c
deleted file mode 100644
index d73fbbafd5f..00000000000
--- a/src/mesa/drivers/dri/r200/r200_vtxfmt.c
+++ /dev/null
@@ -1,1234 +0,0 @@
-/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.c,v 1.4 2003/05/06 23:52:08 daenzer Exp $ */
-/*
-Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
-
-The Weather Channel (TM) funded Tungsten Graphics to develop the
-initial release of the Radeon 8500 driver under the XFree86 license.
-This notice must be preserved.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial
-portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Keith Whitwell <[email protected]>
- */
-
-#include "glheader.h"
-#include "imports.h"
-#include "r200_context.h"
-#include "r200_state.h"
-#include "r200_ioctl.h"
-#include "r200_tex.h"
-#include "r200_tcl.h"
-#include "r200_swtcl.h"
-#include "r200_vtxfmt.h"
-
-#include "api_noop.h"
-#include "api_arrayelt.h"
-#include "context.h"
-#include "mtypes.h"
-#include "enums.h"
-#include "glapi.h"
-#include "colormac.h"
-#include "light.h"
-#include "state.h"
-#include "vtxfmt.h"
-
-#include "tnl/tnl.h"
-#include "tnl/t_context.h"
-#include "tnl/t_array_api.h"
-#include "tnl/t_save_api.h"
-
-#include "dispatch.h"
-
-static void r200VtxFmtFlushVertices( GLcontext *, GLuint );
-
-static void count_func( const char *name, struct dynfn *l )
-{
- int i = 0;
- struct dynfn *f;
- foreach (f, l) i++;
- if (i) fprintf(stderr, "%s: %d\n", name, i );
-}
-
-static void count_funcs( r200ContextPtr rmesa )
-{
- count_func( "Vertex2f", &rmesa->vb.dfn_cache.Vertex2f );
- count_func( "Vertex2fv", &rmesa->vb.dfn_cache.Vertex2fv );
- count_func( "Vertex3f", &rmesa->vb.dfn_cache.Vertex3f );
- count_func( "Vertex3fv", &rmesa->vb.dfn_cache.Vertex3fv );
- count_func( "Color4ub", &rmesa->vb.dfn_cache.Color4ub );
- count_func( "Color4ubv", &rmesa->vb.dfn_cache.Color4ubv );
- count_func( "Color3ub", &rmesa->vb.dfn_cache.Color3ub );
- count_func( "Color3ubv", &rmesa->vb.dfn_cache.Color3ubv );
- count_func( "Color4f", &rmesa->vb.dfn_cache.Color4f );
- count_func( "Color4fv", &rmesa->vb.dfn_cache.Color4fv );
- count_func( "Color3f", &rmesa->vb.dfn_cache.Color3f );
- count_func( "Color3fv", &rmesa->vb.dfn_cache.Color3fv );
- count_func( "SecondaryColor3f", &rmesa->vb.dfn_cache.SecondaryColor3fEXT );
- count_func( "SecondaryColor3fv", &rmesa->vb.dfn_cache.SecondaryColor3fvEXT );
- count_func( "SecondaryColor3ub", &rmesa->vb.dfn_cache.SecondaryColor3ubEXT );
- count_func( "SecondaryColor3ubv", &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT );
- count_func( "Normal3f", &rmesa->vb.dfn_cache.Normal3f );
- count_func( "Normal3fv", &rmesa->vb.dfn_cache.Normal3fv );
- count_func( "TexCoord3f", &rmesa->vb.dfn_cache.TexCoord3f );
- count_func( "TexCoord3fv", &rmesa->vb.dfn_cache.TexCoord3fv );
- count_func( "TexCoord2f", &rmesa->vb.dfn_cache.TexCoord2f );
- count_func( "TexCoord2fv", &rmesa->vb.dfn_cache.TexCoord2fv );
- count_func( "TexCoord1f", &rmesa->vb.dfn_cache.TexCoord1f );
- count_func( "TexCoord1fv", &rmesa->vb.dfn_cache.TexCoord1fv );
- count_func( "MultiTexCoord3fARB", &rmesa->vb.dfn_cache.MultiTexCoord3fARB );
- count_func( "MultiTexCoord3fvARB", &rmesa->vb.dfn_cache.MultiTexCoord3fvARB );
- count_func( "MultiTexCoord2fARB", &rmesa->vb.dfn_cache.MultiTexCoord2fARB );
- count_func( "MultiTexCoord2fvARB", &rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
- count_func( "MultiTexCoord1fARB", &rmesa->vb.dfn_cache.MultiTexCoord1fARB );
- count_func( "MultiTexCoord1fvARB", &rmesa->vb.dfn_cache.MultiTexCoord1fvARB );
-/* count_func( "FogCoordfEXT", &rmesa->vb.dfn_cache.FogCoordfEXT );
- count_func( "FogCoordfvEXT", &rmesa->vb.dfn_cache.FogCoordfvEXT );*/
-}
-
-static void r200NewList( GLcontext *ctx, GLuint list, GLenum mode )
-{
- VFMT_FALLBACK( __FUNCTION__ );
- _tnl_NewList( ctx, list, mode );
- return;
-}
-
-void r200_copy_to_current( GLcontext *ctx )
-{
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- unsigned i;
-
- if (R200_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s\n", __FUNCTION__);
-
- assert(ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT);
-
- if (rmesa->vb.vtxfmt_0 & R200_VTX_N0) {
- ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0] = rmesa->vb.normalptr[0];
- ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1] = rmesa->vb.normalptr[1];
- ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2] = rmesa->vb.normalptr[2];
- }
-
- if (rmesa->vb.vtxfmt_0 & R200_VTX_DISCRETE_FOG) {
- ctx->Current.Attrib[VERT_ATTRIB_FOG][0] = rmesa->vb.fogptr[0];
- }
-
- switch( VTX_COLOR(rmesa->vb.vtxfmt_0, 0) ) {
- case R200_VTX_PK_RGBA:
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->red );
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->green );
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->blue );
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->alpha );
- break;
-
- case R200_VTX_FP_RGB:
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] = rmesa->vb.floatcolorptr[0];
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] = rmesa->vb.floatcolorptr[1];
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] = rmesa->vb.floatcolorptr[2];
- break;
-
- case R200_VTX_FP_RGBA:
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] = rmesa->vb.floatcolorptr[0];
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] = rmesa->vb.floatcolorptr[1];
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] = rmesa->vb.floatcolorptr[2];
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = rmesa->vb.floatcolorptr[3];
- break;
-
- default:
- break;
- }
-
- if (VTX_COLOR(rmesa->vb.vtxfmt_0, 1) == R200_VTX_PK_RGBA) {
- ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0] = UBYTE_TO_FLOAT( rmesa->vb.specptr->red );
- ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1] = UBYTE_TO_FLOAT( rmesa->vb.specptr->green );
- ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2] = UBYTE_TO_FLOAT( rmesa->vb.specptr->blue );
- }
-
- for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) {
- const unsigned count = VTX_TEXn_COUNT( rmesa->vb.vtxfmt_1, i );
- GLfloat * const src = rmesa->vb.texcoordptr[i];
-
- if ( count != 0 ) {
- switch( count ) {
- case 3:
- ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][1] = src[1];
- ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][2] = src[2];
- break;
- case 2:
- ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][1] = src[1];
- ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][2] = 0.0F;
- break;
- case 1:
- ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][1] = 0.0F;
- ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][2] = 0.0F;
- break;
- }
-
- ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][0] = src[0];
- ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][3] = 1.0F;
- }
- }
-
- ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT;
-}
-
-static GLboolean discreet_gl_prim[GL_POLYGON+1] = {
- 1, /* 0 points */
- 1, /* 1 lines */
- 0, /* 2 line_strip */
- 0, /* 3 line_loop */
- 1, /* 4 tris */
- 0, /* 5 tri_fan */
- 0, /* 6 tri_strip */
- 1, /* 7 quads */
- 0, /* 8 quadstrip */
- 0, /* 9 poly */
-};
-
-static void flush_prims( r200ContextPtr rmesa )
-{
- int i,j;
- struct r200_dma_region tmp = rmesa->dma.current;
-
- tmp.buf->refcount++;
- tmp.aos_size = rmesa->vb.vertex_size;
- tmp.aos_stride = rmesa->vb.vertex_size;
- tmp.aos_start = GET_START(&tmp);
-
- rmesa->dma.current.ptr = rmesa->dma.current.start +=
- (rmesa->vb.initial_counter - rmesa->vb.counter) *
- rmesa->vb.vertex_size * 4;
-
- rmesa->tcl.vertex_format = rmesa->vb.vtxfmt_0;
- rmesa->tcl.aos_components[0] = &tmp;
- rmesa->tcl.nr_aos_components = 1;
- rmesa->dma.flush = NULL;
-
- /* Optimize the primitive list:
- */
- if (rmesa->vb.nrprims > 1) {
- for (j = 0, i = 1 ; i < rmesa->vb.nrprims; i++) {
- int pj = rmesa->vb.primlist[j].prim & 0xf;
- int pi = rmesa->vb.primlist[i].prim & 0xf;
-
- if (pj == pi && discreet_gl_prim[pj] &&
- rmesa->vb.primlist[i].start == rmesa->vb.primlist[j].end) {
- rmesa->vb.primlist[j].end = rmesa->vb.primlist[i].end;
- }
- else {
- j++;
- if (j != i) rmesa->vb.primlist[j] = rmesa->vb.primlist[i];
- }
- }
- rmesa->vb.nrprims = j+1;
- }
-
- if (rmesa->vb.vtxfmt_0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] ||
- rmesa->vb.vtxfmt_1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) {
- R200_STATECHANGE( rmesa, vtx );
- rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = rmesa->vb.vtxfmt_0;
- rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = rmesa->vb.vtxfmt_1;
- }
-
-
- for (i = 0 ; i < rmesa->vb.nrprims; i++) {
- if (R200_DEBUG & DEBUG_PRIMS)
- fprintf(stderr, "vtxfmt prim %d: %s %d..%d\n", i,
- _mesa_lookup_enum_by_nr( rmesa->vb.primlist[i].prim &
- PRIM_MODE_MASK ),
- rmesa->vb.primlist[i].start,
- rmesa->vb.primlist[i].end);
-
- if (rmesa->vb.primlist[i].start < rmesa->vb.primlist[i].end)
- r200EmitPrimitive( rmesa->glCtx,
- rmesa->vb.primlist[i].start,
- rmesa->vb.primlist[i].end,
- rmesa->vb.primlist[i].prim );
- }
-
- rmesa->vb.nrprims = 0;
- r200ReleaseDmaRegion( rmesa, &tmp, __FUNCTION__ );
-}
-
-
-static void start_prim( r200ContextPtr rmesa, GLuint mode )
-{
- if (R200_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s %d\n", __FUNCTION__,
- rmesa->vb.initial_counter - rmesa->vb.counter);
-
- rmesa->vb.primlist[rmesa->vb.nrprims].start =
- rmesa->vb.initial_counter - rmesa->vb.counter;
- rmesa->vb.primlist[rmesa->vb.nrprims].prim = mode;
-}
-
-static void note_last_prim( r200ContextPtr rmesa, GLuint flags )
-{
- if (R200_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s %d\n", __FUNCTION__,
- rmesa->vb.initial_counter - rmesa->vb.counter);
-
- if (rmesa->vb.prim[0] != GL_POLYGON+1) {
- rmesa->vb.primlist[rmesa->vb.nrprims].prim |= flags;
- rmesa->vb.primlist[rmesa->vb.nrprims].end =
- rmesa->vb.initial_counter - rmesa->vb.counter;
-
- if (++(rmesa->vb.nrprims) == R200_MAX_PRIMS)
- flush_prims( rmesa );
- }
-}
-
-
-static void copy_vertex( r200ContextPtr rmesa, GLuint n, GLfloat *dst )
-{
- GLuint i;
- GLfloat *src = (GLfloat *)(rmesa->dma.current.address +
- rmesa->dma.current.ptr +
- (rmesa->vb.primlist[rmesa->vb.nrprims].start + n) *
- rmesa->vb.vertex_size * 4);
-
- if (R200_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "copy_vertex %d\n", rmesa->vb.primlist[rmesa->vb.nrprims].start + n);
-
- for (i = 0 ; i < rmesa->vb.vertex_size; i++) {
- dst[i] = src[i];
- }
-}
-
-/* NOTE: This actually reads the copied vertices back from uncached
- * memory. Could also use the counter/notify mechanism to populate
- * tmp on the fly as vertices are generated.
- */
-static GLuint copy_dma_verts( r200ContextPtr rmesa, GLfloat (*tmp)[R200_MAX_VERTEX_SIZE] )
-{
- GLuint ovf, i;
- GLuint nr = (rmesa->vb.initial_counter - rmesa->vb.counter) -
- rmesa->vb.primlist[rmesa->vb.nrprims].start;
-
- if (R200_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s %d verts\n", __FUNCTION__, nr);
-
- switch( rmesa->vb.prim[0] )
- {
- case GL_POINTS:
- return 0;
- case GL_LINES:
- ovf = nr&1;
- for (i = 0 ; i < ovf ; i++)
- copy_vertex( rmesa, nr-ovf+i, tmp[i] );
- return i;
- case GL_TRIANGLES:
- ovf = nr%3;
- for (i = 0 ; i < ovf ; i++)
- copy_vertex( rmesa, nr-ovf+i, tmp[i] );
- return i;
- case GL_QUADS:
- ovf = nr&3;
- for (i = 0 ; i < ovf ; i++)
- copy_vertex( rmesa, nr-ovf+i, tmp[i] );
- return i;
- case GL_LINE_STRIP:
- if (nr == 0)
- return 0;
- copy_vertex( rmesa, nr-1, tmp[0] );
- return 1;
- case GL_LINE_LOOP:
- case GL_TRIANGLE_FAN:
- case GL_POLYGON:
- if (nr == 0)
- return 0;
- else if (nr == 1) {
- copy_vertex( rmesa, 0, tmp[0] );
- return 1;
- } else {
- copy_vertex( rmesa, 0, tmp[0] );
- copy_vertex( rmesa, nr-1, tmp[1] );
- return 2;
- }
- case GL_TRIANGLE_STRIP:
- ovf = MIN2( nr, 2 );
- for (i = 0 ; i < ovf ; i++)
- copy_vertex( rmesa, nr-ovf+i, tmp[i] );
- return i;
- case GL_QUAD_STRIP:
- switch (nr) {
- case 0: ovf = 0; break;
- case 1: ovf = 1; break;
- default: ovf = 2 + (nr&1); break;
- }
- for (i = 0 ; i < ovf ; i++)
- copy_vertex( rmesa, nr-ovf+i, tmp[i] );
- return i;
- default:
- assert(0);
- return 0;
- }
-}
-
-static void VFMT_FALLBACK_OUTSIDE_BEGIN_END( const char *caller )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
- if (R200_DEBUG & (DEBUG_VFMT|DEBUG_FALLBACKS))
- fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
-
- if (ctx->Driver.NeedFlush)
- r200VtxFmtFlushVertices( ctx, ctx->Driver.NeedFlush );
-
- if (ctx->NewState)
- _mesa_update_state( ctx ); /* clear state so fell_back sticks */
-
- _tnl_wakeup_exec( ctx );
- ctx->Driver.FlushVertices = r200FlushVertices;
- ctx->Driver.NewList = _tnl_NewList;
-
- assert( rmesa->dma.flush == 0 );
- rmesa->vb.fell_back = GL_TRUE;
- rmesa->vb.installed = GL_FALSE;
-}
-
-
-/**
- * \todo
- * An interesting optimization of this function would be to have 3 element
- * table with the dispatch offsets of the TexCoord?fv functions, use count
- * to look-up the table, and a specialized version of GL_CALL that used the
- * offset number instead of the name.
- */
-static void dispatch_multitexcoord( GLuint count, GLuint unit, GLfloat * f )
-{
- switch( count ) {
- case 3:
- CALL_MultiTexCoord3fvARB(GET_DISPATCH(), (GL_TEXTURE0+unit, f));
- break;
- case 2:
- CALL_MultiTexCoord2fvARB(GET_DISPATCH(), (GL_TEXTURE0+unit, f));
- break;
- case 1:
- CALL_MultiTexCoord1fvARB(GET_DISPATCH(), (GL_TEXTURE0+unit, f));
- break;
- default:
- assert( count == 0 );
- break;
- }
-}
-
-void VFMT_FALLBACK( const char *caller )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLfloat tmp[3][R200_MAX_VERTEX_SIZE];
- GLuint i, prim;
- GLuint ind0 = rmesa->vb.vtxfmt_0;
- GLuint ind1 = rmesa->vb.vtxfmt_1;
- GLuint nrverts;
- GLfloat alpha = 1.0;
- GLuint count;
- GLuint unit;
-
- if (R200_DEBUG & (DEBUG_FALLBACKS|DEBUG_VFMT))
- fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
-
- if (rmesa->vb.prim[0] == GL_POLYGON+1) {
- VFMT_FALLBACK_OUTSIDE_BEGIN_END( __FUNCTION__ );
- return;
- }
-
- /* Copy vertices out of dma:
- */
- nrverts = copy_dma_verts( rmesa, tmp );
-
- /* Finish the prim at this point:
- */
- note_last_prim( rmesa, 0 );
- flush_prims( rmesa );
-
- /* Update ctx->Driver.CurrentExecPrimitive and swap in swtnl.
- */
- prim = rmesa->vb.prim[0];
- ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1;
- _tnl_wakeup_exec( ctx );
- ctx->Driver.FlushVertices = r200FlushVertices;
-
- assert(rmesa->dma.flush == 0);
- rmesa->vb.fell_back = GL_TRUE;
- rmesa->vb.installed = GL_FALSE;
- CALL_Begin(GET_DISPATCH(), (prim));
-
- if (rmesa->vb.installed_color_3f_sz == 4)
- alpha = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3];
-
- /* Replay saved vertices
- */
- for (i = 0 ; i < nrverts; i++) {
- GLuint offset = 3;
-
- if (ind0 & R200_VTX_N0) {
- CALL_Normal3fv(GET_DISPATCH(), (&tmp[i][offset]));
- offset += 3;
- }
-
- if (ind0 & R200_VTX_DISCRETE_FOG) {
- CALL_FogCoordfvEXT(GET_DISPATCH(), (&tmp[i][offset]));
- offset++;
- }
-
- if (VTX_COLOR(ind0, 0) == R200_VTX_PK_RGBA) {
- CALL_Color4ubv(GET_DISPATCH(), ((GLubyte *)&tmp[i][offset]));
- offset++;
- }
- else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGBA) {
- CALL_Color4fv(GET_DISPATCH(), (&tmp[i][offset]));
- offset+=4;
- }
- else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGB) {
- CALL_Color3fv(GET_DISPATCH(), (&tmp[i][offset]));
- offset+=3;
- }
-
- if (VTX_COLOR(ind0, 1) == R200_VTX_PK_RGBA) {
- CALL_SecondaryColor3ubvEXT(GET_DISPATCH(), ((GLubyte *)&tmp[i][offset]));
- offset++;
- }
-
- for ( unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++ ) {
- count = VTX_TEXn_COUNT( ind1, unit );
- dispatch_multitexcoord( count, unit, &tmp[i][offset] );
- offset += count;
- }
-
- CALL_Vertex3fv(GET_DISPATCH(), (&tmp[i][0]));
- }
-
- /* Replay current vertex
- */
- if (ind0 & R200_VTX_N0)
- CALL_Normal3fv(GET_DISPATCH(), (rmesa->vb.normalptr));
- if (ind0 & R200_VTX_DISCRETE_FOG) {
- CALL_FogCoordfvEXT(GET_DISPATCH(), (rmesa->vb.fogptr));
- }
-
- if (VTX_COLOR(ind0, 0) == R200_VTX_PK_RGBA) {
- CALL_Color4ub(GET_DISPATCH(), (rmesa->vb.colorptr->red,
- rmesa->vb.colorptr->green,
- rmesa->vb.colorptr->blue,
- rmesa->vb.colorptr->alpha));
- }
- else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGBA) {
- CALL_Color4fv(GET_DISPATCH(), (rmesa->vb.floatcolorptr));
- }
- else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGB) {
- if (rmesa->vb.installed_color_3f_sz == 4 && alpha != 1.0) {
- CALL_Color4f(GET_DISPATCH(), (rmesa->vb.floatcolorptr[0],
- rmesa->vb.floatcolorptr[1],
- rmesa->vb.floatcolorptr[2],
- alpha));
- }
- else {
- CALL_Color3fv(GET_DISPATCH(), (rmesa->vb.floatcolorptr));
- }
- }
-
- if (VTX_COLOR(ind0, 1) == R200_VTX_PK_RGBA)
- CALL_SecondaryColor3ubEXT(GET_DISPATCH(), (rmesa->vb.specptr->red,
- rmesa->vb.specptr->green,
- rmesa->vb.specptr->blue));
-
- for ( unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++ ) {
- count = VTX_TEXn_COUNT( ind1, unit );
- dispatch_multitexcoord( count, unit, rmesa->vb.texcoordptr[unit] );
- }
-}
-
-
-
-static void wrap_buffer( void )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLfloat tmp[3][R200_MAX_VERTEX_SIZE];
- GLuint i, nrverts;
-
- if (R200_DEBUG & (DEBUG_VFMT|DEBUG_PRIMS))
- fprintf(stderr, "%s %d\n", __FUNCTION__,
- rmesa->vb.initial_counter - rmesa->vb.counter);
-
- /* Don't deal with parity.
- */
- if ((((rmesa->vb.initial_counter - rmesa->vb.counter) -
- rmesa->vb.primlist[rmesa->vb.nrprims].start) & 1)) {
- rmesa->vb.counter++;
- rmesa->vb.initial_counter++;
- return;
- }
-
- /* Copy vertices out of dma:
- */
- if (rmesa->vb.prim[0] == GL_POLYGON+1)
- nrverts = 0;
- else {
- nrverts = copy_dma_verts( rmesa, tmp );
-
- if (R200_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%d vertices to copy\n", nrverts);
-
- /* Finish the prim at this point:
- */
- note_last_prim( rmesa, 0 );
- }
-
- /* Fire any buffered primitives
- */
- flush_prims( rmesa );
-
- /* Get new buffer
- */
- r200RefillCurrentDmaRegion( rmesa );
-
- /* Reset counter, dmaptr
- */
- rmesa->vb.dmaptr = (int *)(rmesa->dma.current.ptr + rmesa->dma.current.address);
- rmesa->vb.counter = (rmesa->dma.current.end - rmesa->dma.current.ptr) /
- (rmesa->vb.vertex_size * 4);
- rmesa->vb.counter--;
- rmesa->vb.initial_counter = rmesa->vb.counter;
- rmesa->vb.notify = wrap_buffer;
-
- rmesa->dma.flush = flush_prims;
-
- /* Restart wrapped primitive:
- */
- if (rmesa->vb.prim[0] != GL_POLYGON+1)
- start_prim( rmesa, rmesa->vb.prim[0] );
-
-
- /* Reemit saved vertices
- */
- for (i = 0 ; i < nrverts; i++) {
- if (R200_DEBUG & DEBUG_VERTS) {
- int j;
- fprintf(stderr, "re-emit vertex %d to %p\n", i,
- (void *)rmesa->vb.dmaptr);
- if (R200_DEBUG & DEBUG_VERBOSE)
- for (j = 0 ; j < rmesa->vb.vertex_size; j++)
- fprintf(stderr, "\t%08x/%f\n", *(int*)&tmp[i][j], tmp[i][j]);
- }
-
- memcpy( rmesa->vb.dmaptr, tmp[i], rmesa->vb.vertex_size * 4 );
- rmesa->vb.dmaptr += rmesa->vb.vertex_size;
- rmesa->vb.counter--;
- }
-}
-
-
-/**
- * Determines the hardware vertex format based on the current state vector.
- *
- * \returns
- * If the hardware TCL unit is capable of handling the current state vector,
- * \c GL_TRUE is returned. Otherwise, \c GL_FALSE is returned.
- *
- * \todo
- * Make this color format selection data driven. If we receive only ubytes,
- * send color as ubytes. Also check if converting (with free checking for
- * overflow) is cheaper than sending floats directly.
- *
- * \todo
- * When intializing texture coordinates, it might be faster to just copy the
- * entire \c VERT_ATTRIB_TEX0 vector into the vertex buffer. It may mean that
- * some of the data (i.e., the last texture coordinate components) get copied
- * over, but that still may be faster than the conditional branching. If
- * nothing else, the code will be smaller and easier to follow.
- */
-static GLboolean check_vtx_fmt( GLcontext *ctx )
-{
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLuint ind0 = R200_VTX_Z0;
- GLuint ind1 = 0;
- GLuint i;
- GLuint count[R200_MAX_TEXTURE_UNITS];
-
- if (rmesa->TclFallback || rmesa->vb.fell_back || ctx->CompileFlag ||
- (ctx->Fog.Enabled && (ctx->Fog.FogCoordinateSource == GL_FOG_COORD)) ||
- /* TODO: set tcl out fmt/compsel and reenable vtxfmt code */
- ctx->VertexProgram._Enabled)
- return GL_FALSE;
-
- if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT)
- ctx->Driver.FlushVertices( ctx, FLUSH_UPDATE_CURRENT );
-
- /* Make all this event-driven:
- */
- if (ctx->Light.Enabled) {
- ind0 |= R200_VTX_N0;
-
- if (ctx->Light.ColorMaterialEnabled)
- ind0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT;
- else
- ind0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT;
- }
- else {
- /* TODO: make this data driven?
- */
- ind0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT;
-
- if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
- ind0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT;
- }
- }
-
- if ( ctx->Fog.FogCoordinateSource == GL_FOG_COORD ) {
- ind0 |= R200_VTX_DISCRETE_FOG;
- }
-
- for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) {
- count[i] = 0;
-
- if (ctx->Texture.Unit[i]._ReallyEnabled) {
- if (rmesa->TexGenNeedNormals[i]) {
- ind0 |= R200_VTX_N0;
- }
- else {
- switch( ctx->Texture.Unit[i]._ReallyEnabled ) {
- case TEXTURE_CUBE_BIT:
- case TEXTURE_3D_BIT:
- count[i] = 3;
- break;
- case TEXTURE_2D_BIT:
- case TEXTURE_RECT_BIT:
- count[i] = 2;
- break;
- case TEXTURE_1D_BIT:
- count[i] = 1;
- break;
- }
-
- ind1 |= count[i] << (3 * i);
- }
- }
- }
-
- if (R200_DEBUG & (DEBUG_VFMT|DEBUG_STATE))
- fprintf(stderr, "%s: format: 0x%x, 0x%x\n", __FUNCTION__, ind0, ind1 );
-
- R200_NEWPRIM(rmesa);
- rmesa->vb.vtxfmt_0 = ind0;
- rmesa->vb.vtxfmt_1 = ind1;
- rmesa->vb.prim = &ctx->Driver.CurrentExecPrimitive;
-
- rmesa->vb.vertex_size = 3;
- rmesa->vb.normalptr = ctx->Current.Attrib[VERT_ATTRIB_NORMAL];
- rmesa->vb.colorptr = NULL;
- rmesa->vb.floatcolorptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
- rmesa->vb.fogptr = ctx->Current.Attrib[VERT_ATTRIB_FOG];
- rmesa->vb.specptr = NULL;
- rmesa->vb.floatspecptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR1];
- rmesa->vb.texcoordptr[0] = ctx->Current.Attrib[VERT_ATTRIB_TEX0];
- rmesa->vb.texcoordptr[1] = ctx->Current.Attrib[VERT_ATTRIB_TEX1];
- rmesa->vb.texcoordptr[2] = ctx->Current.Attrib[VERT_ATTRIB_TEX2];
- rmesa->vb.texcoordptr[3] = ctx->Current.Attrib[VERT_ATTRIB_TEX3];
- rmesa->vb.texcoordptr[4] = ctx->Current.Attrib[VERT_ATTRIB_TEX4];
- rmesa->vb.texcoordptr[5] = ctx->Current.Attrib[VERT_ATTRIB_TEX5];
- rmesa->vb.texcoordptr[6] = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; /* dummy */
- rmesa->vb.texcoordptr[7] = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; /* dummy */
-
- /* Run through and initialize the vertex components in the order
- * the hardware understands:
- */
- if (ind0 & R200_VTX_N0) {
- rmesa->vb.normalptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f;
- rmesa->vb.vertex_size += 3;
- rmesa->vb.normalptr[0] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0];
- rmesa->vb.normalptr[1] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1];
- rmesa->vb.normalptr[2] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2];
- }
-
- if (ind0 & R200_VTX_DISCRETE_FOG) {
- rmesa->vb.fogptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f;
- rmesa->vb.vertex_size += 1;
- rmesa->vb.fogptr[0] = ctx->Current.Attrib[VERT_ATTRIB_FOG][0];
- }
-
- if (VTX_COLOR(ind0, 0) == R200_VTX_PK_RGBA) {
- rmesa->vb.colorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].color;
- rmesa->vb.vertex_size += 1;
- UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->red, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] );
- UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->green, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] );
- UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->blue, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] );
- UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->alpha, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] );
- }
- else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGBA) {
- rmesa->vb.floatcolorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f;
- rmesa->vb.vertex_size += 4;
- rmesa->vb.floatcolorptr[0] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0];
- rmesa->vb.floatcolorptr[1] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1];
- rmesa->vb.floatcolorptr[2] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2];
- rmesa->vb.floatcolorptr[3] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3];
- }
- else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGB) {
- rmesa->vb.floatcolorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f;
- rmesa->vb.vertex_size += 3;
- rmesa->vb.floatcolorptr[0] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0];
- rmesa->vb.floatcolorptr[1] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1];
- rmesa->vb.floatcolorptr[2] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2];
- }
-
- if (VTX_COLOR(ind0, 1) == R200_VTX_PK_RGBA) {
- rmesa->vb.specptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].color;
- rmesa->vb.vertex_size += 1;
- UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->red, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0] );
- UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->green, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1] );
- UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->blue, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2] );
- }
-
-
- for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) {
- if ( count[i] != 0 ) {
- float * const attr = ctx->Current.Attrib[VERT_ATTRIB_TEX0+i];
- unsigned j;
-
- rmesa->vb.texcoordptr[i] = &rmesa->vb.vertex[rmesa->vb.vertex_size].f;
-
- for ( j = 0 ; j < count[i] ; j++ ) {
- rmesa->vb.texcoordptr[i][j] = attr[j];
- }
-
- rmesa->vb.vertex_size += count[i];
- }
- }
-
- if (rmesa->vb.installed_vertex_format != rmesa->vb.vtxfmt_0) {
- if (R200_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "reinstall on vertex_format change\n");
- _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt );
- rmesa->vb.installed_vertex_format = rmesa->vb.vtxfmt_0;
- }
-
- if (R200_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s -- success\n", __FUNCTION__);
-
- return GL_TRUE;
-}
-
-
-void r200VtxfmtInvalidate( GLcontext *ctx )
-{
- r200ContextPtr rmesa = R200_CONTEXT( ctx );
-
- rmesa->vb.recheck = GL_TRUE;
- rmesa->vb.fell_back = GL_FALSE;
-}
-
-
-static void r200VtxfmtValidate( GLcontext *ctx )
-{
- r200ContextPtr rmesa = R200_CONTEXT( ctx );
-
- if (R200_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s\n", __FUNCTION__);
-
- if (ctx->Driver.NeedFlush)
- ctx->Driver.FlushVertices( ctx, ctx->Driver.NeedFlush );
-
- rmesa->vb.recheck = GL_FALSE;
-
- if (check_vtx_fmt( ctx )) {
- if (!rmesa->vb.installed) {
- if (R200_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "reinstall (new install)\n");
-
- _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt );
- ctx->Driver.FlushVertices = r200VtxFmtFlushVertices;
- ctx->Driver.NewList = r200NewList;
- rmesa->vb.installed = GL_TRUE;
- }
- else if (R200_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s: already installed", __FUNCTION__);
- }
- else {
- if (R200_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s: failed\n", __FUNCTION__);
-
- if (rmesa->vb.installed) {
- if (rmesa->dma.flush)
- rmesa->dma.flush( rmesa );
- _tnl_wakeup_exec( ctx );
- ctx->Driver.FlushVertices = r200FlushVertices;
- ctx->Driver.NewList =_tnl_NewList;
- rmesa->vb.installed = GL_FALSE;
- }
- }
-}
-
-
-
-/* Materials:
- */
-static void r200_Materialfv( GLenum face, GLenum pname,
- const GLfloat *params )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT( ctx );
-
- if (R200_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s\n", __FUNCTION__);
-
- if (rmesa->vb.prim[0] != GL_POLYGON+1) {
- VFMT_FALLBACK( __FUNCTION__ );
- CALL_Materialfv(GET_DISPATCH(), (face, pname, params));
- return;
- }
- _mesa_noop_Materialfv( face, pname, params );
- r200UpdateMaterial( ctx );
-}
-
-
-/* Begin/End
- */
-static void r200_Begin( GLenum mode )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
- if (R200_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s( %s )\n", __FUNCTION__,
- _mesa_lookup_enum_by_nr( mode ));
-
- if (mode > GL_POLYGON) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glBegin" );
- return;
- }
-
- if (rmesa->vb.prim[0] != GL_POLYGON+1) {
- _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" );
- return;
- }
-
- if (ctx->NewState)
- _mesa_update_state( ctx );
-
- if (rmesa->NewGLState)
- r200ValidateState( ctx );
-
- if (rmesa->vb.recheck)
- r200VtxfmtValidate( ctx );
-
- if (!rmesa->vb.installed) {
- CALL_Begin(GET_DISPATCH(), (mode));
- return;
- }
-
-
- if (rmesa->dma.flush && rmesa->vb.counter < 12) {
- if (R200_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s: flush almost-empty buffers\n", __FUNCTION__);
- flush_prims( rmesa );
- }
-
- /* Need to arrange to save vertices here? Or always copy from dma (yuk)?
- */
- if (!rmesa->dma.flush) {
- if (rmesa->dma.current.ptr + 12*rmesa->vb.vertex_size*4 >
- rmesa->dma.current.end) {
- R200_NEWPRIM( rmesa );
- r200RefillCurrentDmaRegion( rmesa );
- }
-
- rmesa->vb.dmaptr = (int *)(rmesa->dma.current.address + rmesa->dma.current.ptr);
- rmesa->vb.counter = (rmesa->dma.current.end - rmesa->dma.current.ptr) /
- (rmesa->vb.vertex_size * 4);
- rmesa->vb.counter--;
- rmesa->vb.initial_counter = rmesa->vb.counter;
- rmesa->vb.notify = wrap_buffer;
- rmesa->dma.flush = flush_prims;
- ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
- }
-
-
- rmesa->vb.prim[0] = mode;
- start_prim( rmesa, mode | PRIM_BEGIN );
-}
-
-
-
-static void r200_End( void )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
- if (R200_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s\n", __FUNCTION__);
-
- if (rmesa->vb.prim[0] == GL_POLYGON+1) {
- _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" );
- return;
- }
-
- note_last_prim( rmesa, PRIM_END );
- rmesa->vb.prim[0] = GL_POLYGON+1;
-}
-
-
-/* Fallback on difficult entrypoints:
- */
-#define PRE_LOOPBACK( FUNC ) \
-do { \
- if (R200_DEBUG & DEBUG_VFMT) \
- fprintf(stderr, "%s\n", __FUNCTION__); \
- VFMT_FALLBACK( __FUNCTION__ ); \
-} while (0)
-#define TAG(x) r200_fallback_##x
-#include "vtxfmt_tmp.h"
-
-
-
-static GLboolean r200NotifyBegin( GLcontext *ctx, GLenum p )
-{
- r200ContextPtr rmesa = R200_CONTEXT( ctx );
-
- if (R200_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s\n", __FUNCTION__);
-
- assert(!rmesa->vb.installed);
-
- if (ctx->NewState)
- _mesa_update_state( ctx );
-
- if (rmesa->NewGLState)
- r200ValidateState( ctx );
-
- if (ctx->Driver.NeedFlush)
- ctx->Driver.FlushVertices( ctx, ctx->Driver.NeedFlush );
-
- if (rmesa->vb.recheck)
- r200VtxfmtValidate( ctx );
-
- if (!rmesa->vb.installed) {
- if (R200_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s -- failed\n", __FUNCTION__);
- return GL_FALSE;
- }
-
- r200_Begin( p );
- return GL_TRUE;
-}
-
-static void r200VtxFmtFlushVertices( GLcontext *ctx, GLuint flags )
-{
- r200ContextPtr rmesa = R200_CONTEXT( ctx );
-
- if (R200_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s\n", __FUNCTION__);
-
- assert(rmesa->vb.installed);
-
- if (flags & FLUSH_UPDATE_CURRENT) {
- r200_copy_to_current( ctx );
- if (R200_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "reinstall on update_current\n");
- _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt );
- ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT;
- }
-
- if (flags & FLUSH_STORED_VERTICES) {
- assert (rmesa->dma.flush == 0 ||
- rmesa->dma.flush == flush_prims);
- if (rmesa->dma.flush == flush_prims)
- flush_prims( rmesa );
- ctx->Driver.NeedFlush &= ~FLUSH_STORED_VERTICES;
- }
-}
-
-
-
-/* At this point, don't expect very many versions of each function to
- * be generated, so not concerned about freeing them?
- */
-
-
-/**
- * Called once during context creation.
- */
-void r200VtxfmtInit( GLcontext *ctx, GLboolean useCodegen )
-{
- r200ContextPtr rmesa = R200_CONTEXT( ctx );
- GLvertexformat *vfmt = &(rmesa->vb.vtxfmt);
-
- /* start by initializing to no-op functions */
- _mesa_noop_vtxfmt_init(vfmt);
-
- /* Hook in chooser functions for codegen, etc:
- */
- r200VtxfmtInitChoosers( vfmt );
-
- /* Handled fully in supported states, but no codegen:
- */
- vfmt->Materialfv = r200_Materialfv;
- vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */
- vfmt->Begin = r200_Begin;
- vfmt->End = r200_End;
-
- /* Fallback for performance reasons: (Fix with cva/elt path here and
- * dmatmp2.h style primitive-merging)
- *
- * These should call NotifyBegin(), as should _tnl_EvalMesh, to allow
- * a driver-hook.
- */
- vfmt->DrawArrays = r200_fallback_DrawArrays;
- vfmt->DrawElements = r200_fallback_DrawElements;
- vfmt->DrawRangeElements = r200_fallback_DrawRangeElements;
-
- /* Active but unsupported -- fallback if we receive these:
- */
- vfmt->CallList = r200_fallback_CallList;
- vfmt->CallLists = r200_fallback_CallLists;
- vfmt->EvalCoord1f = r200_fallback_EvalCoord1f;
- vfmt->EvalCoord1fv = r200_fallback_EvalCoord1fv;
- vfmt->EvalCoord2f = r200_fallback_EvalCoord2f;
- vfmt->EvalCoord2fv = r200_fallback_EvalCoord2fv;
- vfmt->EvalMesh1 = r200_fallback_EvalMesh1;
- vfmt->EvalMesh2 = r200_fallback_EvalMesh2;
- vfmt->EvalPoint1 = r200_fallback_EvalPoint1;
- vfmt->EvalPoint2 = r200_fallback_EvalPoint2;
- vfmt->TexCoord4f = r200_fallback_TexCoord4f;
- vfmt->TexCoord4fv = r200_fallback_TexCoord4fv;
- vfmt->MultiTexCoord4fARB = r200_fallback_MultiTexCoord4fARB;
- vfmt->MultiTexCoord4fvARB = r200_fallback_MultiTexCoord4fvARB;
- vfmt->Vertex4f = r200_fallback_Vertex4f;
- vfmt->Vertex4fv = r200_fallback_Vertex4fv;
- vfmt->VertexAttrib1fNV = r200_fallback_VertexAttrib1fNV;
- vfmt->VertexAttrib1fvNV = r200_fallback_VertexAttrib1fvNV;
- vfmt->VertexAttrib2fNV = r200_fallback_VertexAttrib2fNV;
- vfmt->VertexAttrib2fvNV = r200_fallback_VertexAttrib2fvNV;
- vfmt->VertexAttrib3fNV = r200_fallback_VertexAttrib3fNV;
- vfmt->VertexAttrib3fvNV = r200_fallback_VertexAttrib3fvNV;
- vfmt->VertexAttrib4fNV = r200_fallback_VertexAttrib4fNV;
- vfmt->VertexAttrib4fvNV = r200_fallback_VertexAttrib4fvNV;
- vfmt->FogCoordfEXT = r200_fallback_FogCoordfEXT;
- vfmt->FogCoordfvEXT = r200_fallback_FogCoordfvEXT;
-
- (void)r200_fallback_vtxfmt;
-
- TNL_CONTEXT(ctx)->Driver.NotifyBegin = r200NotifyBegin;
-
- rmesa->vb.enabled = 1;
- rmesa->vb.prim = &ctx->Driver.CurrentExecPrimitive;
- rmesa->vb.primflags = 0;
-
- make_empty_list( &rmesa->vb.dfn_cache.Vertex2f );
- make_empty_list( &rmesa->vb.dfn_cache.Vertex2fv );
- make_empty_list( &rmesa->vb.dfn_cache.Vertex3f );
- make_empty_list( &rmesa->vb.dfn_cache.Vertex3fv );
- make_empty_list( &rmesa->vb.dfn_cache.Color4ub );
- make_empty_list( &rmesa->vb.dfn_cache.Color4ubv );
- make_empty_list( &rmesa->vb.dfn_cache.Color3ub );
- make_empty_list( &rmesa->vb.dfn_cache.Color3ubv );
- make_empty_list( &rmesa->vb.dfn_cache.Color4f );
- make_empty_list( &rmesa->vb.dfn_cache.Color4fv );
- make_empty_list( &rmesa->vb.dfn_cache.Color3f );
- make_empty_list( &rmesa->vb.dfn_cache.Color3fv );
- make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3fEXT );
- make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3fvEXT );
- make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3ubEXT );
- make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT );
- make_empty_list( &rmesa->vb.dfn_cache.Normal3f );
- make_empty_list( &rmesa->vb.dfn_cache.Normal3fv );
- make_empty_list( &rmesa->vb.dfn_cache.TexCoord3f );
- make_empty_list( &rmesa->vb.dfn_cache.TexCoord3fv );
- make_empty_list( &rmesa->vb.dfn_cache.TexCoord2f );
- make_empty_list( &rmesa->vb.dfn_cache.TexCoord2fv );
- make_empty_list( &rmesa->vb.dfn_cache.TexCoord1f );
- make_empty_list( &rmesa->vb.dfn_cache.TexCoord1fv );
- make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord3fARB );
- make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord3fvARB );
- make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord2fARB );
- make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
- make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord1fARB );
- make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord1fvARB );
-/* make_empty_list( &rmesa->vb.dfn_cache.FogCoordfEXT );
- make_empty_list( &rmesa->vb.dfn_cache.FogCoordfvEXT );*/
-
- r200InitCodegen( &rmesa->vb.codegen, useCodegen );
-}
-
-static void free_funcs( struct dynfn *l )
-{
- struct dynfn *f, *tmp;
- foreach_s (f, tmp, l) {
- remove_from_list( f );
- _mesa_exec_free( f->code );
- _mesa_free( f );
- }
-}
-
-void r200VtxfmtUnbindContext( GLcontext *ctx )
-{
-}
-
-
-void r200VtxfmtMakeCurrent( GLcontext *ctx )
-{
-}
-
-
-void r200VtxfmtDestroy( GLcontext *ctx )
-{
- r200ContextPtr rmesa = R200_CONTEXT( ctx );
-
- count_funcs( rmesa );
- free_funcs( &rmesa->vb.dfn_cache.Vertex2f );
- free_funcs( &rmesa->vb.dfn_cache.Vertex2fv );
- free_funcs( &rmesa->vb.dfn_cache.Vertex3f );
- free_funcs( &rmesa->vb.dfn_cache.Vertex3fv );
- free_funcs( &rmesa->vb.dfn_cache.Color4ub );
- free_funcs( &rmesa->vb.dfn_cache.Color4ubv );
- free_funcs( &rmesa->vb.dfn_cache.Color3ub );
- free_funcs( &rmesa->vb.dfn_cache.Color3ubv );
- free_funcs( &rmesa->vb.dfn_cache.Color4f );
- free_funcs( &rmesa->vb.dfn_cache.Color4fv );
- free_funcs( &rmesa->vb.dfn_cache.Color3f );
- free_funcs( &rmesa->vb.dfn_cache.Color3fv );
- free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3ubEXT );
- free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT );
- free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3fEXT );
- free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3fvEXT );
- free_funcs( &rmesa->vb.dfn_cache.Normal3f );
- free_funcs( &rmesa->vb.dfn_cache.Normal3fv );
- free_funcs( &rmesa->vb.dfn_cache.TexCoord3f );
- free_funcs( &rmesa->vb.dfn_cache.TexCoord3fv );
- free_funcs( &rmesa->vb.dfn_cache.TexCoord2f );
- free_funcs( &rmesa->vb.dfn_cache.TexCoord2fv );
- free_funcs( &rmesa->vb.dfn_cache.TexCoord1f );
- free_funcs( &rmesa->vb.dfn_cache.TexCoord1fv );
- free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord3fARB );
- free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord3fvARB );
- free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord2fARB );
- free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
- free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord1fARB );
- free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord1fvARB );
-/* free_funcs( &rmesa->vb.dfn_cache.FogCoordfEXT );
- free_funcs( &rmesa->vb.dfn_cache.FogCoordfvEXT );*/
-}
-
diff --git a/src/mesa/drivers/dri/r200/r200_vtxfmt.h b/src/mesa/drivers/dri/r200/r200_vtxfmt.h
deleted file mode 100644
index 46999191e04..00000000000
--- a/src/mesa/drivers/dri/r200/r200_vtxfmt.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.h,v 1.1 2002/10/30 12:51:53 alanh Exp $ */
-/*
-Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
-
-The Weather Channel (TM) funded Tungsten Graphics to develop the
-initial release of the Radeon 8500 driver under the XFree86 license.
-This notice must be preserved.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial
-portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Keith Whitwell <[email protected]>
- */
-
-#ifndef __R200_VTXFMT_H__
-#define __R200_VTXFMT_H__
-
-#include "r200_context.h"
-
-
-
-extern void r200VtxfmtUpdate( GLcontext *ctx );
-extern void r200VtxfmtInit( GLcontext *ctx, GLboolean useCodegen );
-extern void r200VtxfmtInvalidate( GLcontext *ctx );
-extern void r200VtxfmtDestroy( GLcontext *ctx );
-extern void r200VtxfmtInitChoosers( GLvertexformat *vfmt );
-
-extern void r200VtxfmtMakeCurrent( GLcontext *ctx );
-extern void r200VtxfmtUnbindContext( GLcontext *ctx );
-
-extern void r200_copy_to_current( GLcontext *ctx );
-extern void VFMT_FALLBACK( const char *caller );
-
-#define DFN( FUNC, CACHE) \
-do { \
- char *start = (char *)&FUNC; \
- char *end = (char *)&FUNC##_end; \
- insert_at_head( &CACHE, dfn ); \
- dfn->key[0] = key[0]; \
- dfn->key[1] = key[1]; \
- dfn->code = _mesa_exec_malloc( end - start ); \
- _mesa_memcpy(dfn->code, start, end - start); \
-} \
-while ( 0 )
-
-#define FIXUP( CODE, OFFSET, CHECKVAL, NEWVAL ) \
-do { \
- int *icode = (int *)(CODE+OFFSET); \
- assert (*icode == CHECKVAL); \
- *icode = (int)NEWVAL; \
-} while (0)
-
-
-/* Useful for figuring out the offsets:
- */
-#define FIXUP2( CODE, OFFSET, CHECKVAL, NEWVAL ) \
-do { \
- while (*(int *)(CODE+OFFSET) != CHECKVAL) OFFSET++; \
- /*fprintf(stderr, "%s/%d CVAL %x OFFSET %d VAL %x\n", __FUNCTION__,*/ \
- /* __LINE__, CHECKVAL, OFFSET, (int)(NEWVAL));*/ \
- *(int *)(CODE+OFFSET) = (int)(NEWVAL); \
- OFFSET += 4; \
-} while (0)
-
-/*
- */
-void r200InitCodegen( struct dfn_generators *gen, GLboolean useCodegen );
-void r200InitX86Codegen( struct dfn_generators *gen );
-void r200InitSSECodegen( struct dfn_generators *gen );
-
-
-
-/* Defined in r200_vtxfmt_x86.c
- */
-struct dynfn *r200_makeX86Vertex2f( GLcontext *, const int * );
-struct dynfn *r200_makeX86Vertex2fv( GLcontext *, const int * );
-struct dynfn *r200_makeX86Vertex3f( GLcontext *, const int * );
-struct dynfn *r200_makeX86Vertex3fv( GLcontext *, const int * );
-struct dynfn *r200_makeX86Color4ub( GLcontext *, const int * );
-struct dynfn *r200_makeX86Color4ubv( GLcontext *, const int * );
-struct dynfn *r200_makeX86Color3ub( GLcontext *, const int * );
-struct dynfn *r200_makeX86Color3ubv( GLcontext *, const int * );
-struct dynfn *r200_makeX86Color4f( GLcontext *, const int * );
-struct dynfn *r200_makeX86Color4fv( GLcontext *, const int * );
-struct dynfn *r200_makeX86Color3f( GLcontext *, const int * );
-struct dynfn *r200_makeX86Color3fv( GLcontext *, const int * );
-struct dynfn *r200_makeX86SecondaryColor3ubEXT( GLcontext *, const int * );
-struct dynfn *r200_makeX86SecondaryColor3ubvEXT( GLcontext *, const int * );
-struct dynfn *r200_makeX86SecondaryColor3fEXT( GLcontext *, const int * );
-struct dynfn *r200_makeX86SecondaryColor3fvEXT( GLcontext *, const int * );
-struct dynfn *r200_makeX86Normal3f( GLcontext *, const int * );
-struct dynfn *r200_makeX86Normal3fv( GLcontext *, const int * );
-struct dynfn *r200_makeX86TexCoord2f( GLcontext *, const int * );
-struct dynfn *r200_makeX86TexCoord2fv( GLcontext *, const int * );
-struct dynfn *r200_makeX86TexCoord1f( GLcontext *, const int * );
-struct dynfn *r200_makeX86TexCoord1fv( GLcontext *, const int * );
-struct dynfn *r200_makeX86MultiTexCoord2fARB( GLcontext *, const int * );
-struct dynfn *r200_makeX86MultiTexCoord2fvARB( GLcontext *, const int * );
-struct dynfn *r200_makeX86MultiTexCoord1fARB( GLcontext *, const int * );
-struct dynfn *r200_makeX86MultiTexCoord1fvARB( GLcontext *, const int * );
-
-#endif
diff --git a/src/mesa/drivers/dri/r200/r200_vtxfmt_c.c b/src/mesa/drivers/dri/r200/r200_vtxfmt_c.c
deleted file mode 100644
index 1db5950c8ff..00000000000
--- a/src/mesa/drivers/dri/r200/r200_vtxfmt_c.c
+++ /dev/null
@@ -1,1002 +0,0 @@
-/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_c.c,v 1.2 2002/12/16 16:18:56 dawes Exp $ */
-/*
-Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
-
-The Weather Channel (TM) funded Tungsten Graphics to develop the
-initial release of the Radeon 8500 driver under the XFree86 license.
-This notice must be preserved.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial
-portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Keith Whitwell <[email protected]>
- */
-
-#include "glheader.h"
-#include "imports.h"
-#include "mtypes.h"
-#include "colormac.h"
-#include "simple_list.h"
-#include "api_noop.h"
-#include "vtxfmt.h"
-
-#include "r200_vtxfmt.h"
-#include "r200_tcl.h"
-
-#include "dispatch.h"
-
-/* Fallback versions of all the entrypoints for situations where
- * codegen isn't available. This is still a lot faster than the
- * vb/pipeline implementation in Mesa.
- */
-static void r200_Vertex3f( GLfloat x, GLfloat y, GLfloat z )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- int i;
-
- *rmesa->vb.dmaptr++ = *(int *)&x;
- *rmesa->vb.dmaptr++ = *(int *)&y;
- *rmesa->vb.dmaptr++ = *(int *)&z;
-
- for (i = 3; i < rmesa->vb.vertex_size; i++)
- *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i;
-
- if (--rmesa->vb.counter == 0)
- rmesa->vb.notify();
-}
-
-
-static void r200_Vertex3fv( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- int i;
-
- *rmesa->vb.dmaptr++ = *(int *)&v[0];
- *rmesa->vb.dmaptr++ = *(int *)&v[1];
- *rmesa->vb.dmaptr++ = *(int *)&v[2];
-
- for (i = 3; i < rmesa->vb.vertex_size; i++)
- *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i;
-
- if (--rmesa->vb.counter == 0)
- rmesa->vb.notify();
-}
-
-
-static void r200_Vertex2f( GLfloat x, GLfloat y )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- int i;
-
- *rmesa->vb.dmaptr++ = *(int *)&x;
- *rmesa->vb.dmaptr++ = *(int *)&y;
- *rmesa->vb.dmaptr++ = 0;
-
- for (i = 3; i < rmesa->vb.vertex_size; i++)
- *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i;
-
- if (--rmesa->vb.counter == 0)
- rmesa->vb.notify();
-}
-
-
-static void r200_Vertex2fv( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- int i;
-
- *rmesa->vb.dmaptr++ = *(int *)&v[0];
- *rmesa->vb.dmaptr++ = *(int *)&v[1];
- *rmesa->vb.dmaptr++ = 0;
-
- for (i = 3; i < rmesa->vb.vertex_size; i++)
- *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i;
-
- if (--rmesa->vb.counter == 0)
- rmesa->vb.notify();
-}
-
-
-
-/* Color for ubyte (packed) color formats:
- */
-#if 0
-static void r200_Color3ub_ub( GLubyte r, GLubyte g, GLubyte b )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- r200_color_t *dest = rmesa->vb.colorptr;
- dest->red = r;
- dest->green = g;
- dest->blue = b;
- dest->alpha = 0xff;
-}
-
-static void r200_Color3ubv_ub( const GLubyte *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- r200_color_t *dest = rmesa->vb.colorptr;
- dest->red = v[0];
- dest->green = v[1];
- dest->blue = v[2];
- dest->alpha = 0xff;
-}
-
-static void r200_Color4ub_ub( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- r200_color_t *dest = rmesa->vb.colorptr;
- dest->red = r;
- dest->green = g;
- dest->blue = b;
- dest->alpha = a;
-}
-
-static void r200_Color4ubv_ub( const GLubyte *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- *(GLuint *)rmesa->vb.colorptr = LE32_TO_CPU(*(GLuint *)v);
-}
-#endif /* 0 */
-
-static void r200_Color3f_ub( GLfloat r, GLfloat g, GLfloat b )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- r200_color_t *dest = rmesa->vb.colorptr;
- UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r );
- UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g );
- UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b );
- dest->alpha = 255;
-}
-
-static void r200_Color3fv_ub( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- r200_color_t *dest = rmesa->vb.colorptr;
- UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] );
- UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] );
- UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] );
- dest->alpha = 255;
-}
-
-static void r200_Color4f_ub( GLfloat r, GLfloat g, GLfloat b, GLfloat a )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- r200_color_t *dest = rmesa->vb.colorptr;
- UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r );
- UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g );
- UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b );
- UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, a );
-}
-
-static void r200_Color4fv_ub( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- r200_color_t *dest = rmesa->vb.colorptr;
- UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] );
- UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] );
- UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] );
- UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, v[3] );
-}
-
-
-/* Color for float color+alpha formats:
- */
-#if 0
-static void r200_Color3ub_4f( GLubyte r, GLubyte g, GLubyte b )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = UBYTE_TO_FLOAT(r);
- dest[1] = UBYTE_TO_FLOAT(g);
- dest[2] = UBYTE_TO_FLOAT(b);
- dest[3] = 1.0;
-}
-
-static void r200_Color3ubv_4f( const GLubyte *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = UBYTE_TO_FLOAT(v[0]);
- dest[1] = UBYTE_TO_FLOAT(v[1]);
- dest[2] = UBYTE_TO_FLOAT(v[2]);
- dest[3] = 1.0;
-}
-
-static void r200_Color4ub_4f( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = UBYTE_TO_FLOAT(r);
- dest[1] = UBYTE_TO_FLOAT(g);
- dest[2] = UBYTE_TO_FLOAT(b);
- dest[3] = UBYTE_TO_FLOAT(a);
-}
-
-static void r200_Color4ubv_4f( const GLubyte *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = UBYTE_TO_FLOAT(v[0]);
- dest[1] = UBYTE_TO_FLOAT(v[1]);
- dest[2] = UBYTE_TO_FLOAT(v[2]);
- dest[3] = UBYTE_TO_FLOAT(v[3]);
-}
-#endif /* 0 */
-
-
-static void r200_Color3f_4f( GLfloat r, GLfloat g, GLfloat b )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = r;
- dest[1] = g;
- dest[2] = b;
- dest[3] = 1.0;
-}
-
-static void r200_Color3fv_4f( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = v[0];
- dest[1] = v[1];
- dest[2] = v[2];
- dest[3] = 1.0;
-}
-
-static void r200_Color4f_4f( GLfloat r, GLfloat g, GLfloat b, GLfloat a )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = r;
- dest[1] = g;
- dest[2] = b;
- dest[3] = a;
-}
-
-static void r200_Color4fv_4f( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = v[0];
- dest[1] = v[1];
- dest[2] = v[2];
- dest[3] = v[3];
-}
-
-
-/* Color for float color formats:
- */
-#if 0
-static void r200_Color3ub_3f( GLubyte r, GLubyte g, GLubyte b )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = UBYTE_TO_FLOAT(r);
- dest[1] = UBYTE_TO_FLOAT(g);
- dest[2] = UBYTE_TO_FLOAT(b);
-}
-
-static void r200_Color3ubv_3f( const GLubyte *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = UBYTE_TO_FLOAT(v[0]);
- dest[1] = UBYTE_TO_FLOAT(v[1]);
- dest[2] = UBYTE_TO_FLOAT(v[2]);
-}
-
-static void r200_Color4ub_3f( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = UBYTE_TO_FLOAT(r);
- dest[1] = UBYTE_TO_FLOAT(g);
- dest[2] = UBYTE_TO_FLOAT(b);
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT(a);
-}
-
-static void r200_Color4ubv_3f( const GLubyte *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = UBYTE_TO_FLOAT(v[0]);
- dest[1] = UBYTE_TO_FLOAT(v[1]);
- dest[2] = UBYTE_TO_FLOAT(v[2]);
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT(v[3]);
-}
-#endif /* 0 */
-
-
-static void r200_Color3f_3f( GLfloat r, GLfloat g, GLfloat b )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = r;
- dest[1] = g;
- dest[2] = b;
-}
-
-static void r200_Color3fv_3f( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = v[0];
- dest[1] = v[1];
- dest[2] = v[2];
-}
-
-static void r200_Color4f_3f( GLfloat r, GLfloat g, GLfloat b, GLfloat a )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = r;
- dest[1] = g;
- dest[2] = b;
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = a;
-}
-
-static void r200_Color4fv_3f( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = v[0];
- dest[1] = v[1];
- dest[2] = v[2];
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = v[3];
-}
-
-
-/* Secondary Color:
- */
-#if 0
-static void r200_SecondaryColor3ubEXT_ub( GLubyte r, GLubyte g, GLubyte b )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- r200_color_t *dest = rmesa->vb.specptr;
- dest->red = r;
- dest->green = g;
- dest->blue = b;
- dest->alpha = 0xff;
-}
-
-static void r200_SecondaryColor3ubvEXT_ub( const GLubyte *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- r200_color_t *dest = rmesa->vb.specptr;
- dest->red = v[0];
- dest->green = v[1];
- dest->blue = v[2];
- dest->alpha = 0xff;
-}
-#endif /* 0 */
-
-static void r200_SecondaryColor3fEXT_ub( GLfloat r, GLfloat g, GLfloat b )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- r200_color_t *dest = rmesa->vb.specptr;
- UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r );
- UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g );
- UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b );
- dest->alpha = 255;
-}
-
-static void r200_SecondaryColor3fvEXT_ub( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- r200_color_t *dest = rmesa->vb.specptr;
- UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] );
- UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] );
- UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] );
- dest->alpha = 255;
-}
-
-#if 0
-static void r200_SecondaryColor3ubEXT_3f( GLubyte r, GLubyte g, GLubyte b )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatspecptr;
- dest[0] = UBYTE_TO_FLOAT(r);
- dest[1] = UBYTE_TO_FLOAT(g);
- dest[2] = UBYTE_TO_FLOAT(b);
- dest[3] = 1.0;
-}
-
-static void r200_SecondaryColor3ubvEXT_3f( const GLubyte *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatspecptr;
- dest[0] = UBYTE_TO_FLOAT(v[0]);
- dest[1] = UBYTE_TO_FLOAT(v[1]);
- dest[2] = UBYTE_TO_FLOAT(v[2]);
- dest[3] = 1.0;
-}
-#endif /* 0 */
-
-static void r200_SecondaryColor3fEXT_3f( GLfloat r, GLfloat g, GLfloat b )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatspecptr;
- dest[0] = r;
- dest[1] = g;
- dest[2] = b;
- dest[3] = 1.0;
-}
-
-static void r200_SecondaryColor3fvEXT_3f( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatspecptr;
- dest[0] = v[0];
- dest[1] = v[1];
- dest[2] = v[2];
- dest[3] = 1.0;
-}
-
-
-
-/* Normal
- */
-static void r200_Normal3f( GLfloat n0, GLfloat n1, GLfloat n2 )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.normalptr;
- dest[0] = n0;
- dest[1] = n1;
- dest[2] = n2;
-}
-
-static void r200_Normal3fv( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.normalptr;
- dest[0] = v[0];
- dest[1] = v[1];
- dest[2] = v[2];
-}
-
-
-/* FogCoord
- */
-static void r200_FogCoordfEXT( GLfloat f )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.fogptr;
- dest[0] = r200ComputeFogBlendFactor( ctx, f );
-/* ctx->Current.Attrib[VERT_ATTRIB_FOG][0] = f;*/
-}
-
-static void r200_FogCoordfvEXT( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.fogptr;
- dest[0] = r200ComputeFogBlendFactor( ctx, v[0] );
-/* ctx->Current.Attrib[VERT_ATTRIB_FOG][0] = v[0];*/
-}
-
-
-/* TexCoord
- */
-
-/* \todo maybe (target & 4 ? target & 5 : target & 3) is more save than (target & 7) */
-static void r200_MultiTexCoord1fARB(GLenum target, GLfloat s)
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLint unit = (target & 7);
- GLfloat * const dest = rmesa->vb.texcoordptr[unit];
-
- switch( ctx->Texture.Unit[unit]._ReallyEnabled ) {
- case TEXTURE_CUBE_BIT:
- case TEXTURE_3D_BIT:
- dest[2] = 0.0;
- /* FALLTHROUGH */
- case TEXTURE_2D_BIT:
- case TEXTURE_RECT_BIT:
- dest[1] = 0.0;
- /* FALLTHROUGH */
- case TEXTURE_1D_BIT:
- dest[0] = s;
- }
-}
-
-static void r200_MultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t)
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLint unit = (target & 7);
- GLfloat * const dest = rmesa->vb.texcoordptr[unit];
-
- switch( ctx->Texture.Unit[unit]._ReallyEnabled ) {
- case TEXTURE_CUBE_BIT:
- case TEXTURE_3D_BIT:
- dest[2] = 0.0;
- /* FALLTHROUGH */
- case TEXTURE_2D_BIT:
- case TEXTURE_RECT_BIT:
- dest[1] = t;
- dest[0] = s;
- break;
- default:
- VFMT_FALLBACK(__FUNCTION__);
- CALL_MultiTexCoord2fARB(GET_DISPATCH(), (target, s, t));
- return;
- }
-}
-
-static void r200_MultiTexCoord3fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r)
-{
- GET_CURRENT_CONTEXT(ctx);
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLint unit = (target & 7);
- GLfloat * const dest = rmesa->vb.texcoordptr[unit];
-
- switch( ctx->Texture.Unit[unit]._ReallyEnabled ) {
- case TEXTURE_CUBE_BIT:
- case TEXTURE_3D_BIT:
- dest[2] = r;
- dest[1] = t;
- dest[0] = s;
- break;
- default:
- VFMT_FALLBACK(__FUNCTION__);
- CALL_MultiTexCoord3fARB(GET_DISPATCH(), (target, s, t, r));
- return;
- }
-}
-
-static void r200_TexCoord1f(GLfloat s)
-{
- r200_MultiTexCoord1fARB(GL_TEXTURE0, s);
-}
-
-static void r200_TexCoord2f(GLfloat s, GLfloat t)
-{
- r200_MultiTexCoord2fARB(GL_TEXTURE0, s, t);
-}
-
-static void r200_TexCoord3f(GLfloat s, GLfloat t, GLfloat r)
-{
- r200_MultiTexCoord3fARB(GL_TEXTURE0, s, t, r);
-}
-
-static void r200_TexCoord1fv(const GLfloat *v)
-{
- r200_MultiTexCoord1fARB(GL_TEXTURE0, v[0]);
-}
-
-static void r200_TexCoord2fv(const GLfloat *v)
-{
- r200_MultiTexCoord2fARB(GL_TEXTURE0, v[0], v[1]);
-}
-
-static void r200_TexCoord3fv(const GLfloat *v)
-{
- r200_MultiTexCoord3fARB(GL_TEXTURE0, v[0], v[1], v[2]);
-}
-
-static void r200_MultiTexCoord1fvARB(GLenum target, const GLfloat *v)
-{
- r200_MultiTexCoord1fARB(target, v[0]);
-}
-
-static void r200_MultiTexCoord2fvARB(GLenum target, const GLfloat *v)
-{
- r200_MultiTexCoord2fARB(target, v[0], v[1]);
-}
-
-static void r200_MultiTexCoord3fvARB(GLenum target, const GLfloat *v)
-{
- r200_MultiTexCoord3fARB(target, v[0], v[1], v[2]);
-}
-
-
-static struct dynfn *lookup( struct dynfn *l, const int *key )
-{
- struct dynfn *f;
-
- foreach( f, l ) {
- if (f->key[0] == key[0] && f->key[1] == key[1])
- return f;
- }
-
- return NULL;
-}
-
-/* Can't use the loopback template for this:
- */
-
-#define CHOOSE(FN, FNTYPE, MASK0, MASK1, ARGS1, ARGS2 ) \
-static void choose_##FN ARGS1 \
-{ \
- GET_CURRENT_CONTEXT(ctx); \
- r200ContextPtr rmesa = R200_CONTEXT(ctx); \
- int key[2]; \
- struct dynfn *dfn; \
- \
- key[0] = rmesa->vb.vtxfmt_0 & MASK0; \
- key[1] = rmesa->vb.vtxfmt_1 & MASK1; \
- \
- dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \
- if (dfn == 0) \
- dfn = rmesa->vb.codegen.FN( ctx, key ); \
- else if (R200_DEBUG & DEBUG_CODEGEN) \
- fprintf(stderr, "%s -- cached codegen\n", __FUNCTION__ ); \
- \
- if (dfn) \
- SET_ ## FN (ctx->Exec, (FNTYPE)(dfn->code)); \
- else { \
- if (R200_DEBUG & DEBUG_CODEGEN) \
- fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \
- SET_ ## FN (ctx->Exec, r200_##FN); \
- } \
- \
- ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \
- CALL_ ## FN (ctx->Exec, ARGS2); \
-}
-
-
-
-/* For the _3f case, only allow one color function to be hooked in at
- * a time. Eventually, use a similar mechanism to allow selecting the
- * color component of the vertex format based on client behaviour.
- *
- * Note: Perform these actions even if there is a codegen or cached
- * codegen version of the chosen function.
- */
-#define CHOOSE_COLOR(FN, FNTYPE, NR, MASK0, MASK1, ARGS1, ARGS2 ) \
-static void choose_##FN ARGS1 \
-{ \
- GET_CURRENT_CONTEXT(ctx); \
- r200ContextPtr rmesa = R200_CONTEXT(ctx); \
- int key[2]; \
- struct dynfn *dfn; \
- \
- key[0] = rmesa->vb.vtxfmt_0 & MASK0; \
- key[1] = rmesa->vb.vtxfmt_1 & MASK1; \
- \
- if (VTX_COLOR(rmesa->vb.vtxfmt_0,0) == R200_VTX_PK_RGBA) { \
- SET_ ## FN (ctx->Exec, r200_##FN##_ub); \
- } \
- else if (VTX_COLOR(rmesa->vb.vtxfmt_0,0) == R200_VTX_FP_RGB) { \
- \
- if (rmesa->vb.installed_color_3f_sz != NR) { \
- rmesa->vb.installed_color_3f_sz = NR; \
- if (NR == 3) ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = 1.0; \
- if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) { \
- r200_copy_to_current( ctx ); \
- _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); \
- CALL_ ## FN (ctx->Exec, ARGS2); \
- return; \
- } \
- } \
- \
- SET_ ## FN (ctx->Exec, r200_##FN##_3f); \
- } \
- else { \
- SET_ ## FN (ctx->Exec, r200_##FN##_4f); \
- } \
- \
- \
- dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \
- if (!dfn) dfn = rmesa->vb.codegen.FN( ctx, key ); \
- \
- if (dfn) { \
- if (R200_DEBUG & DEBUG_CODEGEN) \
- fprintf(stderr, "%s -- codegen version\n", __FUNCTION__ ); \
- SET_ ## FN (ctx->Exec, (FNTYPE)dfn->code); \
- } \
- else if (R200_DEBUG & DEBUG_CODEGEN) \
- fprintf(stderr, "%s -- 'c' version\n", __FUNCTION__ ); \
- \
- ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \
- CALL_ ## FN (ctx->Exec, ARGS2); \
-}
-
-
-
-/* Right now there are both _ub and _3f versions of the secondary color
- * functions. Currently, we only set-up the hardware to use the _ub versions.
- * The _3f versions are needed for the cases where secondary color isn't used
- * in the vertex format, but it still needs to be stored in the context
- * state vector.
- */
-#define CHOOSE_SECONDARY_COLOR(FN, FNTYPE, MASK0, MASK1, ARGS1, ARGS2 ) \
-static void choose_##FN ARGS1 \
-{ \
- GET_CURRENT_CONTEXT(ctx); \
- r200ContextPtr rmesa = R200_CONTEXT(ctx); \
- int key[2]; \
- struct dynfn *dfn; \
- \
- key[0] = rmesa->vb.vtxfmt_0 & MASK0; \
- key[1] = rmesa->vb.vtxfmt_1 & MASK1; \
- \
- dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \
- if (dfn == 0) \
- dfn = rmesa->vb.codegen.FN( ctx, key ); \
- else if (R200_DEBUG & DEBUG_CODEGEN) \
- fprintf(stderr, "%s -- cached version\n", __FUNCTION__ ); \
- \
- if (dfn) \
- SET_ ## FN (ctx->Exec, (FNTYPE)(dfn->code)); \
- else { \
- if (R200_DEBUG & DEBUG_CODEGEN) \
- fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \
- SET_ ## FN (ctx->Exec, (VTX_COLOR(rmesa->vb.vtxfmt_0,1) == R200_VTX_PK_RGBA) \
- ? r200_##FN##_ub : r200_##FN##_3f); \
- } \
- \
- ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \
- CALL_ ## FN (ctx->Exec, ARGS2); \
-}
-
-
-
-
-
-
-
-/* VTXFMT_0
- */
-#define MASK_XYZW (R200_VTX_W0|R200_VTX_Z0)
-#define MASK_NORM (MASK_XYZW|R200_VTX_N0)
-#define MASK_FOG (MASK_NORM |R200_VTX_DISCRETE_FOG)
-#define MASK_COLOR (MASK_FOG |(R200_VTX_COLOR_MASK<<R200_VTX_COLOR_0_SHIFT))
-#define MASK_SPEC (MASK_COLOR|(R200_VTX_COLOR_MASK<<R200_VTX_COLOR_1_SHIFT))
-
-/* VTXFMT_1
- */
-#define MASK_ST0 (0x7 << R200_VTX_TEX0_COMP_CNT_SHIFT)
-/* FIXME: maybe something like in the radeon driver is needed here? */
-
-
-typedef void (*p4f)( GLfloat, GLfloat, GLfloat, GLfloat );
-typedef void (*p3f)( GLfloat, GLfloat, GLfloat );
-typedef void (*p2f)( GLfloat, GLfloat );
-typedef void (*p1f)( GLfloat );
-typedef void (*pe3f)( GLenum, GLfloat, GLfloat, GLfloat );
-typedef void (*pe2f)( GLenum, GLfloat, GLfloat );
-typedef void (*pe1f)( GLenum, GLfloat );
-typedef void (*p4ub)( GLubyte, GLubyte, GLubyte, GLubyte );
-typedef void (*p3ub)( GLubyte, GLubyte, GLubyte );
-typedef void (*pfv)( const GLfloat * );
-typedef void (*pefv)( GLenum, const GLfloat * );
-typedef void (*pubv)( const GLubyte * );
-
-
-CHOOSE(Normal3f, p3f, MASK_NORM, 0,
- (GLfloat a,GLfloat b,GLfloat c), (a,b,c))
-CHOOSE(Normal3fv, pfv, MASK_NORM, 0,
- (const GLfloat *v), (v))
-
-#if 0
-CHOOSE_COLOR(Color4ub, p4ub, 4, MASK_COLOR, 0,
- (GLubyte a,GLubyte b, GLubyte c, GLubyte d), (a,b,c,d))
-CHOOSE_COLOR(Color4ubv, pubv, 4, MASK_COLOR, 0,
- (const GLubyte *v), (v))
-CHOOSE_COLOR(Color3ub, p3ub, 3, MASK_COLOR, 0,
- (GLubyte a,GLubyte b, GLubyte c), (a,b,c))
-CHOOSE_COLOR(Color3ubv, pubv, 3, MASK_COLOR, 0,
- (const GLubyte *v), (v))
-CHOOSE_SECONDARY_COLOR(SecondaryColor3ubEXT, p3ub, MASK_SPEC, 0,
- (GLubyte a,GLubyte b, GLubyte c), (a,b,c))
-CHOOSE_SECONDARY_COLOR(SecondaryColor3ubvEXT, pubv, MASK_SPEC, 0,
- (const GLubyte *v), (v))
-#endif
-
-CHOOSE_COLOR(Color4f, p4f, 4, MASK_COLOR, 0,
- (GLfloat a,GLfloat b, GLfloat c, GLfloat d), (a,b,c,d))
-CHOOSE_COLOR(Color4fv, pfv, 4, MASK_COLOR, 0,
- (const GLfloat *v), (v))
-CHOOSE_COLOR(Color3f, p3f, 3, MASK_COLOR, 0,
- (GLfloat a,GLfloat b, GLfloat c), (a,b,c))
-CHOOSE_COLOR(Color3fv, pfv, 3, MASK_COLOR, 0,
- (const GLfloat *v), (v))
-
-
-CHOOSE_SECONDARY_COLOR(SecondaryColor3fEXT, p3f, MASK_SPEC, 0,
- (GLfloat a,GLfloat b, GLfloat c), (a,b,c))
-CHOOSE_SECONDARY_COLOR(SecondaryColor3fvEXT, pfv, MASK_SPEC, 0,
- (const GLfloat *v), (v))
-
-CHOOSE(TexCoord3f, p3f, ~0, MASK_ST0,
- (GLfloat a,GLfloat b,GLfloat c), (a,b,c))
-CHOOSE(TexCoord3fv, pfv, ~0, MASK_ST0,
- (const GLfloat *v), (v))
-CHOOSE(TexCoord2f, p2f, ~0, MASK_ST0,
- (GLfloat a,GLfloat b), (a,b))
-CHOOSE(TexCoord2fv, pfv, ~0, MASK_ST0,
- (const GLfloat *v), (v))
-CHOOSE(TexCoord1f, p1f, ~0, MASK_ST0,
- (GLfloat a), (a))
-CHOOSE(TexCoord1fv, pfv, ~0, MASK_ST0,
- (const GLfloat *v), (v))
-
-CHOOSE(MultiTexCoord3fARB, pe3f, ~0, ~0,
- (GLenum u,GLfloat a,GLfloat b,GLfloat c), (u,a,b,c))
-CHOOSE(MultiTexCoord3fvARB, pefv, ~0, ~0,
- (GLenum u,const GLfloat *v), (u,v))
-CHOOSE(MultiTexCoord2fARB, pe2f, ~0, ~0,
- (GLenum u,GLfloat a,GLfloat b), (u,a,b))
-CHOOSE(MultiTexCoord2fvARB, pefv, ~0, ~0,
- (GLenum u,const GLfloat *v), (u,v))
-CHOOSE(MultiTexCoord1fARB, pe1f, ~0, ~0,
- (GLenum u,GLfloat a), (u,a))
-CHOOSE(MultiTexCoord1fvARB, pefv, ~0, ~0,
- (GLenum u,const GLfloat *v), (u,v))
-
-CHOOSE(Vertex3f, p3f, ~0, ~0,
- (GLfloat a,GLfloat b,GLfloat c), (a,b,c))
-CHOOSE(Vertex3fv, pfv, ~0, ~0,
- (const GLfloat *v), (v))
-CHOOSE(Vertex2f, p2f, ~0, ~0,
- (GLfloat a,GLfloat b), (a,b))
-CHOOSE(Vertex2fv, pfv, ~0, ~0,
- (const GLfloat *v), (v))
-
-CHOOSE(FogCoordfEXT, p1f, MASK_FOG, ~0,
- (GLfloat f), (f))
-CHOOSE(FogCoordfvEXT, pfv, MASK_FOG, ~0,
- (const GLfloat *f), (f))
-
-
-
-
-void r200VtxfmtInitChoosers( GLvertexformat *vfmt )
-{
- vfmt->Color3f = choose_Color3f;
- vfmt->Color3fv = choose_Color3fv;
- vfmt->Color4f = choose_Color4f;
- vfmt->Color4fv = choose_Color4fv;
- vfmt->SecondaryColor3fEXT = choose_SecondaryColor3fEXT;
- vfmt->SecondaryColor3fvEXT = choose_SecondaryColor3fvEXT;
- vfmt->MultiTexCoord1fARB = choose_MultiTexCoord1fARB;
- vfmt->MultiTexCoord1fvARB = choose_MultiTexCoord1fvARB;
- vfmt->MultiTexCoord2fARB = choose_MultiTexCoord2fARB;
- vfmt->MultiTexCoord2fvARB = choose_MultiTexCoord2fvARB;
- vfmt->MultiTexCoord3fARB = choose_MultiTexCoord3fARB;
- vfmt->MultiTexCoord3fvARB = choose_MultiTexCoord3fvARB;
- vfmt->Normal3f = choose_Normal3f;
- vfmt->Normal3fv = choose_Normal3fv;
- vfmt->TexCoord1f = choose_TexCoord1f;
- vfmt->TexCoord1fv = choose_TexCoord1fv;
- vfmt->TexCoord2f = choose_TexCoord2f;
- vfmt->TexCoord2fv = choose_TexCoord2fv;
- vfmt->TexCoord3f = choose_TexCoord3f;
- vfmt->TexCoord3fv = choose_TexCoord3fv;
- vfmt->Vertex2f = choose_Vertex2f;
- vfmt->Vertex2fv = choose_Vertex2fv;
- vfmt->Vertex3f = choose_Vertex3f;
- vfmt->Vertex3fv = choose_Vertex3fv;
-/* vfmt->FogCoordfEXT = choose_FogCoordfEXT;
- vfmt->FogCoordfvEXT = choose_FogCoordfvEXT;*/
-
- /* TODO: restore ubyte colors to vtxfmt.
- */
-#if 0
- vfmt->Color3ub = choose_Color3ub;
- vfmt->Color3ubv = choose_Color3ubv;
- vfmt->Color4ub = choose_Color4ub;
- vfmt->Color4ubv = choose_Color4ubv;
- vfmt->SecondaryColor3ubEXT = choose_SecondaryColor3ubEXT;
- vfmt->SecondaryColor3ubvEXT = choose_SecondaryColor3ubvEXT;
-#endif
-}
-
-
-static struct dynfn *codegen_noop( GLcontext *ctx, const int *key )
-{
- (void) ctx; (void) key;
- return NULL;
-}
-
-void r200InitCodegen( struct dfn_generators *gen, GLboolean useCodegen )
-{
- gen->Vertex3f = codegen_noop;
- gen->Vertex3fv = codegen_noop;
- gen->Color4ub = codegen_noop;
- gen->Color4ubv = codegen_noop;
- gen->Normal3f = codegen_noop;
- gen->Normal3fv = codegen_noop;
-
- gen->TexCoord3f = codegen_noop;
- gen->TexCoord3fv = codegen_noop;
- gen->TexCoord2f = codegen_noop;
- gen->TexCoord2fv = codegen_noop;
- gen->TexCoord1f = codegen_noop;
- gen->TexCoord1fv = codegen_noop;
-
- gen->MultiTexCoord3fARB = codegen_noop;
- gen->MultiTexCoord3fvARB = codegen_noop;
- gen->MultiTexCoord2fARB = codegen_noop;
- gen->MultiTexCoord2fvARB = codegen_noop;
- gen->MultiTexCoord1fARB = codegen_noop;
- gen->MultiTexCoord1fvARB = codegen_noop;
-/* gen->FogCoordfEXT = codegen_noop;
- gen->FogCoordfvEXT = codegen_noop;*/
-
- gen->Vertex2f = codegen_noop;
- gen->Vertex2fv = codegen_noop;
- gen->Color3ub = codegen_noop;
- gen->Color3ubv = codegen_noop;
- gen->Color4f = codegen_noop;
- gen->Color4fv = codegen_noop;
- gen->Color3f = codegen_noop;
- gen->Color3fv = codegen_noop;
- gen->SecondaryColor3fEXT = codegen_noop;
- gen->SecondaryColor3fvEXT = codegen_noop;
- gen->SecondaryColor3ubEXT = codegen_noop;
- gen->SecondaryColor3ubvEXT = codegen_noop;
-
- if (useCodegen) {
-#if defined(USE_X86_ASM)
- r200InitX86Codegen( gen );
-#endif
-
-#if defined(USE_SSE_ASM)
- r200InitSSECodegen( gen );
-#endif
- }
-}
diff --git a/src/mesa/drivers/dri/r200/r200_vtxfmt_sse.c b/src/mesa/drivers/dri/r200/r200_vtxfmt_sse.c
deleted file mode 100644
index 5901730494a..00000000000
--- a/src/mesa/drivers/dri/r200/r200_vtxfmt_sse.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_sse.c,v 1.1 2002/10/30 12:51:53 alanh Exp $ */
-/*
-Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
-
-The Weather Channel (TM) funded Tungsten Graphics to develop the
-initial release of the Radeon 8500 driver under the XFree86 license.
-This notice must be preserved.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial
-portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Keith Whitwell <[email protected]>
- */
-
-#include "glheader.h"
-#include "imports.h"
-#include "simple_list.h"
-#include "r200_vtxfmt.h"
-
-#if defined(USE_SSE_ASM)
-#include "x86/common_x86_asm.h"
-
-#define EXTERN( FUNC ) \
-extern const char *FUNC; \
-extern const char *FUNC##_end
-
-EXTERN( _sse_Attribute2fv );
-EXTERN( _sse_Attribute2f );
-EXTERN( _sse_Attribute3fv );
-EXTERN( _sse_Attribute3f );
-EXTERN( _sse_MultiTexCoord2fv );
-EXTERN( _sse_MultiTexCoord2f );
-EXTERN( _sse_MultiTexCoord2fv_2 );
-EXTERN( _sse_MultiTexCoord2f_2 );
-
-/* Build specialized versions of the immediate calls on the fly for
- * the current state.
- */
-
-static struct dynfn *r200_makeSSEAttribute2fv( struct dynfn * cache, const int * key,
- const char * name, void * dest)
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (R200_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x\n", name, key[0] );
-
- DFN ( _sse_Attribute2fv, (*cache) );
- FIXUP(dfn->code, 10, 0x0, (int)dest);
- return dfn;
-}
-
-static struct dynfn *r200_makeSSEAttribute2f( struct dynfn * cache, const int * key,
- const char * name, void * dest )
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (R200_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x\n", name, key[0] );
-
- DFN ( _sse_Attribute2f, (*cache) );
- FIXUP(dfn->code, 8, 0x0, (int)dest);
- return dfn;
-}
-
-static struct dynfn *r200_makeSSEAttribute3fv( struct dynfn * cache, const int * key,
- const char * name, void * dest)
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (R200_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x\n", name, key[0] );
-
- DFN ( _sse_Attribute3fv, (*cache) );
- FIXUP(dfn->code, 13, 0x0, (int)dest);
- FIXUP(dfn->code, 18, 0x8, 8+(int)dest);
- return dfn;
-}
-
-static struct dynfn *r200_makeSSEAttribute3f( struct dynfn * cache, const int * key,
- const char * name, void * dest )
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (R200_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x\n", name, key[0] );
-
- DFN ( _sse_Attribute3f, (*cache) );
- FIXUP(dfn->code, 12, 0x0, (int)dest);
- FIXUP(dfn->code, 17, 0x8, 8+(int)dest);
- return dfn;
-}
-
-static struct dynfn *r200_makeSSENormal3fv( GLcontext *ctx, const int *key )
-{
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
- return r200_makeSSEAttribute3fv( & rmesa->vb.dfn_cache.Normal3fv, key,
- __FUNCTION__, rmesa->vb.normalptr );
-}
-
-static struct dynfn *r200_makeSSENormal3f( GLcontext *ctx, const int * key )
-{
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
- return r200_makeSSEAttribute3f( & rmesa->vb.dfn_cache.Normal3f, key,
- __FUNCTION__, rmesa->vb.normalptr );
-}
-
-static struct dynfn *r200_makeSSEColor3fv( GLcontext *ctx, const int * key )
-{
- if (VTX_COLOR(key[0],0) != R200_VTX_FP_RGB)
- return NULL;
- else
- {
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
- return r200_makeSSEAttribute3fv( & rmesa->vb.dfn_cache.Color3fv, key,
- __FUNCTION__, rmesa->vb.floatcolorptr );
- }
-}
-
-static struct dynfn *r200_makeSSEColor3f( GLcontext *ctx, const int * key )
-{
- if (VTX_COLOR(key[0],0) != R200_VTX_FP_RGB)
- return NULL;
- else
- {
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
- return r200_makeSSEAttribute3f( & rmesa->vb.dfn_cache.Color3f, key,
- __FUNCTION__, rmesa->vb.floatcolorptr );
- }
-}
-
-#if 0 /* Temporarily disabled as it is broken w/the new cubemap code. - idr */
-static struct dynfn *r200_makeSSETexCoord2fv( GLcontext *ctx, const int * key )
-{
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
- return r200_makeSSEAttribute2fv( & rmesa->vb.dfn_cache.TexCoord2fv, key,
- __FUNCTION__, rmesa->vb.texcoordptr[0] );
-}
-
-static struct dynfn *r200_makeSSETexCoord2f( GLcontext *ctx, const int * key )
-{
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
- return r200_makeSSEAttribute2f( & rmesa->vb.dfn_cache.TexCoord2f, key,
- __FUNCTION__, rmesa->vb.texcoordptr[0] );
-}
-
-static struct dynfn *r200_makeSSEMultiTexCoord2fv( GLcontext *ctx, const int * key )
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
- if (R200_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] );
-
- if (rmesa->vb.texcoordptr[1] == rmesa->vb.texcoordptr[0]+4) {
- DFN ( _sse_MultiTexCoord2fv, rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
- FIXUP(dfn->code, 18, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]);
- } else {
- DFN ( _sse_MultiTexCoord2fv_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
- FIXUP(dfn->code, 14, 0x0, (int)rmesa->vb.texcoordptr);
- }
- return dfn;
-}
-
-static struct dynfn *r200_makeSSEMultiTexCoord2f( GLcontext *ctx, const int * key )
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
- if (R200_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] );
-
- if (rmesa->vb.texcoordptr[1] == rmesa->vb.texcoordptr[0]+4) {
- DFN ( _sse_MultiTexCoord2f, rmesa->vb.dfn_cache.MultiTexCoord2fARB );
- FIXUP(dfn->code, 16, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]);
- } else {
- DFN ( _sse_MultiTexCoord2f_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB );
- FIXUP(dfn->code, 15, 0x0, (int)rmesa->vb.texcoordptr);
- }
- return dfn;
-}
-#endif
-
-void r200InitSSECodegen( struct dfn_generators *gen )
-{
- if ( cpu_has_xmm ) {
- gen->Normal3fv = (void *) r200_makeSSENormal3fv;
- gen->Normal3f = (void *) r200_makeSSENormal3f;
- gen->Color3fv = (void *) r200_makeSSEColor3fv;
- gen->Color3f = (void *) r200_makeSSEColor3f;
-#if 0 /* Temporarily disabled as it is broken w/the new cubemap code. - idr */
- gen->TexCoord2fv = (void *) r200_makeSSETexCoord2fv;
- gen->TexCoord2f = (void *) r200_makeSSETexCoord2f;
- gen->MultiTexCoord2fvARB = (void *) r200_makeSSEMultiTexCoord2fv;
- gen->MultiTexCoord2fARB = (void *) r200_makeSSEMultiTexCoord2f;
-#endif
- }
-}
-
-#else
-
-void r200InitSSECodegen( struct dfn_generators *gen )
-{
- (void) gen;
-}
-
-#endif
diff --git a/src/mesa/drivers/dri/r200/r200_vtxfmt_x86.c b/src/mesa/drivers/dri/r200/r200_vtxfmt_x86.c
deleted file mode 100644
index b78a55c31f6..00000000000
--- a/src/mesa/drivers/dri/r200/r200_vtxfmt_x86.c
+++ /dev/null
@@ -1,440 +0,0 @@
-/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_x86.c,v 1.2 2002/12/16 16:18:56 dawes Exp $ */
-/*
-Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
-
-The Weather Channel (TM) funded Tungsten Graphics to develop the
-initial release of the Radeon 8500 driver under the XFree86 license.
-This notice must be preserved.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial
-portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Keith Whitwell <[email protected]>
- */
-
-#include "glheader.h"
-#include "imports.h"
-#include "simple_list.h"
-#include "r200_vtxfmt.h"
-
-#if defined(USE_X86_ASM)
-
-#define EXTERN( FUNC ) \
-extern const char *FUNC; \
-extern const char *FUNC##_end
-
-EXTERN ( _x86_Attribute2fv );
-EXTERN ( _x86_Attribute2f );
-EXTERN ( _x86_Attribute3fv );
-EXTERN ( _x86_Attribute3f );
-EXTERN ( _x86_Vertex3fv_6 );
-EXTERN ( _x86_Vertex3fv_8 );
-EXTERN ( _x86_Vertex3fv );
-EXTERN ( _x86_Vertex3f_4 );
-EXTERN ( _x86_Vertex3f_6 );
-EXTERN ( _x86_Vertex3f );
-EXTERN ( _x86_Color4ubv_ub );
-EXTERN ( _x86_Color4ubv_4f );
-EXTERN ( _x86_Color4ub_ub );
-EXTERN ( _x86_MultiTexCoord2fv );
-EXTERN ( _x86_MultiTexCoord2fv_2 );
-EXTERN ( _x86_MultiTexCoord2f );
-EXTERN ( _x86_MultiTexCoord2f_2 );
-
-
-/* Build specialized versions of the immediate calls on the fly for
- * the current state. Generic x86 versions.
- */
-
-struct dynfn *r200_makeX86Vertex3f( GLcontext *ctx, const int *key )
-{
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (R200_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x 0x%08x %d\n", __FUNCTION__,
- key[0], key[1], rmesa->vb.vertex_size );
-
- switch (rmesa->vb.vertex_size) {
- case 4: {
-
- DFN ( _x86_Vertex3f_4, rmesa->vb.dfn_cache.Vertex3f );
- FIXUP(dfn->code, 2, 0x0, (int)&rmesa->vb.dmaptr);
- FIXUP(dfn->code, 25, 0x0, (int)&rmesa->vb.vertex[3]);
- FIXUP(dfn->code, 36, 0x0, (int)&rmesa->vb.counter);
- FIXUP(dfn->code, 46, 0x0, (int)&rmesa->vb.dmaptr);
- FIXUP(dfn->code, 51, 0x0, (int)&rmesa->vb.counter);
- FIXUP(dfn->code, 60, 0x0, (int)&rmesa->vb.notify);
- break;
- }
- case 6: {
-
- DFN ( _x86_Vertex3f_6, rmesa->vb.dfn_cache.Vertex3f );
- FIXUP(dfn->code, 3, 0x0, (int)&rmesa->vb.dmaptr);
- FIXUP(dfn->code, 28, 0x0, (int)&rmesa->vb.vertex[3]);
- FIXUP(dfn->code, 34, 0x0, (int)&rmesa->vb.vertex[4]);
- FIXUP(dfn->code, 40, 0x0, (int)&rmesa->vb.vertex[5]);
- FIXUP(dfn->code, 57, 0x0, (int)&rmesa->vb.counter);
- FIXUP(dfn->code, 63, 0x0, (int)&rmesa->vb.dmaptr);
- FIXUP(dfn->code, 70, 0x0, (int)&rmesa->vb.counter);
- FIXUP(dfn->code, 79, 0x0, (int)&rmesa->vb.notify);
- break;
- }
- default: {
-
- DFN ( _x86_Vertex3f, rmesa->vb.dfn_cache.Vertex3f );
- FIXUP(dfn->code, 3, 0x0, (int)&rmesa->vb.vertex[3]);
- FIXUP(dfn->code, 9, 0x0, (int)&rmesa->vb.dmaptr);
- FIXUP(dfn->code, 37, 0x0, rmesa->vb.vertex_size-3);
- FIXUP(dfn->code, 44, 0x0, (int)&rmesa->vb.counter);
- FIXUP(dfn->code, 50, 0x0, (int)&rmesa->vb.dmaptr);
- FIXUP(dfn->code, 56, 0x0, (int)&rmesa->vb.counter);
- FIXUP(dfn->code, 67, 0x0, (int)&rmesa->vb.notify);
- break;
- }
- }
-
- return dfn;
-}
-
-
-
-struct dynfn *r200_makeX86Vertex3fv( GLcontext *ctx, const int *key )
-{
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (R200_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x 0x%08x %d\n", __FUNCTION__,
- key[0], key[1], rmesa->vb.vertex_size );
-
- switch (rmesa->vb.vertex_size) {
- case 6: {
-
- DFN ( _x86_Vertex3fv_6, rmesa->vb.dfn_cache.Vertex3fv );
- FIXUP(dfn->code, 1, 0x00000000, (int)&rmesa->vb.dmaptr);
- FIXUP(dfn->code, 27, 0x0000001c, (int)&rmesa->vb.vertex[3]);
- FIXUP(dfn->code, 33, 0x00000020, (int)&rmesa->vb.vertex[4]);
- FIXUP(dfn->code, 45, 0x00000024, (int)&rmesa->vb.vertex[5]);
- FIXUP(dfn->code, 56, 0x00000000, (int)&rmesa->vb.dmaptr);
- FIXUP(dfn->code, 61, 0x00000004, (int)&rmesa->vb.counter);
- FIXUP(dfn->code, 67, 0x00000004, (int)&rmesa->vb.counter);
- FIXUP(dfn->code, 76, 0x00000008, (int)&rmesa->vb.notify);
- break;
- }
-
-
- case 8: {
-
- DFN ( _x86_Vertex3fv_8, rmesa->vb.dfn_cache.Vertex3fv );
- FIXUP(dfn->code, 1, 0x00000000, (int)&rmesa->vb.dmaptr);
- FIXUP(dfn->code, 27, 0x0000001c, (int)&rmesa->vb.vertex[3]);
- FIXUP(dfn->code, 33, 0x00000020, (int)&rmesa->vb.vertex[4]);
- FIXUP(dfn->code, 45, 0x0000001c, (int)&rmesa->vb.vertex[5]);
- FIXUP(dfn->code, 51, 0x00000020, (int)&rmesa->vb.vertex[6]);
- FIXUP(dfn->code, 63, 0x00000024, (int)&rmesa->vb.vertex[7]);
- FIXUP(dfn->code, 74, 0x00000000, (int)&rmesa->vb.dmaptr);
- FIXUP(dfn->code, 79, 0x00000004, (int)&rmesa->vb.counter);
- FIXUP(dfn->code, 85, 0x00000004, (int)&rmesa->vb.counter);
- FIXUP(dfn->code, 94, 0x00000008, (int)&rmesa->vb.notify);
- break;
- }
-
-
-
- default: {
-
- DFN ( _x86_Vertex3fv, rmesa->vb.dfn_cache.Vertex3fv );
- FIXUP(dfn->code, 8, 0x01010101, (int)&rmesa->vb.dmaptr);
- FIXUP(dfn->code, 32, 0x00000006, rmesa->vb.vertex_size-3);
- FIXUP(dfn->code, 37, 0x00000058, (int)&rmesa->vb.vertex[3]);
- FIXUP(dfn->code, 45, 0x01010101, (int)&rmesa->vb.dmaptr);
- FIXUP(dfn->code, 50, 0x02020202, (int)&rmesa->vb.counter);
- FIXUP(dfn->code, 58, 0x02020202, (int)&rmesa->vb.counter);
- FIXUP(dfn->code, 67, 0x0, (int)&rmesa->vb.notify);
- break;
- }
- }
-
- return dfn;
-}
-
-static struct dynfn *
-r200_makeX86Attribute2fv( struct dynfn * cache, const int *key,
- const char * name, void * dest )
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (R200_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x\n", name, key[0] );
-
- DFN ( _x86_Attribute2fv, (*cache) );
- FIXUP(dfn->code, 11, 0x0, (int)dest);
- FIXUP(dfn->code, 16, 0x4, 4+(int)dest);
-
- return dfn;
-}
-
-static struct dynfn *
-r200_makeX86Attribute2f( struct dynfn * cache, const int *key,
- const char * name, void * dest )
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (R200_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x\n", name, key[0] );
-
- DFN ( _x86_Attribute2f, (*cache) );
- FIXUP(dfn->code, 1, 0x0, (int)dest);
-
- return dfn;
-}
-
-
-static struct dynfn *
-r200_makeX86Attribute3fv( struct dynfn * cache, const int *key,
- const char * name, void * dest )
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (R200_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x\n", name, key[0] );
-
- DFN ( _x86_Attribute3fv, (*cache) );
- FIXUP(dfn->code, 14, 0x0, (int)dest);
- FIXUP(dfn->code, 20, 0x4, 4+(int)dest);
- FIXUP(dfn->code, 25, 0x8, 8+(int)dest);
-
- return dfn;
-}
-
-static struct dynfn *
-r200_makeX86Attribute3f( struct dynfn * cache, const int *key,
- const char * name, void * dest )
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (R200_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x\n", name, key[0] );
-
- DFN ( _x86_Attribute3f, (*cache) );
- FIXUP(dfn->code, 14, 0x0, (int)dest);
- FIXUP(dfn->code, 20, 0x4, 4+(int)dest);
- FIXUP(dfn->code, 25, 0x8, 8+(int)dest);
-
- return dfn;
-}
-
-struct dynfn *r200_makeX86Normal3fv( GLcontext *ctx, const int *key )
-{
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
- return r200_makeX86Attribute3fv( & rmesa->vb.dfn_cache.Normal3fv, key,
- __FUNCTION__, rmesa->vb.normalptr );
-}
-
-struct dynfn *r200_makeX86Normal3f( GLcontext *ctx, const int *key )
-{
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
- return r200_makeX86Attribute3f( & rmesa->vb.dfn_cache.Normal3f, key,
- __FUNCTION__, rmesa->vb.normalptr );
-}
-
-struct dynfn *r200_makeX86Color4ubv( GLcontext *ctx, const int *key )
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
-
- if (R200_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] );
-
- if (VTX_COLOR(key[0],0) == R200_VTX_PK_RGBA) {
- DFN ( _x86_Color4ubv_ub, rmesa->vb.dfn_cache.Color4ubv);
- FIXUP(dfn->code, 5, 0x12345678, (int)rmesa->vb.colorptr);
- return dfn;
- }
- else {
-
- DFN ( _x86_Color4ubv_4f, rmesa->vb.dfn_cache.Color4ubv);
- FIXUP(dfn->code, 2, 0x00000000, (int)_mesa_ubyte_to_float_color_tab);
- FIXUP(dfn->code, 27, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr);
- FIXUP(dfn->code, 33, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr+4);
- FIXUP(dfn->code, 55, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr+8);
- FIXUP(dfn->code, 61, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr+12);
- return dfn;
- }
-}
-
-struct dynfn *r200_makeX86Color4ub( GLcontext *ctx, const int *key )
-{
- if (R200_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] );
-
- if (VTX_COLOR(key[0],0) == R200_VTX_PK_RGBA) {
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
- DFN ( _x86_Color4ub_ub, rmesa->vb.dfn_cache.Color4ub );
- FIXUP(dfn->code, 18, 0x0, (int)rmesa->vb.colorptr);
- FIXUP(dfn->code, 24, 0x0, (int)rmesa->vb.colorptr+1);
- FIXUP(dfn->code, 30, 0x0, (int)rmesa->vb.colorptr+2);
- FIXUP(dfn->code, 36, 0x0, (int)rmesa->vb.colorptr+3);
- return dfn;
- }
- else
- return NULL;
-}
-
-
-struct dynfn *r200_makeX86Color3fv( GLcontext *ctx, const int *key )
-{
- if (VTX_COLOR(key[0],0) != R200_VTX_FP_RGB)
- return NULL;
- else
- {
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
- return r200_makeX86Attribute3fv( & rmesa->vb.dfn_cache.Color3fv, key,
- __FUNCTION__, rmesa->vb.floatcolorptr );
- }
-}
-
-struct dynfn *r200_makeX86Color3f( GLcontext *ctx, const int *key )
-{
- if (VTX_COLOR(key[0],0) != R200_VTX_FP_RGB)
- return NULL;
- else
- {
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
- return r200_makeX86Attribute3f( & rmesa->vb.dfn_cache.Color3f, key,
- __FUNCTION__, rmesa->vb.floatcolorptr );
- }
-}
-
-
-
-#if 0 /* Temporarily disabled as it is broken w/the new cubemap code. - idr */
-struct dynfn *r200_makeX86TexCoord2fv( GLcontext *ctx, const int *key )
-{
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
- return r200_makeX86Attribute2fv( & rmesa->vb.dfn_cache.TexCoord2fv, key,
- __FUNCTION__, rmesa->vb.texcoordptr[0] );
-}
-
-struct dynfn *r200_makeX86TexCoord2f( GLcontext *ctx, const int *key )
-{
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
- return r200_makeX86Attribute2f( & rmesa->vb.dfn_cache.TexCoord2f, key,
- __FUNCTION__, rmesa->vb.texcoordptr[0] );
-}
-
-struct dynfn *r200_makeX86MultiTexCoord2fvARB( GLcontext *ctx, const int *key )
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
- if (R200_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x 0x%08x\n", __FUNCTION__, key[0], key[1] );
-
- if (rmesa->vb.texcoordptr[1] == rmesa->vb.texcoordptr[0]+4) {
- DFN ( _x86_MultiTexCoord2fv, rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
- FIXUP(dfn->code, 21, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]);
- FIXUP(dfn->code, 27, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]+4);
- } else {
- DFN ( _x86_MultiTexCoord2fv_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
- FIXUP(dfn->code, 14, 0x0, (int)rmesa->vb.texcoordptr);
- }
- return dfn;
-}
-
-struct dynfn *r200_makeX86MultiTexCoord2fARB( GLcontext *ctx,
- const int *key )
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
- if (R200_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x 0x%08x\n", __FUNCTION__, key[0], key[1] );
-
- if (rmesa->vb.texcoordptr[1] == rmesa->vb.texcoordptr[0]+4) {
- DFN ( _x86_MultiTexCoord2f, rmesa->vb.dfn_cache.MultiTexCoord2fARB );
- FIXUP(dfn->code, 20, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]);
- FIXUP(dfn->code, 26, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]+4);
- }
- else {
- /* Note: this might get generated multiple times, even though the
- * actual emitted code is the same.
- */
- DFN ( _x86_MultiTexCoord2f_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB );
- FIXUP(dfn->code, 18, 0x0, (int)rmesa->vb.texcoordptr);
- }
- return dfn;
-}
-#endif
-
-void r200InitX86Codegen( struct dfn_generators *gen )
-{
- gen->Vertex3f = r200_makeX86Vertex3f;
- gen->Vertex3fv = r200_makeX86Vertex3fv;
- gen->Color4ub = r200_makeX86Color4ub; /* PKCOLOR only */
- gen->Color4ubv = r200_makeX86Color4ubv; /* PKCOLOR only */
- gen->Normal3f = r200_makeX86Normal3f;
- gen->Normal3fv = r200_makeX86Normal3fv;
-#if 0 /* Temporarily disabled as it is broken w/the new cubemap code. - idr */
- gen->TexCoord2f = r200_makeX86TexCoord2f;
- gen->TexCoord2fv = r200_makeX86TexCoord2fv;
- gen->MultiTexCoord2fARB = r200_makeX86MultiTexCoord2fARB;
- gen->MultiTexCoord2fvARB = r200_makeX86MultiTexCoord2fvARB;
-#endif
- gen->Color3f = r200_makeX86Color3f;
- gen->Color3fv = r200_makeX86Color3fv;
-
- /* Not done:
- */
-/* gen->Vertex2f = r200_makeX86Vertex2f; */
-/* gen->Vertex2fv = r200_makeX86Vertex2fv; */
-/* gen->Color3ub = r200_makeX86Color3ub; */
-/* gen->Color3ubv = r200_makeX86Color3ubv; */
-/* gen->Color4f = r200_makeX86Color4f; */
-/* gen->Color4fv = r200_makeX86Color4fv; */
-/* gen->TexCoord1f = r200_makeX86TexCoord1f; */
-/* gen->TexCoord1fv = r200_makeX86TexCoord1fv; */
-/* gen->MultiTexCoord1fARB = r200_makeX86MultiTexCoord1fARB; */
-/* gen->MultiTexCoord1fvARB = r200_makeX86MultiTexCoord1fvARB; */
-}
-
-
-#else
-
-void r200InitX86Codegen( struct dfn_generators *gen )
-{
- (void) gen;
-}
-
-#endif
diff --git a/src/mesa/drivers/dri/r200/r200_vtxtmp_x86.S b/src/mesa/drivers/dri/r200/r200_vtxtmp_x86.S
deleted file mode 100644
index 5e33c7bdeea..00000000000
--- a/src/mesa/drivers/dri/r200/r200_vtxtmp_x86.S
+++ /dev/null
@@ -1,499 +0,0 @@
-/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxtmp_x86.S,v 1.2 2002/11/07 18:31:59 tsi Exp $ */
-/**************************************************************************
-
-Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas.
-
-All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-on the rights to use, copy, modify, merge, publish, distribute, sub
-license, and/or sell copies of the Software, and to permit persons to whom
-the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice (including the next
-paragraph) shall be included in all copies or substantial portions of the
-Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
-ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-#define GLOBL( x ) \
-.globl x; \
-x:
-
-.data
-.align 4
-
-/*
- vertex 3f vertex size 4
-*/
-
-GLOBL ( _x86_Vertex3f_4 )
- movl (0), %ecx
- movl 4(%esp), %eax
- movl 8(%esp), %edx
- movl %eax, (%ecx)
- movl %edx, 4(%ecx)
- movl 12(%esp), %eax
- movl (0), %edx
- movl %eax, 8(%ecx)
- movl %edx, 12(%ecx)
- movl (0), %eax
- addl $16, %ecx
- dec %eax
- movl %ecx, (0)
- movl %eax, (0)
- je .1
- ret
-.1: jmp *0
-
-GLOBL ( _x86_Vertex3f_4_end )
-
-/*
- vertex 3f vertex size 6
-*/
-GLOBL ( _x86_Vertex3f_6 )
- push %edi
- movl (0), %edi
- movl 8(%esp), %eax
- movl 12(%esp), %edx
- movl 16(%esp), %ecx
- movl %eax, (%edi)
- movl %edx, 4(%edi)
- movl %ecx, 8(%edi)
- movl (0), %eax
- movl (0), %edx
- movl (0), %ecx
- movl %eax, 12(%edi)
- movl %edx, 16(%edi)
- movl %ecx, 20(%edi)
- addl $24, %edi
- movl (0), %eax
- movl %edi, (0)
- dec %eax
- pop %edi
- movl %eax, (0)
- je .2
- ret
-.2: jmp *0
-GLOBL ( _x86_Vertex3f_6_end )
-/*
- vertex 3f generic size
-*/
-GLOBL ( _x86_Vertex3f )
- push %edi
- push %esi
- movl $0, %esi
- movl (0), %edi
- movl 12(%esp), %eax
- movl 16(%esp), %edx
- movl 20(%esp), %ecx
- movl %eax, (%edi)
- movl %edx, 4(%edi)
- movl %ecx, 8(%edi)
- addl $12, %edi
- movl $0, %ecx
- repz
- movsl %ds:(%esi), %es:(%edi)
- movl (0), %eax
- movl %edi, (0)
- dec %eax
- movl %eax, (0)
- pop %esi
- pop %edi
- je .3
- ret
-.3: jmp *0
-
-GLOBL ( _x86_Vertex3f_end )
-
-/*
- Vertex 3fv vertex size 6
-*/
-GLOBL ( _x86_Vertex3fv_6 )
- movl (0), %eax
- movl 4(%esp), %ecx
- movl (%ecx), %edx
- movl %edx, (%eax)
- movl 4(%ecx), %edx
- movl 8(%ecx), %ecx
- movl %edx, 4(%eax)
- movl %ecx, 8(%eax)
- movl (28), %edx
- movl (32), %ecx
- movl %edx, 12(%eax)
- movl %ecx, 16(%eax)
- movl (36), %edx
- movl %edx, 20(%eax)
- addl $24, %eax
- movl %eax, 0
- movl 4, %eax
- dec %eax
- movl %eax, 4
- je .4
- ret
-.4: jmp *8
-
-GLOBL ( _x86_Vertex3fv_6_end )
-
-/*
- Vertex 3fv vertex size 8
-*/
-GLOBL ( _x86_Vertex3fv_8 )
- movl (0), %eax
- movl 4(%esp), %ecx
- movl (%ecx), %edx
- movl %edx ,(%eax)
- movl 4(%ecx) ,%edx
- movl 8(%ecx) ,%ecx
- movl %edx, 4(%eax)
- movl %ecx, 8(%eax)
- movl (28), %edx
- movl (32), %ecx
- movl %edx, 12(%eax)
- movl %ecx, 16(%eax)
- movl (28), %edx
- movl (32), %ecx
- movl %edx, 20(%eax)
- movl %ecx, 24(%eax)
- movl (36), %edx
- movl %edx, 28(%eax)
- addl $32, %eax
- movl %eax, (0)
- movl 4, %eax
- dec %eax
- movl %eax, (4)
- je .5
- ret
-.5: jmp *8
-
-GLOBL ( _x86_Vertex3fv_8_end )
-
-/*
- Vertex 3fv generic vertex size
-*/
-GLOBL ( _x86_Vertex3fv )
- movl 4(%esp), %edx
- push %edi
- push %esi
- movl (0x1010101), %edi
- movl (%edx), %eax
- movl 4(%edx), %ecx
- movl 8(%edx), %esi
- movl %eax, (%edi)
- movl %ecx, 4(%edi)
- movl %esi, 8(%edi)
- addl $12, %edi
- movl $6, %ecx
- movl $0x58, %esi
- repz
- movsl %ds:(%esi), %es:(%edi)
- movl %edi, (0x1010101)
- movl (0x2020202), %eax
- pop %esi
- pop %edi
- dec %eax
- movl %eax, (0x2020202)
- je .6
- ret
-.6: jmp *0
-GLOBL ( _x86_Vertex3fv_end )
-
-
-/**
- * Generic handler for 2 float format data. This can be used for
- * TexCoord2f and possibly other functions.
- */
-
-GLOBL ( _x86_Attribute2f )
- movl $0x0, %edx
- movl 4(%esp), %eax
- movl 8(%esp), %ecx
- movl %eax, (%edx)
- movl %ecx, 4(%edx)
- ret
-GLOBL ( _x86_Attribute2f_end )
-
-
-/**
- * Generic handler for 2 float vector format data. This can be used for
- * TexCoord2fv and possibly other functions.
- */
-
-GLOBL( _x86_Attribute2fv)
- movl 4(%esp), %eax /* load 'v' off stack */
- movl (%eax), %ecx /* load v[0] */
- movl 4(%eax), %eax /* load v[1] */
- movl %ecx, 0 /* store v[0] to current vertex */
- movl %eax, 4 /* store v[1] to current vertex */
- ret
-GLOBL ( _x86_Attribute2fv_end )
-
-
-/**
- * Generic handler for 3 float format data. This can be used for
- * Normal3f, Color3f (when the color target is also float), or
- * TexCoord3f.
- */
-
-GLOBL ( _x86_Attribute3f )
- movl 4(%esp), %ecx
- movl 8(%esp), %edx
- movl 12(%esp), %eax
- movl %ecx, 0
- movl %edx, 4
- movl %eax, 8
- ret
-GLOBL ( _x86_Attribute3f_end )
-
-/**
- * Generic handler for 3 float vector format data. This can be used for
- * Normal3f, Color3f (when the color target is also float), or
- * TexCoord3f.
- */
-
-GLOBL( _x86_Attribute3fv)
- movl 4(%esp), %eax /* load 'v' off stack */
- movl (%eax), %ecx /* load v[0] */
- movl 4(%eax), %edx /* load v[1] */
- movl 8(%eax), %eax /* load v[2] */
- movl %ecx, 0 /* store v[0] to current vertex */
- movl %edx, 4 /* store v[1] to current vertex */
- movl %eax, 8 /* store v[2] to current vertex */
- ret
-GLOBL ( _x86_Attribute3fv_end )
-
-
-/*
- Color 4ubv_ub
-*/
-GLOBL ( _x86_Color4ubv_ub )
- movl 4(%esp), %eax
- movl $0x12345678, %edx
- movl (%eax), %eax
- movl %eax, (%edx)
- ret
-GLOBL ( _x86_Color4ubv_ub_end )
-
-/*
- Color 4ubv 4f
-*/
-GLOBL ( _x86_Color4ubv_4f )
- push %ebx
- movl $0, %edx
- xor %eax, %eax
- xor %ecx, %ecx
- movl 8(%esp), %ebx
- movl (%ebx), %ebx
- mov %bl, %al
- mov %bh, %cl
- movl (%edx,%eax,4),%eax
- movl (%edx,%ecx,4),%ecx
- movl %eax, (0xdeadbeaf)
- movl %ecx, (0xdeadbeaf)
- xor %eax, %eax
- xor %ecx, %ecx
- shr $16, %ebx
- mov %bl, %al
- mov %bh, %cl
- movl (%edx,%eax,4), %eax
- movl (%edx,%ecx,4), %ecx
- movl %eax, (0xdeadbeaf)
- movl %ecx, (0xdeadbeaf)
- pop %ebx
- ret
-GLOBL ( _x86_Color4ubv_4f_end )
-
-/*
-
- Color4ub_ub
-*/
-GLOBL( _x86_Color4ub_ub )
- push %ebx
- movl 8(%esp), %eax
- movl 12(%esp), %edx
- movl 16(%esp), %ecx
- movl 20(%esp), %ebx
- mov %al, (0)
- mov %dl, (0)
- mov %cl, (0)
- mov %bl, (0)
- pop %ebx
- ret
-GLOBL( _x86_Color4ub_ub_end )
-
-
-/* \todo: change the "and $7, %eax" to something like "target & 4 ? target & 5 : target & 3)" */
-/*
- MultiTexCoord2fv st0/st1
-*/
-GLOBL( _x86_MultiTexCoord2fv )
- movl 4(%esp), %eax
- movl 8(%esp), %ecx
- and $7, %eax
- movl (%ecx), %edx
- shl $3, %eax
- movl 4(%ecx), %ecx
- movl %edx, 0xdeadbeef(%eax)
- movl %ecx, 0xdeadbeef(%eax)
- ret
-GLOBL( _x86_MultiTexCoord2fv_end )
-
-/*
- MultiTexCoord2fv
-*/
-
-GLOBL( _x86_MultiTexCoord2fv_2 )
- movl 4(%esp,1), %eax
- movl 8(%esp,1), %ecx
- and $0x7, %eax
- movl 0(,%eax,4), %edx
- movl (%ecx), %eax
- movl %eax, (%edx)
- movl 4(%ecx), %eax
- movl %eax, 4(%edx)
- ret
-GLOBL( _x86_MultiTexCoord2fv_2_end )
-
-/*
- MultiTexCoord2f st0/st1
-*/
-GLOBL( _x86_MultiTexCoord2f )
- movl 4(%esp), %eax
- movl 8(%esp), %edx
- movl 12(%esp), %ecx
- and $7, %eax
- shl $3, %eax
- movl %edx, 0xdeadbeef(%eax)
- movl %ecx, 0xdeadbeef(%eax)
- ret
-GLOBL( _x86_MultiTexCoord2f_end )
-
-/*
- MultiTexCoord2f
-*/
-GLOBL( _x86_MultiTexCoord2f_2 )
- movl 4(%esp), %eax
- movl 8(%esp), %edx
- movl 12(%esp,1), %ecx
- and $7,%eax
- movl 0(,%eax,4), %eax
- movl %edx, (%eax)
- movl %ecx, 4(%eax)
- ret
-GLOBL( _x86_MultiTexCoord2f_2_end )
-
-#if defined(USE_SSE_ASM)
-/**
- * This can be used as a template for either Color3fv (when the color
- * target is also a 3f) or Normal3fv.
- */
-
-GLOBL( _sse_Attribute3fv )
- movl 4(%esp), %eax
- movlps (%eax), %xmm0
- movl 8(%eax), %eax
- movlps %xmm0, 0
- movl %eax, 8
- ret
-GLOBL( _sse_Attribute3fv_end )
-
-/**
- * This can be used as a template for either Color3f (when the color
- * target is also a 3f) or Normal3f.
- */
-
-GLOBL( _sse_Attribute3f )
- movlps 4(%esp), %xmm0
- movl 12(%esp), %eax
- movlps %xmm0, 0
- movl %eax, 8
- ret
-GLOBL( _sse_Attribute3f_end )
-
-
-/**
- * Generic handler for 2 float vector format data. This can be used for
- * TexCoord2fv and possibly other functions.
- */
-
-GLOBL( _sse_Attribute2fv )
- movl 4(%esp), %eax
- movlps (%eax), %xmm0
- movlps %xmm0, 0
- ret
-GLOBL( _sse_Attribute2fv_end )
-
-
-/**
- * Generic handler for 2 float format data. This can be used for
- * TexCoord2f and possibly other functions.
- */
-
-GLOBL( _sse_Attribute2f )
- movlps 4(%esp), %xmm0
- movlps %xmm0, 0
- ret
-GLOBL( _sse_Attribute2f_end )
-
-/*
- MultiTexCoord2fv st0/st1
-*/
-GLOBL( _sse_MultiTexCoord2fv )
- movl 4(%esp), %eax
- movl 8(%esp), %ecx
- and $7, %eax
- movlps (%ecx), %xmm0
- movlps %xmm0, 0xdeadbeef(,%eax,8)
- ret
-GLOBL( _sse_MultiTexCoord2fv_end )
-
-/*
- MultiTexCoord2fv
-*/
-GLOBL( _sse_MultiTexCoord2fv_2 )
- movl 4(%esp), %eax
- movl 8(%esp), %ecx
- and $0x7, %eax
- movl 0(,%eax,4), %edx
- movlps (%ecx), %xmm0
- movlps %xmm0, (%edx)
- ret
-GLOBL( _sse_MultiTexCoord2fv_2_end )
-
-/*
- MultiTexCoord2f st0/st1
-*/
-GLOBL( _sse_MultiTexCoord2f )
- movl 4(%esp), %eax
- and $7, %eax
- movlps 8(%esp), %xmm0
- movlps %xmm0, 0xdeadbeef(,%eax,8)
- ret
-GLOBL( _sse_MultiTexCoord2f_end )
-
-/*
- MultiTexCoord2f
-*/
-GLOBL( _sse_MultiTexCoord2f_2 )
- movl 4(%esp), %eax
- movlps 8(%esp), %xmm0
- and $7,%eax
- movl 0(,%eax,4), %eax
- movlps %xmm0, (%eax)
- ret
-GLOBL( _sse_MultiTexCoord2f_2_end )
-#endif
-
-#if defined (__ELF__) && defined (__linux__)
- .section .note.GNU-stack,"",%progbits
-#endif
diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile
index 5abb91d9876..2ee23289341 100644
--- a/src/mesa/drivers/dri/r300/Makefile
+++ b/src/mesa/drivers/dri/r300/Makefile
@@ -90,9 +90,11 @@ COMMON_SYMLINKS = \
include ../Makefile.template
-$(SYMLINKS):
+server:
mkdir -p server
- for i in $(SYMLINKS) ; do rm -f $$i && test -f ../radeon/$$i && ln -s ../../radeon/$$i $$i ; done
+
+$(SYMLINKS): server
+ @[ -e $@ ] || ln -sf ../../radeon/$@ server/
$(COMMON_SYMLINKS):
@[ -e $@ ] || ln -sf ../radeon/$@ ./
diff --git a/src/mesa/drivers/dri/r300/r200_context.h b/src/mesa/drivers/dri/r300/r200_context.h
deleted file mode 100644
index a06d7152d78..00000000000
--- a/src/mesa/drivers/dri/r300/r200_context.h
+++ /dev/null
@@ -1,822 +0,0 @@
-/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_context.h,v 1.2 2002/12/16 16:18:54 dawes Exp $ */
-/*
-Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
-
-The Weather Channel (TM) funded Tungsten Graphics to develop the
-initial release of the Radeon 8500 driver under the XFree86 license.
-This notice must be preserved.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial
-portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Keith Whitwell <[email protected]>
- */
-
-#ifndef __R200_CONTEXT_H__
-#define __R200_CONTEXT_H__
-
-#ifdef GLX_DIRECT_RENDERING
-
-#include "tnl/t_vertex.h"
-#include "drm.h"
-#include "radeon_drm.h"
-#include "dri_util.h"
-#include "texmem.h"
-
-#include "macros.h"
-#include "mtypes.h"
-#include "colormac.h"
-#include "r200_reg.h"
-#include "radeon_context.h"
-
-#define ENABLE_HW_3D_TEXTURE 1 /* XXX this is temporary! */
-
-struct r200_context;
-typedef struct r200_context r200ContextRec;
-typedef struct r200_context *r200ContextPtr;
-
-#include "mm.h"
-
-/* The blit width for texture uploads
- */
-#define BLIT_WIDTH_BYTES 1024
-
-/* Use the templated vertex format:
- */
-#define COLOR_IS_RGBA
-#define TAG(x) r200##x
-#include "tnl_dd/t_dd_vertex.h"
-#undef TAG
-
-typedef void (*r200_tri_func) (r200ContextPtr,
- r200Vertex *, r200Vertex *, r200Vertex *);
-
-typedef void (*r200_line_func) (r200ContextPtr, r200Vertex *, r200Vertex *);
-
-typedef void (*r200_point_func) (r200ContextPtr, r200Vertex *);
-
-struct r200_depthbuffer_state {
- GLfloat scale;
-};
-
-struct r200_stencilbuffer_state {
- GLboolean hwBuffer;
- GLuint clear; /* rb3d_stencilrefmask value */
-};
-
-struct r200_stipple_state {
- GLuint mask[32];
-};
-
-typedef struct r200_tex_obj r200TexObj, *r200TexObjPtr;
-
-/* Texture object in locally shared texture space.
- */
-struct r200_tex_obj {
- driTextureObject base;
-
- GLuint bufAddr; /* Offset to start of locally
- shared texture block */
-
- GLuint dirty_state; /* Flags (1 per texunit) for
- whether or not this texobj
- has dirty hardware state
- (pp_*) that needs to be
- brought into the
- texunit. */
-
- drm_radeon_tex_image_t image[6][RADEON_MAX_TEXTURE_LEVELS];
- /* Six, for the cube faces */
-
- GLuint pp_txfilter; /* hardware register values */
- GLuint pp_txformat;
- GLuint pp_txformat_x;
- GLuint pp_txoffset; /* Image location in texmem.
- All cube faces follow. */
- GLuint pp_txsize; /* npot only */
- GLuint pp_txpitch; /* npot only */
- GLuint pp_border_color;
- GLuint pp_cubic_faces; /* cube face 1,2,3,4 log2 sizes */
-
- GLboolean border_fallback;
-};
-
-struct r200_texture_env_state {
- r200TexObjPtr texobj;
- GLenum format;
- GLenum envMode;
-};
-
-#define R200_MAX_TEXTURE_UNITS 6
-
-struct r200_texture_state {
- struct r200_texture_env_state unit[R200_MAX_TEXTURE_UNITS];
-};
-
-struct r200_state_atom {
- struct r200_state_atom *next, *prev;
- const char *name; /* for debug */
- int cmd_size; /* size in bytes */
- GLuint idx;
- int *cmd; /* one or more cmd's */
- int *lastcmd; /* one or more cmd's */
- int *savedcmd; /* one or more cmd's */
- GLboolean dirty;
- GLboolean(*check) (GLcontext *, int); /* is this state active? */
-};
-
-/* Trying to keep these relatively short as the variables are becoming
- * extravagently long. Drop the driver name prefix off the front of
- * everything - I think we know which driver we're in by now, and keep the
- * prefix to 3 letters unless absolutely impossible.
- */
-
-#define CTX_CMD_0 0
-#define CTX_PP_MISC 1
-#define CTX_PP_FOG_COLOR 2
-#define CTX_RE_SOLID_COLOR 3
-#define CTX_RB3D_BLENDCNTL 4
-#define CTX_RB3D_DEPTHOFFSET 5
-#define CTX_RB3D_DEPTHPITCH 6
-#define CTX_RB3D_ZSTENCILCNTL 7
-#define CTX_CMD_1 8
-#define CTX_PP_CNTL 9
-#define CTX_RB3D_CNTL 10
-#define CTX_RB3D_COLOROFFSET 11
-#define CTX_CMD_2 12 /* why */
-#define CTX_RB3D_COLORPITCH 13 /* why */
-#define CTX_STATE_SIZE_OLDDRM 14
-#define CTX_CMD_3 14
-#define CTX_RB3D_BLENDCOLOR 15
-#define CTX_RB3D_ABLENDCNTL 16
-#define CTX_RB3D_CBLENDCNTL 17
-#define CTX_STATE_SIZE_NEWDRM 18
-
-#define SET_CMD_0 0
-#define SET_SE_CNTL 1
-#define SET_RE_CNTL 2 /* replace se_coord_fmt */
-#define SET_STATE_SIZE 3
-
-#define VTE_CMD_0 0
-#define VTE_SE_VTE_CNTL 1
-#define VTE_STATE_SIZE 2
-
-#define LIN_CMD_0 0
-#define LIN_RE_LINE_PATTERN 1
-#define LIN_RE_LINE_STATE 2
-#define LIN_CMD_1 3
-#define LIN_SE_LINE_WIDTH 4
-#define LIN_STATE_SIZE 5
-
-#define MSK_CMD_0 0
-#define MSK_RB3D_STENCILREFMASK 1
-#define MSK_RB3D_ROPCNTL 2
-#define MSK_RB3D_PLANEMASK 3
-#define MSK_STATE_SIZE 4
-
-#define VPT_CMD_0 0
-#define VPT_SE_VPORT_XSCALE 1
-#define VPT_SE_VPORT_XOFFSET 2
-#define VPT_SE_VPORT_YSCALE 3
-#define VPT_SE_VPORT_YOFFSET 4
-#define VPT_SE_VPORT_ZSCALE 5
-#define VPT_SE_VPORT_ZOFFSET 6
-#define VPT_STATE_SIZE 7
-
-#define ZBS_CMD_0 0
-#define ZBS_SE_ZBIAS_FACTOR 1
-#define ZBS_SE_ZBIAS_CONSTANT 2
-#define ZBS_STATE_SIZE 3
-
-#define MSC_CMD_0 0
-#define MSC_RE_MISC 1
-#define MSC_STATE_SIZE 2
-
-#define TAM_CMD_0 0
-#define TAM_DEBUG3 1
-#define TAM_STATE_SIZE 2
-
-#define TEX_CMD_0 0
-#define TEX_PP_TXFILTER 1 /*2c00 */
-#define TEX_PP_TXFORMAT 2 /*2c04 */
-#define TEX_PP_TXFORMAT_X 3 /*2c08 */
-#define TEX_PP_TXSIZE 4 /*2c0c */
-#define TEX_PP_TXPITCH 5 /*2c10 */
-#define TEX_PP_BORDER_COLOR 6 /*2c14 */
-#define TEX_CMD_1 7
-#define TEX_PP_TXOFFSET 8 /*2d00 */
-#define TEX_STATE_SIZE 9
-
-#define CUBE_CMD_0 0 /* 1 register follows */
-#define CUBE_PP_CUBIC_FACES 1 /* 0x2c18 */
-#define CUBE_CMD_1 2 /* 5 registers follow */
-#define CUBE_PP_CUBIC_OFFSET_F1 3 /* 0x2d04 */
-#define CUBE_PP_CUBIC_OFFSET_F2 4 /* 0x2d08 */
-#define CUBE_PP_CUBIC_OFFSET_F3 5 /* 0x2d0c */
-#define CUBE_PP_CUBIC_OFFSET_F4 6 /* 0x2d10 */
-#define CUBE_PP_CUBIC_OFFSET_F5 7 /* 0x2d14 */
-#define CUBE_STATE_SIZE 8
-
-#define PIX_CMD_0 0
-#define PIX_PP_TXCBLEND 1
-#define PIX_PP_TXCBLEND2 2
-#define PIX_PP_TXABLEND 3
-#define PIX_PP_TXABLEND2 4
-#define PIX_STATE_SIZE 5
-
-#define TF_CMD_0 0
-#define TF_TFACTOR_0 1
-#define TF_TFACTOR_1 2
-#define TF_TFACTOR_2 3
-#define TF_TFACTOR_3 4
-#define TF_TFACTOR_4 5
-#define TF_TFACTOR_5 6
-#define TF_STATE_SIZE 7
-
-#define TCL_CMD_0 0
-#define TCL_LIGHT_MODEL_CTL_0 1
-#define TCL_LIGHT_MODEL_CTL_1 2
-#define TCL_PER_LIGHT_CTL_0 3
-#define TCL_PER_LIGHT_CTL_1 4
-#define TCL_PER_LIGHT_CTL_2 5
-#define TCL_PER_LIGHT_CTL_3 6
-#define TCL_CMD_1 7
-#define TCL_UCP_VERT_BLEND_CTL 8
-#define TCL_STATE_SIZE 9
-
-#define MSL_CMD_0 0
-#define MSL_MATRIX_SELECT_0 1
-#define MSL_MATRIX_SELECT_1 2
-#define MSL_MATRIX_SELECT_2 3
-#define MSL_MATRIX_SELECT_3 4
-#define MSL_MATRIX_SELECT_4 5
-#define MSL_STATE_SIZE 6
-
-#define TCG_CMD_0 0
-#define TCG_TEX_PROC_CTL_2 1
-#define TCG_TEX_PROC_CTL_3 2
-#define TCG_TEX_PROC_CTL_0 3
-#define TCG_TEX_PROC_CTL_1 4
-#define TCG_TEX_CYL_WRAP_CTL 5
-#define TCG_STATE_SIZE 6
-
-#define MTL_CMD_0 0
-#define MTL_EMMISSIVE_RED 1
-#define MTL_EMMISSIVE_GREEN 2
-#define MTL_EMMISSIVE_BLUE 3
-#define MTL_EMMISSIVE_ALPHA 4
-#define MTL_AMBIENT_RED 5
-#define MTL_AMBIENT_GREEN 6
-#define MTL_AMBIENT_BLUE 7
-#define MTL_AMBIENT_ALPHA 8
-#define MTL_DIFFUSE_RED 9
-#define MTL_DIFFUSE_GREEN 10
-#define MTL_DIFFUSE_BLUE 11
-#define MTL_DIFFUSE_ALPHA 12
-#define MTL_SPECULAR_RED 13
-#define MTL_SPECULAR_GREEN 14
-#define MTL_SPECULAR_BLUE 15
-#define MTL_SPECULAR_ALPHA 16
-#define MTL_CMD_1 17
-#define MTL_SHININESS 18
-#define MTL_STATE_SIZE 19
-
-#define VAP_CMD_0 0
-#define VAP_SE_VAP_CNTL 1
-#define VAP_STATE_SIZE 2
-
-/* Replaces a lot of packet info from radeon
- */
-#define VTX_CMD_0 0
-#define VTX_VTXFMT_0 1
-#define VTX_VTXFMT_1 2
-#define VTX_TCL_OUTPUT_VTXFMT_0 3
-#define VTX_TCL_OUTPUT_VTXFMT_1 4
-#define VTX_CMD_1 5
-#define VTX_TCL_OUTPUT_COMPSEL 6
-#define VTX_CMD_2 7
-#define VTX_STATE_CNTL 8
-#define VTX_STATE_SIZE 9
-
-#define VTX_COLOR(v,n) (((v)>>(R200_VTX_COLOR_0_SHIFT+(n)*2))&\
- R200_VTX_COLOR_MASK)
-
-/**
- * Given the \c R200_SE_VTX_FMT_1 for the current vertex state, determine
- * how many components are in texture coordinate \c n.
- */
-#define VTX_TEXn_COUNT(v,n) (((v) >> (3 * n)) & 0x07)
-
-#define MAT_CMD_0 0
-#define MAT_ELT_0 1
-#define MAT_STATE_SIZE 17
-
-#define GRD_CMD_0 0
-#define GRD_VERT_GUARD_CLIP_ADJ 1
-#define GRD_VERT_GUARD_DISCARD_ADJ 2
-#define GRD_HORZ_GUARD_CLIP_ADJ 3
-#define GRD_HORZ_GUARD_DISCARD_ADJ 4
-#define GRD_STATE_SIZE 5
-
-/* position changes frequently when lighting in modelpos - separate
- * out to new state item?
- */
-#define LIT_CMD_0 0
-#define LIT_AMBIENT_RED 1
-#define LIT_AMBIENT_GREEN 2
-#define LIT_AMBIENT_BLUE 3
-#define LIT_AMBIENT_ALPHA 4
-#define LIT_DIFFUSE_RED 5
-#define LIT_DIFFUSE_GREEN 6
-#define LIT_DIFFUSE_BLUE 7
-#define LIT_DIFFUSE_ALPHA 8
-#define LIT_SPECULAR_RED 9
-#define LIT_SPECULAR_GREEN 10
-#define LIT_SPECULAR_BLUE 11
-#define LIT_SPECULAR_ALPHA 12
-#define LIT_POSITION_X 13
-#define LIT_POSITION_Y 14
-#define LIT_POSITION_Z 15
-#define LIT_POSITION_W 16
-#define LIT_DIRECTION_X 17
-#define LIT_DIRECTION_Y 18
-#define LIT_DIRECTION_Z 19
-#define LIT_DIRECTION_W 20
-#define LIT_ATTEN_QUADRATIC 21
-#define LIT_ATTEN_LINEAR 22
-#define LIT_ATTEN_CONST 23
-#define LIT_ATTEN_XXX 24
-#define LIT_CMD_1 25
-#define LIT_SPOT_DCD 26
-#define LIT_SPOT_DCM 27
-#define LIT_SPOT_EXPONENT 28
-#define LIT_SPOT_CUTOFF 29
-#define LIT_SPECULAR_THRESH 30
-#define LIT_RANGE_CUTOFF 31 /* ? */
-#define LIT_ATTEN_CONST_INV 32
-#define LIT_STATE_SIZE 33
-
-/* Fog
- */
-#define FOG_CMD_0 0
-#define FOG_R 1
-#define FOG_C 2
-#define FOG_D 3
-#define FOG_PAD 4
-#define FOG_STATE_SIZE 5
-
-/* UCP
- */
-#define UCP_CMD_0 0
-#define UCP_X 1
-#define UCP_Y 2
-#define UCP_Z 3
-#define UCP_W 4
-#define UCP_STATE_SIZE 5
-
-/* GLT - Global ambient
- */
-#define GLT_CMD_0 0
-#define GLT_RED 1
-#define GLT_GREEN 2
-#define GLT_BLUE 3
-#define GLT_ALPHA 4
-#define GLT_STATE_SIZE 5
-
-/* EYE
- */
-#define EYE_CMD_0 0
-#define EYE_X 1
-#define EYE_Y 2
-#define EYE_Z 3
-#define EYE_RESCALE_FACTOR 4
-#define EYE_STATE_SIZE 5
-
-/* CST - constant state
- */
-#define CST_CMD_0 0
-#define CST_PP_CNTL_X 1
-#define CST_CMD_1 2
-#define CST_RB3D_DEPTHXY_OFFSET 3
-#define CST_CMD_2 4
-#define CST_RE_AUX_SCISSOR_CNTL 5
-#define CST_CMD_3 6
-#define CST_RE_SCISSOR_TL_0 7
-#define CST_RE_SCISSOR_BR_0 8
-#define CST_CMD_4 9
-#define CST_SE_VAP_CNTL_STATUS 10
-#define CST_CMD_5 11
-#define CST_RE_POINTSIZE 12
-#define CST_CMD_6 13
-#define CST_SE_TCL_INPUT_VTX_0 14
-#define CST_SE_TCL_INPUT_VTX_1 15
-#define CST_SE_TCL_INPUT_VTX_2 16
-#define CST_SE_TCL_INPUT_VTX_3 17
-#define CST_STATE_SIZE 18
-
-struct r200_hw_state {
- /* Head of the linked list of state atoms. */
- struct r200_state_atom atomlist;
-
- /* Hardware state, stored as cmdbuf commands:
- * -- Need to doublebuffer for
- * - reviving state after loss of context
- * - eliding noop statechange loops? (except line stipple count)
- */
- struct r200_state_atom ctx;
- struct r200_state_atom set;
- struct r200_state_atom vte;
- struct r200_state_atom lin;
- struct r200_state_atom msk;
- struct r200_state_atom vpt;
- struct r200_state_atom vap;
- struct r200_state_atom vtx;
- struct r200_state_atom tcl;
- struct r200_state_atom msl;
- struct r200_state_atom tcg;
- struct r200_state_atom msc;
- struct r200_state_atom cst;
- struct r200_state_atom tam;
- struct r200_state_atom tf;
- struct r200_state_atom tex[6];
- struct r200_state_atom cube[6];
- struct r200_state_atom zbs;
- struct r200_state_atom mtl[2];
- struct r200_state_atom mat[9];
- struct r200_state_atom lit[8]; /* includes vec, scl commands */
- struct r200_state_atom ucp[6];
- struct r200_state_atom pix[6]; /* pixshader stages */
- struct r200_state_atom eye; /* eye pos */
- struct r200_state_atom grd; /* guard band clipping */
- struct r200_state_atom fog;
- struct r200_state_atom glt;
-
- int max_state_size; /* Number of bytes necessary for a full state emit. */
- GLboolean is_dirty, all_dirty;
-};
-
-struct r200_colorbuffer_state {
- int roundEnable;
-};
-
-struct r200_state {
- /* Derived state for internal purposes:
- */
- struct r200_colorbuffer_state color;
- struct r200_depthbuffer_state depth;
- struct r200_stencilbuffer_state stencil;
- struct r200_stipple_state stipple;
- struct r200_texture_state texture;
-};
-
-/* Need refcounting on dma buffers:
- */
-struct r200_dma_buffer {
- int refcount; /* the number of retained regions in buf */
- drmBufPtr buf;
-};
-
-#define GET_START(rvb) (rmesa->radeon.radeonScreen->gart_buffer_offset + \
- (rvb)->address - rmesa->dma.buf0_address + \
- (rvb)->start)
-
-/* A retained region, eg vertices for indexed vertices.
- */
-struct r200_dma_region {
- struct r200_dma_buffer *buf;
- char *address; /* == buf->address */
- int start, end, ptr; /* offsets from start of buf */
- int aos_start;
- int aos_stride;
- int aos_size;
-};
-
-struct r200_dma {
- /* Active dma region. Allocations for vertices and retained
- * regions come from here. Also used for emitting random vertices,
- * these may be flushed by calling flush_current();
- */
- struct r200_dma_region current;
-
- void (*flush) (r200ContextPtr);
-
- char *buf0_address; /* start of buf[0], for index calcs */
- GLuint nr_released_bufs; /* flush after so many buffers released */
-};
-
-#define R200_CMD_BUF_SZ (8*1024)
-
-struct r200_store {
- GLuint statenr;
- GLuint primnr;
- char cmd_buf[R200_CMD_BUF_SZ];
- int cmd_used;
- int elts_start;
-};
-
-/* r200_tcl.c
- */
-struct r200_tcl_info {
- GLuint vertex_format;
- GLint last_offset;
- GLuint hw_primitive;
-
- struct r200_dma_region *aos_components[8];
- GLuint nr_aos_components;
-
- GLuint *Elts;
-
- struct r200_dma_region indexed_verts;
- struct r200_dma_region obj;
- struct r200_dma_region rgba;
- struct r200_dma_region spec;
- struct r200_dma_region fog;
- struct r200_dma_region tex[R200_MAX_TEXTURE_UNITS];
- struct r200_dma_region norm;
-};
-
-/* r200_swtcl.c
- */
-struct r200_swtcl_info {
- GLuint RenderIndex;
-
- /**
- * Size of a hardware vertex. This is calculated when \c ::vertex_attrs is
- * installed in the Mesa state vector.
- */
- GLuint vertex_size;
-
- /**
- * Attributes instructing the Mesa TCL pipeline where / how to put vertex
- * data in the hardware buffer.
- */
- struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX];
-
- /**
- * Number of elements of \c ::vertex_attrs that are actually used.
- */
- GLuint vertex_attr_count;
-
- /**
- * Cached pointer to the buffer where Mesa will store vertex data.
- */
- GLubyte *verts;
-
- /* Fallback rasterization functions
- */
- r200_point_func draw_point;
- r200_line_func draw_line;
- r200_tri_func draw_tri;
-
- GLuint hw_primitive;
- GLenum render_primitive;
- GLuint numverts;
-
- /**
- * Offset of the 4UB color data within a hardware (swtcl) vertex.
- */
- GLuint coloroffset;
-
- /**
- * Offset of the 3UB specular color data within a hardware (swtcl) vertex.
- */
- GLuint specoffset;
-
- /**
- * Should Mesa project vertex data or will the hardware do it?
- */
- GLboolean needproj;
-
- struct r200_dma_region indexed_verts;
-};
-
-struct r200_ioctl {
- GLuint vertex_offset;
- GLuint vertex_size;
-};
-
-#define R200_MAX_PRIMS 64
-
-/* Want to keep a cache of these around. Each is parameterized by
- * only a single value which has only a small range. Only expect a
- * few, so just rescan the list each time?
- */
-struct dynfn {
- struct dynfn *next, *prev;
- int key[2];
- char *code;
-};
-
-struct dfn_lists {
- struct dynfn Vertex2f;
- struct dynfn Vertex2fv;
- struct dynfn Vertex3f;
- struct dynfn Vertex3fv;
- struct dynfn Color4ub;
- struct dynfn Color4ubv;
- struct dynfn Color3ub;
- struct dynfn Color3ubv;
- struct dynfn Color4f;
- struct dynfn Color4fv;
- struct dynfn Color3f;
- struct dynfn Color3fv;
- struct dynfn SecondaryColor3ubEXT;
- struct dynfn SecondaryColor3ubvEXT;
- struct dynfn SecondaryColor3fEXT;
- struct dynfn SecondaryColor3fvEXT;
- struct dynfn Normal3f;
- struct dynfn Normal3fv;
- struct dynfn TexCoord3f;
- struct dynfn TexCoord3fv;
- struct dynfn TexCoord2f;
- struct dynfn TexCoord2fv;
- struct dynfn TexCoord1f;
- struct dynfn TexCoord1fv;
- struct dynfn MultiTexCoord3fARB;
- struct dynfn MultiTexCoord3fvARB;
- struct dynfn MultiTexCoord2fARB;
- struct dynfn MultiTexCoord2fvARB;
- struct dynfn MultiTexCoord1fARB;
- struct dynfn MultiTexCoord1fvARB;
-};
-
-struct dfn_generators {
- struct dynfn *(*Vertex2f) (GLcontext *, const int *);
- struct dynfn *(*Vertex2fv) (GLcontext *, const int *);
- struct dynfn *(*Vertex3f) (GLcontext *, const int *);
- struct dynfn *(*Vertex3fv) (GLcontext *, const int *);
- struct dynfn *(*Color4ub) (GLcontext *, const int *);
- struct dynfn *(*Color4ubv) (GLcontext *, const int *);
- struct dynfn *(*Color3ub) (GLcontext *, const int *);
- struct dynfn *(*Color3ubv) (GLcontext *, const int *);
- struct dynfn *(*Color4f) (GLcontext *, const int *);
- struct dynfn *(*Color4fv) (GLcontext *, const int *);
- struct dynfn *(*Color3f) (GLcontext *, const int *);
- struct dynfn *(*Color3fv) (GLcontext *, const int *);
- struct dynfn *(*SecondaryColor3ubEXT) (GLcontext *, const int *);
- struct dynfn *(*SecondaryColor3ubvEXT) (GLcontext *, const int *);
- struct dynfn *(*SecondaryColor3fEXT) (GLcontext *, const int *);
- struct dynfn *(*SecondaryColor3fvEXT) (GLcontext *, const int *);
- struct dynfn *(*Normal3f) (GLcontext *, const int *);
- struct dynfn *(*Normal3fv) (GLcontext *, const int *);
- struct dynfn *(*TexCoord3f) (GLcontext *, const int *);
- struct dynfn *(*TexCoord3fv) (GLcontext *, const int *);
- struct dynfn *(*TexCoord2f) (GLcontext *, const int *);
- struct dynfn *(*TexCoord2fv) (GLcontext *, const int *);
- struct dynfn *(*TexCoord1f) (GLcontext *, const int *);
- struct dynfn *(*TexCoord1fv) (GLcontext *, const int *);
- struct dynfn *(*MultiTexCoord3fARB) (GLcontext *, const int *);
- struct dynfn *(*MultiTexCoord3fvARB) (GLcontext *, const int *);
- struct dynfn *(*MultiTexCoord2fARB) (GLcontext *, const int *);
- struct dynfn *(*MultiTexCoord2fvARB) (GLcontext *, const int *);
- struct dynfn *(*MultiTexCoord1fARB) (GLcontext *, const int *);
- struct dynfn *(*MultiTexCoord1fvARB) (GLcontext *, const int *);
-};
-
-struct r200_prim {
- GLuint start;
- GLuint end;
- GLuint prim;
-};
-
- /* A maximum total of 29 elements per vertex: 3 floats for position, 3
- * floats for normal, 4 floats for color, 4 bytes for secondary color,
- * 3 floats for each texture unit (18 floats total).
- *
- * we maybe need add. 4 to prevent segfault if someone specifies
- * GL_TEXTURE6/GL_TEXTURE7 (esp. for the codegen-path) (FIXME: )
- *
- * The position data is never actually stored here, so 3 elements could be
- * trimmed out of the buffer.
- */
-
-#define R200_MAX_VERTEX_SIZE ((3*6)+11)
-
-struct r200_vbinfo {
- GLint counter, initial_counter;
- GLint *dmaptr;
- void (*notify) (void);
- GLint vertex_size;
-
- union {
- float f;
- int i;
- r200_color_t color;
- } vertex[R200_MAX_VERTEX_SIZE];
-
- GLfloat *normalptr;
- GLfloat *floatcolorptr;
- r200_color_t *colorptr;
- GLfloat *floatspecptr;
- r200_color_t *specptr;
- GLfloat *texcoordptr[8]; /* 6 (TMU) + 2 for r200_vtxfmt_c.c when GL_TEXTURE6/7 */
-
- GLenum *prim; /* &ctx->Driver.CurrentExecPrimitive */
- GLuint primflags;
- GLboolean enabled; /* *_NO_VTXFMT / *_NO_TCL env vars */
- GLboolean installed;
- GLboolean fell_back;
- GLboolean recheck;
- GLint nrverts;
- GLuint vtxfmt_0, vtxfmt_1;
-
- GLuint installed_vertex_format;
- GLuint installed_color_3f_sz;
-
- struct r200_prim primlist[R200_MAX_PRIMS];
- int nrprims;
-
- struct dfn_lists dfn_cache;
- struct dfn_generators codegen;
- GLvertexformat vtxfmt;
-};
-
-/**
- * R200 context structure.
- */
-struct r200_context {
- struct radeon_context radeon; /* parent class, must be first */
-
- /* Driver and hardware state management
- */
- struct r200_hw_state hw;
- struct r200_state state;
-
- /* Texture object bookkeeping
- */
- unsigned nr_heaps;
- driTexHeap *texture_heaps[RADEON_NR_TEX_HEAPS];
- driTextureObject swapped;
- int texture_depth;
- float initialMaxAnisotropy;
-
- /* Rasterization and vertex state:
- */
- GLuint NewGLState;
-
- /* Vertex buffers
- */
- struct r200_ioctl ioctl;
- struct r200_dma dma;
- struct r200_store store;
- GLboolean save_on_next_unlock;
-
- /* Clientdata textures;
- */
- GLuint prefer_gart_client_texturing;
-
- /* TCL stuff
- */
- GLmatrix TexGenMatrix[R200_MAX_TEXTURE_UNITS];
- GLboolean recheck_texgen[R200_MAX_TEXTURE_UNITS];
- GLboolean TexGenNeedNormals[R200_MAX_TEXTURE_UNITS];
- GLuint TexMatEnabled;
- GLuint TexMatCompSel;
- GLuint TexGenEnabled;
- GLuint TexGenInputs;
- GLuint TexGenCompSel;
- GLmatrix tmpmat;
-
- /* r200_tcl.c
- */
- struct r200_tcl_info tcl;
-
- /* r200_swtcl.c
- */
- struct r200_swtcl_info swtcl;
-
- /* r200_vtxfmt.c
- */
- struct r200_vbinfo vb;
-};
-
-#define R200_CONTEXT(ctx) ((r200ContextPtr)(ctx->DriverCtx))
-
-extern void r200DestroyContext(__DRIcontextPrivate * driContextPriv);
-extern GLboolean r200CreateContext(const __GLcontextModes * glVisual,
- __DRIcontextPrivate * driContextPriv,
- void *sharedContextPrivate);
-
-#endif
-#endif /* __R200_CONTEXT_H__ */
diff --git a/src/mesa/drivers/dri/r300/r200_ioctl.h b/src/mesa/drivers/dri/r300/r200_ioctl.h
deleted file mode 100644
index db7bd7697f1..00000000000
--- a/src/mesa/drivers/dri/r300/r200_ioctl.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
-Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
-
-The Weather Channel (TM) funded Tungsten Graphics to develop the
-initial release of the Radeon 8500 driver under the XFree86 license.
-This notice must be preserved.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial
-portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Keith Whitwell <[email protected]>
- */
-
-#ifndef __R200_IOCTL_H__
-#define __R200_IOCTL_H__
-
-#include "simple_list.h"
-#include "radeon_dri.h"
-#include "radeon_lock.h"
-
-#include "xf86drm.h"
-#include "drm.h"
-#include "r200_context.h"
-#include "radeon_drm.h"
-
-extern void r200EmitState(r200ContextPtr rmesa);
-extern void r200EmitVertexAOS(r200ContextPtr rmesa,
- GLuint vertex_size, GLuint offset);
-
-extern void r200EmitVbufPrim(r200ContextPtr rmesa,
- GLuint primitive, GLuint vertex_nr);
-
-extern void r200FlushElts(r200ContextPtr rmesa);
-
-extern GLushort *r200AllocEltsOpenEnded(r200ContextPtr rmesa,
- GLuint primitive, GLuint min_nr);
-
-extern void r200EmitAOS(r200ContextPtr rmesa,
- struct r200_dma_region **regions,
- GLuint n, GLuint offset);
-
-extern void r200EmitBlit(r200ContextPtr rmesa,
- GLuint color_fmt,
- GLuint src_pitch,
- GLuint src_offset,
- GLuint dst_pitch,
- GLuint dst_offset,
- GLint srcx, GLint srcy,
- GLint dstx, GLint dsty, GLuint w, GLuint h);
-
-extern void r200EmitWait(r200ContextPtr rmesa, GLuint flags);
-
-extern void r200FlushCmdBuf(r200ContextPtr rmesa, const char *);
-extern int r200FlushCmdBufLocked(r200ContextPtr rmesa, const char *caller);
-extern void r200Flush(GLcontext * ctx);
-
-extern void r200RefillCurrentDmaRegion(r200ContextPtr rmesa);
-
-extern void r200AllocDmaRegion(r200ContextPtr rmesa,
- struct r200_dma_region *region,
- int bytes, int alignment);
-
-extern void r200AllocDmaRegionVerts(r200ContextPtr rmesa,
- struct r200_dma_region *region,
- int numverts, int vertsize, int alignment);
-
-extern void r200ReleaseDmaRegion(r200ContextPtr rmesa,
- struct r200_dma_region *region,
- const char *caller);
-
-extern void r200WaitForVBlank(r200ContextPtr rmesa);
-extern void r200InitIoctlFuncs(struct dd_function_table *functions);
-
-extern void *r200AllocateMemoryMESA(__DRInativeDisplay * dpy, int scrn,
- GLsizei size, GLfloat readfreq,
- GLfloat writefreq, GLfloat priority);
-extern void r200FreeMemoryMESA(__DRInativeDisplay * dpy, int scrn,
- GLvoid * pointer);
-extern GLuint r200GetMemoryOffsetMESA(__DRInativeDisplay * dpy, int scrn,
- const GLvoid * pointer);
-
-extern GLboolean r200IsGartMemory(r200ContextPtr rmesa, const GLvoid * pointer,
- GLint size);
-
-extern GLuint r200GartOffsetFromVirtual(r200ContextPtr rmesa,
- const GLvoid * pointer);
-
-void r200SaveHwState(r200ContextPtr radeon);
-void r200SetUpAtomList(r200ContextPtr rmesa);
-
-/* ================================================================
- * Helper macros:
- */
-
-/* Close off the last primitive, if it exists.
- */
-#define R200_NEWPRIM( rmesa ) \
-do { \
- if ( rmesa->dma.flush ) \
- rmesa->dma.flush( rmesa ); \
-} while (0)
-
-/* Can accomodate several state changes and primitive changes without
- * actually firing the buffer.
- */
-#define R200_STATECHANGE( rmesa, ATOM ) \
-do { \
- R200_NEWPRIM( rmesa ); \
- rmesa->hw.ATOM.dirty = GL_TRUE; \
- rmesa->hw.is_dirty = GL_TRUE; \
-} while (0)
-
-#define R200_DB_STATE( ATOM ) \
- memcpy( rmesa->hw.ATOM.lastcmd, rmesa->hw.ATOM.cmd, \
- rmesa->hw.ATOM.cmd_size * 4)
-
-static __inline int R200_DB_STATECHANGE(r200ContextPtr rmesa,
- struct r200_state_atom *atom)
-{
- if (memcmp(atom->cmd, atom->lastcmd, atom->cmd_size * 4)) {
- int *tmp;
- R200_NEWPRIM(rmesa);
- atom->dirty = GL_TRUE;
- rmesa->hw.is_dirty = GL_TRUE;
- tmp = atom->cmd;
- atom->cmd = atom->lastcmd;
- atom->lastcmd = tmp;
- return 1;
- } else
- return 0;
-}
-
-/* Fire the buffered vertices no matter what.
- */
-#define R200_FIREVERTICES( r200 ) \
-do { \
- if ( (r200)->store.cmd_used || (r200)->dma.flush ) { \
- radeonFlush( (r200)->radeon.glCtx ); \
- } \
-} while (0)
-
-/* Command lengths. Note that any time you ensure ELTS_BUFSZ or VBUF_BUFSZ
- * are available, you will also be adding an rmesa->state.max_state_size because
- * r200EmitState is called from within r200EmitVbufPrim and r200FlushElts.
- */
-#define AOS_BUFSZ(nr) ((3 + ((nr / 2) * 3) + ((nr & 1) * 2)) * sizeof(int))
-#define VERT_AOS_BUFSZ (5 * sizeof(int))
-#define ELTS_BUFSZ(nr) (12 + nr * 2)
-#define VBUF_BUFSZ (3 * sizeof(int))
-
-/* Ensure that a minimum amount of space is available in the command buffer.
- * This is used to ensure atomicity of state updates with the rendering requests
- * that rely on them.
- *
- * An alternative would be to implement a "soft lock" such that when the buffer
- * wraps at an inopportune time, we grab the lock, flush the current buffer,
- * and hang on to the lock until the critical section is finished and we flush
- * the buffer again and unlock.
- */
-static __inline void r200EnsureCmdBufSpace(r200ContextPtr rmesa, int bytes)
-{
- if (rmesa->store.cmd_used + bytes > R200_CMD_BUF_SZ)
- r200FlushCmdBuf(rmesa, __FUNCTION__);
- assert(bytes <= R200_CMD_BUF_SZ);
-}
-
-/* Alloc space in the command buffer
- */
-static __inline char *r200AllocCmdBuf(r200ContextPtr rmesa,
- int bytes, const char *where)
-{
- char *head;
-
- if (rmesa->store.cmd_used + bytes > R200_CMD_BUF_SZ)
- r200FlushCmdBuf(rmesa, where);
-
- head = rmesa->store.cmd_buf + rmesa->store.cmd_used;
- rmesa->store.cmd_used += bytes;
- assert(rmesa->store.cmd_used <= R200_CMD_BUF_SZ);
- return head;
-}
-
-#endif /* __R200_IOCTL_H__ */
diff --git a/src/mesa/drivers/dri/r300/r200_reg.h b/src/mesa/drivers/dri/r300/r200_reg.h
deleted file mode 100644
index 1336e961ac6..00000000000
--- a/src/mesa/drivers/dri/r300/r200_reg.h
+++ /dev/null
@@ -1,1423 +0,0 @@
-/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_reg.h,v 1.2 2002/12/16 16:18:54 dawes Exp $ */
-/*
-Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
-
-The Weather Channel (TM) funded Tungsten Graphics to develop the
-initial release of the Radeon 8500 driver under the XFree86 license.
-This notice must be preserved.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial
-portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#ifndef _R200_REG_H_
-#define _R200_REG_H_
-
-#define R200_PP_MISC 0x1c14
-#define R200_REF_ALPHA_MASK 0x000000ff
-#define R200_ALPHA_TEST_FAIL (0 << 8)
-#define R200_ALPHA_TEST_LESS (1 << 8)
-#define R200_ALPHA_TEST_LEQUAL (2 << 8)
-#define R200_ALPHA_TEST_EQUAL (3 << 8)
-#define R200_ALPHA_TEST_GEQUAL (4 << 8)
-#define R200_ALPHA_TEST_GREATER (5 << 8)
-#define R200_ALPHA_TEST_NEQUAL (6 << 8)
-#define R200_ALPHA_TEST_PASS (7 << 8)
-#define R200_ALPHA_TEST_OP_MASK (7 << 8)
-#define R200_CHROMA_FUNC_FAIL (0 << 16)
-#define R200_CHROMA_FUNC_PASS (1 << 16)
-#define R200_CHROMA_FUNC_NEQUAL (2 << 16)
-#define R200_CHROMA_FUNC_EQUAL (3 << 16)
-#define R200_CHROMA_KEY_NEAREST (0 << 18)
-#define R200_CHROMA_KEY_ZERO (1 << 18)
-#define R200_RIGHT_HAND_CUBE_D3D (0 << 24)
-#define R200_RIGHT_HAND_CUBE_OGL (1 << 24)
-#define R200_PP_FOG_COLOR 0x1c18
-#define R200_FOG_COLOR_MASK 0x00ffffff
-#define R200_FOG_VERTEX (0 << 24)
-#define R200_FOG_TABLE (1 << 24)
-#define R200_FOG_USE_DEPTH (0 << 25)
-#define R200_FOG_USE_W (1 << 25)
-#define R200_FOG_USE_DIFFUSE_ALPHA (2 << 25)
-#define R200_FOG_USE_SPEC_ALPHA (3 << 25)
-#define R200_FOG_USE_VTX_FOG (4 << 25)
-#define R200_FOG_USE_MASK (7 << 25)
-#define R200_RE_SOLID_COLOR 0x1c1c
-#define R200_RB3D_BLENDCNTL 0x1c20
-#define R200_COMB_FCN_MASK (7 << 12)
-#define R200_COMB_FCN_ADD_CLAMP (0 << 12)
-#define R200_COMB_FCN_ADD_NOCLAMP (1 << 12)
-#define R200_COMB_FCN_SUB_CLAMP (2 << 12)
-#define R200_COMB_FCN_SUB_NOCLAMP (3 << 12)
-#define R200_COMB_FCN_MIN (4 << 12)
-#define R200_COMB_FCN_MAX (5 << 12)
-#define R200_COMB_FCN_RSUB_CLAMP (6 << 12)
-#define R200_COMB_FCN_RSUB_NOCLAMP (7 << 12)
-#define R200_BLEND_GL_ZERO (32)
-#define R200_BLEND_GL_ONE (33)
-#define R200_BLEND_GL_SRC_COLOR (34)
-#define R200_BLEND_GL_ONE_MINUS_SRC_COLOR (35)
-#define R200_BLEND_GL_DST_COLOR (36)
-#define R200_BLEND_GL_ONE_MINUS_DST_COLOR (37)
-#define R200_BLEND_GL_SRC_ALPHA (38)
-#define R200_BLEND_GL_ONE_MINUS_SRC_ALPHA (39)
-#define R200_BLEND_GL_DST_ALPHA (40)
-#define R200_BLEND_GL_ONE_MINUS_DST_ALPHA (41)
-#define R200_BLEND_GL_SRC_ALPHA_SATURATE (42) /* src factor only */
-#define R200_BLEND_GL_CONST_COLOR (43)
-#define R200_BLEND_GL_ONE_MINUS_CONST_COLOR (44)
-#define R200_BLEND_GL_CONST_ALPHA (45)
-#define R200_BLEND_GL_ONE_MINUS_CONST_ALPHA (46)
-#define R200_BLEND_MASK (63)
-#define R200_SRC_BLEND_SHIFT (16)
-#define R200_DST_BLEND_SHIFT (24)
-#define R200_RB3D_DEPTHOFFSET 0x1c24
-#define R200_RB3D_DEPTHPITCH 0x1c28
-#define R200_DEPTHPITCH_MASK 0x00001ff8
-#define R200_DEPTH_ENDIAN_NO_SWAP (0 << 18)
-#define R200_DEPTH_ENDIAN_WORD_SWAP (1 << 18)
-#define R200_DEPTH_ENDIAN_DWORD_SWAP (2 << 18)
-#define R200_RB3D_ZSTENCILCNTL 0x1c2c
-#define R200_DEPTH_FORMAT_MASK (0xf << 0)
-#define R200_DEPTH_FORMAT_16BIT_INT_Z (0 << 0)
-#define R200_DEPTH_FORMAT_24BIT_INT_Z (2 << 0)
-#define R200_DEPTH_FORMAT_24BIT_FLOAT_Z (3 << 0)
-#define R200_DEPTH_FORMAT_32BIT_INT_Z (4 << 0)
-#define R200_DEPTH_FORMAT_32BIT_FLOAT_Z (5 << 0)
-#define R200_DEPTH_FORMAT_24BIT_FLOAT_W (9 << 0)
-#define R200_DEPTH_FORMAT_32BIT_FLOAT_W (11 << 0)
-#define R200_Z_TEST_NEVER (0 << 4)
-#define R200_Z_TEST_LESS (1 << 4)
-#define R200_Z_TEST_LEQUAL (2 << 4)
-#define R200_Z_TEST_EQUAL (3 << 4)
-#define R200_Z_TEST_GEQUAL (4 << 4)
-#define R200_Z_TEST_GREATER (5 << 4)
-#define R200_Z_TEST_NEQUAL (6 << 4)
-#define R200_Z_TEST_ALWAYS (7 << 4)
-#define R200_Z_TEST_MASK (7 << 4)
-#define R200_STENCIL_TEST_NEVER (0 << 12)
-#define R200_STENCIL_TEST_LESS (1 << 12)
-#define R200_STENCIL_TEST_LEQUAL (2 << 12)
-#define R200_STENCIL_TEST_EQUAL (3 << 12)
-#define R200_STENCIL_TEST_GEQUAL (4 << 12)
-#define R200_STENCIL_TEST_GREATER (5 << 12)
-#define R200_STENCIL_TEST_NEQUAL (6 << 12)
-#define R200_STENCIL_TEST_ALWAYS (7 << 12)
-#define R200_STENCIL_TEST_MASK (0x7 << 12)
-#define R200_STENCIL_FAIL_KEEP (0 << 16)
-#define R200_STENCIL_FAIL_ZERO (1 << 16)
-#define R200_STENCIL_FAIL_REPLACE (2 << 16)
-#define R200_STENCIL_FAIL_INC (3 << 16)
-#define R200_STENCIL_FAIL_DEC (4 << 16)
-#define R200_STENCIL_FAIL_INVERT (5 << 16)
-#define R200_STENCIL_FAIL_INC_WRAP (6 << 16)
-#define R200_STENCIL_FAIL_DEC_WRAP (7 << 16)
-#define R200_STENCIL_FAIL_MASK (0x7 << 16)
-#define R200_STENCIL_ZPASS_KEEP (0 << 20)
-#define R200_STENCIL_ZPASS_ZERO (1 << 20)
-#define R200_STENCIL_ZPASS_REPLACE (2 << 20)
-#define R200_STENCIL_ZPASS_INC (3 << 20)
-#define R200_STENCIL_ZPASS_DEC (4 << 20)
-#define R200_STENCIL_ZPASS_INVERT (5 << 20)
-#define R200_STENCIL_ZPASS_INC_WRAP (6 << 20)
-#define R200_STENCIL_ZPASS_DEC_WRAP (7 << 20)
-#define R200_STENCIL_ZPASS_MASK (0x7 << 20)
-#define R200_STENCIL_ZFAIL_KEEP (0 << 24)
-#define R200_STENCIL_ZFAIL_ZERO (1 << 24)
-#define R200_STENCIL_ZFAIL_REPLACE (2 << 24)
-#define R200_STENCIL_ZFAIL_INC (3 << 24)
-#define R200_STENCIL_ZFAIL_DEC (4 << 24)
-#define R200_STENCIL_ZFAIL_INVERT (5 << 24)
-#define R200_STENCIL_ZFAIL_INC_WRAP (6 << 24)
-#define R200_STENCIL_ZFAIL_DEC_WRAP (7 << 24)
-#define R200_STENCIL_ZFAIL_MASK (0x7 << 24)
-#define R200_Z_WRITE_ENABLE (1 << 30)
-/*gap*/
-#define R200_PP_CNTL 0x1c38
-#define R200_TEX_0_ENABLE 0x00000010
-#define R200_TEX_1_ENABLE 0x00000020
-#define R200_TEX_2_ENABLE 0x00000040
-#define R200_TEX_3_ENABLE 0x00000080
-#define R200_TEX_4_ENABLE 0x00000100
-#define R200_TEX_5_ENABLE 0x00000200
-#define R200_TEX_ENABLE_MASK 0x000003f0
-#define R200_FILTER_ROUND_MODE_MASK 0x00000400
-#define R200_TEX_BLEND_7_ENABLE 0x00000800
-#define R200_TEX_BLEND_0_ENABLE 0x00001000
-#define R200_TEX_BLEND_1_ENABLE 0x00002000
-#define R200_TEX_BLEND_2_ENABLE 0x00004000
-#define R200_TEX_BLEND_3_ENABLE 0x00008000
-#define R200_TEX_BLEND_4_ENABLE 0x00010000
-#define R200_TEX_BLEND_5_ENABLE 0x00020000
-#define R200_TEX_BLEND_6_ENABLE 0x00040000
-#define R200_MULTI_PASS_ENABLE 0x00080000
-#define R200_SPECULAR_ENABLE 0x00200000
-#define R200_FOG_ENABLE 0x00400000
-#define R200_ALPHA_TEST_ENABLE 0x00800000
-#define R200_ANTI_ALIAS_NONE 0x00000000
-#define R200_ANTI_ALIAS_LINE 0x01000000
-#define R200_ANTI_ALIAS_POLY 0x02000000
-#define R200_ANTI_ALIAS_MASK 0x03000000
-#define R200_RB3D_CNTL 0x1c3c
-#define R200_ALPHA_BLEND_ENABLE (1 << 0)
-#define R200_PLANE_MASK_ENABLE (1 << 1)
-#define R200_DITHER_ENABLE (1 << 2)
-#define R200_ROUND_ENABLE (1 << 3)
-#define R200_SCALE_DITHER_ENABLE (1 << 4)
-#define R200_DITHER_INIT (1 << 5)
-#define R200_ROP_ENABLE (1 << 6)
-#define R200_STENCIL_ENABLE (1 << 7)
-#define R200_Z_ENABLE (1 << 8)
-#define R200_DEPTH_XZ_OFFEST_ENABLE (1 << 9)
-#define R200_COLOR_FORMAT_ARGB1555 (3 << 10)
-#define R200_COLOR_FORMAT_RGB565 (4 << 10)
-#define R200_COLOR_FORMAT_ARGB8888 (6 << 10)
-#define R200_COLOR_FORMAT_RGB332 (7 << 10)
-#define R200_COLOR_FORMAT_Y8 (8 << 10)
-#define R200_COLOR_FORMAT_RGB8 (9 << 10)
-#define R200_COLOR_FORMAT_YUV422_VYUY (11 << 10)
-#define R200_COLOR_FORMAT_YUV422_YVYU (12 << 10)
-#define R200_COLOR_FORMAT_aYUV444 (14 << 10)
-#define R200_COLOR_FORMAT_ARGB4444 (15 << 10)
-#define R200_CLRCMP_FLIP_ENABLE (1 << 14)
-#define R200_SEPARATE_ALPHA_ENABLE (1 << 16)
-#define R200_RB3D_COLOROFFSET 0x1c40
-#define R200_COLOROFFSET_MASK 0xfffffff0
-#define R200_RE_WIDTH_HEIGHT 0x1c44
-#define R200_RE_WIDTH_SHIFT 0
-#define R200_RE_HEIGHT_SHIFT 16
-#define R200_RB3D_COLORPITCH 0x1c48
-#define R200_COLORPITCH_MASK 0x000001ff8
-#define R200_COLOR_ENDIAN_NO_SWAP (0 << 18)
-#define R200_COLOR_ENDIAN_WORD_SWAP (1 << 18)
-#define R200_COLOR_ENDIAN_DWORD_SWAP (2 << 18)
-#define R200_SE_CNTL 0x1c4c
-#define R200_FFACE_CULL_CW (0 << 0)
-#define R200_FFACE_CULL_CCW (1 << 0)
-#define R200_FFACE_CULL_DIR_MASK (1 << 0)
-#define R200_BFACE_CULL (0 << 1)
-#define R200_BFACE_SOLID (3 << 1)
-#define R200_FFACE_CULL (0 << 3)
-#define R200_FFACE_SOLID (3 << 3)
-#define R200_FFACE_CULL_MASK (3 << 3)
-#define R200_FLAT_SHADE_VTX_0 (0 << 6)
-#define R200_FLAT_SHADE_VTX_1 (1 << 6)
-#define R200_FLAT_SHADE_VTX_2 (2 << 6)
-#define R200_FLAT_SHADE_VTX_LAST (3 << 6)
-#define R200_DIFFUSE_SHADE_SOLID (0 << 8)
-#define R200_DIFFUSE_SHADE_FLAT (1 << 8)
-#define R200_DIFFUSE_SHADE_GOURAUD (2 << 8)
-#define R200_DIFFUSE_SHADE_MASK (3 << 8)
-#define R200_ALPHA_SHADE_SOLID (0 << 10)
-#define R200_ALPHA_SHADE_FLAT (1 << 10)
-#define R200_ALPHA_SHADE_GOURAUD (2 << 10)
-#define R200_ALPHA_SHADE_MASK (3 << 10)
-#define R200_SPECULAR_SHADE_SOLID (0 << 12)
-#define R200_SPECULAR_SHADE_FLAT (1 << 12)
-#define R200_SPECULAR_SHADE_GOURAUD (2 << 12)
-#define R200_SPECULAR_SHADE_MASK (3 << 12)
-#define R200_FOG_SHADE_SOLID (0 << 14)
-#define R200_FOG_SHADE_FLAT (1 << 14)
-#define R200_FOG_SHADE_GOURAUD (2 << 14)
-#define R200_FOG_SHADE_MASK (3 << 14)
-#define R200_ZBIAS_ENABLE_POINT (1 << 16)
-#define R200_ZBIAS_ENABLE_LINE (1 << 17)
-#define R200_ZBIAS_ENABLE_TRI (1 << 18)
-#define R200_WIDELINE_ENABLE (1 << 20)
-#define R200_VTX_PIX_CENTER_D3D (0 << 27)
-#define R200_VTX_PIX_CENTER_OGL (1 << 27)
-#define R200_ROUND_MODE_TRUNC (0 << 28)
-#define R200_ROUND_MODE_ROUND (1 << 28)
-#define R200_ROUND_MODE_ROUND_EVEN (2 << 28)
-#define R200_ROUND_MODE_ROUND_ODD (3 << 28)
-#define R200_ROUND_PREC_16TH_PIX (0 << 30)
-#define R200_ROUND_PREC_8TH_PIX (1 << 30)
-#define R200_ROUND_PREC_4TH_PIX (2 << 30)
-#define R200_ROUND_PREC_HALF_PIX (3 << 30)
-#define R200_RE_CNTL 0x1c50
-#define R200_STIPPLE_ENABLE 0x1
-#define R200_SCISSOR_ENABLE 0x2
-#define R200_PATTERN_ENABLE 0x4
-#define R200_PERSPECTIVE_ENABLE 0x8
-#define R200_POINT_SMOOTH 0x20
-#define R200_VTX_STQ0_D3D 0x00010000
-#define R200_VTX_STQ1_D3D 0x00040000
-#define R200_VTX_STQ2_D3D 0x00100000
-#define R200_VTX_STQ3_D3D 0x00400000
-#define R200_VTX_STQ4_D3D 0x01000000
-#define R200_VTX_STQ5_D3D 0x04000000
-/* gap */
-#define R200_RE_STIPPLE_ADDR 0x1cc8
-#define R200_RE_STIPPLE_DATA 0x1ccc
-#define R200_RE_LINE_PATTERN 0x1cd0
-#define R200_LINE_PATTERN_MASK 0x0000ffff
-#define R200_LINE_REPEAT_COUNT_SHIFT 16
-#define R200_LINE_PATTERN_START_SHIFT 24
-#define R200_LINE_PATTERN_LITTLE_BIT_ORDER (0 << 28)
-#define R200_LINE_PATTERN_BIG_BIT_ORDER (1 << 28)
-#define R200_LINE_PATTERN_AUTO_RESET (1 << 29)
-#define R200_RE_LINE_STATE 0x1cd4
-#define R200_LINE_CURRENT_PTR_SHIFT 0
-#define R200_LINE_CURRENT_COUNT_SHIFT 8
-#define R200_RE_SCISSOR_TL_0 0x1cd8
-#define R200_RE_SCISSOR_BR_0 0x1cdc
-#define R200_RE_SCISSOR_TL_1 0x1ce0
-#define R200_RE_SCISSOR_BR_1 0x1ce4
-#define R200_RE_SCISSOR_TL_2 0x1ce8
-#define R200_RE_SCISSOR_BR_2 0x1cec
-/* gap */
-#define R200_RB3D_DEPTHXY_OFFSET 0x1d60
-#define R200_DEPTHX_SHIFT 0
-#define R200_DEPTHY_SHIFT 16
-/* gap */
-#define R200_RB3D_STENCILREFMASK 0x1d7c
-#define R200_STENCIL_REF_SHIFT 0
-#define R200_STENCIL_REF_MASK (0xff << 0)
-#define R200_STENCIL_MASK_SHIFT 16
-#define R200_STENCIL_VALUE_MASK (0xff << 16)
-#define R200_STENCIL_WRITEMASK_SHIFT 24
-#define R200_STENCIL_WRITE_MASK (0xff << 24)
-#define R200_RB3D_ROPCNTL 0x1d80
-#define R200_ROP_MASK (15 << 8)
-#define R200_ROP_CLEAR (0 << 8)
-#define R200_ROP_NOR (1 << 8)
-#define R200_ROP_AND_INVERTED (2 << 8)
-#define R200_ROP_COPY_INVERTED (3 << 8)
-#define R200_ROP_AND_REVERSE (4 << 8)
-#define R200_ROP_INVERT (5 << 8)
-#define R200_ROP_XOR (6 << 8)
-#define R200_ROP_NAND (7 << 8)
-#define R200_ROP_AND (8 << 8)
-#define R200_ROP_EQUIV (9 << 8)
-#define R200_ROP_NOOP (10 << 8)
-#define R200_ROP_OR_INVERTED (11 << 8)
-#define R200_ROP_COPY (12 << 8)
-#define R200_ROP_OR_REVERSE (13 << 8)
-#define R200_ROP_OR (14 << 8)
-#define R200_ROP_SET (15 << 8)
-#define R200_RB3D_PLANEMASK 0x1d84
-/* gap */
-#define R200_SE_VPORT_XSCALE 0x1d98
-#define R200_SE_VPORT_XOFFSET 0x1d9c
-#define R200_SE_VPORT_YSCALE 0x1da0
-#define R200_SE_VPORT_YOFFSET 0x1da4
-#define R200_SE_VPORT_ZSCALE 0x1da8
-#define R200_SE_VPORT_ZOFFSET 0x1dac
-#define R200_SE_ZBIAS_FACTOR 0x1db0
-#define R200_SE_ZBIAS_CONSTANT 0x1db4
-#define R200_SE_LINE_WIDTH 0x1db8
-#define R200_LINE_WIDTH_SHIFT 0x00000000
-#define R200_MINPOINTSIZE_SHIFT 0x00000010
-/* gap */
-#define R200_SE_VAP_CNTL 0x2080
-#define R200_VAP_TCL_ENABLE 0x00000001
-#define R200_VAP_SINGLE_BUF_STATE_ENABLE 0x00000010
-#define R200_VAP_FORCE_W_TO_ONE 0x00010000
-#define R200_VAP_D3D_TEX_DEFAULT 0x00020000
-#define R200_VAP_VF_MAX_VTX_NUM__SHIFT 18
-#define R200_VAP_DX_CLIP_SPACE_DEF 0x00400000
-#define R200_SE_VF_CNTL 0x2084
-#define R200_VF_PRIM_NONE 0x00000000
-#define R200_VF_PRIM_POINTS 0x00000001
-#define R200_VF_PRIM_LINES 0x00000002
-#define R200_VF_PRIM_LINE_STRIP 0x00000003
-#define R200_VF_PRIM_TRIANGLES 0x00000004
-#define R200_VF_PRIM_TRIANGLE_FAN 0x00000005
-#define R200_VF_PRIM_TRIANGLE_STRIP 0x00000006
-#define R200_VF_PRIM_RECT_LIST 0x00000008
-#define R200_VF_PRIM_3VRT_POINTS 0x00000009
-#define R200_VF_PRIM_3VRT_LINES 0x0000000a
-#define R200_VF_PRIM_POINT_SPRITES 0x0000000b
-#define R200_VF_PRIM_LINE_LOOP 0x0000000c
-#define R200_VF_PRIM_QUADS 0x0000000d
-#define R200_VF_PRIM_QUAD_STRIP 0x0000000e
-#define R200_VF_PRIM_POLYGON 0x0000000f
-#define R200_VF_PRIM_MASK 0x0000000f
-#define R200_VF_PRIM_WALK_IND 0x00000010
-#define R200_VF_PRIM_WALK_LIST 0x00000020
-#define R200_VF_PRIM_WALK_RING 0x00000030
-#define R200_VF_PRIM_WALK_MASK 0x00000030
-#define R200_VF_COLOR_ORDER_RGBA 0x00000040
-#define R200_VF_TCL_OUTPUT_VTX_ENABLE 0x00000200
-#define R200_VF_INDEX_SZ_4 0x00000800
-#define R200_VF_VERTEX_NUMBER_MASK 0xffff0000
-#define R200_VF_VERTEX_NUMBER_SHIFT 16
-#define R200_SE_VTX_FMT_0 0x2088
-#define R200_VTX_XY 0 /* always have xy */
-#define R200_VTX_Z0 (1<<0)
-#define R200_VTX_W0 (1<<1)
-#define R200_VTX_WEIGHT_COUNT_SHIFT (2)
-#define R200_VTX_PV_MATRIX_SEL (1<<5)
-#define R200_VTX_N0 (1<<6)
-#define R200_VTX_POINT_SIZE (1<<7)
-#define R200_VTX_DISCRETE_FOG (1<<8)
-#define R200_VTX_SHININESS_0 (1<<9)
-#define R200_VTX_SHININESS_1 (1<<10)
-#define R200_VTX_COLOR_NOT_PRESENT 0
-#define R200_VTX_PK_RGBA 1
-#define R200_VTX_FP_RGB 2
-#define R200_VTX_FP_RGBA 3
-#define R200_VTX_COLOR_MASK 3
-#define R200_VTX_COLOR_0_SHIFT 11
-#define R200_VTX_COLOR_1_SHIFT 13
-#define R200_VTX_COLOR_2_SHIFT 15
-#define R200_VTX_COLOR_3_SHIFT 17
-#define R200_VTX_COLOR_4_SHIFT 19
-#define R200_VTX_COLOR_5_SHIFT 21
-#define R200_VTX_COLOR_6_SHIFT 23
-#define R200_VTX_COLOR_7_SHIFT 25
-#define R200_VTX_XY1 (1<<28)
-#define R200_VTX_Z1 (1<<29)
-#define R200_VTX_W1 (1<<30)
-#define R200_VTX_N1 (1<<31)
-#define R200_SE_VTX_FMT_1 0x208c
-#define R200_VTX_TEX0_COMP_CNT_SHIFT 0
-#define R200_VTX_TEX1_COMP_CNT_SHIFT 3
-#define R200_VTX_TEX2_COMP_CNT_SHIFT 6
-#define R200_VTX_TEX3_COMP_CNT_SHIFT 9
-#define R200_VTX_TEX4_COMP_CNT_SHIFT 12
-#define R200_VTX_TEX5_COMP_CNT_SHIFT 15
-#define R200_SE_TCL_OUTPUT_VTX_FMT_0 0x2090
-#define R200_SE_TCL_OUTPUT_VTX_FMT_1 0x2094
-/* gap */
-#define R200_SE_VTE_CNTL 0x20b0
-#define R200_VPORT_X_SCALE_ENA 0x00000001
-#define R200_VPORT_X_OFFSET_ENA 0x00000002
-#define R200_VPORT_Y_SCALE_ENA 0x00000004
-#define R200_VPORT_Y_OFFSET_ENA 0x00000008
-#define R200_VPORT_Z_SCALE_ENA 0x00000010
-#define R200_VPORT_Z_OFFSET_ENA 0x00000020
-#define R200_VTX_XY_FMT 0x00000100
-#define R200_VTX_Z_FMT 0x00000200
-#define R200_VTX_W0_FMT 0x00000400
-#define R200_VTX_W0_NORMALIZE 0x00000800
-#define R200_VTX_ST_DENORMALIZED 0x00001000
-/* gap */
-#define R200_SE_VTX_NUM_ARRAYS 0x20c0
-#define R200_SE_VTX_AOS_ATTR01 0x20c4
-#define R200_SE_VTX_AOS_ADDR0 0x20c8
-#define R200_SE_VTX_AOS_ADDR1 0x20cc
-#define R200_SE_VTX_AOS_ATTR23 0x20d0
-#define R200_SE_VTX_AOS_ADDR2 0x20d4
-#define R200_SE_VTX_AOS_ADDR3 0x20d8
-#define R200_SE_VTX_AOS_ATTR45 0x20dc
-#define R200_SE_VTX_AOS_ADDR4 0x20e0
-#define R200_SE_VTX_AOS_ADDR5 0x20e4
-#define R200_SE_VTX_AOS_ATTR67 0x20e8
-#define R200_SE_VTX_AOS_ADDR6 0x20ec
-#define R200_SE_VTX_AOS_ADDR7 0x20f0
-#define R200_SE_VTX_AOS_ATTR89 0x20f4
-#define R200_SE_VTX_AOS_ADDR8 0x20f8
-#define R200_SE_VTX_AOS_ADDR9 0x20fc
-#define R200_SE_VTX_AOS_ATTR1011 0x2100
-#define R200_SE_VTX_AOS_ADDR10 0x2104
-#define R200_SE_VTX_AOS_ADDR11 0x2108
-#define R200_SE_VF_MAX_VTX_INDX 0x210c
-#define R200_SE_VF_MIN_VTX_INDX 0x2110
-/* gap */
-#define R200_SE_VAP_CNTL_STATUS 0x2140
-#define R200_VC_NO_SWAP (0 << 0)
-#define R200_VC_16BIT_SWAP (1 << 0)
-#define R200_VC_32BIT_SWAP (2 << 0)
-/* gap */
-#define R200_SE_VTX_STATE_CNTL 0x2180
-#define R200_VSC_COLOR_0_ASSEMBLY_CNTL_SHIFT 0x00000000
-#define R200_VSC_COLOR_1_ASSEMBLY_CNTL_SHIFT 0x00000002
-#define R200_VSC_COLOR_2_ASSEMBLY_CNTL_SHIFT 0x00000004
-#define R200_VSC_COLOR_3_ASSEMBLY_CNTL_SHIFT 0x00000006
-#define R200_VSC_COLOR_4_ASSEMBLY_CNTL_SHIFT 0x00000008
-#define R200_VSC_COLOR_5_ASSEMBLY_CNTL_SHIFT 0x0000000a
-#define R200_VSC_COLOR_6_ASSEMBLY_CNTL_SHIFT 0x0000000c
-#define R200_VSC_COLOR_7_ASSEMBLY_CNTL_SHIFT 0x0000000e
-#define R200_VSC_UPDATE_USER_COLOR_0_ENABLE 0x00010000
-#define R200_VSC_UPDATE_USER_COLOR_1_ENABLE 0x00020000
-/* gap */
-#define R200_SE_TCL_VECTOR_INDX_REG 0x2200
-#define R200_SE_TCL_VECTOR_DATA_REG 0x2204
-#define R200_SE_TCL_SCALAR_INDX_REG 0x2208
-#define R200_SE_TCL_SCALAR_DATA_REG 0x220c
-/* gap */
-#define R200_SE_TCL_MATRIX_SEL_0 0x2230
-#define R200_MODELVIEW_0_SHIFT (0)
-#define R200_MODELVIEW_1_SHIFT (8)
-#define R200_MODELVIEW_2_SHIFT (16)
-#define R200_MODELVIEW_3_SHIFT (24)
-#define R200_SE_TCL_MATRIX_SEL_1 0x2234
-#define R200_IT_MODELVIEW_0_SHIFT (0)
-#define R200_IT_MODELVIEW_1_SHIFT (8)
-#define R200_IT_MODELVIEW_2_SHIFT (16)
-#define R200_IT_MODELVIEW_3_SHIFT (24)
-#define R200_SE_TCL_MATRIX_SEL_2 0x2238
-#define R200_MODELPROJECT_0_SHIFT (0)
-#define R200_MODELPROJECT_1_SHIFT (8)
-#define R200_MODELPROJECT_2_SHIFT (16)
-#define R200_MODELPROJECT_3_SHIFT (24)
-#define R200_SE_TCL_MATRIX_SEL_3 0x223c
-#define R200_TEXMAT_0_SHIFT 0
-#define R200_TEXMAT_1_SHIFT 8
-#define R200_TEXMAT_2_SHIFT 16
-#define R200_TEXMAT_3_SHIFT 24
-#define R200_SE_TCL_MATRIX_SEL_4 0x2240
-#define R200_TEXMAT_4_SHIFT 0
-#define R200_TEXMAT_5_SHIFT 8
-/* gap */
-#define R200_SE_TCL_OUTPUT_VTX_COMP_SEL 0x2250
-#define R200_OUTPUT_XYZW (1<<0)
-#define R200_OUTPUT_COLOR_0 (1<<8)
-#define R200_OUTPUT_COLOR_1 (1<<9)
-#define R200_OUTPUT_TEX_0 (1<<16)
-#define R200_OUTPUT_TEX_1 (1<<17)
-#define R200_OUTPUT_TEX_2 (1<<18)
-#define R200_OUTPUT_TEX_3 (1<<19)
-#define R200_OUTPUT_TEX_4 (1<<20)
-#define R200_OUTPUT_TEX_5 (1<<21)
-#define R200_OUTPUT_TEX_MASK (0x3f<<16)
-#define R200_OUTPUT_DISCRETE_FOG (1<<24)
-#define R200_OUTPUT_PT_SIZE (1<<25)
-#define R200_FORCE_INORDER_PROC (1<<31)
-#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0 0x2254
-#define R200_VERTEX_POSITION_ADDR__SHIFT 0x00000000
-#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_1 0x2258
-#define R200_VTX_COLOR_0_ADDR__SHIFT 0x00000000
-#define R200_VTX_COLOR_1_ADDR__SHIFT 0x00000008
-#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_2 0x225c
-#define R200_VTX_TEX_0_ADDR__SHIFT 0x00000000
-#define R200_VTX_TEX_1_ADDR__SHIFT 0x00000008
-#define R200_VTX_TEX_2_ADDR__SHIFT 0x00000010
-#define R200_VTX_TEX_3_ADDR__SHIFT 0x00000018
-#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_3 0x2260
-#define R200_VTX_TEX_4_ADDR__SHIFT 0x00000000
-#define R200_VTX_TEX_5_ADDR__SHIFT 0x00000008
-
-/* gap */
-#define R200_SE_TCL_LIGHT_MODEL_CTL_0 0x2268
-#define R200_LIGHTING_ENABLE (1<<0)
-#define R200_LIGHT_IN_MODELSPACE (1<<1)
-#define R200_LOCAL_VIEWER (1<<2)
-#define R200_NORMALIZE_NORMALS (1<<3)
-#define R200_RESCALE_NORMALS (1<<4)
-#define R200_SPECULAR_LIGHTS (1<<5)
-#define R200_DIFFUSE_SPECULAR_COMBINE (1<<6)
-#define R200_LIGHT_ALPHA (1<<7)
-#define R200_LOCAL_LIGHT_VEC_GL (1<<8)
-#define R200_LIGHT_NO_NORMAL_AMBIENT_ONLY (1<<9)
-#define R200_LIGHT_TWOSIDE (1<<10)
-#define R200_FRONT_SHININESS_SOURCE_SHIFT (0xb)
-#define R200_BACK_SHININESS_SOURCE_SHIFT (0xd)
-#define R200_LM0_SOURCE_MATERIAL_0 (0)
-#define R200_LM0_SOURCE_MATERIAL_1 (1)
-#define R200_LM0_SOURCE_VERTEX_SHININESS_0 (2)
-#define R200_LM0_SOURCE_VERTEX_SHININESS_1 (3)
-#define R200_SE_TCL_LIGHT_MODEL_CTL_1 0x226c
-#define R200_LM1_SOURCE_LIGHT_PREMULT (0)
-#define R200_LM1_SOURCE_MATERIAL_0 (1)
-#define R200_LM1_SOURCE_VERTEX_COLOR_0 (2)
-#define R200_LM1_SOURCE_VERTEX_COLOR_1 (3)
-#define R200_LM1_SOURCE_VERTEX_COLOR_2 (4)
-#define R200_LM1_SOURCE_VERTEX_COLOR_3 (5)
-#define R200_LM1_SOURCE_VERTEX_COLOR_4 (6)
-#define R200_LM1_SOURCE_VERTEX_COLOR_5 (7)
-#define R200_LM1_SOURCE_VERTEX_COLOR_6 (8)
-#define R200_LM1_SOURCE_VERTEX_COLOR_7 (9)
-#define R200_LM1_SOURCE_MATERIAL_1 (0xf)
-#define R200_FRONT_EMISSIVE_SOURCE_SHIFT (0)
-#define R200_FRONT_AMBIENT_SOURCE_SHIFT (4)
-#define R200_FRONT_DIFFUSE_SOURCE_SHIFT (8)
-#define R200_FRONT_SPECULAR_SOURCE_SHIFT (12)
-#define R200_BACK_EMISSIVE_SOURCE_SHIFT (16)
-#define R200_BACK_AMBIENT_SOURCE_SHIFT (20)
-#define R200_BACK_DIFFUSE_SOURCE_SHIFT (24)
-#define R200_BACK_SPECULAR_SOURCE_SHIFT (28)
-#define R200_SE_TCL_PER_LIGHT_CTL_0 0x2270
-#define R200_LIGHT_0_ENABLE (1<<0)
-#define R200_LIGHT_0_ENABLE_AMBIENT (1<<1)
-#define R200_LIGHT_0_ENABLE_SPECULAR (1<<2)
-#define R200_LIGHT_0_IS_LOCAL (1<<3)
-#define R200_LIGHT_0_IS_SPOT (1<<4)
-#define R200_LIGHT_0_DUAL_CONE (1<<5)
-#define R200_LIGHT_0_ENABLE_RANGE_ATTEN (1<<6)
-#define R200_LIGHT_0_CONSTANT_RANGE_ATTEN (1<<7)
-#define R200_LIGHT_1_ENABLE (1<<16)
-#define R200_LIGHT_1_ENABLE_AMBIENT (1<<17)
-#define R200_LIGHT_1_ENABLE_SPECULAR (1<<18)
-#define R200_LIGHT_1_IS_LOCAL (1<<19)
-#define R200_LIGHT_1_IS_SPOT (1<<20)
-#define R200_LIGHT_1_DUAL_CONE (1<<21)
-#define R200_LIGHT_1_ENABLE_RANGE_ATTEN (1<<22)
-#define R200_LIGHT_1_CONSTANT_RANGE_ATTEN (1<<23)
-#define R200_LIGHT_0_SHIFT (0)
-#define R200_LIGHT_1_SHIFT (16)
-#define R200_SE_TCL_PER_LIGHT_CTL_1 0x2274
-#define R200_LIGHT_2_SHIFT (0)
-#define R200_LIGHT_3_SHIFT (16)
-#define R200_SE_TCL_PER_LIGHT_CTL_2 0x2278
-#define R200_LIGHT_4_SHIFT (0)
-#define R200_LIGHT_5_SHIFT (16)
-#define R200_SE_TCL_PER_LIGHT_CTL_3 0x227c
-#define R200_LIGHT_6_SHIFT (0)
-#define R200_LIGHT_7_SHIFT (16)
-/* gap */
-#define R200_SE_TCL_TEX_PROC_CTL_2 0x22a8
-#define R200_TEXGEN_0_COMP_MASK_SHIFT (0)
-#define R200_TEXGEN_1_COMP_MASK_SHIFT (4)
-#define R200_TEXGEN_2_COMP_MASK_SHIFT (8)
-#define R200_TEXGEN_3_COMP_MASK_SHIFT (12)
-#define R200_TEXGEN_4_COMP_MASK_SHIFT (16)
-#define R200_TEXGEN_5_COMP_MASK_SHIFT (20)
-#define R200_SE_TCL_TEX_PROC_CTL_3 0x22ac
-#define R200_TEXGEN_0_INPUT_TEX_SHIFT (0)
-#define R200_TEXGEN_1_INPUT_TEX_SHIFT (4)
-#define R200_TEXGEN_2_INPUT_TEX_SHIFT (8)
-#define R200_TEXGEN_3_INPUT_TEX_SHIFT (12)
-#define R200_TEXGEN_4_INPUT_TEX_SHIFT (16)
-#define R200_TEXGEN_5_INPUT_TEX_SHIFT (20)
-#define R200_SE_TCL_TEX_PROC_CTL_0 0x22b0
-#define R200_TEXGEN_TEXMAT_0_ENABLE (1<<0)
-#define R200_TEXGEN_TEXMAT_1_ENABLE (1<<1)
-#define R200_TEXGEN_TEXMAT_2_ENABLE (1<<2)
-#define R200_TEXGEN_TEXMAT_3_ENABLE (1<<3)
-#define R200_TEXGEN_TEXMAT_4_ENABLE (1<<4)
-#define R200_TEXGEN_TEXMAT_5_ENABLE (1<<5)
-#define R200_TEXMAT_0_ENABLE (1<<8)
-#define R200_TEXMAT_1_ENABLE (1<<9)
-#define R200_TEXMAT_2_ENABLE (1<<10)
-#define R200_TEXMAT_3_ENABLE (1<<11)
-#define R200_TEXMAT_4_ENABLE (1<<12)
-#define R200_TEXMAT_5_ENABLE (1<<13)
-#define R200_TEXGEN_FORCE_W_TO_ONE (1<<16)
-#define R200_SE_TCL_TEX_PROC_CTL_1 0x22b4
-#define R200_TEXGEN_INPUT_MASK (0xf)
-#define R200_TEXGEN_INPUT_TEXCOORD_0 (0)
-#define R200_TEXGEN_INPUT_TEXCOORD_1 (1)
-#define R200_TEXGEN_INPUT_TEXCOORD_2 (2)
-#define R200_TEXGEN_INPUT_TEXCOORD_3 (3)
-#define R200_TEXGEN_INPUT_TEXCOORD_4 (4)
-#define R200_TEXGEN_INPUT_TEXCOORD_5 (5)
-#define R200_TEXGEN_INPUT_OBJ (8)
-#define R200_TEXGEN_INPUT_EYE (9)
-#define R200_TEXGEN_INPUT_EYE_NORMAL (0xa)
-#define R200_TEXGEN_INPUT_EYE_REFLECT (0xb)
-#define R200_TEXGEN_INPUT_SPHERE (0xd)
-#define R200_TEXGEN_0_INPUT_SHIFT (0)
-#define R200_TEXGEN_1_INPUT_SHIFT (4)
-#define R200_TEXGEN_2_INPUT_SHIFT (8)
-#define R200_TEXGEN_3_INPUT_SHIFT (12)
-#define R200_TEXGEN_4_INPUT_SHIFT (16)
-#define R200_TEXGEN_5_INPUT_SHIFT (20)
-#define R200_SE_TC_TEX_CYL_WRAP_CTL 0x22b8
-/* gap */
-#define R200_SE_TCL_UCP_VERT_BLEND_CTL 0x22c0
-#define R200_UCP_IN_CLIP_SPACE (1<<0)
-#define R200_UCP_IN_MODEL_SPACE (1<<1)
-#define R200_UCP_ENABLE_0 (1<<2)
-#define R200_UCP_ENABLE_1 (1<<3)
-#define R200_UCP_ENABLE_2 (1<<4)
-#define R200_UCP_ENABLE_3 (1<<5)
-#define R200_UCP_ENABLE_4 (1<<6)
-#define R200_UCP_ENABLE_5 (1<<7)
-#define R200_TCL_FOG_MASK (3<<8)
-#define R200_TCL_FOG_DISABLE (0<<8)
-#define R200_TCL_FOG_EXP (1<<8)
-#define R200_TCL_FOG_EXP2 (2<<8)
-#define R200_TCL_FOG_LINEAR (3<<8)
-#define R200_RNG_BASED_FOG (1<<10)
-#define R200_CLIP_DISABLE (1<<11)
-#define R200_CULL_FRONT_IS_CW (0<<28)
-#define R200_CULL_FRONT_IS_CCW (1<<28)
-#define R200_CULL_FRONT (1<<29)
-#define R200_CULL_BACK (1<<30)
-#define R200_SE_TCL_POINT_SPRITE_CNTL 0x22c4
-/* gap */
-#define R200_SE_VTX_ST_POS_0_X_4 0x2300
-#define R200_SE_VTX_ST_POS_0_Y_4 0x2304
-#define R200_SE_VTX_ST_POS_0_Z_4 0x2308
-#define R200_SE_VTX_ST_POS_0_W_4 0x230c
-#define R200_SE_VTX_ST_NORM_0_X 0x2310
-#define R200_SE_VTX_ST_NORM_0_Y 0x2314
-#define R200_SE_VTX_ST_NORM_0_Z 0x2318
-#define R200_SE_VTX_ST_PVMS 0x231c
-#define R200_SE_VTX_ST_CLR_0_R 0x2320
-#define R200_SE_VTX_ST_CLR_0_G 0x2324
-#define R200_SE_VTX_ST_CLR_0_B 0x2328
-#define R200_SE_VTX_ST_CLR_0_A 0x232c
-#define R200_SE_VTX_ST_CLR_1_R 0x2330
-#define R200_SE_VTX_ST_CLR_1_G 0x2334
-#define R200_SE_VTX_ST_CLR_1_B 0x2338
-#define R200_SE_VTX_ST_CLR_1_A 0x233c
-#define R200_SE_VTX_ST_CLR_2_R 0x2340
-#define R200_SE_VTX_ST_CLR_2_G 0x2344
-#define R200_SE_VTX_ST_CLR_2_B 0x2348
-#define R200_SE_VTX_ST_CLR_2_A 0x234c
-#define R200_SE_VTX_ST_CLR_3_R 0x2350
-#define R200_SE_VTX_ST_CLR_3_G 0x2354
-#define R200_SE_VTX_ST_CLR_3_B 0x2358
-#define R200_SE_VTX_ST_CLR_3_A 0x235c
-#define R200_SE_VTX_ST_CLR_4_R 0x2360
-#define R200_SE_VTX_ST_CLR_4_G 0x2364
-#define R200_SE_VTX_ST_CLR_4_B 0x2368
-#define R200_SE_VTX_ST_CLR_4_A 0x236c
-#define R200_SE_VTX_ST_CLR_5_R 0x2370
-#define R200_SE_VTX_ST_CLR_5_G 0x2374
-#define R200_SE_VTX_ST_CLR_5_B 0x2378
-#define R200_SE_VTX_ST_CLR_5_A 0x237c
-#define R200_SE_VTX_ST_CLR_6_R 0x2380
-#define R200_SE_VTX_ST_CLR_6_G 0x2384
-#define R200_SE_VTX_ST_CLR_6_B 0x2388
-#define R200_SE_VTX_ST_CLR_6_A 0x238c
-#define R200_SE_VTX_ST_CLR_7_R 0x2390
-#define R200_SE_VTX_ST_CLR_7_G 0x2394
-#define R200_SE_VTX_ST_CLR_7_B 0x2398
-#define R200_SE_VTX_ST_CLR_7_A 0x239c
-#define R200_SE_VTX_ST_TEX_0_S 0x23a0
-#define R200_SE_VTX_ST_TEX_0_T 0x23a4
-#define R200_SE_VTX_ST_TEX_0_R 0x23a8
-#define R200_SE_VTX_ST_TEX_0_Q 0x23ac
-#define R200_SE_VTX_ST_TEX_1_S 0x23b0
-#define R200_SE_VTX_ST_TEX_1_T 0x23b4
-#define R200_SE_VTX_ST_TEX_1_R 0x23b8
-#define R200_SE_VTX_ST_TEX_1_Q 0x23bc
-#define R200_SE_VTX_ST_TEX_2_S 0x23c0
-#define R200_SE_VTX_ST_TEX_2_T 0x23c4
-#define R200_SE_VTX_ST_TEX_2_R 0x23c8
-#define R200_SE_VTX_ST_TEX_2_Q 0x23cc
-#define R200_SE_VTX_ST_TEX_3_S 0x23d0
-#define R200_SE_VTX_ST_TEX_3_T 0x23d4
-#define R200_SE_VTX_ST_TEX_3_R 0x23d8
-#define R200_SE_VTX_ST_TEX_3_Q 0x23dc
-#define R200_SE_VTX_ST_TEX_4_S 0x23e0
-#define R200_SE_VTX_ST_TEX_4_T 0x23e4
-#define R200_SE_VTX_ST_TEX_4_R 0x23e8
-#define R200_SE_VTX_ST_TEX_4_Q 0x23ec
-#define R200_SE_VTX_ST_TEX_5_S 0x23f0
-#define R200_SE_VTX_ST_TEX_5_T 0x23f4
-#define R200_SE_VTX_ST_TEX_5_R 0x23f8
-#define R200_SE_VTX_ST_TEX_5_Q 0x23fc
-#define R200_SE_VTX_ST_PNT_SPRT_SZ 0x2400
-#define R200_SE_VTX_ST_DISC_FOG 0x2404
-#define R200_SE_VTX_ST_SHININESS_0 0x2408
-#define R200_SE_VTX_ST_SHININESS_1 0x240c
-#define R200_SE_VTX_ST_BLND_WT_0 0x2410
-#define R200_SE_VTX_ST_BLND_WT_1 0x2414
-#define R200_SE_VTX_ST_BLND_WT_2 0x2418
-#define R200_SE_VTX_ST_BLND_WT_3 0x241c
-#define R200_SE_VTX_ST_POS_1_X 0x2420
-#define R200_SE_VTX_ST_POS_1_Y 0x2424
-#define R200_SE_VTX_ST_POS_1_Z 0x2428
-#define R200_SE_VTX_ST_POS_1_W 0x242c
-#define R200_SE_VTX_ST_NORM_1_X 0x2430
-#define R200_SE_VTX_ST_NORM_1_Y 0x2434
-#define R200_SE_VTX_ST_NORM_1_Z 0x2438
-#define R200_SE_VTX_ST_USR_CLR_0_R 0x2440
-#define R200_SE_VTX_ST_USR_CLR_0_G 0x2444
-#define R200_SE_VTX_ST_USR_CLR_0_B 0x2448
-#define R200_SE_VTX_ST_USR_CLR_0_A 0x244c
-#define R200_SE_VTX_ST_USR_CLR_1_R 0x2450
-#define R200_SE_VTX_ST_USR_CLR_1_G 0x2454
-#define R200_SE_VTX_ST_USR_CLR_1_B 0x2458
-#define R200_SE_VTX_ST_USR_CLR_1_A 0x245c
-#define R200_SE_VTX_ST_CLR_0_PKD 0x2460
-#define R200_SE_VTX_ST_CLR_1_PKD 0x2464
-#define R200_SE_VTX_ST_CLR_2_PKD 0x2468
-#define R200_SE_VTX_ST_CLR_3_PKD 0x246c
-#define R200_SE_VTX_ST_CLR_4_PKD 0x2470
-#define R200_SE_VTX_ST_CLR_5_PKD 0x2474
-#define R200_SE_VTX_ST_CLR_6_PKD 0x2478
-#define R200_SE_VTX_ST_CLR_7_PKD 0x247c
-#define R200_SE_VTX_ST_POS_0_X_2 0x2480
-#define R200_SE_VTX_ST_POS_0_Y_2 0x2484
-#define R200_SE_VTX_ST_PAR_CLR_LD 0x2488
-#define R200_SE_VTX_ST_USR_CLR_PKD 0x248c
-#define R200_SE_VTX_ST_POS_0_X_3 0x2490
-#define R200_SE_VTX_ST_POS_0_Y_3 0x2494
-#define R200_SE_VTX_ST_POS_0_Z_3 0x2498
-#define R200_SE_VTX_ST_END_OF_PKT 0x249c
-/* gap */
-#define R200_RE_POINTSIZE 0x2648
-#define R200_POINTSIZE_SHIFT 0
-#define R200_MAXPOINTSIZE_SHIFT 16
-/* gap */
-#define R200_RE_TOP_LEFT 0x26c0
-#define R200_RE_LEFT_SHIFT 0
-#define R200_RE_TOP_SHIFT 16
-#define R200_RE_MISC 0x26c4
-#define R200_STIPPLE_COORD_MASK 0x1f
-#define R200_STIPPLE_X_OFFSET_SHIFT 0
-#define R200_STIPPLE_X_OFFSET_MASK (0x1f << 0)
-#define R200_STIPPLE_Y_OFFSET_SHIFT 8
-#define R200_STIPPLE_Y_OFFSET_MASK (0x1f << 8)
-#define R200_STIPPLE_LITTLE_BIT_ORDER (0 << 16)
-#define R200_STIPPLE_BIG_BIT_ORDER (1 << 16)
-/* gap */
-#define R200_RE_AUX_SCISSOR_CNTL 0x26f0
-#define R200_EXCLUSIVE_SCISSOR_0 0x01000000
-#define R200_EXCLUSIVE_SCISSOR_1 0x02000000
-#define R200_EXCLUSIVE_SCISSOR_2 0x04000000
-#define R200_SCISSOR_ENABLE_0 0x10000000
-#define R200_SCISSOR_ENABLE_1 0x20000000
-#define R200_SCISSOR_ENABLE_2 0x40000000
-/* gap */
-#define R200_PP_TXFILTER_0 0x2c00
-#define R200_MAG_FILTER_NEAREST (0 << 0)
-#define R200_MAG_FILTER_LINEAR (1 << 0)
-#define R200_MAG_FILTER_MASK (1 << 0)
-#define R200_MIN_FILTER_NEAREST (0 << 1)
-#define R200_MIN_FILTER_LINEAR (1 << 1)
-#define R200_MIN_FILTER_NEAREST_MIP_NEAREST (2 << 1)
-#define R200_MIN_FILTER_NEAREST_MIP_LINEAR (3 << 1)
-#define R200_MIN_FILTER_LINEAR_MIP_NEAREST (6 << 1)
-#define R200_MIN_FILTER_LINEAR_MIP_LINEAR (7 << 1)
-#define R200_MIN_FILTER_ANISO_NEAREST (8 << 1)
-#define R200_MIN_FILTER_ANISO_LINEAR (9 << 1)
-#define R200_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST (10 << 1)
-#define R200_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR (11 << 1)
-#define R200_MIN_FILTER_MASK (15 << 1)
-#define R200_MAX_ANISO_1_TO_1 (0 << 5)
-#define R200_MAX_ANISO_2_TO_1 (1 << 5)
-#define R200_MAX_ANISO_4_TO_1 (2 << 5)
-#define R200_MAX_ANISO_8_TO_1 (3 << 5)
-#define R200_MAX_ANISO_16_TO_1 (4 << 5)
-#define R200_MAX_ANISO_MASK (7 << 5)
-#define R200_MAX_MIP_LEVEL_MASK (0x0f << 16)
-#define R200_MAX_MIP_LEVEL_SHIFT 16
-#define R200_YUV_TO_RGB (1 << 20)
-#define R200_YUV_TEMPERATURE_COOL (0 << 21)
-#define R200_YUV_TEMPERATURE_HOT (1 << 21)
-#define R200_YUV_TEMPERATURE_MASK (1 << 21)
-#define R200_WRAPEN_S (1 << 22)
-#define R200_CLAMP_S_WRAP (0 << 23)
-#define R200_CLAMP_S_MIRROR (1 << 23)
-#define R200_CLAMP_S_CLAMP_LAST (2 << 23)
-#define R200_CLAMP_S_MIRROR_CLAMP_LAST (3 << 23)
-#define R200_CLAMP_S_CLAMP_BORDER (4 << 23)
-#define R200_CLAMP_S_MIRROR_CLAMP_BORDER (5 << 23)
-#define R200_CLAMP_S_CLAMP_GL (6 << 23)
-#define R200_CLAMP_S_MIRROR_CLAMP_GL (7 << 23)
-#define R200_CLAMP_S_MASK (7 << 23)
-#define R200_WRAPEN_T (1 << 26)
-#define R200_CLAMP_T_WRAP (0 << 27)
-#define R200_CLAMP_T_MIRROR (1 << 27)
-#define R200_CLAMP_T_CLAMP_LAST (2 << 27)
-#define R200_CLAMP_T_MIRROR_CLAMP_LAST (3 << 27)
-#define R200_CLAMP_T_CLAMP_BORDER (4 << 27)
-#define R200_CLAMP_T_MIRROR_CLAMP_BORDER (5 << 27)
-#define R200_CLAMP_T_CLAMP_GL (6 << 27)
-#define R200_CLAMP_T_MIRROR_CLAMP_GL (7 << 27)
-#define R200_CLAMP_T_MASK (7 << 27)
-#define R200_KILL_LT_ZERO (1 << 30)
-#define R200_BORDER_MODE_OGL (0 << 31)
-#define R200_BORDER_MODE_D3D (1 << 31)
-#define R200_PP_TXFORMAT_0 0x2c04
-#define R200_TXFORMAT_I8 (0 << 0)
-#define R200_TXFORMAT_AI88 (1 << 0)
-#define R200_TXFORMAT_RGB332 (2 << 0)
-#define R200_TXFORMAT_ARGB1555 (3 << 0)
-#define R200_TXFORMAT_RGB565 (4 << 0)
-#define R200_TXFORMAT_ARGB4444 (5 << 0)
-#define R200_TXFORMAT_ARGB8888 (6 << 0)
-#define R200_TXFORMAT_RGBA8888 (7 << 0)
-#define R200_TXFORMAT_Y8 (8 << 0)
-#define R200_TXFORMAT_AVYU4444 (9 << 0)
-#define R200_TXFORMAT_VYUY422 (10 << 0)
-#define R200_TXFORMAT_YVYU422 (11 << 0)
-#define R200_TXFORMAT_DXT1 (12 << 0)
-#define R200_TXFORMAT_DXT23 (14 << 0)
-#define R200_TXFORMAT_DXT45 (15 << 0)
-#define R200_TXFORMAT_FORMAT_MASK (31 << 0)
-#define R200_TXFORMAT_FORMAT_SHIFT 0
-#define R200_TXFORMAT_ALPHA_IN_MAP (1 << 6)
-#define R200_TXFORMAT_NON_POWER2 (1 << 7)
-#define R200_TXFORMAT_WIDTH_MASK (15 << 8)
-#define R200_TXFORMAT_WIDTH_SHIFT 8
-#define R200_TXFORMAT_HEIGHT_MASK (15 << 12)
-#define R200_TXFORMAT_HEIGHT_SHIFT 12
-#define R200_TXFORMAT_F5_WIDTH_MASK (15 << 16) /* cube face 5 */
-#define R200_TXFORMAT_F5_WIDTH_SHIFT 16
-#define R200_TXFORMAT_F5_HEIGHT_MASK (15 << 20)
-#define R200_TXFORMAT_F5_HEIGHT_SHIFT 20
-#define R200_TXFORMAT_ST_ROUTE_STQ0 (0 << 24)
-#define R200_TXFORMAT_ST_ROUTE_STQ1 (1 << 24)
-#define R200_TXFORMAT_ST_ROUTE_STQ2 (2 << 24)
-#define R200_TXFORMAT_ST_ROUTE_STQ3 (3 << 24)
-#define R200_TXFORMAT_ST_ROUTE_STQ4 (4 << 24)
-#define R200_TXFORMAT_ST_ROUTE_STQ5 (5 << 24)
-#define R200_TXFORMAT_ST_ROUTE_MASK (7 << 24)
-#define R200_TXFORMAT_ST_ROUTE_SHIFT 24
-#define R200_TXFORMAT_ALPHA_MASK_ENABLE (1 << 28)
-#define R200_TXFORMAT_CHROMA_KEY_ENABLE (1 << 29)
-#define R200_TXFORMAT_CUBIC_MAP_ENABLE (1 << 30)
-#define R200_PP_TXFORMAT_X_0 0x2c08
-#define R200_DEPTH_LOG2_MASK (0xf << 0)
-#define R200_DEPTH_LOG2_SHIFT 0
-#define R200_VOLUME_FILTER_SHIFT 4
-#define R200_VOLUME_FILTER_MASK (1 << 4)
-#define R200_VOLUME_FILTER_NEAREST (0 << 4)
-#define R200_VOLUME_FILTER_LINEAR (1 << 4)
-#define R200_WRAPEN_Q (1 << 8)
-#define R200_CLAMP_Q_WRAP (0 << 9)
-#define R200_CLAMP_Q_MIRROR (1 << 9)
-#define R200_CLAMP_Q_CLAMP_LAST (2 << 9)
-#define R200_CLAMP_Q_MIRROR_CLAMP_LAST (3 << 9)
-#define R200_CLAMP_Q_CLAMP_BORDER (4 << 9)
-#define R200_CLAMP_Q_MIRROR_CLAMP_BORDER (5 << 9)
-#define R200_CLAMP_Q_CLAMP_GL (6 << 9)
-#define R200_CLAMP_Q_MIRROR_CLAMP_GL (7 << 9)
-#define R200_CLAMP_Q_MASK (7 << 9)
-#define R200_MIN_MIP_LEVEL_MASK (0xff << 12)
-#define R200_MIN_MIP_LEVEL_SHIFT 12
-#define R200_TEXCOORD_NONPROJ (0 << 16)
-#define R200_TEXCOORD_CUBIC_ENV (1 << 16)
-#define R200_TEXCOORD_VOLUME (2 << 16)
-#define R200_TEXCOORD_PROJ (3 << 16)
-#define R200_TEXCOORD_DEPTH (4 << 16)
-#define R200_TEXCOORD_1D_PROJ (5 << 16)
-#define R200_TEXCOORD_1D (6 << 16)
-#define R200_TEXCOORD_ZERO (7 << 16)
-#define R200_TEXCOORD_MASK (7 << 16)
-#define R200_LOD_BIAS_MASK (0xfff80000)
-#define R200_LOD_BIAS_SHIFT 19
-#define R200_PP_TXSIZE_0 0x2c0c /* NPOT only */
-#define R200_PP_TXPITCH_0 0x2c10 /* NPOT only */
-#define R200_PP_BORDER_COLOR_0 0x2c14
-#define R200_PP_CUBIC_FACES_0 0x2c18
-#define R200_FACE_WIDTH_1_SHIFT 0
-#define R200_FACE_HEIGHT_1_SHIFT 4
-#define R200_FACE_WIDTH_1_MASK (0xf << 0)
-#define R200_FACE_HEIGHT_1_MASK (0xf << 4)
-#define R200_FACE_WIDTH_2_SHIFT 8
-#define R200_FACE_HEIGHT_2_SHIFT 12
-#define R200_FACE_WIDTH_2_MASK (0xf << 8)
-#define R200_FACE_HEIGHT_2_MASK (0xf << 12)
-#define R200_FACE_WIDTH_3_SHIFT 16
-#define R200_FACE_HEIGHT_3_SHIFT 20
-#define R200_FACE_WIDTH_3_MASK (0xf << 16)
-#define R200_FACE_HEIGHT_3_MASK (0xf << 20)
-#define R200_FACE_WIDTH_4_SHIFT 24
-#define R200_FACE_HEIGHT_4_SHIFT 28
-#define R200_FACE_WIDTH_4_MASK (0xf << 24)
-#define R200_FACE_HEIGHT_4_MASK (0xf << 28)
-#define R200_PP_TXFILTER_1 0x2c20
-#define R200_PP_TXFORMAT_1 0x2c24
-#define R200_PP_TXFORMAT_X_1 0x2c28
-#define R200_PP_TXSIZE_1 0x2c2c
-#define R200_PP_TXPITCH_1 0x2c30
-#define R200_PP_BORDER_COLOR_1 0x2c34
-#define R200_PP_CUBIC_FACES_1 0x2c38
-#define R200_PP_TXFILTER_2 0x2c40
-#define R200_PP_TXFORMAT_2 0x2c44
-#define R200_PP_TXSIZE_2 0x2c4c
-#define R200_PP_TXFORMAT_X_2 0x2c48
-#define R200_PP_TXPITCH_2 0x2c50
-#define R200_PP_BORDER_COLOR_2 0x2c54
-#define R200_PP_CUBIC_FACES_2 0x2c58
-#define R200_PP_TXFILTER_3 0x2c60
-#define R200_PP_TXFORMAT_3 0x2c64
-#define R200_PP_TXSIZE_3 0x2c6c
-#define R200_PP_TXFORMAT_X_3 0x2c68
-#define R200_PP_TXPITCH_3 0x2c70
-#define R200_PP_BORDER_COLOR_3 0x2c74
-#define R200_PP_CUBIC_FACES_3 0x2c78
-#define R200_PP_TXFILTER_4 0x2c80
-#define R200_PP_TXFORMAT_4 0x2c84
-#define R200_PP_TXSIZE_4 0x2c8c
-#define R200_PP_TXFORMAT_X_4 0x2c88
-#define R200_PP_TXPITCH_4 0x2c90
-#define R200_PP_BORDER_COLOR_4 0x2c94
-#define R200_PP_CUBIC_FACES_4 0x2c98
-#define R200_PP_TXFILTER_5 0x2ca0
-#define R200_PP_TXFORMAT_5 0x2ca4
-#define R200_PP_TXSIZE_5 0x2cac
-#define R200_PP_TXFORMAT_X_5 0x2ca8
-#define R200_PP_TXPITCH_5 0x2cb0
-#define R200_PP_BORDER_COLOR_5 0x2cb4
-#define R200_PP_CUBIC_FACES_5 0x2cb8
-/* gap */
-#define R200_PP_CNTL_X 0x2cc4
-/* gap */
-#define R200_PP_TXOFFSET_0 0x2d00
-#define R200_TXO_ENDIAN_NO_SWAP (0 << 0)
-#define R200_TXO_ENDIAN_BYTE_SWAP (1 << 0)
-#define R200_TXO_ENDIAN_WORD_SWAP (2 << 0)
-#define R200_TXO_ENDIAN_HALFDW_SWAP (3 << 0)
-#define R200_TXO_OFFSET_MASK 0xffffffe0
-#define R200_TXO_OFFSET_SHIFT 5
-#define R200_PP_CUBIC_OFFSET_F1_0 0x2d04
-#define R200_PP_CUBIC_OFFSET_F2_0 0x2d08
-#define R200_PP_CUBIC_OFFSET_F3_0 0x2d0c
-#define R200_PP_CUBIC_OFFSET_F4_0 0x2d10
-#define R200_PP_CUBIC_OFFSET_F5_0 0x2d14
-#define R200_PP_TXOFFSET_1 0x2d18
-#define R200_PP_CUBIC_OFFSET_F1_1 0x2d1c
-#define R200_PP_CUBIC_OFFSET_F2_1 0x2d20
-#define R200_PP_CUBIC_OFFSET_F3_1 0x2d24
-#define R200_PP_CUBIC_OFFSET_F4_1 0x2d28
-#define R200_PP_CUBIC_OFFSET_F5_1 0x2d2c
-#define R200_PP_TXOFFSET_2 0x2d30
-#define R200_PP_CUBIC_OFFSET_F1_2 0x2d34
-#define R200_PP_CUBIC_OFFSET_F2_2 0x2d38
-#define R200_PP_CUBIC_OFFSET_F3_2 0x2d3c
-#define R200_PP_CUBIC_OFFSET_F4_2 0x2d40
-#define R200_PP_CUBIC_OFFSET_F5_2 0x2d44
-#define R200_PP_TXOFFSET_3 0x2d48
-#define R200_PP_CUBIC_OFFSET_F1_3 0x2d4c
-#define R200_PP_CUBIC_OFFSET_F2_3 0x2d50
-#define R200_PP_CUBIC_OFFSET_F3_3 0x2d54
-#define R200_PP_CUBIC_OFFSET_F4_3 0x2d58
-#define R200_PP_CUBIC_OFFSET_F5_3 0x2d5c
-#define R200_PP_TXOFFSET_4 0x2d60
-#define R200_PP_CUBIC_OFFSET_F1_4 0x2d64
-#define R200_PP_CUBIC_OFFSET_F2_4 0x2d68
-#define R200_PP_CUBIC_OFFSET_F3_4 0x2d6c
-#define R200_PP_CUBIC_OFFSET_F4_4 0x2d70
-#define R200_PP_CUBIC_OFFSET_F5_4 0x2d74
-#define R200_PP_TXOFFSET_5 0x2d78
-#define R200_PP_CUBIC_OFFSET_F1_5 0x2d7c
-#define R200_PP_CUBIC_OFFSET_F2_5 0x2d80
-#define R200_PP_CUBIC_OFFSET_F3_5 0x2d84
-#define R200_PP_CUBIC_OFFSET_F4_5 0x2d88
-#define R200_PP_CUBIC_OFFSET_F5_5 0x2d8c
-/* gap */
-#define R200_PP_TAM_DEBUG3 0x2d9c
-/* gap */
-#define R200_PP_TFACTOR_0 0x2ee0
-#define R200_PP_TFACTOR_1 0x2ee4
-#define R200_PP_TFACTOR_2 0x2ee8
-#define R200_PP_TFACTOR_3 0x2eec
-#define R200_PP_TFACTOR_4 0x2ef0
-#define R200_PP_TFACTOR_5 0x2ef4
-/* gap */
-#define R200_PP_TXCBLEND_0 0x2f00
-#define R200_TXC_ARG_A_ZERO (0)
-#define R200_TXC_ARG_A_CURRENT_COLOR (2)
-#define R200_TXC_ARG_A_CURRENT_ALPHA (3)
-#define R200_TXC_ARG_A_DIFFUSE_COLOR (4)
-#define R200_TXC_ARG_A_DIFFUSE_ALPHA (5)
-#define R200_TXC_ARG_A_SPECULAR_COLOR (6)
-#define R200_TXC_ARG_A_SPECULAR_ALPHA (7)
-#define R200_TXC_ARG_A_TFACTOR_COLOR (8)
-#define R200_TXC_ARG_A_TFACTOR_ALPHA (9)
-#define R200_TXC_ARG_A_R0_COLOR (10)
-#define R200_TXC_ARG_A_R0_ALPHA (11)
-#define R200_TXC_ARG_A_R1_COLOR (12)
-#define R200_TXC_ARG_A_R1_ALPHA (13)
-#define R200_TXC_ARG_A_R2_COLOR (14)
-#define R200_TXC_ARG_A_R2_ALPHA (15)
-#define R200_TXC_ARG_A_R3_COLOR (16)
-#define R200_TXC_ARG_A_R3_ALPHA (17)
-#define R200_TXC_ARG_A_R4_COLOR (18)
-#define R200_TXC_ARG_A_R4_ALPHA (19)
-#define R200_TXC_ARG_A_R5_COLOR (20)
-#define R200_TXC_ARG_A_R5_ALPHA (21)
-#define R200_TXC_ARG_A_TFACTOR1_COLOR (26)
-#define R200_TXC_ARG_A_TFACTOR1_ALPHA (27)
-#define R200_TXC_ARG_A_MASK (31 << 0)
-#define R200_TXC_ARG_A_SHIFT 0
-#define R200_TXC_ARG_B_ZERO (0<<5)
-#define R200_TXC_ARG_B_CURRENT_COLOR (2<<5)
-#define R200_TXC_ARG_B_CURRENT_ALPHA (3<<5)
-#define R200_TXC_ARG_B_DIFFUSE_COLOR (4<<5)
-#define R200_TXC_ARG_B_DIFFUSE_ALPHA (5<<5)
-#define R200_TXC_ARG_B_SPECULAR_COLOR (6<<5)
-#define R200_TXC_ARG_B_SPECULAR_ALPHA (7<<5)
-#define R200_TXC_ARG_B_TFACTOR_COLOR (8<<5)
-#define R200_TXC_ARG_B_TFACTOR_ALPHA (9<<5)
-#define R200_TXC_ARG_B_R0_COLOR (10<<5)
-#define R200_TXC_ARG_B_R0_ALPHA (11<<5)
-#define R200_TXC_ARG_B_R1_COLOR (12<<5)
-#define R200_TXC_ARG_B_R1_ALPHA (13<<5)
-#define R200_TXC_ARG_B_R2_COLOR (14<<5)
-#define R200_TXC_ARG_B_R2_ALPHA (15<<5)
-#define R200_TXC_ARG_B_R3_COLOR (16<<5)
-#define R200_TXC_ARG_B_R3_ALPHA (17<<5)
-#define R200_TXC_ARG_B_R4_COLOR (18<<5)
-#define R200_TXC_ARG_B_R4_ALPHA (19<<5)
-#define R200_TXC_ARG_B_R5_COLOR (20<<5)
-#define R200_TXC_ARG_B_R5_ALPHA (21<<5)
-#define R200_TXC_ARG_B_TFACTOR1_COLOR (26<<5)
-#define R200_TXC_ARG_B_TFACTOR1_ALPHA (27<<5)
-#define R200_TXC_ARG_B_MASK (31 << 5)
-#define R200_TXC_ARG_B_SHIFT 5
-#define R200_TXC_ARG_C_ZERO (0<<10)
-#define R200_TXC_ARG_C_CURRENT_COLOR (2<<10)
-#define R200_TXC_ARG_C_CURRENT_ALPHA (3<<10)
-#define R200_TXC_ARG_C_DIFFUSE_COLOR (4<<10)
-#define R200_TXC_ARG_C_DIFFUSE_ALPHA (5<<10)
-#define R200_TXC_ARG_C_SPECULAR_COLOR (6<<10)
-#define R200_TXC_ARG_C_SPECULAR_ALPHA (7<<10)
-#define R200_TXC_ARG_C_TFACTOR_COLOR (8<<10)
-#define R200_TXC_ARG_C_TFACTOR_ALPHA (9<<10)
-#define R200_TXC_ARG_C_R0_COLOR (10<<10)
-#define R200_TXC_ARG_C_R0_ALPHA (11<<10)
-#define R200_TXC_ARG_C_R1_COLOR (12<<10)
-#define R200_TXC_ARG_C_R1_ALPHA (13<<10)
-#define R200_TXC_ARG_C_R2_COLOR (14<<10)
-#define R200_TXC_ARG_C_R2_ALPHA (15<<10)
-#define R200_TXC_ARG_C_R3_COLOR (16<<10)
-#define R200_TXC_ARG_C_R3_ALPHA (17<<10)
-#define R200_TXC_ARG_C_R4_COLOR (18<<10)
-#define R200_TXC_ARG_C_R4_ALPHA (19<<10)
-#define R200_TXC_ARG_C_R5_COLOR (20<<10)
-#define R200_TXC_ARG_C_R5_ALPHA (21<<10)
-#define R200_TXC_ARG_C_TFACTOR1_COLOR (26<<10)
-#define R200_TXC_ARG_C_TFACTOR1_ALPHA (27<<10)
-#define R200_TXC_ARG_C_MASK (31 << 10)
-#define R200_TXC_ARG_C_SHIFT 10
-#define R200_TXC_COMP_ARG_A (1 << 16)
-#define R200_TXC_COMP_ARG_A_SHIFT (16)
-#define R200_TXC_BIAS_ARG_A (1 << 17)
-#define R200_TXC_SCALE_ARG_A (1 << 18)
-#define R200_TXC_NEG_ARG_A (1 << 19)
-#define R200_TXC_COMP_ARG_B (1 << 20)
-#define R200_TXC_COMP_ARG_B_SHIFT (20)
-#define R200_TXC_BIAS_ARG_B (1 << 21)
-#define R200_TXC_SCALE_ARG_B (1 << 22)
-#define R200_TXC_NEG_ARG_B (1 << 23)
-#define R200_TXC_COMP_ARG_C (1 << 24)
-#define R200_TXC_COMP_ARG_C_SHIFT (24)
-#define R200_TXC_BIAS_ARG_C (1 << 25)
-#define R200_TXC_SCALE_ARG_C (1 << 26)
-#define R200_TXC_NEG_ARG_C (1 << 27)
-#define R200_TXC_OP_MADD (0 << 28)
-#define R200_TXC_OP_CND0 (2 << 28)
-#define R200_TXC_OP_LERP (3 << 28)
-#define R200_TXC_OP_DOT3 (4 << 28)
-#define R200_TXC_OP_DOT4 (5 << 28)
-#define R200_TXC_OP_CONDITIONAL (6 << 28)
-#define R200_TXC_OP_DOT2_ADD (7 << 28)
-#define R200_TXC_OP_MASK (7 << 28)
-#define R200_PP_TXCBLEND2_0 0x2f04
-#define R200_TXC_TFACTOR_SEL_SHIFT 0
-#define R200_TXC_TFACTOR_SEL_MASK 0x7
-#define R200_TXC_TFACTOR1_SEL_SHIFT 4
-#define R200_TXC_TFACTOR1_SEL_MASK (0x7 << 4)
-#define R200_TXC_SCALE_SHIFT 8
-#define R200_TXC_SCALE_MASK (7 << 8)
-#define R200_TXC_SCALE_1X (0 << 8)
-#define R200_TXC_SCALE_2X (1 << 8)
-#define R200_TXC_SCALE_4X (2 << 8)
-#define R200_TXC_SCALE_8X (3 << 8)
-#define R200_TXC_SCALE_INV2 (5 << 8)
-#define R200_TXC_SCALE_INV4 (6 << 8)
-#define R200_TXC_SCALE_INV8 (7 << 8)
-#define R200_TXC_CLAMP_SHIFT 12
-#define R200_TXC_CLAMP_MASK (3 << 12)
-#define R200_TXC_CLAMP_WRAP (0 << 12)
-#define R200_TXC_CLAMP_0_1 (1 << 12)
-#define R200_TXC_CLAMP_8_8 (2 << 12)
-#define R200_TXC_OUTPUT_REG_MASK (7 << 16)
-#define R200_TXC_OUTPUT_REG_NONE (0 << 16)
-#define R200_TXC_OUTPUT_REG_R0 (1 << 16)
-#define R200_TXC_OUTPUT_REG_R1 (2 << 16)
-#define R200_TXC_OUTPUT_REG_R2 (3 << 16)
-#define R200_TXC_OUTPUT_REG_R3 (4 << 16)
-#define R200_TXC_OUTPUT_REG_R4 (5 << 16)
-#define R200_TXC_OUTPUT_REG_R5 (6 << 16)
-#define R200_TXC_OUTPUT_MASK_MASK (7 << 20)
-#define R200_TXC_OUTPUT_MASK_RGB (0 << 20)
-#define R200_TXC_OUTPUT_MASK_RG (1 << 20)
-#define R200_TXC_OUTPUT_MASK_RB (2 << 20)
-#define R200_TXC_OUTPUT_MASK_R (3 << 20)
-#define R200_TXC_OUTPUT_MASK_GB (4 << 20)
-#define R200_TXC_OUTPUT_MASK_G (5 << 20)
-#define R200_TXC_OUTPUT_MASK_B (6 << 20)
-#define R200_TXC_OUTPUT_MASK_NONE (7 << 20)
-#define R200_TXC_REPL_NORMAL 0
-#define R200_TXC_REPL_RED 1
-#define R200_TXC_REPL_GREEN 2
-#define R200_TXC_REPL_BLUE 3
-#define R200_TXC_REPL_ARG_A_SHIFT 26
-#define R200_TXC_REPL_ARG_A_MASK (3 << 26)
-#define R200_TXC_REPL_ARG_B_SHIFT 28
-#define R200_TXC_REPL_ARG_B_MASK (3 << 28)
-#define R200_TXC_REPL_ARG_C_SHIFT 30
-#define R200_TXC_REPL_ARG_C_MASK (3 << 30)
-#define R200_PP_TXABLEND_0 0x2f08
-#define R200_TXA_ARG_A_ZERO (0)
-#define R200_TXA_ARG_A_CURRENT_ALPHA (2) /* guess */
-#define R200_TXA_ARG_A_CURRENT_BLUE (3) /* guess */
-#define R200_TXA_ARG_A_DIFFUSE_ALPHA (4)
-#define R200_TXA_ARG_A_DIFFUSE_BLUE (5)
-#define R200_TXA_ARG_A_SPECULAR_ALPHA (6)
-#define R200_TXA_ARG_A_SPECULAR_BLUE (7)
-#define R200_TXA_ARG_A_TFACTOR_ALPHA (8)
-#define R200_TXA_ARG_A_TFACTOR_BLUE (9)
-#define R200_TXA_ARG_A_R0_ALPHA (10)
-#define R200_TXA_ARG_A_R0_BLUE (11)
-#define R200_TXA_ARG_A_R1_ALPHA (12)
-#define R200_TXA_ARG_A_R1_BLUE (13)
-#define R200_TXA_ARG_A_R2_ALPHA (14)
-#define R200_TXA_ARG_A_R2_BLUE (15)
-#define R200_TXA_ARG_A_R3_ALPHA (16)
-#define R200_TXA_ARG_A_R3_BLUE (17)
-#define R200_TXA_ARG_A_R4_ALPHA (18)
-#define R200_TXA_ARG_A_R4_BLUE (19)
-#define R200_TXA_ARG_A_R5_ALPHA (20)
-#define R200_TXA_ARG_A_R5_BLUE (21)
-#define R200_TXA_ARG_A_TFACTOR1_ALPHA (26)
-#define R200_TXA_ARG_A_TFACTOR1_BLUE (27)
-#define R200_TXA_ARG_A_MASK (31 << 0)
-#define R200_TXA_ARG_A_SHIFT 0
-#define R200_TXA_ARG_B_ZERO (0<<5)
-#define R200_TXA_ARG_B_CURRENT_ALPHA (2<<5) /* guess */
-#define R200_TXA_ARG_B_CURRENT_BLUE (3<<5) /* guess */
-#define R200_TXA_ARG_B_DIFFUSE_ALPHA (4<<5)
-#define R200_TXA_ARG_B_DIFFUSE_BLUE (5<<5)
-#define R200_TXA_ARG_B_SPECULAR_ALPHA (6<<5)
-#define R200_TXA_ARG_B_SPECULAR_BLUE (7<<5)
-#define R200_TXA_ARG_B_TFACTOR_ALPHA (8<<5)
-#define R200_TXA_ARG_B_TFACTOR_BLUE (9<<5)
-#define R200_TXA_ARG_B_R0_ALPHA (10<<5)
-#define R200_TXA_ARG_B_R0_BLUE (11<<5)
-#define R200_TXA_ARG_B_R1_ALPHA (12<<5)
-#define R200_TXA_ARG_B_R1_BLUE (13<<5)
-#define R200_TXA_ARG_B_R2_ALPHA (14<<5)
-#define R200_TXA_ARG_B_R2_BLUE (15<<5)
-#define R200_TXA_ARG_B_R3_ALPHA (16<<5)
-#define R200_TXA_ARG_B_R3_BLUE (17<<5)
-#define R200_TXA_ARG_B_R4_ALPHA (18<<5)
-#define R200_TXA_ARG_B_R4_BLUE (19<<5)
-#define R200_TXA_ARG_B_R5_ALPHA (20<<5)
-#define R200_TXA_ARG_B_R5_BLUE (21<<5)
-#define R200_TXA_ARG_B_TFACTOR1_ALPHA (26<<5)
-#define R200_TXA_ARG_B_TFACTOR1_BLUE (27<<5)
-#define R200_TXA_ARG_B_MASK (31 << 5)
-#define R200_TXA_ARG_B_SHIFT 5
-#define R200_TXA_ARG_C_ZERO (0<<10)
-#define R200_TXA_ARG_C_CURRENT_ALPHA (2<<10) /* guess */
-#define R200_TXA_ARG_C_CURRENT_BLUE (3<<10) /* guess */
-#define R200_TXA_ARG_C_DIFFUSE_ALPHA (4<<10)
-#define R200_TXA_ARG_C_DIFFUSE_BLUE (5<<10)
-#define R200_TXA_ARG_C_SPECULAR_ALPHA (6<<10)
-#define R200_TXA_ARG_C_SPECULAR_BLUE (7<<10)
-#define R200_TXA_ARG_C_TFACTOR_ALPHA (8<<10)
-#define R200_TXA_ARG_C_TFACTOR_BLUE (9<<10)
-#define R200_TXA_ARG_C_R0_ALPHA (10<<10)
-#define R200_TXA_ARG_C_R0_BLUE (11<<10)
-#define R200_TXA_ARG_C_R1_ALPHA (12<<10)
-#define R200_TXA_ARG_C_R1_BLUE (13<<10)
-#define R200_TXA_ARG_C_R2_ALPHA (14<<10)
-#define R200_TXA_ARG_C_R2_BLUE (15<<10)
-#define R200_TXA_ARG_C_R3_ALPHA (16<<10)
-#define R200_TXA_ARG_C_R3_BLUE (17<<10)
-#define R200_TXA_ARG_C_R4_ALPHA (18<<10)
-#define R200_TXA_ARG_C_R4_BLUE (19<<10)
-#define R200_TXA_ARG_C_R5_ALPHA (20<<10)
-#define R200_TXA_ARG_C_R5_BLUE (21<<10)
-#define R200_TXA_ARG_C_TFACTOR1_ALPHA (26<<10)
-#define R200_TXA_ARG_C_TFACTOR1_BLUE (27<<10)
-#define R200_TXA_ARG_C_MASK (31 << 10)
-#define R200_TXA_ARG_C_SHIFT 10
-#define R200_TXA_COMP_ARG_A (1 << 16)
-#define R200_TXA_COMP_ARG_A_SHIFT (16)
-#define R200_TXA_BIAS_ARG_A (1 << 17)
-#define R200_TXA_SCALE_ARG_A (1 << 18)
-#define R200_TXA_NEG_ARG_A (1 << 19)
-#define R200_TXA_COMP_ARG_B (1 << 20)
-#define R200_TXA_COMP_ARG_B_SHIFT (20)
-#define R200_TXA_BIAS_ARG_B (1 << 21)
-#define R200_TXA_SCALE_ARG_B (1 << 22)
-#define R200_TXA_NEG_ARG_B (1 << 23)
-#define R200_TXA_COMP_ARG_C (1 << 24)
-#define R200_TXA_COMP_ARG_C_SHIFT (24)
-#define R200_TXA_BIAS_ARG_C (1 << 25)
-#define R200_TXA_SCALE_ARG_C (1 << 26)
-#define R200_TXA_NEG_ARG_C (1 << 27)
-#define R200_TXA_OP_MADD (0 << 28)
-#define R200_TXA_OP_CND0 (2 << 28)
-#define R200_TXA_OP_LERP (3 << 28)
-#define R200_TXA_OP_CONDITIONAL (6 << 28)
-#define R200_TXA_OP_MASK (7 << 28)
-#define R200_PP_TXABLEND2_0 0x2f0c
-#define R200_TXA_TFACTOR_SEL_SHIFT 0
-#define R200_TXA_TFACTOR_SEL_MASK 0x7
-#define R200_TXA_TFACTOR1_SEL_SHIFT 4
-#define R200_TXA_TFACTOR1_SEL_MASK (0x7 << 4)
-#define R200_TXA_SCALE_SHIFT 8
-#define R200_TXA_SCALE_MASK (7 << 8)
-#define R200_TXA_SCALE_1X (0 << 8)
-#define R200_TXA_SCALE_2X (1 << 8)
-#define R200_TXA_SCALE_4X (2 << 8)
-#define R200_TXA_SCALE_8X (3 << 8)
-#define R200_TXA_SCALE_INV2 (5 << 8)
-#define R200_TXA_SCALE_INV4 (6 << 8)
-#define R200_TXA_SCALE_INV8 (7 << 8)
-#define R200_TXA_CLAMP_SHIFT 12
-#define R200_TXA_CLAMP_MASK (3 << 12)
-#define R200_TXA_CLAMP_WRAP (0 << 12)
-#define R200_TXA_CLAMP_0_1 (1 << 12)
-#define R200_TXA_CLAMP_8_8 (2 << 12)
-#define R200_TXA_OUTPUT_REG_MASK (7 << 16)
-#define R200_TXA_OUTPUT_REG_NONE (0 << 16)
-#define R200_TXA_OUTPUT_REG_R0 (1 << 16)
-#define R200_TXA_OUTPUT_REG_R1 (2 << 16)
-#define R200_TXA_OUTPUT_REG_R2 (3 << 16)
-#define R200_TXA_OUTPUT_REG_R3 (4 << 16)
-#define R200_TXA_OUTPUT_REG_R4 (5 << 16)
-#define R200_TXA_OUTPUT_REG_R5 (6 << 16)
-#define R200_TXA_DOT_ALPHA (1 << 20)
-#define R200_TXA_REPL_NORMAL 0
-#define R200_TXA_REPL_RED 1
-#define R200_TXA_REPL_GREEN 2
-#define R200_TXA_REPL_ARG_A_SHIFT 26
-#define R200_TXA_REPL_ARG_A_MASK (3 << 26)
-#define R200_TXA_REPL_ARG_B_SHIFT 28
-#define R200_TXA_REPL_ARG_B_MASK (3 << 28)
-#define R200_TXA_REPL_ARG_C_SHIFT 30
-#define R200_TXA_REPL_ARG_C_MASK (3 << 30)
-#define R200_PP_TXCBLEND_1 0x2f10
-#define R200_PP_TXCBLEND2_1 0x2f14
-#define R200_PP_TXABLEND_1 0x2f18
-#define R200_PP_TXABLEND2_1 0x2f1c
-#define R200_PP_TXCBLEND_2 0x2f20
-#define R200_PP_TXCBLEND2_2 0x2f24
-#define R200_PP_TXABLEND_2 0x2f28
-#define R200_PP_TXABLEND2_2 0x2f2c
-#define R200_PP_TXCBLEND_3 0x2f30
-#define R200_PP_TXCBLEND2_3 0x2f34
-#define R200_PP_TXABLEND_3 0x2f38
-#define R200_PP_TXABLEND2_3 0x2f3c
-#define R200_PP_TXCBLEND_4 0x2f40
-#define R200_PP_TXCBLEND2_4 0x2f44
-#define R200_PP_TXABLEND_4 0x2f48
-#define R200_PP_TXABLEND2_4 0x2f4c
-#define R200_PP_TXCBLEND_5 0x2f50
-#define R200_PP_TXCBLEND2_5 0x2f54
-#define R200_PP_TXABLEND_5 0x2f58
-#define R200_PP_TXABLEND2_5 0x2f5c
-#define R200_PP_TXCBLEND_6 0x2f60
-#define R200_PP_TXCBLEND2_6 0x2f64
-#define R200_PP_TXABLEND_6 0x2f68
-#define R200_PP_TXABLEND2_6 0x2f6c
-#define R200_PP_TXCBLEND_7 0x2f70
-#define R200_PP_TXCBLEND2_7 0x2f74
-#define R200_PP_TXABLEND_7 0x2f78
-#define R200_PP_TXABLEND2_7 0x2f7c
-/* gap */
-#define R200_RB3D_BLENDCOLOR 0x3218 /* ARGB 8888 */
-#define R200_RB3D_ABLENDCNTL 0x321C /* see BLENDCTL */
-#define R200_RB3D_CBLENDCNTL 0x3220 /* see BLENDCTL */
-
-/*
- * Offsets in TCL vector state. NOTE: Hardwiring matrix positions.
- * Multiple contexts could collaberate to eliminate state bouncing.
- */
-#define R200_VS_LIGHT_AMBIENT_ADDR 0x00000028
-#define R200_VS_LIGHT_DIFFUSE_ADDR 0x00000030
-#define R200_VS_LIGHT_SPECULAR_ADDR 0x00000038
-#define R200_VS_LIGHT_DIRPOS_ADDR 0x00000040
-#define R200_VS_LIGHT_HWVSPOT_ADDR 0x00000048
-#define R200_VS_LIGHT_ATTENUATION_ADDR 0x00000050
-#define R200_VS_SPOT_DUAL_CONE 0x00000058
-#define R200_VS_GLOBAL_AMBIENT_ADDR 0x0000005C
-#define R200_VS_FOG_PARAM_ADDR 0x0000005D
-#define R200_VS_EYE_VECTOR_ADDR 0x0000005E
-#define R200_VS_UCP_ADDR 0x00000060
-#define R200_VS_PNT_SPRITE_VPORT_SCALE 0x00000068
-#define R200_VS_MATRIX_0_MV 0x00000080
-#define R200_VS_MATRIX_1_INV_MV 0x00000084
-#define R200_VS_MATRIX_2_MVP 0x00000088
-#define R200_VS_MATRIX_3_TEX0 0x0000008C
-#define R200_VS_MATRIX_4_TEX1 0x00000090
-#define R200_VS_MATRIX_5_TEX2 0x00000094
-#define R200_VS_MATRIX_6_TEX3 0x00000098
-#define R200_VS_MATRIX_7_TEX4 0x0000009C
-#define R200_VS_MATRIX_8_TEX5 0x000000A0
-#define R200_VS_MAT_0_EMISS 0x000000B0
-#define R200_VS_MAT_0_AMB 0x000000B1
-#define R200_VS_MAT_0_DIF 0x000000B2
-#define R200_VS_MAT_0_SPEC 0x000000B3
-#define R200_VS_MAT_1_EMISS 0x000000B4
-#define R200_VS_MAT_1_AMB 0x000000B5
-#define R200_VS_MAT_1_DIF 0x000000B6
-#define R200_VS_MAT_1_SPEC 0x000000B7
-#define R200_VS_EYE2CLIP_MTX 0x000000B8
-#define R200_VS_PNT_SPRITE_ATT_CONST 0x000000BC
-#define R200_VS_PNT_SPRITE_EYE_IN_MODEL 0x000000BD
-#define R200_VS_PNT_SPRITE_CLAMP 0x000000BE
-#define R200_VS_MAX 0x000001C0
-
-/*
- * Offsets in TCL scalar state
- */
-#define R200_SS_LIGHT_DCD_ADDR 0x00000000
-#define R200_SS_LIGHT_DCM_ADDR 0x00000008
-#define R200_SS_LIGHT_SPOT_EXPONENT_ADDR 0x00000010
-#define R200_SS_LIGHT_SPOT_CUTOFF_ADDR 0x00000018
-#define R200_SS_LIGHT_SPECULAR_THRESH_ADDR 0x00000020
-#define R200_SS_LIGHT_RANGE_CUTOFF_SQRD 0x00000028
-#define R200_SS_LIGHT_RANGE_ATT_CONST 0x00000030
-#define R200_SS_VERT_GUARD_CLIP_ADJ_ADDR 0x00000080
-#define R200_SS_VERT_GUARD_DISCARD_ADJ_ADDR 0x00000081
-#define R200_SS_HORZ_GUARD_CLIP_ADJ_ADDR 0x00000082
-#define R200_SS_HORZ_GUARD_DISCARD_ADJ_ADDR 0x00000083
-#define R200_SS_MAT_0_SHININESS 0x00000100
-#define R200_SS_MAT_1_SHININESS 0x00000101
-
-/*
- * Matrix indices
- */
-#define R200_MTX_MV 0
-#define R200_MTX_IMV 1
-#define R200_MTX_MVP 2
-#define R200_MTX_TEX0 3
-#define R200_MTX_TEX1 4
-#define R200_MTX_TEX2 5
-#define R200_MTX_TEX3 6
-#define R200_MTX_TEX4 7
-#define R200_MTX_TEX5 8
-
-/* Color formats for 2d packets
- */
-#define R200_CP_COLOR_FORMAT_CI8 2
-#define R200_CP_COLOR_FORMAT_ARGB1555 3
-#define R200_CP_COLOR_FORMAT_RGB565 4
-#define R200_CP_COLOR_FORMAT_ARGB8888 6
-#define R200_CP_COLOR_FORMAT_RGB332 7
-#define R200_CP_COLOR_FORMAT_RGB8 9
-#define R200_CP_COLOR_FORMAT_ARGB4444 15
-
-/*
- * CP type-3 packets
- */
-#define R200_CP_CMD_NOP 0xC0001000
-#define R200_CP_CMD_NEXT_CHAR 0xC0001900
-#define R200_CP_CMD_PLY_NEXTSCAN 0xC0001D00
-#define R200_CP_CMD_SET_SCISSORS 0xC0001E00
-#define R200_CP_CMD_LOAD_MICROCODE 0xC0002400
-#define R200_CP_CMD_WAIT_FOR_IDLE 0xC0002600
-#define R200_CP_CMD_3D_DRAW_VBUF 0xC0002800
-#define R200_CP_CMD_3D_DRAW_IMMD 0xC0002900
-#define R200_CP_CMD_3D_DRAW_INDX 0xC0002A00
-#define R200_CP_CMD_LOAD_PALETTE 0xC0002C00
-#define R200_CP_CMD_3D_LOAD_VBPNTR 0xC0002F00
-#define R200_CP_CMD_INDX_BUFFER 0xC0003300
-#define R200_CP_CMD_3D_DRAW_VBUF_2 0xC0003400
-#define R200_CP_CMD_3D_DRAW_IMMD_2 0xC0003500
-#define R200_CP_CMD_3D_DRAW_INDX_2 0xC0003600
-#define R200_CP_CMD_PAINT 0xC0009100
-#define R200_CP_CMD_BITBLT 0xC0009200
-#define R200_CP_CMD_SMALLTEXT 0xC0009300
-#define R200_CP_CMD_HOSTDATA_BLT 0xC0009400
-#define R200_CP_CMD_POLYLINE 0xC0009500
-#define R200_CP_CMD_POLYSCANLINES 0xC0009800
-#define R200_CP_CMD_PAINT_MULTI 0xC0009A00
-#define R200_CP_CMD_BITBLT_MULTI 0xC0009B00
-#define R200_CP_CMD_TRANS_BITBLT 0xC0009C00
-
-#endif
diff --git a/src/mesa/drivers/dri/r300/r200_state.h b/src/mesa/drivers/dri/r300/r200_state.h
deleted file mode 100644
index 3e1a9c8ba19..00000000000
--- a/src/mesa/drivers/dri/r300/r200_state.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
-
-The Weather Channel (TM) funded Tungsten Graphics to develop the
-initial release of the Radeon 8500 driver under the XFree86 license.
-This notice must be preserved.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial
-portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Keith Whitwell <[email protected]>
- */
-
-#ifndef __R200_STATE_H__
-#define __R200_STATE_H__
-
-#ifdef GLX_DIRECT_RENDERING
-
-#include "r200_context.h"
-
-extern void r200InitState(r200ContextPtr rmesa);
-extern void r200InitStateFuncs(struct dd_function_table *functions);
-extern void r200InitTnlFuncs(GLcontext * ctx);
-
-extern void r200UpdateMaterial(GLcontext * ctx);
-
-extern void r200UpdateViewportOffset(GLcontext * ctx);
-extern void r200UpdateWindow(GLcontext * ctx);
-
-extern void r200ValidateState(GLcontext * ctx);
-
-extern void r200PrintDirty(r200ContextPtr rmesa, const char *msg);
-
-extern void r200LightingSpaceChange(GLcontext * ctx);
-
-#endif
-#endif
diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c
index 54eb081d055..d10a9d87d31 100644
--- a/src/mesa/drivers/dri/r300/r300_context.c
+++ b/src/mesa/drivers/dri/r300/r300_context.c
@@ -44,7 +44,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
@@ -73,6 +73,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
int future_hw_tcl_on=1;
int hw_tcl_on=1;
+#define need_GL_EXT_stencil_two_side
#define need_GL_ARB_multisample
#define need_GL_ARB_texture_compression
#define need_GL_ARB_vertex_buffer_object
@@ -126,6 +127,10 @@ const struct dri_extension card_extensions[] = {
{NULL, NULL}
};
+const struct dri_extension stencil_two_side[] = {
+ {"GL_EXT_stencil_two_side", GL_EXT_stencil_two_side_functions},
+};
+
extern struct tnl_pipeline_stage _r300_render_stage;
extern const struct tnl_pipeline_stage _r300_tcl_stage;
extern const struct tnl_pipeline_stage _r300_texrect_stage;
@@ -195,6 +200,8 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
*/
driParseConfigFiles(&r300->radeon.optionCache, &screen->optionCache,
screen->driScreen->myNum, "r300");
+ r300->initialMaxAnisotropy = driQueryOptionf(&r300->radeon.optionCache,
+ "def_max_anisotropy");
//r300->texmicrotile = GL_TRUE;
@@ -287,7 +294,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
/* Initialize the software rasterizer and helper modules.
*/
_swrast_CreateContext(ctx);
- _ac_CreateContext(ctx);
+ _vbo_CreateContext(ctx);
_tnl_CreateContext(ctx);
_swsetup_CreateContext(ctx);
_swsetup_Wakeup(ctx);
@@ -300,7 +307,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
/* Try and keep materials and vertices separate:
*/
- _tnl_isolate_materials(ctx, GL_TRUE);
+/* _tnl_isolate_materials(ctx, GL_TRUE); */
/* Configure swrast and TNL to match hardware characteristics:
*/
@@ -331,6 +338,9 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
driInitExtensions(ctx, card_extensions, GL_TRUE);
+ if (driQueryOptionb(&r300->radeon.optionCache, "disable_stencil_two_side") == 0)
+ driInitSingleExtension(ctx, stencil_two_side);
+
if (r300->radeon.glCtx->Mesa_DXTn && !driQueryOptionb (&r300->radeon.optionCache, "disable_s3tc")) {
_mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
_mesa_enable_extension( ctx, "GL_S3_s3tc" );
@@ -478,7 +488,7 @@ void r300DestroyContext(__DRIcontextPrivate * driContextPriv)
_swsetup_DestroyContext(r300->radeon.glCtx);
_tnl_ProgramCacheDestroy(r300->radeon.glCtx);
_tnl_DestroyContext(r300->radeon.glCtx);
- _ac_DestroyContext(r300->radeon.glCtx);
+ _vbo_DestroyContext(r300->radeon.glCtx);
_swrast_DestroyContext(r300->radeon.glCtx);
if (r300->dma.current.buf) {
diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h
index dd3ecbb2357..48b50bca653 100644
--- a/src/mesa/drivers/dri/r300/r300_context.h
+++ b/src/mesa/drivers/dri/r300/r300_context.h
@@ -48,7 +48,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "radeon_context.h"
#define USER_BUFFERS
-#define RADEON_VTXFMT_A
+/* KW: Disable this code. Driver should hook into vbo module
+ * directly, see i965 driver for example.
+ */
+/* #define RADEON_VTXFMT_A */
#define HW_VBOS
/* We don't handle 16 bits elts swapping yet */
@@ -726,6 +729,11 @@ struct r300_fragment_program {
GLboolean params_uptodate;
int max_temp_idx;
+
+ /* the index of the sin constant is stored here */
+ GLint const_sin[2];
+
+ GLuint optimization;
};
#define R300_MAX_AOS_ARRAYS 16
@@ -754,7 +762,7 @@ struct radeon_vertex_buffer {
struct dt AttribPtr[VERT_ATTRIB_MAX];
- struct tnl_prim *Primitive;
+ const struct _mesa_prim *Primitive;
GLuint PrimitiveCount;
GLint LockFirst;
GLsizei LockCount;
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c
index 32c0128eaa2..8e45bd54030 100644
--- a/src/mesa/drivers/dri/r300/r300_fragprog.c
+++ b/src/mesa/drivers/dri/r300/r300_fragprog.c
@@ -33,7 +33,6 @@
/*TODO'S
*
- * - COS/SIN/SCS instructions
* - Depth write, WPOS/FOGC inputs
* - FogOption
* - Verify results of opcodes for accuracy, I've only checked them
@@ -51,18 +50,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)
+
+#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)
-/***************************************
- * begin: useful data structions for fragment program generation
- ***************************************/
+
+/*
+ * Datas structures for fragment program generation
+ */
/* description of r300 native hw instructions */
static const struct {
@@ -86,20 +177,23 @@ 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)
+
+/* mapping from SWIZZLE_* to r300 native values for scalar insns */
+#define SWIZZLE_HALF 6
+
+#define MAKE_SWZ3(x, y, z) (MAKE_SWIZZLE4(SWIZZLE_##x, \
+ SWIZZLE_##y, \
+ SWIZZLE_##z, \
+ SWIZZLE_ZERO))
static const struct r300_pfs_swizzle {
GLuint hash; /* swizzle value this matches */
GLuint base; /* base value for hw swizzle */
@@ -117,42 +211,30 @@ static const struct r300_pfs_swizzle {
{ MAKE_SWZ3(W, Z, Y), R300_FPI0_ARGC_SRC0CA_WZY, 1, SLOT_BOTH },
{ MAKE_SWZ3(ONE, ONE, ONE), R300_FPI0_ARGC_ONE, 0, 0},
{ MAKE_SWZ3(ZERO, ZERO, ZERO), R300_FPI0_ARGC_ZERO, 0, 0},
- { PFS_INVAL, R300_FPI0_ARGC_HALF, 0, 0},
+ { MAKE_SWZ3(HALF, HALF, HALF), R300_FPI0_ARGC_HALF, 0, 0},
{ PFS_INVAL, 0, 0, 0},
};
-#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 */
static const struct {
int base; /* hw value of swizzle */
int stride; /* difference between SRC0/1/2 */
@@ -166,58 +248,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,263 +331,360 @@ 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 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);
+#endif
+
+ if (REG_GET_VSWZ(src) != SWIZZLE_XYZ ||
+ REG_GET_SSWZ(src) != SWIZZLE_W) {
+ GLuint vsrcswz = (v_swiz[REG_GET_VSWZ(src)].hash & (SWZ_X_MASK|SWZ_Y_MASK|SWZ_Z_MASK)) | REG_GET_SSWZ(src) << 9;
+ GLint i;
+
+ GLuint newswz = 0;
+ GLuint offset;
+ for(i=0; i < 4; ++i){
+ offset = GET_SWZ(arbswz, i);
+
+ newswz |= (offset <= 3)?GET_SWZ(vsrcswz, offset) << i*3:offset << i*3;
+ }
+
+ arbswz = newswz & (SWZ_X_MASK|SWZ_Y_MASK|SWZ_Z_MASK);
+ REG_SET_SSWZ(src, GET_SWZ(newswz, 3));
+ }
+ else
+ {
+ /* set scalar swizzling */
+ REG_SET_SSWZ(src, GET_SWZ(arbswz, 3));
+ }
do {
+ vswz = REG_GET_VSWZ(src);
do {
-#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;
+ 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,
@@ -533,13 +705,13 @@ 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);
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 */
@@ -549,22 +721,24 @@ static pfs_reg_t t_scalar_src(struct r300_fragment_program *rp,
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);
@@ -576,66 +750,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;
@@ -643,17 +828,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;
@@ -679,8 +865,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;
@@ -691,7 +877,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);
}
@@ -703,7 +889,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;
@@ -713,8 +899,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);
@@ -754,13 +940,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);
@@ -770,7 +956,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;
@@ -819,9 +1007,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;
@@ -833,20 +1024,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;
@@ -863,7 +1058,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)) {
@@ -879,12 +1075,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_SSWZ(src[i])].flags & SLOT_VECTOR)) {
vpos = spos = MAX2(vpos, spos);
break;
}
@@ -908,20 +1104,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);
@@ -943,8 +1141,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);
@@ -968,11 +1166,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 {
@@ -985,33 +1183,52 @@ 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
+static void make_sin_const(struct r300_fragment_program *rp)
+{
+ if(rp->const_sin[0] == -1){
+ GLfloat cnstv[4];
+
+ cnstv[0] = 1.273239545; // 4/PI
+ cnstv[1] =-0.405284735; // -4/(PI*PI)
+ cnstv[2] = 3.141592654; // PI
+ cnstv[3] = 0.2225; // weight
+ rp->const_sin[0] = emit_const4fv(rp, cnstv);
+
+ cnstv[0] = 0.5;
+ cnstv[1] = -1.5;
+ cnstv[2] = 0.159154943; // 1/(2*PI)
+ cnstv[3] = 6.283185307; // 2*PI
+ rp->const_sin[1] = emit_const4fv(rp, cnstv);
+ }
+}
+
static GLboolean parse_program(struct r300_fragment_program *rp)
{
struct gl_fragment_program *mp = &rp->mesa_program;
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};
@@ -1058,62 +1275,71 @@ static GLboolean parse_program(struct r300_fragment_program *rp)
break;
case OPCODE_COS:
/*
- * cos using taylor serie:
- * cos(x) = 1 - x^2/2! + x^4/4! - x^6/6!
+ * cos using a parabola (see SIN):
+ * cos(x):
+ * x += PI/2
+ * x = (x/(2*PI))+0.5
+ * x = frac(x)
+ * x = (x*2*PI)-PI
+ * result = sin(x)
*/
temp = get_temp_reg(rp);
- cnstv[0] = 0.5;
- cnstv[1] = 0.041666667;
- cnstv[2] = 0.001388889;
- cnstv[4] = 0.0;
- cnst = emit_const4fv(rp, cnstv);
+ make_sin_const(rp);
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,
+ /* add 0.5*PI and do range reduction */
+
+ emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X,
+ swizzle(rp->const_sin[0], Z, Z, Z, Z), //PI
+ pfs_half,
+ swizzle(keep(src[0]), X, X, X, X),
+ 0);
+
+ emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X,
swizzle(temp, X, X, X, X),
- pfs_one,
+ swizzle(rp->const_sin[1], Z, Z, Z, Z),
+ pfs_half,
+ 0);
+
+ emit_arith(rp, PFS_OP_FRC, temp, WRITEMASK_X,
+ swizzle(temp, X, X, X, X),
+ undef,
+ undef,
+ 0);
+
+ emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Z,
+ swizzle(temp, X, X, X, X),
+ swizzle(rp->const_sin[1], W, W, W, W), //2*PI
+ negate(swizzle(rp->const_sin[0], Z, Z, Z, Z)), //-PI
+ 0);
+
+ /* SIN */
+
+ emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X | WRITEMASK_Y,
+ swizzle(temp, Z, Z, Z, Z),
+ rp->const_sin[0],
pfs_zero,
+ 0);
+
+ emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X,
+ swizzle(temp, Y, Y, Y, Y),
+ absolute(swizzle(temp, Z, Z, Z, Z)),
+ swizzle(temp, X, X, X, X),
+ 0);
+
+ emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Y,
+ swizzle(temp, X, X, X, X),
+ absolute(swizzle(temp, X, X, X, X)),
+ negate(swizzle(temp, X, X, X, X)),
+ 0);
+
+
+ emit_arith(rp, PFS_OP_MAD, dest, mask,
+ swizzle(temp, Y, Y, Y, Y),
+ swizzle(rp->const_sin[0], W, W, W, W),
+ swizzle(temp, X, X, X, X),
flags);
+
free_temp(rp, temp);
break;
case OPCODE_DP3:
@@ -1167,7 +1393,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,
@@ -1222,7 +1448,7 @@ static GLboolean parse_program(struct r300_fragment_program *rp)
* change the compare to (t.x + 0.5) > 0.5 we may
* save one instruction by doing CMP -t.x
*/
- cnstv[0] = cnstv[1] = cnstv[2] = cnstv[4] = 0.50001;
+ cnstv[0] = cnstv[1] = cnstv[2] = cnstv[3] = 0.50001;
src[0] = t_src(rp, fpi->SrcReg[0]);
temp = get_temp_reg(rp);
cnst = emit_const4fv(rp, cnstv);
@@ -1353,7 +1579,93 @@ static GLboolean parse_program(struct r300_fragment_program *rp)
flags);
break;
case OPCODE_SCS:
- ERROR("SCS not implemented\n");
+ /*
+ * cos using a parabola (see SIN):
+ * cos(x):
+ * x += PI/2
+ * x = (x/(2*PI))+0.5
+ * x = frac(x)
+ * x = (x*2*PI)-PI
+ * result = sin(x)
+ */
+ temp = get_temp_reg(rp);
+ make_sin_const(rp);
+ src[0] = t_scalar_src(rp, fpi->SrcReg[0]);
+
+ /* add 0.5*PI and do range reduction */
+
+ emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X|WRITEMASK_Y,
+ swizzle(rp->const_sin[0], Z, Z, Z, Z),
+ rp->const_sin[1],
+ swizzle(keep(src[0]), X, X, X, X),
+ 0);
+
+ emit_arith(rp, PFS_OP_CMP, temp, WRITEMASK_W,
+ swizzle(rp->const_sin[0], Z, Z, Z, Z),
+ negate(pfs_half),
+ swizzle(keep(src[0]), X, X, X, X),
+ 0);
+
+ emit_arith(rp, PFS_OP_CMP, temp, WRITEMASK_Z,
+ swizzle(temp, X, X, X, X),
+ swizzle(temp, Y, Y, Y, Y),
+ swizzle(temp, W, W, W, W),
+ 0);
+
+ emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X | WRITEMASK_Y,
+ swizzle(temp, Z, Z, Z, Z),
+ rp->const_sin[0],
+ pfs_zero,
+ 0);
+
+ emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_W,
+ swizzle(temp, Y, Y, Y, Y),
+ absolute(swizzle(temp, Z, Z, Z, Z)),
+ swizzle(temp, X, X, X, X),
+ 0);
+
+ if(mask & WRITEMASK_Y)
+ {
+ emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X | WRITEMASK_Y,
+ swizzle(keep(src[0]), X, X, X, X),
+ rp->const_sin[0],
+ pfs_zero,
+ 0);
+
+ emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X,
+ swizzle(temp, Y, Y, Y, Y),
+ absolute(swizzle(keep(src[0]), X, X, X, X)),
+ swizzle(temp, X, X, X, X),
+ 0);
+ }
+
+ emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Z,
+ swizzle(temp, W, W, W, W),
+ absolute(swizzle(temp, W, W, W, W)),
+ negate(swizzle(temp, W, W, W, W)),
+ 0);
+
+ emit_arith(rp, PFS_OP_MAD, dest, WRITEMASK_X,
+ swizzle(temp, Z, Z, Z, Z),
+ swizzle(rp->const_sin[0], W, W, W, W),
+ swizzle(temp, W, W, W, W),
+ flags);
+
+ if(mask & WRITEMASK_Y)
+ {
+ emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_W,
+ swizzle(temp, X, X, X, X),
+ absolute(swizzle(temp, X, X, X, X)),
+ negate(swizzle(temp, X, X, X, X)),
+ 0);
+
+ emit_arith(rp, PFS_OP_MAD, dest, WRITEMASK_Y,
+ swizzle(temp, W, W, W, W),
+ swizzle(rp->const_sin[0], W, W, W, W),
+ swizzle(temp, X, X, X, X),
+ flags);
+ }
+ free_temp(rp, temp);
break;
case OPCODE_SGE:
src[0] = t_src(rp, fpi->SrcReg[0]);
@@ -1372,68 +1684,63 @@ static GLboolean parse_program(struct r300_fragment_program *rp)
break;
case OPCODE_SIN:
/*
- * sin using taylor serie:
- * sin(x) = x - x^3/3! + x^5/5! - x^7/7!
+ * using a parabola:
+ * sin(x) = 4/pi * x + -4/(pi*pi) * x * abs(x)
+ * extra precision is obtained by weighting against
+ * itself squared.
*/
+
temp = get_temp_reg(rp);
- cnstv[0] = 0.333333333;
- cnstv[1] = 0.008333333;
- cnstv[2] = 0.000198413;
- cnstv[4] = 0.0;
- cnst = emit_const4fv(rp, cnstv);
+ make_sin_const(rp);
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,
+ /* do range reduction */
+
+ emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X,
+ swizzle(keep(src[0]), X, X, X, X),
+ swizzle(rp->const_sin[1], Z, Z, Z, Z),
+ pfs_half,
+ 0);
+
+ emit_arith(rp, PFS_OP_FRC, temp, WRITEMASK_X,
swizzle(temp, X, X, X, X),
- pfs_one,
+ undef,
+ undef,
+ 0);
+
+ emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Z,
+ swizzle(temp, X, X, X, X),
+ swizzle(rp->const_sin[1], W, W, W, W), //2*PI
+ negate(swizzle(rp->const_sin[0], Z, Z, Z, Z)), //PI
+ 0);
+
+ /* SIN */
+
+ emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X | WRITEMASK_Y,
+ swizzle(temp, Z, Z, Z, Z),
+ rp->const_sin[0],
pfs_zero,
+ 0);
+
+ emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X,
+ swizzle(temp, Y, Y, Y, Y),
+ absolute(swizzle(temp, Z, Z, Z, Z)),
+ swizzle(temp, X, X, X, X),
+ 0);
+
+ emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Y,
+ swizzle(temp, X, X, X, X),
+ absolute(swizzle(temp, X, X, X, X)),
+ negate(swizzle(temp, X, X, X, X)),
+ 0);
+
+
+ emit_arith(rp, PFS_OP_MAD, dest, mask,
+ swizzle(temp, Y, Y, Y, Y),
+ swizzle(rp->const_sin[0], W, W, W, W),
+ swizzle(temp, X, X, X, X),
flags);
+
free_temp(rp, temp);
break;
case OPCODE_SLT:
@@ -1505,7 +1812,7 @@ static GLboolean parse_program(struct r300_fragment_program *rp)
/* - Init structures
* - Determine what hwregs each input corresponds to
*/
-static void init_program(struct r300_fragment_program *rp)
+static void init_program(r300ContextPtr r300, struct r300_fragment_program *rp)
{
struct r300_pfs_compile_state *cs = NULL;
struct gl_fragment_program *mp = &rp->mesa_program;
@@ -1515,6 +1822,7 @@ static void init_program(struct r300_fragment_program *rp)
int i,j;
/* New compile, reset tracking data */
+ rp->optimization = driQueryOptioni(&r300->radeon.optionCache, "fp_optimization");
rp->translated = GL_FALSE;
rp->error = GL_FALSE;
rp->cs = cs = &(R300_CONTEXT(rp->ctx)->state.pfs_compile);
@@ -1527,6 +1835,7 @@ static void init_program(struct r300_fragment_program *rp)
rp->max_temp_idx = 0;
rp->node[0].alu_end = -1;
rp->node[0].tex_end = -1;
+ rp->const_sin[0] = -1;
_mesa_memset(cs, 0, sizeof(*rp->cs));
for (i=0;i<PFS_MAX_ALU_INST;i++) {
@@ -1640,13 +1949,13 @@ static void update_params(struct r300_fragment_program *rp)
rp->params_uptodate = GL_TRUE;
}
-void r300_translate_fragment_shader(struct r300_fragment_program *rp)
+void r300_translate_fragment_shader(r300ContextPtr r300, struct r300_fragment_program *rp)
{
struct r300_pfs_compile_state *cs = NULL;
if (!rp->translated) {
- init_program(rp);
+ init_program(r300, rp);
cs = rp->cs;
if (parse_program(rp) == GL_FALSE) {
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.h b/src/mesa/drivers/dri/r300/r300_fragprog.h
index 4bbaa07e012..73986abc3cc 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];
@@ -111,8 +112,11 @@ typedef struct r300_fragment_program_swizzle {
((0 | SRC_CONST) << R300_FPI3_SRC1A_SHIFT) | \
((0 | SRC_CONST) << R300_FPI3_SRC2A_SHIFT))
+#define DRI_CONF_FP_OPTIMIZATION_SPEED 0
+#define DRI_CONF_FP_OPTIMIZATION_QUALITY 1
+
struct r300_fragment_program;
-extern void r300_translate_fragment_shader(struct r300_fragment_program *rp);
+extern void r300_translate_fragment_shader(r300ContextPtr r300, struct r300_fragment_program *rp);
#endif
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_swz.c b/src/mesa/drivers/dri/r300/r300_fragprog_swz.c
deleted file mode 100644
index b29331d7bde..00000000000
--- 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_render.c b/src/mesa/drivers/dri/r300/r300_render.c
index 03f168365dc..211c451f661 100644
--- a/src/mesa/drivers/dri/r300/r300_render.c
+++ b/src/mesa/drivers/dri/r300/r300_render.c
@@ -42,7 +42,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "api_arrayelt.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "tnl/t_vp_build.h"
@@ -352,7 +352,7 @@ GLboolean r300_run_vb_render(GLcontext *ctx,
r300EmitState(rmesa);
for(i=0; i < VB->PrimitiveCount; i++){
- GLuint prim = VB->Primitive[i].mode;
+ GLuint prim = _tnl_translate_prim(&VB->Primitive[i]);
GLuint start = VB->Primitive[i].start;
GLuint length = VB->Primitive[i].count;
@@ -385,8 +385,18 @@ GLboolean r300_run_vb_render(GLcontext *ctx,
int r300Fallback(GLcontext *ctx)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
+ struct r300_fragment_program *rp =
+ (struct r300_fragment_program *)
+ (char *)ctx->FragmentProgram._Current;
int i;
+ if (rp) {
+ if (!rp->translated)
+ r300_translate_fragment_shader(r300, rp);
+
+ FALLBACK_IF(!rp->translated);
+ }
+
/* We do not do SELECT or FEEDBACK (yet ?)
* Is it worth doing them ?
*/
@@ -406,6 +416,10 @@ int r300Fallback(GLcontext *ctx)
*/
FALLBACK_IF(ctx->Fog.Enabled);
#endif
+ FALLBACK_IF(ctx->Stencil._TestTwoSide &&
+ (ctx->Stencil.Ref[0] != ctx->Stencil.Ref[1] ||
+ ctx->Stencil.ValueMask[0] != ctx->Stencil.ValueMask[1] ||
+ ctx->Stencil.WriteMask[0] != ctx->Stencil.WriteMask[1]));
if(!r300->disable_lowimpact_fallback){
/* GL_POLYGON_OFFSET_POINT */
diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
index 72255066d59..906dfceb482 100644
--- a/src/mesa/drivers/dri/r300/r300_state.c
+++ b/src/mesa/drivers/dri/r300/r300_state.c
@@ -46,7 +46,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "api_arrayelt.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "texformat.h"
@@ -509,7 +509,6 @@ static void r300Enable(GLcontext* ctx, GLenum cap, GLboolean state)
if (r300->state.stencil.hw_stencil) {
R300_STATECHANGE(r300, zs);
if (state) {
- WARN_ONCE("TODO - double side stencil !\n");
r300->hw.zs.cmd[R300_ZS_CNTL_0] |=
R300_RB3D_STENCIL_ENABLE;
} else {
@@ -863,9 +862,12 @@ static void r300StencilFuncSeparate(GLcontext * ctx, GLenum face,
(R300_RB3D_ZS2_STENCIL_MASK << R300_RB3D_ZS2_STENCIL_MASK_SHIFT));
flag = translate_func(ctx->Stencil.Function[0]);
-
- rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= (flag << R300_RB3D_ZS1_FRONT_FUNC_SHIFT)
- | (flag << R300_RB3D_ZS1_BACK_FUNC_SHIFT);
+ rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= (flag << R300_RB3D_ZS1_FRONT_FUNC_SHIFT);
+
+ if (ctx->Stencil._TestTwoSide)
+ flag = translate_func(ctx->Stencil.Function[1]);
+
+ rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= (flag << R300_RB3D_ZS1_BACK_FUNC_SHIFT);
rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |= refmask;
}
@@ -894,10 +896,19 @@ static void r300StencilOpSeparate(GLcontext * ctx, GLenum face, GLenum fail,
rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
(translate_stencil_op(ctx->Stencil.FailFunc[0]) << R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT)
|(translate_stencil_op(ctx->Stencil.ZFailFunc[0]) << R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT)
- |(translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT)
- |(translate_stencil_op(ctx->Stencil.FailFunc[0]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT)
- |(translate_stencil_op(ctx->Stencil.ZFailFunc[0]) << R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT)
- |(translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT);
+ |(translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT);
+
+ if (ctx->Stencil._TestTwoSide) {
+ rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
+ (translate_stencil_op(ctx->Stencil.FailFunc[1]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT)
+ |(translate_stencil_op(ctx->Stencil.ZFailFunc[1]) << R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT)
+ |(translate_stencil_op(ctx->Stencil.ZPassFunc[1]) << R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT);
+ } else {
+ rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
+ (translate_stencil_op(ctx->Stencil.FailFunc[0]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT)
+ |(translate_stencil_op(ctx->Stencil.ZFailFunc[0]) << R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT)
+ |(translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT);
+ }
}
static void r300ClearStencil(GLcontext * ctx, GLint s)
@@ -1809,10 +1820,10 @@ void r300SetupPixelShader(r300ContextPtr rmesa)
if (!rp) /* should only happenen once, just after context is created */
return;
- r300_translate_fragment_shader(rp);
+ r300_translate_fragment_shader(rmesa, rp);
if (!rp->translated) {
fprintf(stderr, "%s: No valid fragment shader, exiting\n", __func__);
- exit(-1);
+ return;
}
#define OUTPUT_FIELD(st, reg, field) \
@@ -1874,7 +1885,7 @@ static void r300InvalidateState(GLcontext * ctx, GLuint new_state)
_swrast_InvalidateState(ctx, new_state);
_swsetup_InvalidateState(ctx, new_state);
- _ac_InvalidateState(ctx, new_state);
+ _vbo_InvalidateState(ctx, new_state);
_tnl_InvalidateState(ctx, new_state);
_ae_invalidate_state(ctx, new_state);
diff --git a/src/mesa/drivers/dri/r300/r300_vertexprog.c b/src/mesa/drivers/dri/r300/r300_vertexprog.c
index 2492a4a3a0a..2ff92e13289 100644
--- a/src/mesa/drivers/dri/r300/r300_vertexprog.c
+++ b/src/mesa/drivers/dri/r300/r300_vertexprog.c
@@ -960,26 +960,23 @@ static void position_invariant(struct gl_program *prog)
static void insert_wpos(struct r300_vertex_program *vp,
struct gl_program *prog,
- GLint pos)
+ GLuint temp_index)
{
GLint tokens[6] = { STATE_INTERNAL, STATE_R300_WINDOW_DIMENSION, 0, 0, 0, 0 };
struct prog_instruction *vpi;
struct prog_instruction *vpi_insert;
- GLuint temp_index;
GLuint window_index;
int i = 0;
vpi = malloc((prog->NumInstructions + 5) * sizeof(struct prog_instruction));
- memcpy(vpi, prog->Instructions, (pos+1) * sizeof(struct prog_instruction));
+ /* all but END */
+ memcpy(vpi, prog->Instructions, (prog->NumInstructions - 1) * sizeof(struct prog_instruction));
+ /* END */
+ memcpy(&vpi[prog->NumInstructions + 4], &prog->Instructions[prog->NumInstructions - 1],
+ sizeof(struct prog_instruction));
- vpi_insert = &vpi[pos];
-
- /* make a copy before outputting VERT_RESULT_HPOS */
- vpi_insert->DstReg.File = vpi_insert->SrcReg[2].File;
- vpi_insert->DstReg.Index = temp_index = vpi_insert->SrcReg[2].Index;
-
- vpi_insert++;
+ vpi_insert = &vpi[prog->NumInstructions - 1];
memset(vpi_insert, 0, 5 * sizeof(struct prog_instruction));
vpi_insert[i].Opcode = OPCODE_MOV;
@@ -1062,8 +1059,6 @@ static void insert_wpos(struct r300_vertex_program *vp,
vpi_insert[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ONE, SWIZZLE_ONE);
i++;
- memcpy(&vpi_insert[i], &prog->Instructions[pos+1], (prog->NumInstructions-(pos+1)) * sizeof(struct prog_instruction));
-
free(prog->Instructions);
prog->Instructions = vpi;
@@ -1078,16 +1073,18 @@ static void pos_as_texcoord(struct r300_vertex_program *vp,
struct gl_program *prog)
{
struct prog_instruction *vpi;
- int pos = 0;
-
- for(vpi = prog->Instructions; vpi->Opcode != OPCODE_END; vpi++, pos++){
+ GLuint tempregi = prog->NumTemporaries;
+ /* should do something else if no temps left... */
+ prog->NumTemporaries++;
+
+ for(vpi = prog->Instructions; vpi->Opcode != OPCODE_END; vpi++){
if( vpi->DstReg.File == PROGRAM_OUTPUT &&
vpi->DstReg.Index == VERT_RESULT_HPOS ){
- insert_wpos(vp, prog, pos);
- break;
+ vpi->DstReg.File = PROGRAM_TEMPORARY;
+ vpi->DstReg.Index = tempregi;
}
}
-
+ insert_wpos(vp, prog, tempregi);
}
static struct r300_vertex_program *build_program(struct r300_vertex_program_key *wanted_key,
@@ -1101,8 +1098,9 @@ static struct r300_vertex_program *build_program(struct r300_vertex_program_key
vp->wpos_idx = wpos_idx;
- if(mesa_vp->IsPositionInvariant)
+ if(mesa_vp->IsPositionInvariant) {
position_invariant(&mesa_vp->Base);
+ }
if(wpos_idx > -1)
pos_as_texcoord(vp, &mesa_vp->Base);
@@ -1158,6 +1156,10 @@ void r300_select_vertex_shader(r300ContextPtr r300)
wanted_key.OutputsWritten |= 1 << (VERT_RESULT_TEX0 + i);
wanted_key.InputsRead = vpc->mesa_program.Base.InputsRead;
+ if(vpc->mesa_program.IsPositionInvariant) {
+ /* we wan't position don't we ? */
+ wanted_key.InputsRead |= (1 << VERT_ATTRIB_POS);
+ }
for (vp = vpc->progs; vp; vp = vp->next)
if (_mesa_memcmp(&vp->key, &wanted_key, sizeof(wanted_key)) == 0) {
@@ -1170,6 +1172,5 @@ void r300_select_vertex_shader(r300ContextPtr r300)
vp = build_program(&wanted_key, &vpc->mesa_program, wpos_idx);
vp->next = vpc->progs;
vpc->progs = vp;
-
r300->selected_vp = vp;
}
diff --git a/src/mesa/drivers/dri/r300/radeon_state.c b/src/mesa/drivers/dri/r300/radeon_state.c
index 0ceaf7ebb7d..ddadf83a003 100644
--- a/src/mesa/drivers/dri/r300/radeon_state.c
+++ b/src/mesa/drivers/dri/r300/radeon_state.c
@@ -41,7 +41,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "light.h"
#include "swrast/swrast.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
#include "swrast_setup/swrast_setup.h"
diff --git a/src/mesa/drivers/dri/r300/radeon_vtxfmt_a.c b/src/mesa/drivers/dri/r300/radeon_vtxfmt_a.c
index 72c03c53ad9..0625e5bc571 100644
--- a/src/mesa/drivers/dri/r300/radeon_vtxfmt_a.c
+++ b/src/mesa/drivers/dri/r300/radeon_vtxfmt_a.c
@@ -46,6 +46,8 @@
#include "state.h"
#include "image.h"
+#include "vbo/vbo_context.h"
+
#define CONV_VB(a, b) rvb->AttribPtr[(a)].size = vb->b->size, \
rvb->AttribPtr[(a)].type = GL_FLOAT, \
rvb->AttribPtr[(a)].stride = vb->b->stride, \
@@ -129,15 +131,7 @@ static int setup_arrays(r300ContextPtr rmesa, GLint start)
CONV(i, VertexAttrib[i]);
for (i=0; i < VERT_ATTRIB_MAX; i++) {
- if (enabled & (1 << i)) {
- rmesa->state.VB.AttribPtr[i].data += rmesa->state.VB.AttribPtr[i].stride * start;
- } else {
- def.data = ctx->Current.Attrib[i];
- memcpy(&rmesa->state.VB.AttribPtr[i], &def, sizeof(struct dt));
- }
-
- /*if(rmesa->state.VB.AttribPtr[i].data == ctx->Current.Attrib[i])
- fprintf(stderr, "%d is default coord\n", i);*/
+ rmesa->state.VB.AttribPtr[i].data += rmesa->state.VB.AttribPtr[i].stride * start;
}
for(i=0; i < VERT_ATTRIB_MAX; i++){
@@ -177,177 +171,18 @@ static int setup_arrays(r300ContextPtr rmesa, GLint start)
void radeon_init_vtxfmt_a(r300ContextPtr rmesa);
-static void radeonDrawElements( GLenum mode, GLsizei count, GLenum type, const GLvoid *c_indices )
-{
- GET_CURRENT_CONTEXT(ctx);
- r300ContextPtr rmesa = R300_CONTEXT(ctx);
- int elt_size;
- int i;
- unsigned int min = ~0, max = 0;
- struct tnl_prim prim;
- static void *ptr = NULL;
- struct r300_dma_region rvb;
- const GLvoid *indices = c_indices;
-
- if (count > 65535) {
- WARN_ONCE("Too many verts!\n");
- goto fallback;
- }
-
- if (ctx->Array.ElementArrayBufferObj->Name) {
- /* use indices in the buffer object */
- if (!ctx->Array.ElementArrayBufferObj->Data) {
- _mesa_warning(ctx, "DrawRangeElements with empty vertex elements buffer!");
- return;
- }
- /* actual address is the sum of pointers */
- indices = (GLvoid *)
- ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Data, (const GLubyte *) c_indices);
- }
-
- if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))
- return;
-
- FLUSH_CURRENT( ctx, 0 );
-
- memset(&rvb, 0, sizeof(rvb));
- switch (type) {
- case GL_UNSIGNED_BYTE:
- for (i=0; i < count; i++) {
- if(((unsigned char *)indices)[i] < min)
- min = ((unsigned char *)indices)[i];
- if(((unsigned char *)indices)[i] > max)
- max = ((unsigned char *)indices)[i];
- }
-
-#ifdef FORCE_32BITS_ELTS
- elt_size = 4;
-#else
- elt_size = 2;
-#endif
- r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size);
- rvb.aos_offset = GET_START(&rvb);
- ptr = rvb.address + rvb.start;
-
-#ifdef FORCE_32BITS_ELTS
- for (i=0; i < count; i++)
- ((unsigned int *)ptr)[i] = ((unsigned char *)indices)[i] - min;
-#else
- for (i=0; i < count; i++)
- ((unsigned short int *)ptr)[i] = ((unsigned char *)indices)[i] - min;
-#endif
- break;
-
- case GL_UNSIGNED_SHORT:
- for (i=0; i < count; i++) {
- if(((unsigned short int *)indices)[i] < min)
- min = ((unsigned short int *)indices)[i];
- if(((unsigned short int *)indices)[i] > max)
- max = ((unsigned short int *)indices)[i];
- }
-
-#ifdef FORCE_32BITS_ELTS
- elt_size = 4;
-#else
- elt_size = 2;
-#endif
-
- r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size);
- rvb.aos_offset = GET_START(&rvb);
- ptr = rvb.address + rvb.start;
-
-#ifdef FORCE_32BITS_ELTS
- for (i=0; i < count; i++)
- ((unsigned int *)ptr)[i] = ((unsigned short int *)indices)[i] - min;
-#else
- for (i=0; i < count; i++)
- ((unsigned short int *)ptr)[i] = ((unsigned short int *)indices)[i] - min;
-#endif
- break;
-
- case GL_UNSIGNED_INT:
- for (i=0; i < count; i++) {
- if(((unsigned int *)indices)[i] < min)
- min = ((unsigned int *)indices)[i];
- if(((unsigned int *)indices)[i] > max)
- max = ((unsigned int *)indices)[i];
- }
-
-#ifdef FORCE_32BITS_ELTS
- elt_size = 4;
-#else
- if (max - min <= 65535)
- elt_size = 2;
- else
- elt_size = 4;
-#endif
- r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size);
- rvb.aos_offset = GET_START(&rvb);
- ptr = rvb.address + rvb.start;
-
-
- if (elt_size == 2)
- for (i=0; i < count; i++)
- ((unsigned short int *)ptr)[i] = ((unsigned int *)indices)[i] - min;
- else
- for (i=0; i < count; i++)
- ((unsigned int *)ptr)[i] = ((unsigned int *)indices)[i] - min;
- break;
-
- default:
- WARN_ONCE("Unknown elt type!\n");
- goto fallback;
- }
-
- if (ctx->NewState)
- _mesa_update_state( ctx );
-
- r300UpdateShaders(rmesa);
-
- if (setup_arrays(rmesa, min) >= R300_FALLBACK_TCL) {
- r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__);
- goto fallback;
- }
-
- rmesa->state.VB.Count = max - min + 1;
-
- r300UpdateShaderStates(rmesa);
-
- rmesa->state.VB.Primitive = &prim;
- rmesa->state.VB.PrimitiveCount = 1;
-
- prim.mode = mode | PRIM_BEGIN | PRIM_END;
- if (rmesa->state.VB.LockCount)
- prim.start = min - rmesa->state.VB.LockFirst;
- else
- prim.start = 0;
- prim.count = count;
-
- rmesa->state.VB.Elts = ptr;
- rmesa->state.VB.elt_size = elt_size;
-
- if (r300_run_vb_render(ctx, NULL)) {
- r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__);
- goto fallback;
- }
-
- if(rvb.buf)
- radeon_mm_use(rmesa, rvb.buf->id);
-
- r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__);
- return;
-
- fallback:
- _tnl_array_init(ctx);
- _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt );
- CALL_DrawElements(GET_DISPATCH(), (mode, count, type, c_indices));
- radeon_init_vtxfmt_a(rmesa);
- _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt );
-}
-static void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei count, GLenum type, const GLvoid *c_indices)
+static void radeonDrawRangeElements(GLcontext *ctx,
+ GLenum mode,
+ GLuint min,
+ GLuint max,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *c_indices)
{
- GET_CURRENT_CONTEXT(ctx);
+#if 1
+ return GL_FALSE;
+#else
r300ContextPtr rmesa = R300_CONTEXT(ctx);
struct tnl_prim prim;
int elt_size;
@@ -371,26 +206,23 @@ static void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei
indices += i * _mesa_sizeof_type(type);
count -= i;
}
- return ;
+ return GL_TRUE;
}
WARN_ONCE("Too many verts!\n");
- goto fallback;
+ return GL_FALSE;
}
if (ctx->Array.ElementArrayBufferObj->Name) {
/* use indices in the buffer object */
if (!ctx->Array.ElementArrayBufferObj->Data) {
_mesa_warning(ctx, "DrawRangeElements with empty vertex elements buffer!");
- return;
+ return GL_TRUE;
}
/* actual address is the sum of pointers */
indices = (GLvoid *)
ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Data, (const GLubyte *) c_indices);
}
- if (!_mesa_validate_DrawRangeElements( ctx, mode, min, max, count, type, indices ))
- return;
-
FLUSH_CURRENT( ctx, 0 );
#ifdef OPTIMIZE_ELTS
min = 0;
@@ -465,7 +297,7 @@ static void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei
default:
WARN_ONCE("Unknown elt type!\n");
- goto fallback;
+ return GL_FALSE;
}
/* XXX: setup_arrays before state update? */
@@ -477,7 +309,7 @@ static void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei
if (setup_arrays(rmesa, min) >= R300_FALLBACK_TCL) {
r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__);
- goto fallback;
+ return GL_FALSE;
}
rmesa->state.VB.Count = max - min + 1;
@@ -501,37 +333,34 @@ static void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei
if (r300_run_vb_render(ctx, NULL)) {
r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__);
- goto fallback;
+ return GL_FALSE;
}
if(rvb.buf)
radeon_mm_use(rmesa, rvb.buf->id);
r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__);
- return ;
-
- fallback:
- _tnl_array_init(ctx);
- _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt );
- CALL_DrawRangeElements(GET_DISPATCH(), (mode, min, max, count, type, c_indices));
- radeon_init_vtxfmt_a(rmesa);
- _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt );
+ return GL_TRUE;
+#endif
}
-static void radeonDrawArrays( GLenum mode, GLint start, GLsizei count )
+static GLboolean radeonDrawArrays( GLcontext *ctx,
+ GLenum mode, GLint start, GLsizei count )
{
+#if 1
+ return GL_FALSE;
+#else
GET_CURRENT_CONTEXT(ctx);
r300ContextPtr rmesa = R300_CONTEXT(ctx);
struct tnl_prim prim;
if (count > 65535) {
+ /* TODO: split into multiple draws.
+ */
WARN_ONCE("Too many verts!\n");
- goto fallback;
+ return GL_FALSE;
}
- if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))
- return;
-
FLUSH_CURRENT( ctx, 0 );
if (ctx->NewState)
@@ -542,7 +371,7 @@ static void radeonDrawArrays( GLenum mode, GLint start, GLsizei count )
r300UpdateShaders(rmesa);
if (setup_arrays(rmesa, start) >= R300_FALLBACK_TCL)
- goto fallback;
+ return GL_FALSE;
rmesa->state.VB.Count = count;
@@ -564,31 +393,70 @@ static void radeonDrawArrays( GLenum mode, GLint start, GLsizei count )
rmesa->state.VB.elt_max = 0;
if (r300_run_vb_render(ctx, NULL))
- goto fallback;
+ return GL_FALSE;
- return ;
-
- fallback:
- _tnl_array_init(ctx);
- _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt );
- CALL_DrawArrays(GET_DISPATCH(), (mode, start, count));
- radeon_init_vtxfmt_a(rmesa);
- _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt );
+ return GL_TRUE;
+#endif
}
+static void radeon_draw_prims( GLcontext *ctx,
+ const struct gl_client_array *arrays[],
+ const struct _mesa_prim *prim,
+ GLuint nr_prims,
+ const struct _mesa_index_buffer *ib,
+ GLuint min_index,
+ GLuint max_index)
+{
+ if (ib == NULL) {
+ for (i = 0; i < nr_prims; i++) {
+ if (!radeonDrawArrays(ctx,
+ prim->mode,
+ prim->start,
+ prim->count)) {
+ /* Fallback
+ */
+ _tnl_draw_prims(ctx,
+ arrays,
+ prim + i,
+ nr_prims - i,
+ ib,
+ min_index,
+ max_index);
+ return;
+ }
+ }
+ } else {
+ for (i = 0; i < nr_prims; i++) {
+ if (!radeonDrawRangeElements(ctx,
+ prim->mode,
+ min_index,
+ max_index,
+ prim->count,
+ ib->types,
+ ib->ptr)) {
+ /* Fallback
+ */
+ _tnl_draw_prims(ctx,
+ arrays,
+ prim + i,
+ nr_prims - i,
+ ib,
+ min_index,
+ max_index);
+ return;
+ }
+ }
+ }
+}
+
void radeon_init_vtxfmt_a(r300ContextPtr rmesa)
{
GLcontext *ctx;
- GLvertexformat *vfmt;
-
- ctx = rmesa->radeon.glCtx;
- vfmt = (GLvertexformat *)ctx->TnlModule.Current;
-
- vfmt->DrawElements = radeonDrawElements;
- vfmt->DrawArrays = radeonDrawArrays;
- vfmt->DrawRangeElements = radeonDrawRangeElements;
+ struct vbo_context *vbo = vbo_context(ctx);
+ vbo->draw_prims = radeon_draw_prims;
}
+
#endif
#ifdef HW_VBOS
diff --git a/src/mesa/drivers/dri/radeon/Makefile b/src/mesa/drivers/dri/radeon/Makefile
index 6e46620b397..f223b2d9228 100644
--- a/src/mesa/drivers/dri/radeon/Makefile
+++ b/src/mesa/drivers/dri/radeon/Makefile
@@ -22,11 +22,7 @@ DRIVER_SOURCES = \
radeon_swtcl.c \
radeon_span.c \
radeon_maos.c \
- radeon_sanity.c \
- radeon_vtxfmt.c \
- radeon_vtxfmt_c.c \
- radeon_vtxfmt_sse.c \
- radeon_vtxfmt_x86.c
+ radeon_sanity.c
C_SOURCES = \
$(COMMON_SOURCES) \
@@ -34,8 +30,7 @@ C_SOURCES = \
DRIVER_DEFINES = -DRADEON_COMMON=0
-X86_SOURCES = \
- radeon_vtxtmp_x86.S
+X86_SOURCES =
include ../Makefile.template
diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c
index 8b92e3fe65f..6bc2c4aa5c5 100644
--- a/src/mesa/drivers/dri/radeon/radeon_context.c
+++ b/src/mesa/drivers/dri/radeon/radeon_context.c
@@ -46,7 +46,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
@@ -60,7 +60,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "radeon_tex.h"
#include "radeon_swtcl.h"
#include "radeon_tcl.h"
-#include "radeon_vtxfmt.h"
#include "radeon_maos.h"
#define need_GL_ARB_multisample
@@ -361,7 +360,7 @@ radeonCreateContext( const __GLcontextModes *glVisual,
/* Initialize the software rasterizer and helper modules.
*/
_swrast_CreateContext( ctx );
- _ac_CreateContext( ctx );
+ _vbo_CreateContext( ctx );
_tnl_CreateContext( ctx );
_swsetup_CreateContext( ctx );
_ae_create_context( ctx );
@@ -370,13 +369,10 @@ radeonCreateContext( const __GLcontextModes *glVisual,
*/
_tnl_destroy_pipeline( ctx );
_tnl_install_pipeline( ctx, radeon_pipeline );
- ctx->Driver.FlushVertices = radeonFlushVertices;
/* Try and keep materials and vertices separate:
*/
- _tnl_isolate_materials( ctx, GL_TRUE );
-
-/* _mesa_allow_light_in_model( ctx, GL_FALSE ); */
+/* _tnl_isolate_materials( ctx, GL_TRUE ); */
/* Configure swrast and T&L to match hardware characteristics:
*/
@@ -450,10 +446,7 @@ radeonCreateContext( const __GLcontextModes *glVisual,
}
if (rmesa->radeonScreen->chip_flags & RADEON_CHIPSET_TCL) {
- if (tcl_mode >= DRI_CONF_TCL_VTXFMT)
- radeonVtxfmtInit( ctx, tcl_mode >= DRI_CONF_TCL_CODEGEN );
-
- _tnl_need_dlist_norm_lengths( ctx, GL_FALSE );
+/* _tnl_need_dlist_norm_lengths( ctx, GL_FALSE ); */
}
return GL_TRUE;
}
@@ -484,7 +477,7 @@ void radeonDestroyContext( __DRIcontextPrivate *driContextPriv )
release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1);
_swsetup_DestroyContext( rmesa->glCtx );
_tnl_DestroyContext( rmesa->glCtx );
- _ac_DestroyContext( rmesa->glCtx );
+ _vbo_DestroyContext( rmesa->glCtx );
_swrast_DestroyContext( rmesa->glCtx );
radeonDestroySwtcl( rmesa->glCtx );
@@ -494,12 +487,6 @@ void radeonDestroyContext( __DRIcontextPrivate *driContextPriv )
radeonFlushCmdBuf( rmesa, __FUNCTION__ );
}
- if (!(rmesa->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE)) {
- int tcl_mode = driQueryOptioni(&rmesa->optionCache, "tcl_mode");
- if (tcl_mode >= DRI_CONF_TCL_VTXFMT)
- radeonVtxfmtDestroy( rmesa->glCtx );
- }
-
_mesa_vector4f_free( &rmesa->tcl.ObjClean );
if (rmesa->state.scissor.pClipRects) {
@@ -621,9 +608,6 @@ radeonMakeCurrent( __DRIcontextPrivate *driContextPriv,
(GLframebuffer *) driDrawPriv->driverPrivate,
(GLframebuffer *) driReadPriv->driverPrivate );
- if (newCtx->vb.enabled)
- radeonVtxfmtMakeCurrent( newCtx->glCtx );
-
} else {
if (RADEON_DEBUG & DEBUG_DRI)
fprintf(stderr, "%s ctx is null\n", __FUNCTION__);
diff --git a/src/mesa/drivers/dri/radeon/radeon_context.h b/src/mesa/drivers/dri/radeon/radeon_context.h
index 0a7c3b2f544..02cea2f4e37 100644
--- a/src/mesa/drivers/dri/radeon/radeon_context.h
+++ b/src/mesa/drivers/dri/radeon/radeon_context.h
@@ -529,7 +529,6 @@ struct radeon_store {
*/
struct radeon_tcl_info {
GLuint vertex_format;
- GLint last_offset;
GLuint hw_primitive;
/* Temporary for cases where incoming vertex data is incompatible
@@ -600,75 +599,6 @@ struct radeon_ioctl {
#define RADEON_MAX_PRIMS 64
-/* Want to keep a cache of these around. Each is parameterized by
- * only a single value which has only a small range. Only expect a
- * few, so just rescan the list each time?
- */
-struct dynfn {
- struct dynfn *next, *prev;
- int key;
- char *code;
-};
-
-struct dfn_lists {
- struct dynfn Vertex2f;
- struct dynfn Vertex2fv;
- struct dynfn Vertex3f;
- struct dynfn Vertex3fv;
- struct dynfn Color4ub;
- struct dynfn Color4ubv;
- struct dynfn Color3ub;
- struct dynfn Color3ubv;
- struct dynfn Color4f;
- struct dynfn Color4fv;
- struct dynfn Color3f;
- struct dynfn Color3fv;
- struct dynfn SecondaryColor3ubEXT;
- struct dynfn SecondaryColor3ubvEXT;
- struct dynfn SecondaryColor3fEXT;
- struct dynfn SecondaryColor3fvEXT;
- struct dynfn Normal3f;
- struct dynfn Normal3fv;
- struct dynfn TexCoord2f;
- struct dynfn TexCoord2fv;
- struct dynfn TexCoord1f;
- struct dynfn TexCoord1fv;
- struct dynfn MultiTexCoord2fARB;
- struct dynfn MultiTexCoord2fvARB;
- struct dynfn MultiTexCoord1fARB;
- struct dynfn MultiTexCoord1fvARB;
-};
-
-struct dfn_generators {
- struct dynfn *(*Vertex2f)( GLcontext *, int );
- struct dynfn *(*Vertex2fv)( GLcontext *, int );
- struct dynfn *(*Vertex3f)( GLcontext *, int );
- struct dynfn *(*Vertex3fv)( GLcontext *, int );
- struct dynfn *(*Color4ub)( GLcontext *, int );
- struct dynfn *(*Color4ubv)( GLcontext *, int );
- struct dynfn *(*Color3ub)( GLcontext *, int );
- struct dynfn *(*Color3ubv)( GLcontext *, int );
- struct dynfn *(*Color4f)( GLcontext *, int );
- struct dynfn *(*Color4fv)( GLcontext *, int );
- struct dynfn *(*Color3f)( GLcontext *, int );
- struct dynfn *(*Color3fv)( GLcontext *, int );
- struct dynfn *(*SecondaryColor3ubEXT)( GLcontext *, int );
- struct dynfn *(*SecondaryColor3ubvEXT)( GLcontext *, int );
- struct dynfn *(*SecondaryColor3fEXT)( GLcontext *, int );
- struct dynfn *(*SecondaryColor3fvEXT)( GLcontext *, int );
- struct dynfn *(*Normal3f)( GLcontext *, int );
- struct dynfn *(*Normal3fv)( GLcontext *, int );
- struct dynfn *(*TexCoord2f)( GLcontext *, int );
- struct dynfn *(*TexCoord2fv)( GLcontext *, int );
- struct dynfn *(*TexCoord1f)( GLcontext *, int );
- struct dynfn *(*TexCoord1fv)( GLcontext *, int );
- struct dynfn *(*MultiTexCoord2fARB)( GLcontext *, int );
- struct dynfn *(*MultiTexCoord2fvARB)( GLcontext *, int );
- struct dynfn *(*MultiTexCoord1fARB)( GLcontext *, int );
- struct dynfn *(*MultiTexCoord1fvARB)( GLcontext *, int );
-};
-
-
struct radeon_prim {
GLuint start;
@@ -685,43 +615,6 @@ struct radeon_prim {
*/
#define RADEON_MAX_VERTEX_SIZE 20
-struct radeon_vbinfo {
- GLint counter, initial_counter;
- GLint *dmaptr;
- void (*notify)( void );
- GLint vertex_size;
-
- union { float f; int i; radeon_color_t color; } vertex[RADEON_MAX_VERTEX_SIZE];
-
- GLfloat *normalptr;
- GLfloat *floatcolorptr;
- radeon_color_t *colorptr;
- GLfloat *floatspecptr;
- radeon_color_t *specptr;
- GLfloat *texcoordptr[4]; /* 3 (TMU) + 1 for radeon_vtxfmt_c.c when GL_TEXTURE3 */
-
- GLenum *prim; /* &ctx->Driver.CurrentExecPrimitive */
- GLuint primflags;
- GLboolean enabled; /* *_NO_VTXFMT / *_NO_TCL env vars */
- GLboolean installed;
- GLboolean fell_back;
- GLboolean recheck;
- GLint nrverts;
- GLuint vertex_format;
-
- GLuint installed_vertex_format;
- GLuint installed_color_3f_sz;
-
- struct radeon_prim primlist[RADEON_MAX_PRIMS];
- int nrprims;
-
- struct dfn_lists dfn_cache;
- struct dfn_generators codegen;
- GLvertexformat vtxfmt;
-};
-
-
-
struct radeon_context {
GLcontext *glCtx; /* Mesa context */
@@ -808,10 +701,6 @@ struct radeon_context {
*/
struct radeon_swtcl_info swtcl;
- /* radeon_vtxfmt.c
- */
- struct radeon_vbinfo vb;
-
/* Mirrors of some DRI state
*/
struct radeon_dri_mirror dri;
diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c
index 737490fcde0..4c64bc201ae 100644
--- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c
+++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c
@@ -1087,10 +1087,6 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask )
}
}
- /* Flip top to bottom */
- cx += dPriv->x;
- cy = dPriv->y + dPriv->h - cy - ch;
-
LOCK_HARDWARE( rmesa );
/* compute region after locking: */
@@ -1099,6 +1095,10 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask )
cw = ctx->DrawBuffer->_Xmax - cx;
ch = ctx->DrawBuffer->_Ymax - cy;
+ /* Flip top to bottom */
+ cx += dPriv->x;
+ cy = dPriv->y + dPriv->h - cy - ch;
+
/* Throttle the number of clear ioctls we do.
*/
while ( 1 ) {
diff --git a/src/mesa/drivers/dri/radeon/radeon_maos_verts.c b/src/mesa/drivers/dri/radeon/radeon_maos_verts.c
index 91a60bb9f15..65dbecf7a6c 100644
--- a/src/mesa/drivers/dri/radeon/radeon_maos_verts.c
+++ b/src/mesa/drivers/dri/radeon/radeon_maos_verts.c
@@ -37,7 +37,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "imports.h"
#include "mtypes.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "math/m_translate.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c
index 279357ab590..fc5aa114621 100644
--- a/src/mesa/drivers/dri/radeon/radeon_screen.c
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.c
@@ -55,6 +55,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r200_span.h"
#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
#include "r300_context.h"
+#include "r300_fragprog.h"
#include "radeon_span.h"
#endif
@@ -163,6 +164,18 @@ DRI_CONF_OPT_BEGIN(disable_lowimpact_fallback,bool,def) \
DRI_CONF_DESC(en,"Disable Low-impact fallback") \
DRI_CONF_OPT_END
+#define DRI_CONF_DISABLE_DOUBLE_SIDE_STENCIL(def) \
+DRI_CONF_OPT_BEGIN(disable_stencil_two_side,bool,def) \
+ DRI_CONF_DESC(en,"Disable GL_EXT_stencil_two_side") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_FP_OPTIMIZATION(def) \
+DRI_CONF_OPT_BEGIN_V(fp_optimization,enum,def,"0:1") \
+ DRI_CONF_DESC_BEGIN(en,"Fragment Program optimization") \
+ DRI_CONF_ENUM(0,"Optimize for Speed") \
+ DRI_CONF_ENUM(1,"Optimize for Quality") \
+ DRI_CONF_DESC_END \
+DRI_CONF_OPT_END
const char __driConfigOptions[] =
DRI_CONF_BEGIN
@@ -174,6 +187,7 @@ DRI_CONF_BEGIN
DRI_CONF_MAX_TEXTURE_COORD_UNITS(8, 2, 8)
DRI_CONF_COMMAND_BUFFER_SIZE(8, 8, 32)
DRI_CONF_DISABLE_FALLBACK(false)
+ DRI_CONF_DISABLE_DOUBLE_SIDE_STENCIL(false)
DRI_CONF_SECTION_END
DRI_CONF_SECTION_QUALITY
DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB)
@@ -184,12 +198,13 @@ DRI_CONF_BEGIN
DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER)
DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC)
DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF)
+ DRI_CONF_FP_OPTIMIZATION(DRI_CONF_FP_OPTIMIZATION_SPEED)
DRI_CONF_SECTION_END
DRI_CONF_SECTION_DEBUG
DRI_CONF_NO_RAST(false)
DRI_CONF_SECTION_END
DRI_CONF_END;
-static const GLuint __driNConfigOptions = 16;
+static const GLuint __driNConfigOptions = 18;
#ifndef RADEON_DEBUG
int RADEON_DEBUG = 0;
diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c
index 216d7dca174..e19202fa443 100644
--- a/src/mesa/drivers/dri/radeon/radeon_state.c
+++ b/src/mesa/drivers/dri/radeon/radeon_state.c
@@ -42,7 +42,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "context.h"
#include "framebuffer.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
#include "swrast_setup/swrast_setup.h"
@@ -53,7 +53,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "radeon_tcl.h"
#include "radeon_tex.h"
#include "radeon_swtcl.h"
-#include "radeon_vtxfmt.h"
#include "drirenderbuffer.h"
static void radeonUpdateSpecular( GLcontext *ctx );
@@ -2303,11 +2302,10 @@ static void radeonInvalidateState( GLcontext *ctx, GLuint new_state )
{
_swrast_InvalidateState( ctx, new_state );
_swsetup_InvalidateState( ctx, new_state );
- _ac_InvalidateState( ctx, new_state );
+ _vbo_InvalidateState( ctx, new_state );
_tnl_InvalidateState( ctx, new_state );
_ae_invalidate_state( ctx, new_state );
RADEON_CONTEXT(ctx)->NewGLState |= new_state;
- radeonVtxfmtInvalidate( ctx );
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_state_init.c b/src/mesa/drivers/dri/radeon/radeon_state_init.c
index 5682d95ae10..5fc34f09331 100644
--- a/src/mesa/drivers/dri/radeon/radeon_state_init.c
+++ b/src/mesa/drivers/dri/radeon/radeon_state_init.c
@@ -33,7 +33,7 @@
#include "api_arrayelt.h"
#include "swrast/swrast.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
#include "swrast_setup/swrast_setup.h"
@@ -44,7 +44,6 @@
#include "radeon_tcl.h"
#include "radeon_tex.h"
#include "radeon_swtcl.h"
-#include "radeon_vtxfmt.h"
#include "xmlpool.h"
diff --git a/src/mesa/drivers/dri/radeon/radeon_swtcl.c b/src/mesa/drivers/dri/radeon/radeon_swtcl.c
index e36a710d33a..7ce1fa67cf6 100644
--- a/src/mesa/drivers/dri/radeon/radeon_swtcl.c
+++ b/src/mesa/drivers/dri/radeon/radeon_swtcl.c
@@ -45,7 +45,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "tnl/tnl.h"
#include "tnl/t_context.h"
#include "tnl/t_pipeline.h"
-#include "tnl/t_vtx_api.h" /* for _tnl_FlushVertices */
#include "radeon_context.h"
#include "radeon_ioctl.h"
@@ -848,14 +847,6 @@ void radeonFallback( GLcontext *ctx, GLuint bit, GLboolean mode )
}
-void radeonFlushVertices( GLcontext *ctx, GLuint flags )
-{
- _tnl_FlushVertices( ctx, flags );
-
- if (flags & FLUSH_STORED_VERTICES)
- RADEON_NEWPRIM( RADEON_CONTEXT( ctx ) );
-}
-
/**********************************************************************/
/* Initialization. */
/**********************************************************************/
diff --git a/src/mesa/drivers/dri/radeon/radeon_swtcl.h b/src/mesa/drivers/dri/radeon/radeon_swtcl.h
index f95a52c0b8e..64f9019513d 100644
--- a/src/mesa/drivers/dri/radeon/radeon_swtcl.h
+++ b/src/mesa/drivers/dri/radeon/radeon_swtcl.h
@@ -43,7 +43,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
extern void radeonInitSwtcl( GLcontext *ctx );
extern void radeonDestroySwtcl( GLcontext *ctx );
-extern void radeonFlushVertices( GLcontext *ctx, GLuint flags );
extern void radeonChooseRenderState( GLcontext *ctx );
extern void radeonChooseVertexState( GLcontext *ctx );
diff --git a/src/mesa/drivers/dri/radeon/radeon_tcl.c b/src/mesa/drivers/dri/radeon/radeon_tcl.c
index ffd49b525b8..5ad044c2628 100644
--- a/src/mesa/drivers/dri/radeon/radeon_tcl.c
+++ b/src/mesa/drivers/dri/radeon/radeon_tcl.c
@@ -39,7 +39,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "mtypes.h"
#include "enums.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
diff --git a/src/mesa/drivers/dri/radeon/radeon_vtxfmt.c b/src/mesa/drivers/dri/radeon/radeon_vtxfmt.c
deleted file mode 100644
index a5a9eb144b5..00000000000
--- a/src/mesa/drivers/dri/radeon/radeon_vtxfmt.c
+++ /dev/null
@@ -1,1086 +0,0 @@
-/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c,v 1.6 2003/05/06 23:52:08 daenzer Exp $ */
-/**************************************************************************
-
-Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
- Tungsten Graphics Inc., Cedar Park, Texas.
-
-All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial
-portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Keith Whitwell <[email protected]>
- */
-#include "glheader.h"
-#include "imports.h"
-#include "api_noop.h"
-#include "api_arrayelt.h"
-#include "context.h"
-#include "mtypes.h"
-#include "enums.h"
-#include "glapi.h"
-#include "colormac.h"
-#include "light.h"
-#include "state.h"
-#include "vtxfmt.h"
-
-#include "tnl/tnl.h"
-#include "tnl/t_context.h"
-#include "tnl/t_array_api.h"
-#include "tnl/t_save_api.h"
-
-#include "radeon_context.h"
-#include "radeon_state.h"
-#include "radeon_ioctl.h"
-#include "radeon_tex.h"
-#include "radeon_tcl.h"
-#include "radeon_swtcl.h"
-#include "radeon_vtxfmt.h"
-
-#define VERT_ATTRIB_TEX(u) (VERT_ATTRIB_TEX0 + (u))
-
-#include "dispatch.h"
-
-static void radeonVtxfmtFlushVertices( GLcontext *, GLuint );
-
-static void count_func( const char *name, struct dynfn *l )
-{
- int i = 0;
- struct dynfn *f;
- foreach (f, l) i++;
- if (i) fprintf(stderr, "%s: %d\n", name, i );
-}
-
-static void count_funcs( radeonContextPtr rmesa )
-{
- count_func( "Vertex2f", &rmesa->vb.dfn_cache.Vertex2f );
- count_func( "Vertex2fv", &rmesa->vb.dfn_cache.Vertex2fv );
- count_func( "Vertex3f", &rmesa->vb.dfn_cache.Vertex3f );
- count_func( "Vertex3fv", &rmesa->vb.dfn_cache.Vertex3fv );
- count_func( "Color4ub", &rmesa->vb.dfn_cache.Color4ub );
- count_func( "Color4ubv", &rmesa->vb.dfn_cache.Color4ubv );
- count_func( "Color3ub", &rmesa->vb.dfn_cache.Color3ub );
- count_func( "Color3ubv", &rmesa->vb.dfn_cache.Color3ubv );
- count_func( "Color4f", &rmesa->vb.dfn_cache.Color4f );
- count_func( "Color4fv", &rmesa->vb.dfn_cache.Color4fv );
- count_func( "Color3f", &rmesa->vb.dfn_cache.Color3f );
- count_func( "Color3fv", &rmesa->vb.dfn_cache.Color3fv );
- count_func( "SecondaryColor3f", &rmesa->vb.dfn_cache.SecondaryColor3fEXT );
- count_func( "SecondaryColor3fv", &rmesa->vb.dfn_cache.SecondaryColor3fvEXT );
- count_func( "SecondaryColor3ub", &rmesa->vb.dfn_cache.SecondaryColor3ubEXT );
- count_func( "SecondaryColor3ubv", &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT );
- count_func( "Normal3f", &rmesa->vb.dfn_cache.Normal3f );
- count_func( "Normal3fv", &rmesa->vb.dfn_cache.Normal3fv );
- count_func( "TexCoord2f", &rmesa->vb.dfn_cache.TexCoord2f );
- count_func( "TexCoord2fv", &rmesa->vb.dfn_cache.TexCoord2fv );
- count_func( "TexCoord1f", &rmesa->vb.dfn_cache.TexCoord1f );
- count_func( "TexCoord1fv", &rmesa->vb.dfn_cache.TexCoord1fv );
- count_func( "MultiTexCoord2fARB", &rmesa->vb.dfn_cache.MultiTexCoord2fARB );
- count_func( "MultiTexCoord2fvARB", &rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
- count_func( "MultiTexCoord1fARB", &rmesa->vb.dfn_cache.MultiTexCoord1fARB );
- count_func( "MultiTexCoord1fvARB", &rmesa->vb.dfn_cache.MultiTexCoord1fvARB );
-}
-
-
-void radeon_copy_to_current( GLcontext *ctx )
-{
- GLuint unit;
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-
- assert(ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT);
-
- if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_N0) {
- ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0] = rmesa->vb.normalptr[0];
- ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1] = rmesa->vb.normalptr[1];
- ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2] = rmesa->vb.normalptr[2];
- }
-
- if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_PKCOLOR) {
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->red );
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->green );
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->blue );
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->alpha );
- }
-
- if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_FPCOLOR) {
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] = rmesa->vb.floatcolorptr[0];
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] = rmesa->vb.floatcolorptr[1];
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] = rmesa->vb.floatcolorptr[2];
- }
-
- if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_FPALPHA)
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = rmesa->vb.floatcolorptr[3];
-
- if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_PKSPEC) {
- ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0] = UBYTE_TO_FLOAT( rmesa->vb.specptr->red );
- ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1] = UBYTE_TO_FLOAT( rmesa->vb.specptr->green );
- ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2] = UBYTE_TO_FLOAT( rmesa->vb.specptr->blue );
- }
-
- for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
- if (rmesa->vb.vertex_format & RADEON_ST_BIT(unit)) {
- ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][0] = rmesa->vb.texcoordptr[unit][0];
- ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][1] = rmesa->vb.texcoordptr[unit][1];
- ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][2] = 0.0F;
- ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][3] = 1.0F;
- }
- }
-
- ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT;
-}
-
-static GLboolean discreet_gl_prim[GL_POLYGON+1] = {
- 1, /* 0 points */
- 1, /* 1 lines */
- 0, /* 2 line_strip */
- 0, /* 3 line_loop */
- 1, /* 4 tris */
- 0, /* 5 tri_fan */
- 0, /* 6 tri_strip */
- 1, /* 7 quads */
- 0, /* 8 quadstrip */
- 0, /* 9 poly */
-};
-
-static void flush_prims( radeonContextPtr rmesa )
-{
- int i,j;
- struct radeon_dma_region tmp = rmesa->dma.current;
-
- tmp.buf->refcount++;
- tmp.aos_size = rmesa->vb.vertex_size;
- tmp.aos_stride = rmesa->vb.vertex_size;
- tmp.aos_start = GET_START(&tmp);
-
- rmesa->dma.current.ptr = rmesa->dma.current.start +=
- (rmesa->vb.initial_counter - rmesa->vb.counter) * rmesa->vb.vertex_size * 4;
-
- rmesa->tcl.vertex_format = rmesa->vb.vertex_format;
- rmesa->tcl.aos_components[0] = &tmp;
- rmesa->tcl.nr_aos_components = 1;
- rmesa->dma.flush = NULL;
-
- /* Optimize the primitive list:
- */
- if (rmesa->vb.nrprims > 1) {
- for (j = 0, i = 1 ; i < rmesa->vb.nrprims; i++) {
- int pj = rmesa->vb.primlist[j].prim & 0xf;
- int pi = rmesa->vb.primlist[i].prim & 0xf;
-
- if (pj == pi && discreet_gl_prim[pj] &&
- rmesa->vb.primlist[i].start == rmesa->vb.primlist[j].end) {
- rmesa->vb.primlist[j].end = rmesa->vb.primlist[i].end;
- }
- else {
- j++;
- if (j != i) rmesa->vb.primlist[j] = rmesa->vb.primlist[i];
- }
- }
- rmesa->vb.nrprims = j+1;
- }
-
- for (i = 0 ; i < rmesa->vb.nrprims; i++) {
- if (RADEON_DEBUG & DEBUG_PRIMS)
- fprintf(stderr, "vtxfmt prim %d: %s %d..%d\n", i,
- _mesa_lookup_enum_by_nr( rmesa->vb.primlist[i].prim &
- PRIM_MODE_MASK ),
- rmesa->vb.primlist[i].start,
- rmesa->vb.primlist[i].end);
-
- radeonEmitPrimitive( rmesa->glCtx,
- rmesa->vb.primlist[i].start,
- rmesa->vb.primlist[i].end,
- rmesa->vb.primlist[i].prim );
- }
-
- rmesa->vb.nrprims = 0;
- radeonReleaseDmaRegion( rmesa, &tmp, __FUNCTION__ );
-}
-
-
-static void start_prim( radeonContextPtr rmesa, GLuint mode )
-{
- if (RADEON_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s %d\n", __FUNCTION__, rmesa->vb.initial_counter - rmesa->vb.counter);
-
- rmesa->vb.primlist[rmesa->vb.nrprims].start = rmesa->vb.initial_counter - rmesa->vb.counter;
- rmesa->vb.primlist[rmesa->vb.nrprims].prim = mode;
-}
-
-static void note_last_prim( radeonContextPtr rmesa, GLuint flags )
-{
- if (RADEON_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s %d\n", __FUNCTION__, rmesa->vb.initial_counter - rmesa->vb.counter);
-
- if (rmesa->vb.prim[0] != GL_POLYGON+1) {
- rmesa->vb.primlist[rmesa->vb.nrprims].prim |= flags;
- rmesa->vb.primlist[rmesa->vb.nrprims].end = rmesa->vb.initial_counter - rmesa->vb.counter;
-
- if (++(rmesa->vb.nrprims) == RADEON_MAX_PRIMS)
- flush_prims( rmesa );
- }
-}
-
-
-static void copy_vertex( radeonContextPtr rmesa, GLuint n, GLfloat *dst )
-{
- GLuint i;
- GLfloat *src = (GLfloat *)(rmesa->dma.current.address +
- rmesa->dma.current.ptr +
- (rmesa->vb.primlist[rmesa->vb.nrprims].start + n) *
- rmesa->vb.vertex_size * 4);
-
- if (RADEON_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "copy_vertex %d\n", rmesa->vb.primlist[rmesa->vb.nrprims].start + n);
-
- for (i = 0 ; i < rmesa->vb.vertex_size; i++) {
- dst[i] = src[i];
- }
-}
-
-/* NOTE: This actually reads the copied vertices back from uncached
- * memory. Could also use the counter/notify mechanism to populate
- * tmp on the fly as vertices are generated.
- */
-static GLuint copy_dma_verts( radeonContextPtr rmesa, GLfloat (*tmp)[RADEON_MAX_VERTEX_SIZE] )
-{
- GLuint ovf, i;
- GLuint nr = (rmesa->vb.initial_counter - rmesa->vb.counter) - rmesa->vb.primlist[rmesa->vb.nrprims].start;
-
- if (RADEON_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s %d verts\n", __FUNCTION__, nr);
-
- switch( rmesa->vb.prim[0] )
- {
- case GL_POINTS:
- return 0;
- case GL_LINES:
- ovf = nr&1;
- for (i = 0 ; i < ovf ; i++)
- copy_vertex( rmesa, nr-ovf+i, tmp[i] );
- return i;
- case GL_TRIANGLES:
- ovf = nr%3;
- for (i = 0 ; i < ovf ; i++)
- copy_vertex( rmesa, nr-ovf+i, tmp[i] );
- return i;
- case GL_QUADS:
- ovf = nr&3;
- for (i = 0 ; i < ovf ; i++)
- copy_vertex( rmesa, nr-ovf+i, tmp[i] );
- return i;
- case GL_LINE_STRIP:
- if (nr == 0)
- return 0;
- copy_vertex( rmesa, nr-1, tmp[0] );
- return 1;
- case GL_LINE_LOOP:
- case GL_TRIANGLE_FAN:
- case GL_POLYGON:
- if (nr == 0)
- return 0;
- else if (nr == 1) {
- copy_vertex( rmesa, 0, tmp[0] );
- return 1;
- } else {
- copy_vertex( rmesa, 0, tmp[0] );
- copy_vertex( rmesa, nr-1, tmp[1] );
- return 2;
- }
- case GL_TRIANGLE_STRIP:
- ovf = MIN2(nr, 2);
- for (i = 0 ; i < ovf ; i++)
- copy_vertex( rmesa, nr-ovf+i, tmp[i] );
- return i;
- case GL_QUAD_STRIP:
- switch (nr) {
- case 0: ovf = 0; break;
- case 1: ovf = 1; break;
- default: ovf = 2 + (nr&1); break;
- }
- for (i = 0 ; i < ovf ; i++)
- copy_vertex( rmesa, nr-ovf+i, tmp[i] );
- return i;
- default:
- assert(0);
- return 0;
- }
-}
-
-static void VFMT_FALLBACK_OUTSIDE_BEGIN_END( const char *caller )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-
- if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_FALLBACKS))
- fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
-
- if (ctx->Driver.NeedFlush)
- radeonVtxfmtFlushVertices( ctx, ctx->Driver.NeedFlush );
-
- if (ctx->NewState)
- _mesa_update_state( ctx ); /* clear state so fell_back sticks */
-
- _tnl_wakeup_exec( ctx );
- ctx->Driver.FlushVertices = radeonFlushVertices;
- ctx->Driver.NewList =_tnl_NewList;
-
- assert( rmesa->dma.flush == 0 );
- rmesa->vb.fell_back = GL_TRUE;
- rmesa->vb.installed = GL_FALSE;
-}
-
-
-static void VFMT_FALLBACK( const char *caller )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat tmp[3][RADEON_MAX_VERTEX_SIZE];
- GLuint i, prim;
- GLuint ind = rmesa->vb.vertex_format;
- GLuint nrverts;
- GLfloat alpha = 1.0;
- GLuint unit;
-
- if (RADEON_DEBUG & (DEBUG_FALLBACKS|DEBUG_VFMT))
- fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
-
- if (rmesa->vb.prim[0] == GL_POLYGON+1) {
- VFMT_FALLBACK_OUTSIDE_BEGIN_END( __FUNCTION__ );
- return;
- }
-
- /* Copy vertices out of dma:
- */
- nrverts = copy_dma_verts( rmesa, tmp );
-
- /* Finish the prim at this point:
- */
- note_last_prim( rmesa, 0 );
- flush_prims( rmesa );
-
- /* Update ctx->Driver.CurrentExecPrimitive and swap in swtnl.
- */
- prim = rmesa->vb.prim[0];
- ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1;
- _tnl_wakeup_exec( ctx );
- ctx->Driver.FlushVertices = radeonFlushVertices;
-
- assert(rmesa->dma.flush == 0);
- rmesa->vb.fell_back = GL_TRUE;
- rmesa->vb.installed = GL_FALSE;
- CALL_Begin(GET_DISPATCH(), (prim));
-
- if (rmesa->vb.installed_color_3f_sz == 4)
- alpha = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3];
-
- /* Replay saved vertices
- */
- for (i = 0 ; i < nrverts; i++) {
- GLuint offset = 3;
- if (ind & RADEON_CP_VC_FRMT_N0) {
- CALL_Normal3fv(GET_DISPATCH(), (&tmp[i][offset]));
- offset += 3;
- }
-
- if (ind & RADEON_CP_VC_FRMT_PKCOLOR) {
- radeon_color_t *col = (radeon_color_t *)&tmp[i][offset];
- CALL_Color4ub(GET_DISPATCH(), (col->red, col->green, col->blue, col->alpha));
- offset++;
- }
- else if (ind & RADEON_CP_VC_FRMT_FPALPHA) {
- CALL_Color4fv(GET_DISPATCH(), (&tmp[i][offset]));
- offset+=4;
- }
- else if (ind & RADEON_CP_VC_FRMT_FPCOLOR) {
- CALL_Color3fv(GET_DISPATCH(), (&tmp[i][offset]));
- offset+=3;
- }
-
- if (ind & RADEON_CP_VC_FRMT_PKSPEC) {
- radeon_color_t *spec = (radeon_color_t *)&tmp[i][offset];
- CALL_SecondaryColor3ubEXT(GET_DISPATCH(), (spec->red, spec->green, spec->blue));
- offset++;
- }
-
- for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
- if (ind & RADEON_ST_BIT(unit)) {
- CALL_MultiTexCoord2fvARB(GET_DISPATCH(), ((GL_TEXTURE0 + unit), &tmp[i][offset]));
- offset += 2;
- }
- }
- CALL_Vertex3fv(GET_DISPATCH(), (&tmp[i][0]));
- }
-
- /* Replay current vertex
- */
- if (ind & RADEON_CP_VC_FRMT_N0)
- CALL_Normal3fv(GET_DISPATCH(), (rmesa->vb.normalptr));
-
- if (ind & RADEON_CP_VC_FRMT_PKCOLOR)
- CALL_Color4ub(GET_DISPATCH(), (rmesa->vb.colorptr->red, rmesa->vb.colorptr->green,
- rmesa->vb.colorptr->blue, rmesa->vb.colorptr->alpha));
- else if (ind & RADEON_CP_VC_FRMT_FPALPHA)
- CALL_Color4fv(GET_DISPATCH(), (rmesa->vb.floatcolorptr));
- else if (ind & RADEON_CP_VC_FRMT_FPCOLOR) {
- if (rmesa->vb.installed_color_3f_sz == 4 && alpha != 1.0)
- CALL_Color4f(GET_DISPATCH(), (rmesa->vb.floatcolorptr[0],
- rmesa->vb.floatcolorptr[1],
- rmesa->vb.floatcolorptr[2],
- alpha));
- else
- CALL_Color3fv(GET_DISPATCH(), (rmesa->vb.floatcolorptr));
- }
-
- if (ind & RADEON_CP_VC_FRMT_PKSPEC)
- CALL_SecondaryColor3ubEXT(GET_DISPATCH(), (rmesa->vb.specptr->red,
- rmesa->vb.specptr->green,
- rmesa->vb.specptr->blue));
-
- for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
- if (ind & RADEON_ST_BIT(unit)) {
- CALL_MultiTexCoord2fvARB(GET_DISPATCH(), ((GL_TEXTURE0 + unit),
- rmesa->vb.texcoordptr[unit]));
- }
- }
-}
-
-static void radeonNewList( GLcontext *ctx, GLuint list, GLenum mode )
-{
- VFMT_FALLBACK( __FUNCTION__ );
- _tnl_NewList( ctx, list, mode );
- return;
-}
-
-
-static void wrap_buffer( void )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat tmp[3][RADEON_MAX_VERTEX_SIZE];
- GLuint i, nrverts;
-
- if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_PRIMS))
- fprintf(stderr, "%s %d\n", __FUNCTION__, rmesa->vb.initial_counter - rmesa->vb.counter);
-
- /* Don't deal with parity.
- */
- if ((((rmesa->vb.initial_counter - rmesa->vb.counter) -
- rmesa->vb.primlist[rmesa->vb.nrprims].start) & 1)) {
- rmesa->vb.counter++;
- rmesa->vb.initial_counter++;
- return;
- }
-
- /* Copy vertices out of dma:
- */
- if (rmesa->vb.prim[0] == GL_POLYGON+1)
- nrverts = 0;
- else {
- nrverts = copy_dma_verts( rmesa, tmp );
-
- if (RADEON_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%d vertices to copy\n", nrverts);
-
- /* Finish the prim at this point:
- */
- note_last_prim( rmesa, 0 );
- }
-
- /* Fire any buffered primitives
- */
- flush_prims( rmesa );
-
- /* Get new buffer
- */
- radeonRefillCurrentDmaRegion( rmesa );
-
- /* Reset counter, dmaptr
- */
- rmesa->vb.dmaptr = (int *)(rmesa->dma.current.ptr + rmesa->dma.current.address);
- rmesa->vb.counter = (rmesa->dma.current.end - rmesa->dma.current.ptr) /
- (rmesa->vb.vertex_size * 4);
- rmesa->vb.counter--;
- rmesa->vb.initial_counter = rmesa->vb.counter;
- rmesa->vb.notify = wrap_buffer;
-
- rmesa->dma.flush = flush_prims;
-
- /* Restart wrapped primitive:
- */
- if (rmesa->vb.prim[0] != GL_POLYGON+1)
- start_prim( rmesa, rmesa->vb.prim[0] );
-
- /* Reemit saved vertices
- */
- for (i = 0 ; i < nrverts; i++) {
- if (RADEON_DEBUG & DEBUG_VERTS) {
- int j;
- fprintf(stderr, "re-emit vertex %d to %p\n", i, (void *)rmesa->vb.dmaptr);
- if (RADEON_DEBUG & DEBUG_VERBOSE)
- for (j = 0 ; j < rmesa->vb.vertex_size; j++)
- fprintf(stderr, "\t%08x/%f\n", *(int*)&tmp[i][j], tmp[i][j]);
- }
-
- memcpy( rmesa->vb.dmaptr, tmp[i], rmesa->vb.vertex_size * 4 );
- rmesa->vb.dmaptr += rmesa->vb.vertex_size;
- rmesa->vb.counter--;
- }
-}
-
-
-
-static GLboolean check_vtx_fmt( GLcontext *ctx )
-{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLuint ind = RADEON_CP_VC_FRMT_Z;
- GLuint unit;
-
- if (rmesa->TclFallback || rmesa->vb.fell_back || ctx->CompileFlag ||
- (ctx->Fog.Enabled && (ctx->Fog.FogCoordinateSource == GL_FOG_COORD)))
- return GL_FALSE;
-
- if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT)
- ctx->Driver.FlushVertices( ctx, FLUSH_UPDATE_CURRENT );
-
- /* Make all this event-driven:
- */
- if (ctx->Light.Enabled) {
- ind |= RADEON_CP_VC_FRMT_N0;
-
- /* TODO: make this data driven: If we receive only ubytes, send
- * color as ubytes. Also check if converting (with free
- * checking for overflow) is cheaper than sending floats
- * directly.
- */
- if (ctx->Light.ColorMaterialEnabled) {
- ind |= (RADEON_CP_VC_FRMT_FPCOLOR |
- RADEON_CP_VC_FRMT_FPALPHA);
- }
- else
- ind |= RADEON_CP_VC_FRMT_PKCOLOR; /* for alpha? */
- }
- else {
- /* TODO: make this data driven?
- */
- ind |= RADEON_CP_VC_FRMT_PKCOLOR;
-
- if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
- ind |= RADEON_CP_VC_FRMT_PKSPEC;
- }
- }
-
- if ( ctx->Fog.FogCoordinateSource == GL_FOG_COORD ) {
- ind |= RADEON_CP_VC_FRMT_PKSPEC;
- }
-
- for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
- if (ctx->Texture.Unit[unit]._ReallyEnabled) {
- if (ctx->Texture.Unit[unit].TexGenEnabled) {
- if (rmesa->TexGenNeedNormals[unit]) {
- ind |= RADEON_CP_VC_FRMT_N0;
- }
- } else {
- if (ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][3] != 1.0) {
- if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_FALLBACKS))
- fprintf(stderr, "%s: q%u\n", __FUNCTION__, unit);
- return GL_FALSE;
- }
- ind |= RADEON_ST_BIT(unit);
- }
- }
- }
-
- if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_STATE))
- fprintf(stderr, "%s: format: 0x%x\n", __FUNCTION__, ind );
-
- RADEON_NEWPRIM(rmesa);
- rmesa->vb.vertex_format = ind;
- rmesa->vb.vertex_size = 3;
- rmesa->vb.prim = &ctx->Driver.CurrentExecPrimitive;
-
- rmesa->vb.normalptr = ctx->Current.Attrib[VERT_ATTRIB_NORMAL];
- rmesa->vb.colorptr = NULL;
- rmesa->vb.floatcolorptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
- rmesa->vb.specptr = NULL;
- rmesa->vb.floatspecptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR1];
- rmesa->vb.texcoordptr[0] = ctx->Current.Attrib[VERT_ATTRIB_TEX0];
- rmesa->vb.texcoordptr[1] = ctx->Current.Attrib[VERT_ATTRIB_TEX1];
- rmesa->vb.texcoordptr[2] = ctx->Current.Attrib[VERT_ATTRIB_TEX2];
- rmesa->vb.texcoordptr[3] = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; /* dummy */
-
- /* Run through and initialize the vertex components in the order
- * the hardware understands:
- */
- if (ind & RADEON_CP_VC_FRMT_N0) {
- rmesa->vb.normalptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f;
- rmesa->vb.vertex_size += 3;
- rmesa->vb.normalptr[0] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0];
- rmesa->vb.normalptr[1] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1];
- rmesa->vb.normalptr[2] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2];
- }
-
- if (ind & RADEON_CP_VC_FRMT_PKCOLOR) {
- rmesa->vb.colorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].color;
- rmesa->vb.vertex_size += 1;
- UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->red, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] );
- UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->green, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] );
- UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->blue, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] );
- UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->alpha, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] );
- }
-
- if (ind & RADEON_CP_VC_FRMT_FPCOLOR) {
- assert(!(ind & RADEON_CP_VC_FRMT_PKCOLOR));
- rmesa->vb.floatcolorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f;
- rmesa->vb.vertex_size += 3;
- rmesa->vb.floatcolorptr[0] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0];
- rmesa->vb.floatcolorptr[1] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1];
- rmesa->vb.floatcolorptr[2] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2];
-
- if (ind & RADEON_CP_VC_FRMT_FPALPHA) {
- rmesa->vb.vertex_size += 1;
- rmesa->vb.floatcolorptr[3] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3];
- }
- }
-
- if (ind & RADEON_CP_VC_FRMT_PKSPEC) {
- rmesa->vb.specptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].color;
- rmesa->vb.vertex_size += 1;
- UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->red, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0] );
- UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->green, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1] );
- UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->blue, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2] );
- /* fog ??? */
-/* UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->alpha,
- radeonComputeFogFactor(ctx->Current.Attrib[VERT_ATTRIB_FOG][0]) ); */
- }
-
- for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
- if (ind & RADEON_ST_BIT(unit)) {
- rmesa->vb.texcoordptr[unit] = &rmesa->vb.vertex[rmesa->vb.vertex_size].f;
- rmesa->vb.vertex_size += 2;
- rmesa->vb.texcoordptr[unit][0] = ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][0];
- rmesa->vb.texcoordptr[unit][1] = ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][1];
- }
- }
-
- if (rmesa->vb.installed_vertex_format != rmesa->vb.vertex_format) {
- if (RADEON_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "reinstall on vertex_format change\n");
- _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt );
- rmesa->vb.installed_vertex_format = rmesa->vb.vertex_format;
- }
-
- if (RADEON_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s -- success\n", __FUNCTION__);
-
- return GL_TRUE;
-}
-
-void radeonVtxfmtInvalidate( GLcontext *ctx )
-{
- radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
-
- rmesa->vb.recheck = GL_TRUE;
- rmesa->vb.fell_back = GL_FALSE;
-}
-
-
-static void radeonVtxfmtValidate( GLcontext *ctx )
-{
- radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
-
- if (RADEON_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s\n", __FUNCTION__);
-
- if (ctx->Driver.NeedFlush)
- ctx->Driver.FlushVertices( ctx, ctx->Driver.NeedFlush );
-
- rmesa->vb.recheck = GL_FALSE;
-
- if (check_vtx_fmt( ctx )) {
- if (!rmesa->vb.installed) {
- if (RADEON_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "reinstall (new install)\n");
-
- _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt );
- ctx->Driver.FlushVertices = radeonVtxfmtFlushVertices;
- ctx->Driver.NewList = radeonNewList;
- rmesa->vb.installed = GL_TRUE;
- }
- else if (RADEON_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s: already installed", __FUNCTION__);
- }
- else {
- if (RADEON_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s: failed\n", __FUNCTION__);
-
- if (rmesa->vb.installed) {
- if (rmesa->dma.flush)
- rmesa->dma.flush( rmesa );
- _tnl_wakeup_exec( ctx );
- ctx->Driver.FlushVertices = radeonFlushVertices;
- ctx->Driver.NewList =_tnl_NewList;
- rmesa->vb.installed = GL_FALSE;
- }
- }
-}
-
-
-
-/* Materials:
- */
-static void radeon_Materialfv( GLenum face, GLenum pname,
- const GLfloat *params )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
-
- if (RADEON_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s\n", __FUNCTION__);
-
- if (rmesa->vb.prim[0] != GL_POLYGON+1) {
- VFMT_FALLBACK( __FUNCTION__ );
- CALL_Materialfv(GET_DISPATCH(), (face, pname, params));
- return;
- }
- _mesa_noop_Materialfv( face, pname, params );
- radeonUpdateMaterial( ctx );
-}
-
-
-/* Begin/End
- */
-static void radeon_Begin( GLenum mode )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-
- if (RADEON_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s( %s )\n", __FUNCTION__,
- _mesa_lookup_enum_by_nr( mode ));
-
- if (mode > GL_POLYGON) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glBegin" );
- return;
- }
-
- if (rmesa->vb.prim[0] != GL_POLYGON+1) {
- _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" );
- return;
- }
-
- if (ctx->NewState)
- _mesa_update_state( ctx );
-
- if (rmesa->NewGLState)
- radeonValidateState( ctx );
-
- if (rmesa->vb.recheck)
- radeonVtxfmtValidate( ctx );
-
- if (!rmesa->vb.installed) {
- CALL_Begin(GET_DISPATCH(), (mode));
- return;
- }
-
-
- if (rmesa->dma.flush && rmesa->vb.counter < 12) {
- if (RADEON_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s: flush almost-empty buffers\n", __FUNCTION__);
- flush_prims( rmesa );
- }
-
- /* Need to arrange to save vertices here? Or always copy from dma (yuk)?
- */
- if (!rmesa->dma.flush) {
-/* FIXME: what are these constants? */
- if (rmesa->dma.current.ptr + 12*rmesa->vb.vertex_size*4 >
- rmesa->dma.current.end) {
- RADEON_NEWPRIM( rmesa );
- radeonRefillCurrentDmaRegion( rmesa );
- }
-
- rmesa->vb.dmaptr = (int *)(rmesa->dma.current.address + rmesa->dma.current.ptr);
- rmesa->vb.counter = (rmesa->dma.current.end - rmesa->dma.current.ptr) /
- (rmesa->vb.vertex_size * 4);
- rmesa->vb.counter--;
- rmesa->vb.initial_counter = rmesa->vb.counter;
- rmesa->vb.notify = wrap_buffer;
- rmesa->dma.flush = flush_prims;
- ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
- }
-
-
- rmesa->vb.prim[0] = mode;
- start_prim( rmesa, mode | PRIM_BEGIN );
-}
-
-
-
-static void radeon_End( void )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-
- if (RADEON_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s\n", __FUNCTION__);
-
- if (rmesa->vb.prim[0] == GL_POLYGON+1) {
- _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" );
- return;
- }
-
- note_last_prim( rmesa, PRIM_END );
- rmesa->vb.prim[0] = GL_POLYGON+1;
-}
-
-
-/* Fallback on difficult entrypoints:
- */
-#define PRE_LOOPBACK( FUNC ) \
-do { \
- if (RADEON_DEBUG & DEBUG_VFMT) \
- fprintf(stderr, "%s\n", __FUNCTION__); \
- VFMT_FALLBACK( __FUNCTION__ ); \
-} while (0)
-#define TAG(x) radeon_fallback_##x
-#include "vtxfmt_tmp.h"
-
-
-
-static GLboolean radeonNotifyBegin( GLcontext *ctx, GLenum p )
-{
- radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
-
- if (RADEON_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s\n", __FUNCTION__);
-
- assert(!rmesa->vb.installed);
-
- if (ctx->NewState)
- _mesa_update_state( ctx );
-
- if (rmesa->NewGLState)
- radeonValidateState( ctx );
-
- if (ctx->Driver.NeedFlush)
- ctx->Driver.FlushVertices( ctx, ctx->Driver.NeedFlush );
-
- if (rmesa->vb.recheck)
- radeonVtxfmtValidate( ctx );
-
- if (!rmesa->vb.installed) {
- if (RADEON_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s -- failed\n", __FUNCTION__);
- return GL_FALSE;
- }
-
- radeon_Begin( p );
- return GL_TRUE;
-}
-
-static void radeonVtxfmtFlushVertices( GLcontext *ctx, GLuint flags )
-{
- radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
-
- if (RADEON_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "%s\n", __FUNCTION__);
-
- assert(rmesa->vb.installed);
-
- if (flags & FLUSH_UPDATE_CURRENT) {
- radeon_copy_to_current( ctx );
- if (RADEON_DEBUG & DEBUG_VFMT)
- fprintf(stderr, "reinstall on update_current\n");
- _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt );
- ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT;
- }
-
- if (flags & FLUSH_STORED_VERTICES) {
- radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
- assert (rmesa->dma.flush == 0 ||
- rmesa->dma.flush == flush_prims);
- if (rmesa->dma.flush == flush_prims)
- flush_prims( RADEON_CONTEXT( ctx ) );
- ctx->Driver.NeedFlush &= ~FLUSH_STORED_VERTICES;
- }
-}
-
-
-
-/* At this point, don't expect very many versions of each function to
- * be generated, so not concerned about freeing them?
- */
-
-
-void radeonVtxfmtInit( GLcontext *ctx, GLboolean useCodegen )
-{
- radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
- GLvertexformat *vfmt = &(rmesa->vb.vtxfmt);
-
- /* start by initializing to no-op functions */
- _mesa_noop_vtxfmt_init(vfmt);
-
- /* Hook in chooser functions for codegen, etc:
- */
- radeonVtxfmtInitChoosers( vfmt );
-
- /* Handled fully in supported states, but no codegen:
- */
- vfmt->Materialfv = radeon_Materialfv;
- vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */
- vfmt->Begin = radeon_Begin;
- vfmt->End = radeon_End;
-
- /* Fallback for performance reasons: (Fix with cva/elt path here and
- * dmatmp2.h style primitive-merging)
- *
- * These should call NotifyBegin(), as should _tnl_EvalMesh, to allow
- * a driver-hook.
- */
- vfmt->DrawArrays = radeon_fallback_DrawArrays;
- vfmt->DrawElements = radeon_fallback_DrawElements;
- vfmt->DrawRangeElements = radeon_fallback_DrawRangeElements;
-
- /* Active but unsupported -- fallback if we receive these:
- */
- vfmt->CallList = radeon_fallback_CallList;
- vfmt->CallLists = radeon_fallback_CallLists;
- vfmt->EvalCoord1f = radeon_fallback_EvalCoord1f;
- vfmt->EvalCoord1fv = radeon_fallback_EvalCoord1fv;
- vfmt->EvalCoord2f = radeon_fallback_EvalCoord2f;
- vfmt->EvalCoord2fv = radeon_fallback_EvalCoord2fv;
- vfmt->EvalMesh1 = radeon_fallback_EvalMesh1;
- vfmt->EvalMesh2 = radeon_fallback_EvalMesh2;
- vfmt->EvalPoint1 = radeon_fallback_EvalPoint1;
- vfmt->EvalPoint2 = radeon_fallback_EvalPoint2;
- vfmt->TexCoord3f = radeon_fallback_TexCoord3f;
- vfmt->TexCoord3fv = radeon_fallback_TexCoord3fv;
- vfmt->TexCoord4f = radeon_fallback_TexCoord4f;
- vfmt->TexCoord4fv = radeon_fallback_TexCoord4fv;
- vfmt->MultiTexCoord3fARB = radeon_fallback_MultiTexCoord3fARB;
- vfmt->MultiTexCoord3fvARB = radeon_fallback_MultiTexCoord3fvARB;
- vfmt->MultiTexCoord4fARB = radeon_fallback_MultiTexCoord4fARB;
- vfmt->MultiTexCoord4fvARB = radeon_fallback_MultiTexCoord4fvARB;
- vfmt->Vertex4f = radeon_fallback_Vertex4f;
- vfmt->Vertex4fv = radeon_fallback_Vertex4fv;
- vfmt->VertexAttrib1fNV = radeon_fallback_VertexAttrib1fNV;
- vfmt->VertexAttrib1fvNV = radeon_fallback_VertexAttrib1fvNV;
- vfmt->VertexAttrib2fNV = radeon_fallback_VertexAttrib2fNV;
- vfmt->VertexAttrib2fvNV = radeon_fallback_VertexAttrib2fvNV;
- vfmt->VertexAttrib3fNV = radeon_fallback_VertexAttrib3fNV;
- vfmt->VertexAttrib3fvNV = radeon_fallback_VertexAttrib3fvNV;
- vfmt->VertexAttrib4fNV = radeon_fallback_VertexAttrib4fNV;
- vfmt->VertexAttrib4fvNV = radeon_fallback_VertexAttrib4fvNV;
- vfmt->FogCoordfEXT = radeon_fallback_FogCoordfEXT;
- vfmt->FogCoordfvEXT = radeon_fallback_FogCoordfvEXT;
-
- (void)radeon_fallback_vtxfmt;
-
- TNL_CONTEXT(ctx)->Driver.NotifyBegin = radeonNotifyBegin;
-
- rmesa->vb.enabled = 1;
- rmesa->vb.prim = &ctx->Driver.CurrentExecPrimitive;
- rmesa->vb.primflags = 0;
-
- make_empty_list( &rmesa->vb.dfn_cache.Vertex2f );
- make_empty_list( &rmesa->vb.dfn_cache.Vertex2fv );
- make_empty_list( &rmesa->vb.dfn_cache.Vertex3f );
- make_empty_list( &rmesa->vb.dfn_cache.Vertex3fv );
- make_empty_list( &rmesa->vb.dfn_cache.Color4ub );
- make_empty_list( &rmesa->vb.dfn_cache.Color4ubv );
- make_empty_list( &rmesa->vb.dfn_cache.Color3ub );
- make_empty_list( &rmesa->vb.dfn_cache.Color3ubv );
- make_empty_list( &rmesa->vb.dfn_cache.Color4f );
- make_empty_list( &rmesa->vb.dfn_cache.Color4fv );
- make_empty_list( &rmesa->vb.dfn_cache.Color3f );
- make_empty_list( &rmesa->vb.dfn_cache.Color3fv );
- make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3fEXT );
- make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3fvEXT );
- make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3ubEXT );
- make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT );
- make_empty_list( &rmesa->vb.dfn_cache.Normal3f );
- make_empty_list( &rmesa->vb.dfn_cache.Normal3fv );
- make_empty_list( &rmesa->vb.dfn_cache.TexCoord2f );
- make_empty_list( &rmesa->vb.dfn_cache.TexCoord2fv );
- make_empty_list( &rmesa->vb.dfn_cache.TexCoord1f );
- make_empty_list( &rmesa->vb.dfn_cache.TexCoord1fv );
- make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord2fARB );
- make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
- make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord1fARB );
- make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord1fvARB );
-
- radeonInitCodegen( &rmesa->vb.codegen, useCodegen );
-}
-
-static void free_funcs( struct dynfn *l )
-{
- struct dynfn *f, *tmp;
- foreach_s (f, tmp, l) {
- remove_from_list( f );
- _mesa_exec_free( f->code );
- _mesa_free( f );
- }
-}
-
-
-
-void radeonVtxfmtMakeCurrent( GLcontext *ctx )
-{
-}
-
-
-void radeonVtxfmtDestroy( GLcontext *ctx )
-{
- radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
-
- count_funcs( rmesa );
- free_funcs( &rmesa->vb.dfn_cache.Vertex2f );
- free_funcs( &rmesa->vb.dfn_cache.Vertex2fv );
- free_funcs( &rmesa->vb.dfn_cache.Vertex3f );
- free_funcs( &rmesa->vb.dfn_cache.Vertex3fv );
- free_funcs( &rmesa->vb.dfn_cache.Color4ub );
- free_funcs( &rmesa->vb.dfn_cache.Color4ubv );
- free_funcs( &rmesa->vb.dfn_cache.Color3ub );
- free_funcs( &rmesa->vb.dfn_cache.Color3ubv );
- free_funcs( &rmesa->vb.dfn_cache.Color4f );
- free_funcs( &rmesa->vb.dfn_cache.Color4fv );
- free_funcs( &rmesa->vb.dfn_cache.Color3f );
- free_funcs( &rmesa->vb.dfn_cache.Color3fv );
- free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3ubEXT );
- free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT );
- free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3fEXT );
- free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3fvEXT );
- free_funcs( &rmesa->vb.dfn_cache.Normal3f );
- free_funcs( &rmesa->vb.dfn_cache.Normal3fv );
- free_funcs( &rmesa->vb.dfn_cache.TexCoord2f );
- free_funcs( &rmesa->vb.dfn_cache.TexCoord2fv );
- free_funcs( &rmesa->vb.dfn_cache.TexCoord1f );
- free_funcs( &rmesa->vb.dfn_cache.TexCoord1fv );
- free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord2fARB );
- free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
- free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord1fARB );
- free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord1fvARB );
-}
-
diff --git a/src/mesa/drivers/dri/radeon/radeon_vtxfmt.h b/src/mesa/drivers/dri/radeon/radeon_vtxfmt.h
deleted file mode 100644
index a656e49e445..00000000000
--- a/src/mesa/drivers/dri/radeon/radeon_vtxfmt.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.h,v 1.3 2002/12/21 17:02:16 dawes Exp $ */
-/**************************************************************************
-
-Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
- Tungsten Graphics Inc., Cedar Park, Texas.
-
-All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial
-portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Keith Whitwell <[email protected]>
- */
-
-#ifndef __RADEON_VTXFMT_H__
-#define __RADEON_VTXFMT_H__
-
-#include "radeon_context.h"
-
-
-extern void radeonVtxfmtUpdate( GLcontext *ctx );
-extern void radeonVtxfmtInit( GLcontext *ctx, GLboolean useCodegen );
-extern void radeonVtxfmtInvalidate( GLcontext *ctx );
-extern void radeonVtxfmtDestroy( GLcontext *ctx );
-extern void radeonVtxfmtInitChoosers( GLvertexformat *vfmt );
-
-extern void radeonVtxfmtMakeCurrent( GLcontext *ctx );
-extern void radeonVtxfmtUnbindContext( GLcontext *ctx );
-
-extern void radeon_copy_to_current( GLcontext *ctx );
-
-#define DFN( FUNC, CACHE) \
-do { \
- char *start = (char *)&FUNC; \
- char *end = (char *)&FUNC##_end; \
- insert_at_head( &CACHE, dfn ); \
- dfn->key = key; \
- dfn->code = _mesa_exec_malloc( end - start ); \
- _mesa_memcpy(dfn->code, start, end - start); \
-} \
-while ( 0 )
-
-#define FIXUP( CODE, OFFSET, CHECKVAL, NEWVAL ) \
-do { \
- int *icode = (int *)(CODE+OFFSET); \
- assert (*icode == CHECKVAL); \
- *icode = (int)NEWVAL; \
-} while (0)
-
-
-/* Useful for figuring out the offsets:
- */
-#define FIXUP2( CODE, OFFSET, CHECKVAL, NEWVAL ) \
-do { \
- while (*(int *)(CODE+OFFSET) != CHECKVAL) OFFSET++; \
- fprintf(stderr, "%s/%d CVAL %x OFFSET %d VAL %x\n", __FUNCTION__, \
- __LINE__, CHECKVAL, OFFSET, (int)(NEWVAL)); \
- *(int *)(CODE+OFFSET) = (int)(NEWVAL); \
- OFFSET += 4; \
-} while (0)
-
-/*
- */
-void radeonInitCodegen( struct dfn_generators *gen, GLboolean useCodegen );
-void radeonInitX86Codegen( struct dfn_generators *gen );
-void radeonInitSSECodegen( struct dfn_generators *gen );
-
-
-
-/* Defined in radeon_vtxfmt_x86.c
- */
-struct dynfn *radeon_makeX86Vertex2f( GLcontext *, int );
-struct dynfn *radeon_makeX86Vertex2fv( GLcontext *, int );
-struct dynfn *radeon_makeX86Vertex3f( GLcontext *, int );
-struct dynfn *radeon_makeX86Vertex3fv( GLcontext *, int );
-struct dynfn *radeon_makeX86Color4ub( GLcontext *, int );
-struct dynfn *radeon_makeX86Color4ubv( GLcontext *, int );
-struct dynfn *radeon_makeX86Color3ub( GLcontext *, int );
-struct dynfn *radeon_makeX86Color3ubv( GLcontext *, int );
-struct dynfn *radeon_makeX86Color4f( GLcontext *, int );
-struct dynfn *radeon_makeX86Color4fv( GLcontext *, int );
-struct dynfn *radeon_makeX86Color3f( GLcontext *, int );
-struct dynfn *radeon_makeX86Color3fv( GLcontext *, int );
-struct dynfn *radeon_makeX86SecondaryColor3ubEXT( GLcontext *, int );
-struct dynfn *radeon_makeX86SecondaryColor3ubvEXT( GLcontext *, int );
-struct dynfn *radeon_makeX86SecondaryColor3fEXT( GLcontext *, int );
-struct dynfn *radeon_makeX86SecondaryColor3fvEXT( GLcontext *, int );
-struct dynfn *radeon_makeX86Normal3f( GLcontext *, int );
-struct dynfn *radeon_makeX86Normal3fv( GLcontext *, int );
-struct dynfn *radeon_makeX86TexCoord2f( GLcontext *, int );
-struct dynfn *radeon_makeX86TexCoord2fv( GLcontext *, int );
-struct dynfn *radeon_makeX86TexCoord1f( GLcontext *, int );
-struct dynfn *radeon_makeX86TexCoord1fv( GLcontext *, int );
-struct dynfn *radeon_makeX86MultiTexCoord2fARB( GLcontext *, int );
-struct dynfn *radeon_makeX86MultiTexCoord2fvARB( GLcontext *, int );
-struct dynfn *radeon_makeX86MultiTexCoord1fARB( GLcontext *, int );
-struct dynfn *radeon_makeX86MultiTexCoord1fvARB( GLcontext *, int );
-
-#endif
diff --git a/src/mesa/drivers/dri/radeon/radeon_vtxfmt_c.c b/src/mesa/drivers/dri/radeon/radeon_vtxfmt_c.c
deleted file mode 100644
index aac029aa0e4..00000000000
--- a/src/mesa/drivers/dri/radeon/radeon_vtxfmt_c.c
+++ /dev/null
@@ -1,924 +0,0 @@
-/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_c.c,v 1.2 2002/12/16 16:18:59 dawes Exp $ */
-/**************************************************************************
-
-Copyright 2002 ATI Technologies Inc., Ontario, Canada, and
- Tungsten Graphics Inc., Cedar Park, Texas.
-
-All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial
-portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Keith Whitwell <[email protected]>
- */
-#include "glheader.h"
-#include "mtypes.h"
-#include "colormac.h"
-#include "simple_list.h"
-#include "api_noop.h"
-#include "vtxfmt.h"
-
-#include "radeon_vtxfmt.h"
-
-#include "dispatch.h"
-
-/* Fallback versions of all the entrypoints for situations where
- * codegen isn't available. This is still a lot faster than the
- * vb/pipeline implementation in Mesa.
- */
-static void radeon_Vertex3f( GLfloat x, GLfloat y, GLfloat z )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- int i;
-
- *rmesa->vb.dmaptr++ = *(int *)&x;
- *rmesa->vb.dmaptr++ = *(int *)&y;
- *rmesa->vb.dmaptr++ = *(int *)&z;
-
- for (i = 3; i < rmesa->vb.vertex_size; i++)
- *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i;
-
- if (--rmesa->vb.counter == 0)
- rmesa->vb.notify();
-}
-
-
-static void radeon_Vertex3fv( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- int i;
-
- *rmesa->vb.dmaptr++ = *(int *)&v[0];
- *rmesa->vb.dmaptr++ = *(int *)&v[1];
- *rmesa->vb.dmaptr++ = *(int *)&v[2];
-
- for (i = 3; i < rmesa->vb.vertex_size; i++)
- *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i;
-
- if (--rmesa->vb.counter == 0)
- rmesa->vb.notify();
-}
-
-
-static void radeon_Vertex2f( GLfloat x, GLfloat y )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- int i;
-
- *rmesa->vb.dmaptr++ = *(int *)&x;
- *rmesa->vb.dmaptr++ = *(int *)&y;
- *rmesa->vb.dmaptr++ = 0;
-
- for (i = 3; i < rmesa->vb.vertex_size; i++)
- *rmesa->vb.dmaptr++ = *(int *)&rmesa->vb.vertex[i];
-
- if (--rmesa->vb.counter == 0)
- rmesa->vb.notify();
-}
-
-
-static void radeon_Vertex2fv( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- int i;
-
- *rmesa->vb.dmaptr++ = *(int *)&v[0];
- *rmesa->vb.dmaptr++ = *(int *)&v[1];
- *rmesa->vb.dmaptr++ = 0;
-
- for (i = 3; i < rmesa->vb.vertex_size; i++)
- *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i;
-
- if (--rmesa->vb.counter == 0)
- rmesa->vb.notify();
-}
-
-
-#if 0
-/* Color for ubyte (packed) color formats:
- */
-static void radeon_Color3ub_ub( GLubyte r, GLubyte g, GLubyte b )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- radeon_color_t *dest = rmesa->vb.colorptr;
- dest->red = r;
- dest->green = g;
- dest->blue = b;
- dest->alpha = 0xff;
-}
-
-static void radeon_Color3ubv_ub( const GLubyte *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- radeon_color_t *dest = rmesa->vb.colorptr;
- dest->red = v[0];
- dest->green = v[1];
- dest->blue = v[2];
- dest->alpha = 0xff;
-}
-
-static void radeon_Color4ub_ub( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- radeon_color_t *dest = rmesa->vb.colorptr;
- dest->red = r;
- dest->green = g;
- dest->blue = b;
- dest->alpha = a;
-}
-
-static void radeon_Color4ubv_ub( const GLubyte *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- *(GLuint *)rmesa->vb.colorptr = LE32_TO_CPU(*(GLuint *)v);
-}
-#endif /* 0 */
-
-static void radeon_Color3f_ub( GLfloat r, GLfloat g, GLfloat b )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- radeon_color_t *dest = rmesa->vb.colorptr;
- UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r );
- UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g );
- UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b );
- dest->alpha = 255;
-}
-
-static void radeon_Color3fv_ub( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- radeon_color_t *dest = rmesa->vb.colorptr;
- UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] );
- UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] );
- UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] );
- dest->alpha = 255;
-}
-
-static void radeon_Color4f_ub( GLfloat r, GLfloat g, GLfloat b, GLfloat a )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- radeon_color_t *dest = rmesa->vb.colorptr;
- UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r );
- UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g );
- UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b );
- UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, a );
-}
-
-static void radeon_Color4fv_ub( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- radeon_color_t *dest = rmesa->vb.colorptr;
- UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] );
- UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] );
- UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] );
- UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, v[3] );
-}
-
-
-/* Color for float color+alpha formats:
- */
-#if 0
-static void radeon_Color3ub_4f( GLubyte r, GLubyte g, GLubyte b )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = UBYTE_TO_FLOAT(r);
- dest[1] = UBYTE_TO_FLOAT(g);
- dest[2] = UBYTE_TO_FLOAT(b);
- dest[3] = 1.0;
-}
-
-static void radeon_Color3ubv_4f( const GLubyte *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = UBYTE_TO_FLOAT(v[0]);
- dest[1] = UBYTE_TO_FLOAT(v[1]);
- dest[2] = UBYTE_TO_FLOAT(v[2]);
- dest[3] = 1.0;
-}
-
-static void radeon_Color4ub_4f( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = UBYTE_TO_FLOAT(r);
- dest[1] = UBYTE_TO_FLOAT(g);
- dest[2] = UBYTE_TO_FLOAT(b);
- dest[3] = UBYTE_TO_FLOAT(a);
-}
-
-static void radeon_Color4ubv_4f( const GLubyte *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = UBYTE_TO_FLOAT(v[0]);
- dest[1] = UBYTE_TO_FLOAT(v[1]);
- dest[2] = UBYTE_TO_FLOAT(v[2]);
- dest[3] = UBYTE_TO_FLOAT(v[3]);
-}
-#endif /* 0 */
-
-
-static void radeon_Color3f_4f( GLfloat r, GLfloat g, GLfloat b )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = r;
- dest[1] = g;
- dest[2] = b;
- dest[3] = 1.0;
-}
-
-static void radeon_Color3fv_4f( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = v[0];
- dest[1] = v[1];
- dest[2] = v[2];
- dest[3] = 1.0;
-}
-
-static void radeon_Color4f_4f( GLfloat r, GLfloat g, GLfloat b, GLfloat a )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = r;
- dest[1] = g;
- dest[2] = b;
- dest[3] = a;
-}
-
-static void radeon_Color4fv_4f( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = v[0];
- dest[1] = v[1];
- dest[2] = v[2];
- dest[3] = v[3];
-}
-
-
-/* Color for float color formats:
- */
-#if 0
-static void radeon_Color3ub_3f( GLubyte r, GLubyte g, GLubyte b )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = UBYTE_TO_FLOAT(r);
- dest[1] = UBYTE_TO_FLOAT(g);
- dest[2] = UBYTE_TO_FLOAT(b);
-}
-
-static void radeon_Color3ubv_3f( const GLubyte *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = UBYTE_TO_FLOAT(v[0]);
- dest[1] = UBYTE_TO_FLOAT(v[1]);
- dest[2] = UBYTE_TO_FLOAT(v[2]);
-}
-
-static void radeon_Color4ub_3f( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = UBYTE_TO_FLOAT(r);
- dest[1] = UBYTE_TO_FLOAT(g);
- dest[2] = UBYTE_TO_FLOAT(b);
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT(a);
-}
-
-static void radeon_Color4ubv_3f( const GLubyte *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = UBYTE_TO_FLOAT(v[0]);
- dest[1] = UBYTE_TO_FLOAT(v[1]);
- dest[2] = UBYTE_TO_FLOAT(v[2]);
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT(v[3]);
-}
-#endif /* 0 */
-
-
-static void radeon_Color3f_3f( GLfloat r, GLfloat g, GLfloat b )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = r;
- dest[1] = g;
- dest[2] = b;
-}
-
-static void radeon_Color3fv_3f( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = v[0];
- dest[1] = v[1];
- dest[2] = v[2];
-}
-
-static void radeon_Color4f_3f( GLfloat r, GLfloat g, GLfloat b, GLfloat a )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = r;
- dest[1] = g;
- dest[2] = b;
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = a;
-}
-
-static void radeon_Color4fv_3f( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatcolorptr;
- dest[0] = v[0];
- dest[1] = v[1];
- dest[2] = v[2];
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = v[3];
-}
-
-
-/* Secondary Color:
- */
-#if 0
-static void radeon_SecondaryColor3ubEXT_ub( GLubyte r, GLubyte g, GLubyte b )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- radeon_color_t *dest = rmesa->vb.specptr;
- dest->red = r;
- dest->green = g;
- dest->blue = b;
- dest->alpha = 0xff;
-}
-
-static void radeon_SecondaryColor3ubvEXT_ub( const GLubyte *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- radeon_color_t *dest = rmesa->vb.specptr;
- dest->red = v[0];
- dest->green = v[1];
- dest->blue = v[2];
- dest->alpha = 0xff;
-}
-#endif /* 0 */
-
-static void radeon_SecondaryColor3fEXT_ub( GLfloat r, GLfloat g, GLfloat b )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- radeon_color_t *dest = rmesa->vb.specptr;
- UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r );
- UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g );
- UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b );
- dest->alpha = 255;
-}
-
-static void radeon_SecondaryColor3fvEXT_ub( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- radeon_color_t *dest = rmesa->vb.specptr;
- UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] );
- UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] );
- UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] );
- dest->alpha = 255;
-}
-
-#if 0
-static void radeon_SecondaryColor3ubEXT_3f( GLubyte r, GLubyte g, GLubyte b )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatspecptr;
- dest[0] = UBYTE_TO_FLOAT(r);
- dest[1] = UBYTE_TO_FLOAT(g);
- dest[2] = UBYTE_TO_FLOAT(b);
- dest[3] = 1.0;
-}
-
-static void radeon_SecondaryColor3ubvEXT_3f( const GLubyte *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatspecptr;
- dest[0] = UBYTE_TO_FLOAT(v[0]);
- dest[1] = UBYTE_TO_FLOAT(v[1]);
- dest[2] = UBYTE_TO_FLOAT(v[2]);
- dest[3] = 1.0;
-}
-#endif /* 0 */
-
-static void radeon_SecondaryColor3fEXT_3f( GLfloat r, GLfloat g, GLfloat b )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatspecptr;
- dest[0] = r;
- dest[1] = g;
- dest[2] = b;
- dest[3] = 1.0;
-}
-
-static void radeon_SecondaryColor3fvEXT_3f( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.floatspecptr;
- dest[0] = v[0];
- dest[1] = v[1];
- dest[2] = v[2];
- dest[3] = 1.0;
-}
-
-
-/* Normal
- */
-static void radeon_Normal3f( GLfloat n0, GLfloat n1, GLfloat n2 )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.normalptr;
- dest[0] = n0;
- dest[1] = n1;
- dest[2] = n2;
-}
-
-static void radeon_Normal3fv( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.normalptr;
- dest[0] = v[0];
- dest[1] = v[1];
- dest[2] = v[2];
-}
-
-
-/* TexCoord
- */
-static void radeon_TexCoord1f( GLfloat s )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.texcoordptr[0];
- dest[0] = s;
- dest[1] = 0;
-}
-
-static void radeon_TexCoord1fv( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.texcoordptr[0];
- dest[0] = v[0];
- dest[1] = 0;
-}
-
-static void radeon_TexCoord2f( GLfloat s, GLfloat t )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.texcoordptr[0];
- dest[0] = s;
- dest[1] = t;
-}
-
-static void radeon_TexCoord2fv( const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.texcoordptr[0];
- dest[0] = v[0];
- dest[1] = v[1];
-}
-
-
-/* MultiTexcoord
- *
- * Technically speaking, these functions should subtract GL_TEXTURE0 from
- * \c target before masking and using it. The value of GL_TEXTURE0 is 0x84C0,
- * which has the low-order 5 bits 0. For all possible valid values of
- * \c target. Subtracting GL_TEXTURE0 has the net effect of masking \c target
- * with 0x1F. Masking with 0x1F and then masking with 0x01 is redundant, so
- * the subtraction has been omitted.
- */
-
-static void radeon_MultiTexCoord1fARB( GLenum target, GLfloat s )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.texcoordptr[target & 3];
- dest[0] = s;
- dest[1] = 0;
-}
-
-static void radeon_MultiTexCoord1fvARB( GLenum target, const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.texcoordptr[target & 3];
- dest[0] = v[0];
- dest[1] = 0;
-}
-
-static void radeon_MultiTexCoord2fARB( GLenum target, GLfloat s, GLfloat t )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.texcoordptr[target & 3];
- dest[0] = s;
- dest[1] = t;
-}
-
-static void radeon_MultiTexCoord2fvARB( GLenum target, const GLfloat *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat *dest = rmesa->vb.texcoordptr[target & 3];
- dest[0] = v[0];
- dest[1] = v[1];
-}
-
-static struct dynfn *lookup( struct dynfn *l, int key )
-{
- struct dynfn *f;
-
- foreach( f, l ) {
- if (f->key == key)
- return f;
- }
-
- return NULL;
-}
-
-/* Can't use the loopback template for this:
- */
-
-#define CHOOSE(FN, FNTYPE, MASK, ACTIVE, ARGS1, ARGS2 ) \
-static void choose_##FN ARGS1 \
-{ \
- GET_CURRENT_CONTEXT(ctx); \
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \
- int key = rmesa->vb.vertex_format & (MASK|ACTIVE); \
- struct dynfn *dfn; \
- \
- dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \
- if (dfn == 0) \
- dfn = rmesa->vb.codegen.FN( ctx, key ); \
- else if (RADEON_DEBUG & DEBUG_CODEGEN) \
- fprintf(stderr, "%s -- cached codegen\n", __FUNCTION__ ); \
- \
- if (dfn) \
- SET_ ## FN (ctx->Exec, (FNTYPE)(dfn->code)); \
- else { \
- if (RADEON_DEBUG & DEBUG_CODEGEN) \
- fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \
- SET_ ## FN (ctx->Exec, radeon_##FN); \
- } \
- \
- ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \
- CALL_ ## FN (ctx->Exec, ARGS2); \
-}
-
-
-
-/* For the _3f case, only allow one color function to be hooked in at
- * a time. Eventually, use a similar mechanism to allow selecting the
- * color component of the vertex format based on client behaviour.
- *
- * Note: Perform these actions even if there is a codegen or cached
- * codegen version of the chosen function.
- */
-#define CHOOSE_COLOR(FN, FNTYPE, NR, MASK, ACTIVE, ARGS1, ARGS2 ) \
-static void choose_##FN ARGS1 \
-{ \
- GET_CURRENT_CONTEXT(ctx); \
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \
- int key = rmesa->vb.vertex_format & (MASK|ACTIVE); \
- struct dynfn *dfn; \
- \
- if (rmesa->vb.vertex_format & ACTIVE_PKCOLOR) { \
- SET_ ## FN (ctx->Exec, radeon_##FN##_ub); \
- } \
- else if ((rmesa->vb.vertex_format & \
- (ACTIVE_FPCOLOR|ACTIVE_FPALPHA)) == ACTIVE_FPCOLOR) { \
- \
- if (rmesa->vb.installed_color_3f_sz != NR) { \
- rmesa->vb.installed_color_3f_sz = NR; \
- if (NR == 3) ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = 1.0; \
- if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) { \
- radeon_copy_to_current( ctx ); \
- _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); \
- CALL_ ## FN (ctx->Exec, ARGS2); \
- return; \
- } \
- } \
- \
- SET_ ## FN (ctx->Exec, radeon_##FN##_3f); \
- } \
- else { \
- SET_ ## FN (ctx->Exec, radeon_##FN##_4f); \
- } \
- \
- \
- dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \
- if (!dfn) dfn = rmesa->vb.codegen.FN( ctx, key ); \
- \
- if (dfn) { \
- if (RADEON_DEBUG & DEBUG_CODEGEN) \
- fprintf(stderr, "%s -- codegen version\n", __FUNCTION__ ); \
- SET_ ## FN (ctx->Exec, (FNTYPE)dfn->code); \
- } \
- else if (RADEON_DEBUG & DEBUG_CODEGEN) \
- fprintf(stderr, "%s -- 'c' version\n", __FUNCTION__ ); \
- \
- ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \
- CALL_ ## FN (ctx->Exec, ARGS2); \
-}
-
-
-
-/* Right now there are both _ub and _3f versions of the secondary color
- * functions. Currently, we only set-up the hardware to use the _ub versions.
- * The _3f versions are needed for the cases where secondary color isn't used
- * in the vertex format, but it still needs to be stored in the context
- * state vector.
- */
-#define CHOOSE_SECONDARY_COLOR(FN, FNTYPE, MASK, ACTIVE, ARGS1, ARGS2 ) \
-static void choose_##FN ARGS1 \
-{ \
- GET_CURRENT_CONTEXT(ctx); \
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \
- int key = rmesa->vb.vertex_format & (MASK|ACTIVE); \
- struct dynfn *dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \
- \
- if (dfn == 0) \
- dfn = rmesa->vb.codegen.FN( ctx, key ); \
- else if (RADEON_DEBUG & DEBUG_CODEGEN) \
- fprintf(stderr, "%s -- cached version\n", __FUNCTION__ ); \
- \
- if (dfn) \
- SET_ ## FN (ctx->Exec, (FNTYPE)(dfn->code)); \
- else { \
- if (RADEON_DEBUG & DEBUG_CODEGEN) \
- fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \
- SET_ ## FN (ctx->Exec, ((rmesa->vb.vertex_format & ACTIVE_PKSPEC) != 0) \
- ? radeon_##FN##_ub : radeon_##FN##_3f); \
- } \
- \
- ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \
- CALL_ ## FN (ctx->Exec, ARGS2); \
-}
-
-
-
-
-
-/* Shorthands
- */
-#define ACTIVE_XYZW (RADEON_CP_VC_FRMT_W0|RADEON_CP_VC_FRMT_Z)
-#define ACTIVE_NORM RADEON_CP_VC_FRMT_N0
-
-#define ACTIVE_PKCOLOR RADEON_CP_VC_FRMT_PKCOLOR
-#define ACTIVE_FPCOLOR RADEON_CP_VC_FRMT_FPCOLOR
-#define ACTIVE_FPALPHA RADEON_CP_VC_FRMT_FPALPHA
-#define ACTIVE_COLOR (ACTIVE_FPCOLOR|ACTIVE_PKCOLOR)
-
-#define ACTIVE_PKSPEC RADEON_CP_VC_FRMT_PKSPEC
-#define ACTIVE_FPSPEC RADEON_CP_VC_FRMT_FPSPEC
-#define ACTIVE_SPEC (ACTIVE_FPSPEC|ACTIVE_PKSPEC)
-
-#define ACTIVE_ST0 RADEON_CP_VC_FRMT_ST0
-#define ACTIVE_ST1 RADEON_CP_VC_FRMT_ST1
-#define ACTIVE_ST2 RADEON_CP_VC_FRMT_ST2
-#define ACTIVE_ST_ALL (RADEON_CP_VC_FRMT_ST1|RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST2)
-
-/* Each codegen function should be able to be fully specified by a
- * subsetted version of rmesa->vb.vertex_format.
- */
-#define MASK_NORM (ACTIVE_XYZW)
-#define MASK_COLOR (MASK_NORM|ACTIVE_NORM)
-#define MASK_SPEC (MASK_COLOR|ACTIVE_COLOR)
-#define MASK_ST0 (MASK_SPEC|ACTIVE_SPEC)
-#define MASK_ST1 (MASK_ST0|ACTIVE_ST0)
-#define MASK_ST2 (MASK_ST1|ACTIVE_ST1)
-#define MASK_ST_ALL (MASK_ST2|ACTIVE_ST2)
-#define MASK_VERTEX (MASK_ST_ALL|ACTIVE_FPALPHA)
-
-
-typedef void (*p4f)( GLfloat, GLfloat, GLfloat, GLfloat );
-typedef void (*p3f)( GLfloat, GLfloat, GLfloat );
-typedef void (*p2f)( GLfloat, GLfloat );
-typedef void (*p1f)( GLfloat );
-typedef void (*pe2f)( GLenum, GLfloat, GLfloat );
-typedef void (*pe1f)( GLenum, GLfloat );
-typedef void (*p4ub)( GLubyte, GLubyte, GLubyte, GLubyte );
-typedef void (*p3ub)( GLubyte, GLubyte, GLubyte );
-typedef void (*pfv)( const GLfloat * );
-typedef void (*pefv)( GLenum, const GLfloat * );
-typedef void (*pubv)( const GLubyte * );
-
-
-CHOOSE(Normal3f, p3f, MASK_NORM, ACTIVE_NORM,
- (GLfloat a,GLfloat b,GLfloat c), (a,b,c))
-CHOOSE(Normal3fv, pfv, MASK_NORM, ACTIVE_NORM,
- (const GLfloat *v), (v))
-
-#if 0
-CHOOSE_COLOR(Color4ub, p4ub, 4, MASK_COLOR, ACTIVE_COLOR,
- (GLubyte a,GLubyte b, GLubyte c, GLubyte d), (a,b,c,d))
-CHOOSE_COLOR(Color4ubv, pubv, 4, MASK_COLOR, ACTIVE_COLOR,
- (const GLubyte *v), (v))
-CHOOSE_COLOR(Color3ub, p3ub, 3, MASK_COLOR, ACTIVE_COLOR,
- (GLubyte a,GLubyte b, GLubyte c), (a,b,c))
-CHOOSE_COLOR(Color3ubv, pubv, 3, MASK_COLOR, ACTIVE_COLOR,
- (const GLubyte *v), (v))
-#endif
-
-CHOOSE_COLOR(Color4f, p4f, 4, MASK_COLOR, ACTIVE_COLOR,
- (GLfloat a,GLfloat b, GLfloat c, GLfloat d), (a,b,c,d))
-CHOOSE_COLOR(Color4fv, pfv, 4, MASK_COLOR, ACTIVE_COLOR,
- (const GLfloat *v), (v))
-CHOOSE_COLOR(Color3f, p3f, 3, MASK_COLOR, ACTIVE_COLOR,
- (GLfloat a,GLfloat b, GLfloat c), (a,b,c))
-CHOOSE_COLOR(Color3fv, pfv, 3, MASK_COLOR, ACTIVE_COLOR,
- (const GLfloat *v), (v))
-
-
-#if 0
-CHOOSE_SECONDARY_COLOR(SecondaryColor3ubEXT, p3ub, MASK_SPEC, ACTIVE_SPEC,
- (GLubyte a,GLubyte b, GLubyte c), (a,b,c))
-CHOOSE_SECONDARY_COLOR(SecondaryColor3ubvEXT, pubv, MASK_SPEC, ACTIVE_SPEC,
- (const GLubyte *v), (v))
-#endif
-CHOOSE_SECONDARY_COLOR(SecondaryColor3fEXT, p3f, MASK_SPEC, ACTIVE_SPEC,
- (GLfloat a,GLfloat b, GLfloat c), (a,b,c))
-CHOOSE_SECONDARY_COLOR(SecondaryColor3fvEXT, pfv, MASK_SPEC, ACTIVE_SPEC,
- (const GLfloat *v), (v))
-
-CHOOSE(TexCoord2f, p2f, MASK_ST0, ACTIVE_ST0,
- (GLfloat a,GLfloat b), (a,b))
-CHOOSE(TexCoord2fv, pfv, MASK_ST0, ACTIVE_ST0,
- (const GLfloat *v), (v))
-CHOOSE(TexCoord1f, p1f, MASK_ST0, ACTIVE_ST0,
- (GLfloat a), (a))
-CHOOSE(TexCoord1fv, pfv, MASK_ST0, ACTIVE_ST0,
- (const GLfloat *v), (v))
-
-CHOOSE(MultiTexCoord2fARB, pe2f, MASK_ST_ALL, ACTIVE_ST_ALL,
- (GLenum u,GLfloat a,GLfloat b), (u,a,b))
-CHOOSE(MultiTexCoord2fvARB, pefv, MASK_ST_ALL, ACTIVE_ST_ALL,
- (GLenum u,const GLfloat *v), (u,v))
-CHOOSE(MultiTexCoord1fARB, pe1f, MASK_ST_ALL, ACTIVE_ST_ALL,
- (GLenum u,GLfloat a), (u,a))
-CHOOSE(MultiTexCoord1fvARB, pefv, MASK_ST_ALL, ACTIVE_ST_ALL,
- (GLenum u,const GLfloat *v), (u,v))
-
-CHOOSE(Vertex3f, p3f, MASK_VERTEX, MASK_VERTEX,
- (GLfloat a,GLfloat b,GLfloat c), (a,b,c))
-CHOOSE(Vertex3fv, pfv, MASK_VERTEX, MASK_VERTEX,
- (const GLfloat *v), (v))
-CHOOSE(Vertex2f, p2f, MASK_VERTEX, MASK_VERTEX,
- (GLfloat a,GLfloat b), (a,b))
-CHOOSE(Vertex2fv, pfv, MASK_VERTEX, MASK_VERTEX,
- (const GLfloat *v), (v))
-
-
-
-
-
-void radeonVtxfmtInitChoosers( GLvertexformat *vfmt )
-{
- vfmt->Color3f = choose_Color3f;
- vfmt->Color3fv = choose_Color3fv;
- vfmt->Color4f = choose_Color4f;
- vfmt->Color4fv = choose_Color4fv;
- vfmt->SecondaryColor3fEXT = choose_SecondaryColor3fEXT;
- vfmt->SecondaryColor3fvEXT = choose_SecondaryColor3fvEXT;
- vfmt->MultiTexCoord1fARB = choose_MultiTexCoord1fARB;
- vfmt->MultiTexCoord1fvARB = choose_MultiTexCoord1fvARB;
- vfmt->MultiTexCoord2fARB = choose_MultiTexCoord2fARB;
- vfmt->MultiTexCoord2fvARB = choose_MultiTexCoord2fvARB;
- vfmt->Normal3f = choose_Normal3f;
- vfmt->Normal3fv = choose_Normal3fv;
- vfmt->TexCoord1f = choose_TexCoord1f;
- vfmt->TexCoord1fv = choose_TexCoord1fv;
- vfmt->TexCoord2f = choose_TexCoord2f;
- vfmt->TexCoord2fv = choose_TexCoord2fv;
- vfmt->Vertex2f = choose_Vertex2f;
- vfmt->Vertex2fv = choose_Vertex2fv;
- vfmt->Vertex3f = choose_Vertex3f;
- vfmt->Vertex3fv = choose_Vertex3fv;
-
-#if 0
- vfmt->Color3ub = choose_Color3ub;
- vfmt->Color3ubv = choose_Color3ubv;
- vfmt->Color4ub = choose_Color4ub;
- vfmt->Color4ubv = choose_Color4ubv;
- vfmt->SecondaryColor3ubEXT = choose_SecondaryColor3ubEXT;
- vfmt->SecondaryColor3ubvEXT = choose_SecondaryColor3ubvEXT;
-#endif
-}
-
-
-static struct dynfn *codegen_noop( GLcontext *ctx, int key )
-{
- (void) ctx; (void) key;
- return NULL;
-}
-
-void radeonInitCodegen( struct dfn_generators *gen, GLboolean useCodegen )
-{
- gen->Vertex3f = codegen_noop;
- gen->Vertex3fv = codegen_noop;
- gen->Color4ub = codegen_noop;
- gen->Color4ubv = codegen_noop;
- gen->Normal3f = codegen_noop;
- gen->Normal3fv = codegen_noop;
- gen->TexCoord2f = codegen_noop;
- gen->TexCoord2fv = codegen_noop;
- gen->MultiTexCoord2fARB = codegen_noop;
- gen->MultiTexCoord2fvARB = codegen_noop;
- gen->Vertex2f = codegen_noop;
- gen->Vertex2fv = codegen_noop;
- gen->Color3ub = codegen_noop;
- gen->Color3ubv = codegen_noop;
- gen->Color4f = codegen_noop;
- gen->Color4fv = codegen_noop;
- gen->Color3f = codegen_noop;
- gen->Color3fv = codegen_noop;
- gen->SecondaryColor3fEXT = codegen_noop;
- gen->SecondaryColor3fvEXT = codegen_noop;
- gen->SecondaryColor3ubEXT = codegen_noop;
- gen->SecondaryColor3ubvEXT = codegen_noop;
- gen->TexCoord1f = codegen_noop;
- gen->TexCoord1fv = codegen_noop;
- gen->MultiTexCoord1fARB = codegen_noop;
- gen->MultiTexCoord1fvARB = codegen_noop;
-
- if (useCodegen) {
-#if defined(USE_X86_ASM)
- radeonInitX86Codegen( gen );
-#endif
-
-#if defined(USE_SSE_ASM)
- radeonInitSSECodegen( gen );
-#endif
- }
-}
diff --git a/src/mesa/drivers/dri/radeon/radeon_vtxfmt_sse.c b/src/mesa/drivers/dri/radeon/radeon_vtxfmt_sse.c
deleted file mode 100644
index 0f0fc9e0653..00000000000
--- a/src/mesa/drivers/dri/radeon/radeon_vtxfmt_sse.c
+++ /dev/null
@@ -1,236 +0,0 @@
-/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_sse.c,v 1.1 2002/10/30 12:51:58 alanh Exp $ */
-/**************************************************************************
-
-Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
- Tungsten Graphics Inc., Cedar Park, Texas.
-
-All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial
-portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Keith Whitwell <[email protected]>
- */
-
-#include "glheader.h"
-#include "imports.h"
-#include "simple_list.h"
-#include "radeon_vtxfmt.h"
-
-#if defined(USE_SSE_ASM)
-#include "x86/common_x86_asm.h"
-
-#define EXTERN( FUNC ) \
-extern const char *FUNC; \
-extern const char *FUNC##_end
-
-EXTERN( _sse_Attribute2fv );
-EXTERN( _sse_Attribute2f );
-EXTERN( _sse_Attribute3fv );
-EXTERN( _sse_Attribute3f );
-EXTERN( _sse_MultiTexCoord2fv );
-EXTERN( _sse_MultiTexCoord2f );
-EXTERN( _sse_MultiTexCoord2fv_2 );
-EXTERN( _sse_MultiTexCoord2f_2 );
-
-/* Build specialized versions of the immediate calls on the fly for
- * the current state.
- */
-
-static struct dynfn *radeon_makeSSEAttribute2fv( struct dynfn * cache, int key,
- const char * name, void * dest)
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (RADEON_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x\n", name, key );
-
- DFN ( _sse_Attribute2fv, (*cache) );
- FIXUP(dfn->code, 10, 0x0, (int)dest);
- return dfn;
-}
-
-static struct dynfn *radeon_makeSSEAttribute2f( struct dynfn * cache, int key,
- const char * name, void * dest )
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (RADEON_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x\n", name, key );
-
- DFN ( _sse_Attribute2f, (*cache) );
- FIXUP(dfn->code, 8, 0x0, (int)dest);
- return dfn;
-}
-
-static struct dynfn *radeon_makeSSEAttribute3fv( struct dynfn * cache, int key,
- const char * name, void * dest)
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (RADEON_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x\n", name, key );
-
- DFN ( _sse_Attribute3fv, (*cache) );
- FIXUP(dfn->code, 13, 0x0, (int)dest);
- FIXUP(dfn->code, 18, 0x8, 8+(int)dest);
- return dfn;
-}
-
-static struct dynfn *radeon_makeSSEAttribute3f( struct dynfn * cache, int key,
- const char * name, void * dest )
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (RADEON_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x\n", name, key );
-
- DFN ( _sse_Attribute3f, (*cache) );
- FIXUP(dfn->code, 12, 0x0, (int)dest);
- FIXUP(dfn->code, 17, 0x8, 8+(int)dest);
- return dfn;
-}
-
-static struct dynfn * radeon_makeSSENormal3fv( GLcontext *ctx, int key )
-{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-
- return radeon_makeSSEAttribute3fv( & rmesa->vb.dfn_cache.Normal3fv, key,
- __FUNCTION__, rmesa->vb.normalptr );
-}
-
-static struct dynfn *radeon_makeSSENormal3f( GLcontext *ctx, int key )
-{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-
- return radeon_makeSSEAttribute3f( & rmesa->vb.dfn_cache.Normal3f, key,
- __FUNCTION__, rmesa->vb.normalptr );
-}
-
-static struct dynfn *radeon_makeSSEColor3fv( GLcontext *ctx, int key )
-{
- if (key & (RADEON_CP_VC_FRMT_PKCOLOR|RADEON_CP_VC_FRMT_FPALPHA))
- return NULL;
- else
- {
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-
- return radeon_makeSSEAttribute3fv( & rmesa->vb.dfn_cache.Color3fv, key,
- __FUNCTION__, rmesa->vb.floatcolorptr );
- }
-}
-
-static struct dynfn *radeon_makeSSEColor3f( GLcontext *ctx, int key )
-{
- if (key & (RADEON_CP_VC_FRMT_PKCOLOR|RADEON_CP_VC_FRMT_FPALPHA))
- return NULL;
- else
- {
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-
- return radeon_makeSSEAttribute3f( & rmesa->vb.dfn_cache.Color3f, key,
- __FUNCTION__, rmesa->vb.floatcolorptr );
- }
-}
-
-static struct dynfn *radeon_makeSSETexCoord2fv( GLcontext *ctx, int key )
-{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-
- return radeon_makeSSEAttribute2fv( & rmesa->vb.dfn_cache.TexCoord2fv, key,
- __FUNCTION__, rmesa->vb.texcoordptr[0] );
-}
-
-static struct dynfn *radeon_makeSSETexCoord2f( GLcontext *ctx, int key )
-{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-
- return radeon_makeSSEAttribute2f( & rmesa->vb.dfn_cache.TexCoord2f, key,
- __FUNCTION__, rmesa->vb.texcoordptr[0] );
-}
-
-#if 0 /* Temporarily disabled - probably needs adjustments for more than 2 tex units -rs */
-static struct dynfn *radeon_makeSSEMultiTexCoord2fv( GLcontext *ctx, int key )
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-
- if (RADEON_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
-
- if ((key & (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) ==
- (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) {
- DFN ( _sse_MultiTexCoord2fv, rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
- FIXUP(dfn->code, 18, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]);
- } else {
- DFN ( _sse_MultiTexCoord2fv_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
- FIXUP(dfn->code, 14, 0x0, (int)rmesa->vb.texcoordptr);
- }
- return dfn;
-}
-
-static struct dynfn *radeon_makeSSEMultiTexCoord2f( GLcontext *ctx, int key )
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-
- if (RADEON_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
-
- if ((key & (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) ==
- (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) {
- DFN ( _sse_MultiTexCoord2f, rmesa->vb.dfn_cache.MultiTexCoord2fARB );
- FIXUP(dfn->code, 16, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]);
- } else {
- DFN ( _sse_MultiTexCoord2f_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB );
- FIXUP(dfn->code, 15, 0x0, (int)rmesa->vb.texcoordptr);
- }
- return dfn;
-}
-#endif
-
-void radeonInitSSECodegen( struct dfn_generators *gen )
-{
- if ( cpu_has_xmm ) {
- gen->Normal3fv = (void *) radeon_makeSSENormal3fv;
- gen->Normal3f = (void *) radeon_makeSSENormal3f;
- gen->Color3fv = (void *) radeon_makeSSEColor3fv;
- gen->Color3f = (void *) radeon_makeSSEColor3f;
- gen->TexCoord2fv = (void *) radeon_makeSSETexCoord2fv;
- gen->TexCoord2f = (void *) radeon_makeSSETexCoord2f;
-#if 0 /* Temporarily disabled - probably needs adjustments for more than 2 tex units -rs */
- gen->MultiTexCoord2fvARB = (void *) radeon_makeSSEMultiTexCoord2fv;
- gen->MultiTexCoord2fARB = (void *) radeon_makeSSEMultiTexCoord2f;
-#endif
- }
-}
-
-#else
-
-void radeonInitSSECodegen( struct dfn_generators *gen )
-{
- (void) gen;
-}
-
-#endif
diff --git a/src/mesa/drivers/dri/radeon/radeon_vtxfmt_x86.c b/src/mesa/drivers/dri/radeon/radeon_vtxfmt_x86.c
deleted file mode 100644
index 529e79065e9..00000000000
--- a/src/mesa/drivers/dri/radeon/radeon_vtxfmt_x86.c
+++ /dev/null
@@ -1,440 +0,0 @@
-/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_x86.c,v 1.2 2002/12/21 17:02:16 dawes Exp $ */
-/**************************************************************************
-
-Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
- Tungsten Graphics Inc., Cedar Park, Texas.
-
-All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial
-portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Keith Whitwell <[email protected]>
- */
-
-#include "glheader.h"
-#include "imports.h"
-#include "simple_list.h"
-#include "radeon_vtxfmt.h"
-
-#if defined(USE_X86_ASM)
-
-#define EXTERN( FUNC ) \
-extern const char *FUNC; \
-extern const char *FUNC##_end
-
-EXTERN ( _x86_Attribute2fv );
-EXTERN ( _x86_Attribute2f );
-EXTERN ( _x86_Attribute3fv );
-EXTERN ( _x86_Attribute3f );
-EXTERN ( _x86_Vertex3fv_6 );
-EXTERN ( _x86_Vertex3fv_8 );
-EXTERN ( _x86_Vertex3fv );
-EXTERN ( _x86_Vertex3f_4 );
-EXTERN ( _x86_Vertex3f_6 );
-EXTERN ( _x86_Vertex3f );
-EXTERN ( _x86_Color4ubv_ub );
-EXTERN ( _x86_Color4ubv_4f );
-EXTERN ( _x86_Color4ub_ub );
-EXTERN ( _x86_MultiTexCoord2fv );
-EXTERN ( _x86_MultiTexCoord2fv_2 );
-EXTERN ( _x86_MultiTexCoord2f );
-EXTERN ( _x86_MultiTexCoord2f_2 );
-
-
-/* Build specialized versions of the immediate calls on the fly for
- * the current state. Generic x86 versions.
- */
-
-struct dynfn *radeon_makeX86Vertex3f( GLcontext *ctx, int key )
-{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (RADEON_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x %d\n", __FUNCTION__, key, rmesa->vb.vertex_size );
-
- switch (rmesa->vb.vertex_size) {
- case 4: {
-
- DFN ( _x86_Vertex3f_4, rmesa->vb.dfn_cache.Vertex3f );
- FIXUP(dfn->code, 2, 0x0, (int)&rmesa->vb.dmaptr);
- FIXUP(dfn->code, 25, 0x0, (int)&rmesa->vb.vertex[3]);
- FIXUP(dfn->code, 36, 0x0, (int)&rmesa->vb.counter);
- FIXUP(dfn->code, 46, 0x0, (int)&rmesa->vb.dmaptr);
- FIXUP(dfn->code, 51, 0x0, (int)&rmesa->vb.counter);
- FIXUP(dfn->code, 60, 0x0, (int)&rmesa->vb.notify);
- break;
- }
- case 6: {
-
- DFN ( _x86_Vertex3f_6, rmesa->vb.dfn_cache.Vertex3f );
- FIXUP(dfn->code, 3, 0x0, (int)&rmesa->vb.dmaptr);
- FIXUP(dfn->code, 28, 0x0, (int)&rmesa->vb.vertex[3]);
- FIXUP(dfn->code, 34, 0x0, (int)&rmesa->vb.vertex[4]);
- FIXUP(dfn->code, 40, 0x0, (int)&rmesa->vb.vertex[5]);
- FIXUP(dfn->code, 57, 0x0, (int)&rmesa->vb.counter);
- FIXUP(dfn->code, 63, 0x0, (int)&rmesa->vb.dmaptr);
- FIXUP(dfn->code, 70, 0x0, (int)&rmesa->vb.counter);
- FIXUP(dfn->code, 79, 0x0, (int)&rmesa->vb.notify);
- break;
- }
- default: {
-
- DFN ( _x86_Vertex3f, rmesa->vb.dfn_cache.Vertex3f );
- FIXUP(dfn->code, 3, 0x0, (int)&rmesa->vb.vertex[3]);
- FIXUP(dfn->code, 9, 0x0, (int)&rmesa->vb.dmaptr);
- FIXUP(dfn->code, 37, 0x0, rmesa->vb.vertex_size-3);
- FIXUP(dfn->code, 44, 0x0, (int)&rmesa->vb.counter);
- FIXUP(dfn->code, 50, 0x0, (int)&rmesa->vb.dmaptr);
- FIXUP(dfn->code, 56, 0x0, (int)&rmesa->vb.counter);
- FIXUP(dfn->code, 67, 0x0, (int)&rmesa->vb.notify);
- break;
- }
- }
-
- return dfn;
-}
-
-
-
-struct dynfn *radeon_makeX86Vertex3fv( GLcontext *ctx, int key )
-{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (RADEON_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x %d\n", __FUNCTION__, key, rmesa->vb.vertex_size );
-
- switch (rmesa->vb.vertex_size) {
- case 6: {
-
- DFN ( _x86_Vertex3fv_6, rmesa->vb.dfn_cache.Vertex3fv );
- FIXUP(dfn->code, 1, 0x00000000, (int)&rmesa->vb.dmaptr);
- FIXUP(dfn->code, 27, 0x0000001c, (int)&rmesa->vb.vertex[3]);
- FIXUP(dfn->code, 33, 0x00000020, (int)&rmesa->vb.vertex[4]);
- FIXUP(dfn->code, 45, 0x00000024, (int)&rmesa->vb.vertex[5]);
- FIXUP(dfn->code, 56, 0x00000000, (int)&rmesa->vb.dmaptr);
- FIXUP(dfn->code, 61, 0x00000004, (int)&rmesa->vb.counter);
- FIXUP(dfn->code, 67, 0x00000004, (int)&rmesa->vb.counter);
- FIXUP(dfn->code, 76, 0x00000008, (int)&rmesa->vb.notify);
- break;
- }
-
-
- case 8: {
-
- DFN ( _x86_Vertex3fv_8, rmesa->vb.dfn_cache.Vertex3fv );
- FIXUP(dfn->code, 1, 0x00000000, (int)&rmesa->vb.dmaptr);
- FIXUP(dfn->code, 27, 0x0000001c, (int)&rmesa->vb.vertex[3]);
- FIXUP(dfn->code, 33, 0x00000020, (int)&rmesa->vb.vertex[4]);
- FIXUP(dfn->code, 45, 0x0000001c, (int)&rmesa->vb.vertex[5]);
- FIXUP(dfn->code, 51, 0x00000020, (int)&rmesa->vb.vertex[6]);
- FIXUP(dfn->code, 63, 0x00000024, (int)&rmesa->vb.vertex[7]);
- FIXUP(dfn->code, 74, 0x00000000, (int)&rmesa->vb.dmaptr);
- FIXUP(dfn->code, 79, 0x00000004, (int)&rmesa->vb.counter);
- FIXUP(dfn->code, 85, 0x00000004, (int)&rmesa->vb.counter);
- FIXUP(dfn->code, 94, 0x00000008, (int)&rmesa->vb.notify);
- break;
- }
-
-
-
- default: {
-
- DFN ( _x86_Vertex3fv, rmesa->vb.dfn_cache.Vertex3fv );
- FIXUP(dfn->code, 8, 0x01010101, (int)&rmesa->vb.dmaptr);
- FIXUP(dfn->code, 32, 0x00000006, rmesa->vb.vertex_size-3);
- FIXUP(dfn->code, 37, 0x00000058, (int)&rmesa->vb.vertex[3]);
- FIXUP(dfn->code, 45, 0x01010101, (int)&rmesa->vb.dmaptr);
- FIXUP(dfn->code, 50, 0x02020202, (int)&rmesa->vb.counter);
- FIXUP(dfn->code, 58, 0x02020202, (int)&rmesa->vb.counter);
- FIXUP(dfn->code, 67, 0x0, (int)&rmesa->vb.notify);
- break;
- }
- }
-
- return dfn;
-}
-
-static struct dynfn *
-radeon_makeX86Attribute2fv( struct dynfn * cache, int key,
- const char * name, void * dest )
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (RADEON_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x\n", name, key );
-
- DFN ( _x86_Attribute2fv, (*cache) );
- FIXUP(dfn->code, 11, 0x0, (int)dest);
- FIXUP(dfn->code, 16, 0x4, 4+(int)dest);
-
- return dfn;
-}
-
-static struct dynfn *
-radeon_makeX86Attribute2f( struct dynfn * cache, int key,
- const char * name, void * dest )
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (RADEON_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x\n", name, key );
-
- DFN ( _x86_Attribute2f, (*cache) );
- FIXUP(dfn->code, 1, 0x0, (int)dest);
-
- return dfn;
-}
-
-
-static struct dynfn *
-radeon_makeX86Attribute3fv( struct dynfn * cache, int key,
- const char * name, void * dest )
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (RADEON_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x\n", name, key );
-
- DFN ( _x86_Attribute3fv, (*cache) );
- FIXUP(dfn->code, 14, 0x0, (int)dest);
- FIXUP(dfn->code, 20, 0x4, 4+(int)dest);
- FIXUP(dfn->code, 25, 0x8, 8+(int)dest);
-
- return dfn;
-}
-
-static struct dynfn *
-radeon_makeX86Attribute3f( struct dynfn * cache, int key,
- const char * name, void * dest )
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (RADEON_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x\n", name, key );
-
- DFN ( _x86_Attribute3f, (*cache) );
- FIXUP(dfn->code, 14, 0x0, (int)dest);
- FIXUP(dfn->code, 20, 0x4, 4+(int)dest);
- FIXUP(dfn->code, 25, 0x8, 8+(int)dest);
-
- return dfn;
-}
-
-struct dynfn *radeon_makeX86Normal3fv( GLcontext *ctx, int key )
-{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-
- return radeon_makeX86Attribute3fv( & rmesa->vb.dfn_cache.Normal3fv, key,
- __FUNCTION__, rmesa->vb.normalptr );
-}
-
-struct dynfn *radeon_makeX86Normal3f( GLcontext *ctx, int key )
-{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-
- return radeon_makeX86Attribute3f( & rmesa->vb.dfn_cache.Normal3f, key,
- __FUNCTION__, rmesa->vb.normalptr );
-}
-
-struct dynfn *radeon_makeX86Color4ubv( GLcontext *ctx, int key )
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-
-
- if (RADEON_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
-
- if (key & RADEON_CP_VC_FRMT_PKCOLOR) {
- DFN ( _x86_Color4ubv_ub, rmesa->vb.dfn_cache.Color4ubv);
- FIXUP(dfn->code, 5, 0x12345678, (int)rmesa->vb.colorptr);
- return dfn;
- }
- else {
-
- DFN ( _x86_Color4ubv_4f, rmesa->vb.dfn_cache.Color4ubv);
- FIXUP(dfn->code, 2, 0x00000000, (int)_mesa_ubyte_to_float_color_tab);
- FIXUP(dfn->code, 27, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr);
- FIXUP(dfn->code, 33, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr+4);
- FIXUP(dfn->code, 55, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr+8);
- FIXUP(dfn->code, 61, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr+12);
- return dfn;
- }
-}
-
-struct dynfn *radeon_makeX86Color4ub( GLcontext *ctx, int key )
-{
- if (RADEON_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
-
- if (key & RADEON_CP_VC_FRMT_PKCOLOR) {
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-
- DFN ( _x86_Color4ub_ub, rmesa->vb.dfn_cache.Color4ub );
- FIXUP(dfn->code, 18, 0x0, (int)rmesa->vb.colorptr);
- FIXUP(dfn->code, 24, 0x0, (int)rmesa->vb.colorptr+1);
- FIXUP(dfn->code, 30, 0x0, (int)rmesa->vb.colorptr+2);
- FIXUP(dfn->code, 36, 0x0, (int)rmesa->vb.colorptr+3);
- return dfn;
- }
- else
- return NULL;
-}
-
-
-struct dynfn *radeon_makeX86Color3fv( GLcontext *ctx, int key )
-{
- if (key & (RADEON_CP_VC_FRMT_PKCOLOR|RADEON_CP_VC_FRMT_FPALPHA))
- return NULL;
- else
- {
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-
- return radeon_makeX86Attribute3fv( & rmesa->vb.dfn_cache.Color3fv, key,
- __FUNCTION__, rmesa->vb.floatcolorptr );
- }
-}
-
-struct dynfn *radeon_makeX86Color3f( GLcontext *ctx, int key )
-{
- if (key & (RADEON_CP_VC_FRMT_PKCOLOR|RADEON_CP_VC_FRMT_FPALPHA))
- return NULL;
- else
- {
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-
- return radeon_makeX86Attribute3f( & rmesa->vb.dfn_cache.Color3f, key,
- __FUNCTION__, rmesa->vb.floatcolorptr );
- }
-}
-
-
-
-struct dynfn *radeon_makeX86TexCoord2fv( GLcontext *ctx, int key )
-{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-
- return radeon_makeX86Attribute2fv( & rmesa->vb.dfn_cache.TexCoord2fv, key,
- __FUNCTION__, rmesa->vb.texcoordptr[0] );
-}
-
-struct dynfn *radeon_makeX86TexCoord2f( GLcontext *ctx, int key )
-{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-
- return radeon_makeX86Attribute2f( & rmesa->vb.dfn_cache.TexCoord2f, key,
- __FUNCTION__, rmesa->vb.texcoordptr[0] );
-}
-
-#if 0 /* Temporarily disabled - probably needs adjustments for more than 2 tex units -rs */
-struct dynfn *radeon_makeX86MultiTexCoord2fvARB( GLcontext *ctx, int key )
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-
- if (RADEON_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
-
- if ((key & (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) ==
- (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) {
- DFN ( _x86_MultiTexCoord2fv, rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
- FIXUP(dfn->code, 21, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]);
- FIXUP(dfn->code, 27, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]+4);
- } else {
- DFN ( _x86_MultiTexCoord2fv_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
- FIXUP(dfn->code, 14, 0x0, (int)rmesa->vb.texcoordptr);
- }
- return dfn;
-}
-
-struct dynfn *radeon_makeX86MultiTexCoord2fARB( GLcontext *ctx,
- int key )
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-
- if (RADEON_DEBUG & DEBUG_CODEGEN)
- fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
-
- if ((key & (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) ==
- (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) {
- DFN ( _x86_MultiTexCoord2f, rmesa->vb.dfn_cache.MultiTexCoord2fARB );
- FIXUP(dfn->code, 20, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]);
- FIXUP(dfn->code, 26, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]+4);
- }
- else {
- /* Note: this might get generated multiple times, even though the
- * actual emitted code is the same.
- */
- DFN ( _x86_MultiTexCoord2f_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB );
- FIXUP(dfn->code, 18, 0x0, (int)rmesa->vb.texcoordptr);
- }
- return dfn;
-}
-#endif
-
-void radeonInitX86Codegen( struct dfn_generators *gen )
-{
- gen->Vertex3f = radeon_makeX86Vertex3f;
- gen->Vertex3fv = radeon_makeX86Vertex3fv;
- gen->Color4ub = radeon_makeX86Color4ub; /* PKCOLOR only */
- gen->Color4ubv = radeon_makeX86Color4ubv; /* PKCOLOR only */
- gen->Normal3f = radeon_makeX86Normal3f;
- gen->Normal3fv = radeon_makeX86Normal3fv;
- gen->TexCoord2f = radeon_makeX86TexCoord2f;
- gen->TexCoord2fv = radeon_makeX86TexCoord2fv;
-#if 0 /* Temporarily disabled - probably needs adjustments for more than 2 tex units -rs */
- gen->MultiTexCoord2fARB = radeon_makeX86MultiTexCoord2fARB;
- gen->MultiTexCoord2fvARB = radeon_makeX86MultiTexCoord2fvARB;
-#endif
- gen->Color3f = radeon_makeX86Color3f;
- gen->Color3fv = radeon_makeX86Color3fv;
-
- /* Not done:
- */
-/* gen->Vertex2f = radeon_makeX86Vertex2f; */
-/* gen->Vertex2fv = radeon_makeX86Vertex2fv; */
-/* gen->Color3ub = radeon_makeX86Color3ub; */
-/* gen->Color3ubv = radeon_makeX86Color3ubv; */
-/* gen->Color4f = radeon_makeX86Color4f; */
-/* gen->Color4fv = radeon_makeX86Color4fv; */
-/* gen->TexCoord1f = radeon_makeX86TexCoord1f; */
-/* gen->TexCoord1fv = radeon_makeX86TexCoord1fv; */
-/* gen->MultiTexCoord1fARB = radeon_makeX86MultiTexCoord1fARB; */
-/* gen->MultiTexCoord1fvARB = radeon_makeX86MultiTexCoord1fvARB; */
-}
-
-
-#else
-
-void radeonInitX86Codegen( struct dfn_generators *gen )
-{
- (void) gen;
-}
-
-#endif
diff --git a/src/mesa/drivers/dri/radeon/radeon_vtxtmp_x86.S b/src/mesa/drivers/dri/radeon/radeon_vtxtmp_x86.S
deleted file mode 100644
index 1b433491aa8..00000000000
--- a/src/mesa/drivers/dri/radeon/radeon_vtxtmp_x86.S
+++ /dev/null
@@ -1,498 +0,0 @@
-/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxtmp_x86.S,v 1.1 2002/10/30 12:51:58 alanh Exp $ */
-/**************************************************************************
-
-Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas.
-
-All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-on the rights to use, copy, modify, merge, publish, distribute, sub
-license, and/or sell copies of the Software, and to permit persons to whom
-the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice (including the next
-paragraph) shall be included in all copies or substantial portions of the
-Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
-ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-#define GLOBL( x ) \
-.globl x; \
-x:
-
-.data
-.align 4
-
-/*
- vertex 3f vertex size 4
-*/
-
-GLOBL ( _x86_Vertex3f_4 )
- movl (0), %ecx
- movl 4(%esp), %eax
- movl 8(%esp), %edx
- movl %eax, (%ecx)
- movl %edx, 4(%ecx)
- movl 12(%esp), %eax
- movl (0), %edx
- movl %eax, 8(%ecx)
- movl %edx, 12(%ecx)
- movl (0), %eax
- addl $16, %ecx
- dec %eax
- movl %ecx, (0)
- movl %eax, (0)
- je .1
- ret
-.1: jmp *0
-
-GLOBL ( _x86_Vertex3f_4_end )
-
-/*
- vertex 3f vertex size 6
-*/
-GLOBL ( _x86_Vertex3f_6 )
- push %edi
- movl (0), %edi
- movl 8(%esp), %eax
- movl 12(%esp), %edx
- movl 16(%esp), %ecx
- movl %eax, (%edi)
- movl %edx, 4(%edi)
- movl %ecx, 8(%edi)
- movl (0), %eax
- movl (0), %edx
- movl (0), %ecx
- movl %eax, 12(%edi)
- movl %edx, 16(%edi)
- movl %ecx, 20(%edi)
- addl $24, %edi
- movl (0), %eax
- movl %edi, (0)
- dec %eax
- pop %edi
- movl %eax, (0)
- je .2
- ret
-.2: jmp *0
-GLOBL ( _x86_Vertex3f_6_end )
-/*
- vertex 3f generic size
-*/
-GLOBL ( _x86_Vertex3f )
- push %edi
- push %esi
- movl $0, %esi
- movl (0), %edi
- movl 12(%esp), %eax
- movl 16(%esp), %edx
- movl 20(%esp), %ecx
- movl %eax, (%edi)
- movl %edx, 4(%edi)
- movl %ecx, 8(%edi)
- addl $12, %edi
- movl $0, %ecx
- repz
- movsl %ds:(%esi), %es:(%edi)
- movl (0), %eax
- movl %edi, (0)
- dec %eax
- movl %eax, (0)
- pop %esi
- pop %edi
- je .3
- ret
-.3: jmp *0
-
-GLOBL ( _x86_Vertex3f_end )
-
-/*
- Vertex 3fv vertex size 6
-*/
-GLOBL ( _x86_Vertex3fv_6 )
- movl (0), %eax
- movl 4(%esp), %ecx
- movl (%ecx), %edx
- movl %edx, (%eax)
- movl 4(%ecx), %edx
- movl 8(%ecx), %ecx
- movl %edx, 4(%eax)
- movl %ecx, 8(%eax)
- movl (28), %edx
- movl (32), %ecx
- movl %edx, 12(%eax)
- movl %ecx, 16(%eax)
- movl (36), %edx
- movl %edx, 20(%eax)
- addl $24, %eax
- movl %eax, 0
- movl 4, %eax
- dec %eax
- movl %eax, 4
- je .4
- ret
-.4: jmp *8
-
-GLOBL ( _x86_Vertex3fv_6_end )
-
-/*
- Vertex 3fv vertex size 8
-*/
-GLOBL ( _x86_Vertex3fv_8 )
- movl (0), %eax
- movl 4(%esp), %ecx
- movl (%ecx), %edx
- movl %edx ,(%eax)
- movl 4(%ecx) ,%edx
- movl 8(%ecx) ,%ecx
- movl %edx, 4(%eax)
- movl %ecx, 8(%eax)
- movl (28), %edx
- movl (32), %ecx
- movl %edx, 12(%eax)
- movl %ecx, 16(%eax)
- movl (28), %edx
- movl (32), %ecx
- movl %edx, 20(%eax)
- movl %ecx, 24(%eax)
- movl (36), %edx
- movl %edx, 28(%eax)
- addl $32, %eax
- movl %eax, (0)
- movl 4, %eax
- dec %eax
- movl %eax, (4)
- je .5
- ret
-.5: jmp *8
-
-GLOBL ( _x86_Vertex3fv_8_end )
-
-/*
- Vertex 3fv generic vertex size
-*/
-GLOBL ( _x86_Vertex3fv )
- movl 4(%esp), %edx
- push %edi
- push %esi
- movl (0x1010101), %edi
- movl (%edx), %eax
- movl 4(%edx), %ecx
- movl 8(%edx), %esi
- movl %eax, (%edi)
- movl %ecx, 4(%edi)
- movl %esi, 8(%edi)
- addl $12, %edi
- movl $6, %ecx
- movl $0x58, %esi
- repz
- movsl %ds:(%esi), %es:(%edi)
- movl %edi, (0x1010101)
- movl (0x2020202), %eax
- pop %esi
- pop %edi
- dec %eax
- movl %eax, (0x2020202)
- je .6
- ret
-.6: jmp *0
-GLOBL ( _x86_Vertex3fv_end )
-
-
-/**
- * Generic handler for 2 float format data. This can be used for
- * TexCoord2f and possibly other functions.
- */
-
-GLOBL ( _x86_Attribute2f )
- movl $0x0, %edx
- movl 4(%esp), %eax
- movl 8(%esp), %ecx
- movl %eax, (%edx)
- movl %ecx, 4(%edx)
- ret
-GLOBL ( _x86_Attribute2f_end )
-
-
-/**
- * Generic handler for 2 float vector format data. This can be used for
- * TexCoord2fv and possibly other functions.
- */
-
-GLOBL( _x86_Attribute2fv)
- movl 4(%esp), %eax /* load 'v' off stack */
- movl (%eax), %ecx /* load v[0] */
- movl 4(%eax), %eax /* load v[1] */
- movl %ecx, 0 /* store v[0] to current vertex */
- movl %eax, 4 /* store v[1] to current vertex */
- ret
-GLOBL ( _x86_Attribute2fv_end )
-
-
-/**
- * Generic handler for 3 float format data. This can be used for
- * Normal3f, Color3f (when the color target is also float), or
- * TexCoord3f.
- */
-
-GLOBL ( _x86_Attribute3f )
- movl 4(%esp), %ecx
- movl 8(%esp), %edx
- movl 12(%esp), %eax
- movl %ecx, 0
- movl %edx, 4
- movl %eax, 8
- ret
-GLOBL ( _x86_Attribute3f_end )
-
-/**
- * Generic handler for 3 float vector format data. This can be used for
- * Normal3f, Color3f (when the color target is also float), or
- * TexCoord3f.
- */
-
-GLOBL( _x86_Attribute3fv)
- movl 4(%esp), %eax /* load 'v' off stack */
- movl (%eax), %ecx /* load v[0] */
- movl 4(%eax), %edx /* load v[1] */
- movl 8(%eax), %eax /* load v[2] */
- movl %ecx, 0 /* store v[0] to current vertex */
- movl %edx, 4 /* store v[1] to current vertex */
- movl %eax, 8 /* store v[2] to current vertex */
- ret
-GLOBL ( _x86_Attribute3fv_end )
-
-
-/*
- Color 4ubv_ub
-*/
-GLOBL ( _x86_Color4ubv_ub )
- movl 4(%esp), %eax
- movl $0x12345678, %edx
- movl (%eax), %eax
- movl %eax, (%edx)
- ret
-GLOBL ( _x86_Color4ubv_ub_end )
-
-/*
- Color 4ubv 4f
-*/
-GLOBL ( _x86_Color4ubv_4f )
- push %ebx
- movl $0, %edx
- xor %eax, %eax
- xor %ecx, %ecx
- movl 8(%esp), %ebx
- movl (%ebx), %ebx
- mov %bl, %al
- mov %bh, %cl
- movl (%edx,%eax,4),%eax
- movl (%edx,%ecx,4),%ecx
- movl %eax, (0xdeadbeaf)
- movl %ecx, (0xdeadbeaf)
- xor %eax, %eax
- xor %ecx, %ecx
- shr $16, %ebx
- mov %bl, %al
- mov %bh, %cl
- movl (%edx,%eax,4), %eax
- movl (%edx,%ecx,4), %ecx
- movl %eax, (0xdeadbeaf)
- movl %ecx, (0xdeadbeaf)
- pop %ebx
- ret
-GLOBL ( _x86_Color4ubv_4f_end )
-
-/*
-
- Color4ub_ub
-*/
-GLOBL( _x86_Color4ub_ub )
- push %ebx
- movl 8(%esp), %eax
- movl 12(%esp), %edx
- movl 16(%esp), %ecx
- movl 20(%esp), %ebx
- mov %al, (0)
- mov %dl, (0)
- mov %cl, (0)
- mov %bl, (0)
- pop %ebx
- ret
-GLOBL( _x86_Color4ub_ub_end )
-
-
-/*
- MultiTexCoord2fv st0/st1
-*/
-GLOBL( _x86_MultiTexCoord2fv )
- movl 4(%esp), %eax
- movl 8(%esp), %ecx
- and $3, %eax
- movl (%ecx), %edx
- shl $3, %eax
- movl 4(%ecx), %ecx
- movl %edx, 0xdeadbeef(%eax)
- movl %ecx, 0xdeadbeef(%eax)
- ret
-GLOBL( _x86_MultiTexCoord2fv_end )
-
-/*
- MultiTexCoord2fv
-*/
-
-GLOBL( _x86_MultiTexCoord2fv_2 )
- movl 4(%esp,1), %eax
- movl 8(%esp,1), %ecx
- and $3, %eax
- movl 0(,%eax,4), %edx
- movl (%ecx), %eax
- movl %eax, (%edx)
- movl 4(%ecx), %eax
- movl %eax, 4(%edx)
- ret
-GLOBL( _x86_MultiTexCoord2fv_2_end )
-
-/*
- MultiTexCoord2f st0/st1
-*/
-GLOBL( _x86_MultiTexCoord2f )
- movl 4(%esp), %eax
- movl 8(%esp), %edx
- movl 12(%esp), %ecx
- and $3, %eax
- shl $3, %eax
- movl %edx, 0xdeadbeef(%eax)
- movl %ecx, 0xdeadbeef(%eax)
- ret
-GLOBL( _x86_MultiTexCoord2f_end )
-
-/*
- MultiTexCoord2f
-*/
-GLOBL( _x86_MultiTexCoord2f_2 )
- movl 4(%esp), %eax
- movl 8(%esp), %edx
- movl 12(%esp,1), %ecx
- and $3,%eax
- movl 0(,%eax,4), %eax
- movl %edx, (%eax)
- movl %ecx, 4(%eax)
- ret
-GLOBL( _x86_MultiTexCoord2f_2_end )
-
-#if defined(USE_SSE_ASM)
-/**
- * This can be used as a template for either Color3fv (when the color
- * target is also a 3f) or Normal3fv.
- */
-
-GLOBL( _sse_Attribute3fv )
- movl 4(%esp), %eax
- movlps (%eax), %xmm0
- movl 8(%eax), %eax
- movlps %xmm0, 0
- movl %eax, 8
- ret
-GLOBL( _sse_Attribute3fv_end )
-
-/**
- * This can be used as a template for either Color3f (when the color
- * target is also a 3f) or Normal3f.
- */
-
-GLOBL( _sse_Attribute3f )
- movlps 4(%esp), %xmm0
- movl 12(%esp), %eax
- movlps %xmm0, 0
- movl %eax, 8
- ret
-GLOBL( _sse_Attribute3f_end )
-
-
-/**
- * Generic handler for 2 float vector format data. This can be used for
- * TexCoord2fv and possibly other functions.
- */
-
-GLOBL( _sse_Attribute2fv )
- movl 4(%esp), %eax
- movlps (%eax), %xmm0
- movlps %xmm0, 0
- ret
-GLOBL( _sse_Attribute2fv_end )
-
-
-/**
- * Generic handler for 2 float format data. This can be used for
- * TexCoord2f and possibly other functions.
- */
-
-GLOBL( _sse_Attribute2f )
- movlps 4(%esp), %xmm0
- movlps %xmm0, 0
- ret
-GLOBL( _sse_Attribute2f_end )
-
-/*
- MultiTexCoord2fv st0/st1
-*/
-GLOBL( _sse_MultiTexCoord2fv )
- movl 4(%esp), %eax
- movl 8(%esp), %ecx
- and $3, %eax
- movlps (%ecx), %xmm0
- movlps %xmm0, 0xdeadbeef(,%eax,8)
- ret
-GLOBL( _sse_MultiTexCoord2fv_end )
-
-/*
- MultiTexCoord2fv
-*/
-GLOBL( _sse_MultiTexCoord2fv_2 )
- movl 4(%esp), %eax
- movl 8(%esp), %ecx
- and $3, %eax
- movl 0(,%eax,4), %edx
- movlps (%ecx), %xmm0
- movlps %xmm0, (%edx)
- ret
-GLOBL( _sse_MultiTexCoord2fv_2_end )
-
-/*
- MultiTexCoord2f st0/st1
-*/
-GLOBL( _sse_MultiTexCoord2f )
- movl 4(%esp), %eax
- and $3, %eax
- movlps 8(%esp), %xmm0
- movlps %xmm0, 0xdeadbeef(,%eax,8)
- ret
-GLOBL( _sse_MultiTexCoord2f_end )
-
-/*
- MultiTexCoord2f
-*/
-GLOBL( _sse_MultiTexCoord2f_2 )
- movl 4(%esp), %eax
- movlps 8(%esp), %xmm0
- and $3,%eax
- movl 0(,%eax,4), %eax
- movlps %xmm0, (%eax)
- ret
-GLOBL( _sse_MultiTexCoord2f_2_end )
-#endif
-
-#if defined (__ELF__) && defined (__linux__)
- .section .note.GNU-stack,"",%progbits
-#endif
diff --git a/src/mesa/drivers/dri/s3v/s3v_context.c b/src/mesa/drivers/dri/s3v/s3v_context.c
index 7b0aa0daee0..2d2f704ad77 100644
--- a/src/mesa/drivers/dri/s3v/s3v_context.c
+++ b/src/mesa/drivers/dri/s3v/s3v_context.c
@@ -6,7 +6,7 @@
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
@@ -139,7 +139,7 @@ GLboolean s3vCreateContext(const __GLcontextModes *glVisual,
/* Initialize the software rasterizer and helper modules.
*/
_swrast_CreateContext( ctx );
- _ac_CreateContext( ctx );
+ _vbo_CreateContext( ctx );
_tnl_CreateContext( ctx );
_swsetup_CreateContext( ctx );
diff --git a/src/mesa/drivers/dri/s3v/s3v_state.c b/src/mesa/drivers/dri/s3v/s3v_state.c
index fcea901c1c9..b86b618c117 100644
--- a/src/mesa/drivers/dri/s3v/s3v_state.c
+++ b/src/mesa/drivers/dri/s3v/s3v_state.c
@@ -10,7 +10,7 @@
#include "colormac.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
/* #define DEBUG(str) printf str */
@@ -825,7 +825,7 @@ static void s3vDDUpdateState( GLcontext *ctx, GLuint new_state )
{
_swrast_InvalidateState( ctx, new_state );
_swsetup_InvalidateState( ctx, new_state );
- _ac_InvalidateState( ctx, new_state );
+ _vbo_InvalidateState( ctx, new_state );
_tnl_InvalidateState( ctx, new_state );
S3V_CONTEXT(ctx)->new_gl_state |= new_state;
}
diff --git a/src/mesa/drivers/dri/s3v/s3v_xmesa.c b/src/mesa/drivers/dri/s3v/s3v_xmesa.c
index 533424cdeab..c451f7452bf 100644
--- a/src/mesa/drivers/dri/s3v/s3v_xmesa.c
+++ b/src/mesa/drivers/dri/s3v/s3v_xmesa.c
@@ -13,7 +13,7 @@
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
/* #define DEBUG(str) printf str */
@@ -38,7 +38,7 @@ s3vDestroyContext(__DRIcontextPrivate *driContextPriv)
if (vmesa) {
_swsetup_DestroyContext( vmesa->glCtx );
_tnl_DestroyContext( vmesa->glCtx );
- _ac_DestroyContext( vmesa->glCtx );
+ _vbo_DestroyContext( vmesa->glCtx );
_swrast_DestroyContext( vmesa->glCtx );
s3vFreeVB( vmesa->glCtx );
diff --git a/src/mesa/drivers/dri/savage/savage_xmesa.c b/src/mesa/drivers/dri/savage/savage_xmesa.c
index f51e321a4a6..ad79b9235c1 100644
--- a/src/mesa/drivers/dri/savage/savage_xmesa.c
+++ b/src/mesa/drivers/dri/savage/savage_xmesa.c
@@ -40,7 +40,7 @@
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/t_pipeline.h"
@@ -509,7 +509,7 @@ savageCreateContext( const __GLcontextModes *mesaVis,
/* Initialize the software rasterizer and helper modules.
*/
_swrast_CreateContext( ctx );
- _ac_CreateContext( ctx );
+ _vbo_CreateContext( ctx );
_tnl_CreateContext( ctx );
_swsetup_CreateContext( ctx );
@@ -599,7 +599,7 @@ savageDestroyContext(__DRIcontextPrivate *driContextPriv)
_swsetup_DestroyContext(imesa->glCtx );
_tnl_DestroyContext( imesa->glCtx );
- _ac_DestroyContext( imesa->glCtx );
+ _vbo_DestroyContext( imesa->glCtx );
_swrast_DestroyContext( imesa->glCtx );
/* free the Mesa context */
diff --git a/src/mesa/drivers/dri/savage/savagestate.c b/src/mesa/drivers/dri/savage/savagestate.c
index 2f20dc23b6e..741a9dda4f7 100644
--- a/src/mesa/drivers/dri/savage/savagestate.c
+++ b/src/mesa/drivers/dri/savage/savagestate.c
@@ -41,7 +41,7 @@
#include "savage_bci.h"
#include "swrast/swrast.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "swrast_setup/swrast_setup.h"
@@ -1673,7 +1673,7 @@ static void savageDDInvalidateState( GLcontext *ctx, GLuint new_state )
{
_swrast_InvalidateState( ctx, new_state );
_swsetup_InvalidateState( ctx, new_state );
- _ac_InvalidateState( ctx, new_state );
+ _vbo_InvalidateState( ctx, new_state );
_tnl_InvalidateState( ctx, new_state );
SAVAGE_CONTEXT(ctx)->new_gl_state |= new_state;
}
diff --git a/src/mesa/drivers/dri/sis/sis6326_state.c b/src/mesa/drivers/dri/sis/sis6326_state.c
index 6bc2c6de3bf..08402fb3e2a 100644
--- a/src/mesa/drivers/dri/sis/sis6326_state.c
+++ b/src/mesa/drivers/dri/sis/sis6326_state.c
@@ -37,7 +37,7 @@
#include "enums.h"
#include "colormac.h"
#include "swrast/swrast.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "swrast_setup/swrast_setup.h"
@@ -645,7 +645,7 @@ sis6326DDInvalidateState( GLcontext *ctx, GLuint new_state )
_swrast_InvalidateState( ctx, new_state );
_swsetup_InvalidateState( ctx, new_state );
- _ac_InvalidateState( ctx, new_state );
+ _vbo_InvalidateState( ctx, new_state );
_tnl_InvalidateState( ctx, new_state );
smesa->NewGLState |= new_state;
}
diff --git a/src/mesa/drivers/dri/sis/sis_context.c b/src/mesa/drivers/dri/sis/sis_context.c
index a300a080ec0..89b81da347a 100644
--- a/src/mesa/drivers/dri/sis/sis_context.c
+++ b/src/mesa/drivers/dri/sis/sis_context.c
@@ -53,7 +53,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
@@ -306,7 +306,7 @@ sisCreateContext( const __GLcontextModes *glVisual,
/* Initialize the software rasterizer and helper modules.
*/
_swrast_CreateContext( ctx );
- _ac_CreateContext( ctx );
+ _vbo_CreateContext( ctx );
_tnl_CreateContext( ctx );
_swsetup_CreateContext( ctx );
@@ -353,7 +353,7 @@ sisDestroyContext ( __DRIcontextPrivate *driContextPriv )
if ( smesa != NULL ) {
_swsetup_DestroyContext( smesa->glCtx );
_tnl_DestroyContext( smesa->glCtx );
- _ac_DestroyContext( smesa->glCtx );
+ _vbo_DestroyContext( smesa->glCtx );
_swrast_DestroyContext( smesa->glCtx );
if (smesa->using_agp)
diff --git a/src/mesa/drivers/dri/sis/sis_state.c b/src/mesa/drivers/dri/sis/sis_state.c
index 2a10a5fbf62..33a2f089b82 100644
--- a/src/mesa/drivers/dri/sis/sis_state.c
+++ b/src/mesa/drivers/dri/sis/sis_state.c
@@ -42,7 +42,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "enums.h"
#include "colormac.h"
#include "swrast/swrast.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "swrast_setup/swrast_setup.h"
@@ -707,7 +707,7 @@ sisDDInvalidateState( GLcontext *ctx, GLuint new_state )
_swrast_InvalidateState( ctx, new_state );
_swsetup_InvalidateState( ctx, new_state );
- _ac_InvalidateState( ctx, new_state );
+ _vbo_InvalidateState( ctx, new_state );
_tnl_InvalidateState( ctx, new_state );
smesa->NewGLState |= new_state;
}
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_context.c b/src/mesa/drivers/dri/tdfx/tdfx_context.c
index bd9dade89b5..a9163f49a8f 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_context.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_context.c
@@ -49,7 +49,7 @@
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
@@ -328,7 +328,7 @@ GLboolean tdfxCreateContext( const __GLcontextModes *mesaVis,
/* Initialize the software rasterizer and helper modules.
*/
_swrast_CreateContext( ctx );
- _ac_CreateContext( ctx );
+ _vbo_CreateContext( ctx );
_tnl_CreateContext( ctx );
_swsetup_CreateContext( ctx );
@@ -609,7 +609,7 @@ tdfxDestroyContext( __DRIcontextPrivate *driContextPriv )
_swsetup_DestroyContext( fxMesa->glCtx );
_tnl_DestroyContext( fxMesa->glCtx );
- _ac_DestroyContext( fxMesa->glCtx );
+ _vbo_DestroyContext( fxMesa->glCtx );
_swrast_DestroyContext( fxMesa->glCtx );
tdfxFreeVB( fxMesa->glCtx );
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_state.c b/src/mesa/drivers/dri/tdfx/tdfx_state.c
index 59e6549e5ef..42cb5dfaa38 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_state.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_state.c
@@ -46,7 +46,7 @@
#include "teximage.h"
#include "swrast/swrast.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
#include "swrast_setup/swrast_setup.h"
@@ -1234,7 +1234,7 @@ static void tdfxDDInvalidateState( GLcontext *ctx, GLuint new_state )
{
_swrast_InvalidateState( ctx, new_state );
_swsetup_InvalidateState( ctx, new_state );
- _ac_InvalidateState( ctx, new_state );
+ _vbo_InvalidateState( ctx, new_state );
_tnl_InvalidateState( ctx, new_state );
TDFX_CONTEXT(ctx)->new_gl_state |= new_state;
}
diff --git a/src/mesa/drivers/dri/trident/trident_context.c b/src/mesa/drivers/dri/trident/trident_context.c
index d3806586475..dbbd1ac0c69 100644
--- a/src/mesa/drivers/dri/trident/trident_context.c
+++ b/src/mesa/drivers/dri/trident/trident_context.c
@@ -30,7 +30,7 @@
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
@@ -143,7 +143,7 @@ tridentCreateContext( const __GLcontextModes *glVisual,
/* Initialize the software rasterizer and helper modules.
*/
_swrast_CreateContext( ctx );
- _ac_CreateContext( ctx );
+ _vbo_CreateContext( ctx );
_tnl_CreateContext( ctx );
_swsetup_CreateContext( ctx );
@@ -183,7 +183,7 @@ tridentDestroyContext(__DRIcontextPrivate *driContextPriv)
if (tmesa) {
_swsetup_DestroyContext( tmesa->glCtx );
_tnl_DestroyContext( tmesa->glCtx );
- _ac_DestroyContext( tmesa->glCtx );
+ _vbo_DestroyContext( tmesa->glCtx );
_swrast_DestroyContext( tmesa->glCtx );
/* free the Mesa context */
diff --git a/src/mesa/drivers/dri/trident/trident_state.c b/src/mesa/drivers/dri/trident/trident_state.c
index 037cce5f862..5303bd422ed 100644
--- a/src/mesa/drivers/dri/trident/trident_state.c
+++ b/src/mesa/drivers/dri/trident/trident_state.c
@@ -26,7 +26,7 @@
*/
#include "trident_context.h"
#include "trident_lock.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
@@ -468,7 +468,7 @@ tridentDDUpdateState( GLcontext *ctx, GLuint new_state )
{
_swrast_InvalidateState( ctx, new_state );
_swsetup_InvalidateState( ctx, new_state );
- _ac_InvalidateState( ctx, new_state );
+ _vbo_InvalidateState( ctx, new_state );
_tnl_InvalidateState( ctx, new_state );
TRIDENT_CONTEXT(ctx)->new_gl_state |= new_state;
}
diff --git a/src/mesa/drivers/dri/unichrome/server/via_dri.c b/src/mesa/drivers/dri/unichrome/server/via_dri.c
index 2fe61e40390..6944bd66f9c 100644
--- a/src/mesa/drivers/dri/unichrome/server/via_dri.c
+++ b/src/mesa/drivers/dri/unichrome/server/via_dri.c
@@ -1179,6 +1179,7 @@ static int viaInitFBDev(DRIDriverContext *ctx)
pVia->Chipset = VIA_KM400;
break;
case PCI_CHIP_VT3204:
+ case PCI_CHIP_VT3344:
pVia->Chipset = VIA_K8M800;
break;
case PCI_CHIP_VT3259:
diff --git a/src/mesa/drivers/dri/unichrome/server/via_regs.h b/src/mesa/drivers/dri/unichrome/server/via_regs.h
index 5c5eecbe831..87e1e9daa92 100644
--- a/src/mesa/drivers/dri/unichrome/server/via_regs.h
+++ b/src/mesa/drivers/dri/unichrome/server/via_regs.h
@@ -44,6 +44,7 @@
#define PCI_CHIP_VT7205 0x7205
#define PCI_CHIP_VT3204 0x3108
#define PCI_CHIP_VT3259 0x3118
+#define PCI_CHIP_VT3344 0x3344
#define BIOS_BSIZE 1024
diff --git a/src/mesa/drivers/dri/unichrome/via_context.c b/src/mesa/drivers/dri/unichrome/via_context.c
index 49c24656551..bc5a414df60 100644
--- a/src/mesa/drivers/dri/unichrome/via_context.c
+++ b/src/mesa/drivers/dri/unichrome/via_context.c
@@ -42,7 +42,7 @@
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/t_pipeline.h"
@@ -583,7 +583,7 @@ viaCreateContext(const __GLcontextModes *visual,
/* Initialize the software rasterizer and helper modules.
*/
_swrast_CreateContext(ctx);
- _ac_CreateContext(ctx);
+ _vbo_CreateContext(ctx);
_tnl_CreateContext(ctx);
_swsetup_CreateContext(ctx);
@@ -708,7 +708,7 @@ viaDestroyContext(__DRIcontextPrivate *driContextPriv)
_swsetup_DestroyContext(vmesa->glCtx);
_tnl_DestroyContext(vmesa->glCtx);
- _ac_DestroyContext(vmesa->glCtx);
+ _vbo_DestroyContext(vmesa->glCtx);
_swrast_DestroyContext(vmesa->glCtx);
/* free the Mesa context */
_mesa_destroy_context(vmesa->glCtx);
diff --git a/src/mesa/drivers/dri/unichrome/via_state.c b/src/mesa/drivers/dri/unichrome/via_state.c
index 2c9cfca522e..30b9dc289a7 100644
--- a/src/mesa/drivers/dri/unichrome/via_state.c
+++ b/src/mesa/drivers/dri/unichrome/via_state.c
@@ -40,7 +40,7 @@
#include "via_3d_reg.h"
#include "swrast/swrast.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "swrast_setup/swrast_setup.h"
@@ -1507,7 +1507,7 @@ static void viaInvalidateState(GLcontext *ctx, GLuint newState)
_swrast_InvalidateState(ctx, newState);
_swsetup_InvalidateState(ctx, newState);
- _ac_InvalidateState(ctx, newState);
+ _vbo_InvalidateState(ctx, newState);
_tnl_InvalidateState(ctx, newState);
}